Index: ip_output.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v retrieving revision 1.229 diff -u -r1.229 ip_output.c --- ip_output.c 2004/08/27 15:39:34 1.229 +++ ip_output.c 2004/09/06 03:17:53 @@ -124,6 +124,7 @@ struct ifnet *ifp = NULL; /* keep compiler happy */ struct mbuf *m0; int hlen = sizeof (struct ip); + int mtu; int len, error = 0; struct sockaddr_in *dst = NULL; /* keep compiler happy */ struct in_ifaddr *ia = NULL; @@ -194,7 +195,7 @@ dst->sin_family != AF_INET || dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { RTFREE(ro->ro_rt); - ro->ro_rt = (struct rtentry *)0; + ro->ro_rt = (struct rtentry *)NULL; } #ifdef IPFIREWALL_FORWARD if (ro->ro_rt == NULL && fwd_tag == NULL) { @@ -252,6 +253,24 @@ else isbroadcast = in_broadcast(dst->sin_addr, ifp); } + /* + * Calculate MTU. If we have a route that is up, use that, + * otherwise use the interface's MTU. + */ + if (ro->ro_rt->rt_flags & (RTF_UP | RTF_HOST)) { + /* + * 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_rmx.rmx_mtu > ifp->if_mtu) + ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu; + mtu = ro->ro_rt->rt_rmx.rmx_mtu; + } else { + mtu = ifp->if_mtu; + } if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { struct in_multi *inm; @@ -370,10 +389,10 @@ */ #ifdef ALTQ if ((!ALTQ_IS_ENABLED(&ifp->if_snd)) && - ((ifp->if_snd.ifq_len + ip->ip_len / ifp->if_mtu + 1) >= + ((ifp->if_snd.ifq_len + ip->ip_len / mtu + 1) >= ifp->if_snd.ifq_maxlen)) #else - if ((ifp->if_snd.ifq_len + ip->ip_len / ifp->if_mtu + 1) >= + if ((ifp->if_snd.ifq_len + ip->ip_len / mtu + 1) >= ifp->if_snd.ifq_maxlen) #endif /* ALTQ */ { @@ -397,7 +416,7 @@ goto bad; } /* don't allow broadcast messages to be fragmented */ - if (ip->ip_len > ifp->if_mtu) { + if (ip->ip_len > mtu) { error = EMSGSIZE; goto bad; } @@ -746,7 +765,7 @@ * If small enough for interface, or the interface will take * care of the fragmentation for us, can just send directly. */ - if (ip->ip_len <= ifp->if_mtu || (ifp->if_hwassist & CSUM_FRAGMENT && + if (ip->ip_len <= mtu || (ifp->if_hwassist & CSUM_FRAGMENT && ((ip->ip_off & IP_DF) == 0))) { ip->ip_len = htons(ip->ip_len); ip->ip_off = htons(ip->ip_off); @@ -776,17 +795,6 @@ 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_mtu > ifp->if_mtu)) { - ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu; - } ipstat.ips_cantfrag++; goto bad; } @@ -795,7 +803,7 @@ * Too large for interface; fragment if possible. If successful, * on return, m will point to a list of packets to be sent. */ - error = ip_fragment(ip, &m, ifp->if_mtu, ifp->if_hwassist, sw_csum); + error = ip_fragment(ip, &m, mtu, ifp->if_hwassist, sw_csum); if (error) goto bad; for (; m; m = m0) {