6.2 mtu now limits size of incomming packet

Julian Elischer julian at elischer.org
Fri Jul 20 22:57:36 UTC 2007


Julian Elischer wrote:
> Eli Dart wrote:
>> see below...
>>
>> Julian Elischer wrote:
>>> Eli Dart wrote:
>>>>
>>>>
>>>> Stephen Clark wrote:
>>>>
>>>>>>
>>>>> So was any decision reached on this issue - will FreeBSD changed
>>>>> to accept a packet on an interface that is larger than the mtu on
>>>>> that interface?
>>>>
>>>> If possible, I'd like to see the ability to enforce interface MTU
>>>> for received packets preserved in a sysctl if it is removed for the
>>>>  default config...  In other words, something like:
>>>>
>>>> net.link.mtu_limits_received_pktsize = 0|1
>>>>
>>>> Then, default it to 0 to preserve 4.x behavior.
>>>
>>> what would this achieve?
>>>
>>> Answering himself.. it MAY allow a driver to optimise a bit by not 
>>> needing to cope with the posibility of receiving jubo packets? I can
>>> not think of any other reason.. (except to break networks that are 
>>> apparently working fine).
>>
>> The networks that are apparently working fine are most likely 
>> misconfigured, IMHO.
>>
>> Others have made a case for permitting an interface to accept as large 
>> a packet as it can, regardless of configured MTU.  That's fine for 
>> theory.
>>
>> My operational experience leads me to a different place.  If an 
>> interface receives a packet that is larger than its configured MTU, I 
>> would prefer that the packet be dropped as a giant and a giants 
>> counter  incremented, regardless of whether the hardware can 
>> theoretically receive the packet.  In modern networks, an MTU mismatch 
>> within a broadcast domain indicates a broken network, IMHO.  If the 
>> devices in the network are configured to enforce MTU for both tx and 
>> rx, more problems get spotted during turnup, rather than surfacing 
>> later on as difficult-to-diagnose problems that users only call about 
>> after they are truly frustrated.  And, if you have a giants counter 
>> (or input error counter) you can look at, it makes it straightforward 
>> to spot the problem.
>>
>> (one could also stretch a bit and say that enforcing MTU on rx might 
>> provide less surprise to code that consumes packets and has knowledge 
>> of the MTU setting of an interface.....unfortunately I don't know 
>> enough about the details of the network stack to know if this is a 
>> real concern)
> 
> then we should have an MRU value.
> mtu is mTu
> 
> note that if the following code is what is doing it, it is only enabled in
> DIAGNOSTIC mode anyhow.
> 
> #ifdef DIAGNOSTIC
>        if (m->m_pkthdr.len >
>            ETHER_MAX_FRAME(ifp, etype, m->m_flags & M_HASFCS) &&
>            (ifp->if_capenable & IFCAP_LRO) == 0) {
>                if_printf(ifp, "discard oversize frame "
>                                "(ether type %x flags %x len %u > max 
> %lu)\n",
>                                etype, m->m_flags, m->m_pkthdr.len,
>                                ETHER_MAX_FRAME(ifp, etype,
>                                                m->m_flags & M_HASFCS));
>                ifp->if_ierrors++;                m_freem(m);
>                return;
>        }

in 6.1 that  would become:
diff -u -r1.193.2.10 if_ethersubr.c
--- if_ethersubr.c      4 Mar 2006 09:23:34 -0000       1.193.2.10
+++ if_ethersubr.c      20 Jul 2007 22:52:43 -0000
@@ -99,6 +99,8 @@
 extern u_char  aarp_org_code[3];
 #endif /* NETATALK */
 
+static int mtu_is_mru = 0;
+
 /* netgraph node hooks for ng_ether(4) */
 void   (*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp);
 void   (*ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m);
@@ -536,16 +559,18 @@
        }
        eh = mtod(m, struct ether_header *);
        etype = ntohs(eh->ether_type);
-       if (m->m_pkthdr.len >
-           ETHER_MAX_FRAME(ifp, etype, m->m_flags & M_HASFCS)) {
-               if_printf(ifp, "discard oversize frame "
-                               "(ether type %x flags %x len %u > max %lu)\n",
-                               etype, m->m_flags, m->m_pkthdr.len,
-                               ETHER_MAX_FRAME(ifp, etype,
-                                               m->m_flags & M_HASFCS));
-               ifp->if_ierrors++;
-               m_freem(m);
-               return;
+       if (mtu_is_mru) {
+               if (m->m_pkthdr.len >
+                   ETHER_MAX_FRAME(ifp, etype, m->m_flags & M_HASFCS)) {
+                       if_printf(ifp, "discard oversize frame "
+                                       "(ether type %x flags %x len %u > max %lu)\n",
+                                       etype, m->m_flags, m->m_pkthdr.len,
+                                       ETHER_MAX_FRAME(ifp, etype,
+                                                       m->m_flags & M_HASFCS));
+                       ifp->if_ierrors++;
+                       m_freem(m);
+                       return;
+               }
        }
        if (m->m_pkthdr.rcvif == NULL) {
                if_printf(ifp, "discard frame w/o interface pointer\n");
@@ -931,9 +982,11 @@
 
 SYSCTL_DECL(_net_link);
 SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");
+SYSCTL_INT(_net_link_ether, OID_AUTO, MTUisMRU, CTLFLAG_RW,
+           &mtu_is_mru,0,"Allow MTU to limit recieved packet size");
 #if defined(INET) || defined(INET6)
 SYSCTL_INT(_net_link_ether, OID_AUTO, ipfw, CTLFLAG_RW,
            &ether_ipfw,0,"Pass ether pkts through firewall");
 #endif
 
 #if 0





possibly wrapped in #ifdef MTUISMRU
so people could avoid the extra overhead.


More information about the freebsd-net mailing list