[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: system/1878: MTU problem when sending mail using postfix



On Thu, Jun 21, 2001 at 11:44:50AM -0400, Niels Provos wrote:
> Hi,
> 
> your fix is not complete.
> 
> tcp_mtudisc() just fixes up the TCP segment size based on interface MTU
> and route MTU.
> 
> You forgot about the part in ip_output(),  this is the corresponding
> code snip from FreeBSD:

Well, it's a bit late, ...

You're absolutely right ! I've tested this code and it works as
expected.

For Damien & Vincent, the right patch (if you didn't picket it
yourself from -current) is :

--- ip_output.c 2001/04/14 00:30:59     1.89
+++ ip_output.c 2001/06/24 11:11:08
@@ -630,6 +630,18 @@
         */
        if (ip->ip_off & IP_DF) {
                error = EMSGSIZE;
+               /*
+                * This case can happen if the user changed the MTU
+                * of an interface after enabling IP on it.  Because
+                * most netifs don't keep track of routes pointing to
+                * them, there is no way for one to update all its
+                * routes when the MTU is changed.
+                */
+               if ((ro->ro_rt->rt_flags & (RTF_UP | RTF_HOST))
+                   && !(ro->ro_rt->rt_rmx.rmx_locks & RTV_MTU)
+                   && (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu)) {
+                       ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu;
+               }
                ipstat.ips_cantfrag++;
                goto bad;
        }
--- tcp_output.c        2001/06/06 22:35:11     1.34.4.1
+++ tcp_output.c        2001/06/24 11:10:19
@@ -1081,6 +1081,16 @@
                        tcp_quench(tp->t_inpcb, 0);
                        return (0);
                }
+               if (error == EMSGSIZE) {
+                       /*
+                        * ip_output() will have already fixed the route
+                        * for us.  tcp_mtudisc() will, as its last action,
+                        * initiate retransmission, so it is important to
+                        * not do so here.
+                        */
+                       tcp_mtudisc(tp->t_inpcb, 0);
+                       return (0);
+               }
                if ((error == EHOSTUNREACH || error == ENETDOWN)
                    && TCPS_HAVERCVDSYN(tp->t_state)) {
                        tp->t_softerror = error;


-- 
Rémi