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,
ðer_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