diff options
author | luigi <luigi@FreeBSD.org> | 2002-08-04 23:55:06 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 2002-08-04 23:55:06 +0000 |
commit | a86f01c7176b2b4bc02ad8b92b300dec503849f2 (patch) | |
tree | a398d48b12396834afe00ee1a8595fee14457624 | |
parent | eab6aceed81b6fde781962b732f25806087a9cda (diff) | |
download | FreeBSD-src-a86f01c7176b2b4bc02ad8b92b300dec503849f2.zip FreeBSD-src-a86f01c7176b2b4bc02ad8b92b300dec503849f2.tar.gz |
Extend the interface to ether_input(): a NULL eh pointer means that
the mbuf contains the ethernet header (eh) as well, which ether_input()
will strip off as needed.
This permits the removal (in a backward compatible way) of the
header removal code which right now is replicated in all drivers,
sometimes in an inconsistent way. Also, because many functions
called after ether_input() require the eh in the mbuf, eventually
we can propagate the interface and handle outdated drivers just
in ether_input().
Individual driver changes to use the new interface will follow as
we have a chance to touch them.
NOTE THAT THIS CHANGE IS FULLY BACKWARD COMPATIBLE AND DOES NOT BREAK
BINARY COMPATIBILITY FOR DRIVERS.
MFC after: 3 days
-rw-r--r-- | sys/net/if_ethersubr.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 693f184..53c744d 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -535,30 +535,44 @@ ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst, } /* - * Process a received Ethernet packet; - * the packet is in the mbuf chain m without - * the ether header, which is provided separately. + * Process a received Ethernet packet. We have two different interfaces: + * one (conventional) assumes the packet in the mbuf, with the ethernet + * header provided separately in *eh. The second one (new) has everything + * in the mbuf, and we can tell it because eh == NULL. + * The caller MUST MAKE SURE that there are at least + * sizeof(struct ether_header) bytes in the first mbuf. + * + * This allows us to concentrate in one place a bunch of code which + * is replicated in all device drivers. Also, many functions called + * from ether_input() try to put the eh back into the mbuf, so we + * can later propagate the 'contiguous packet' interface to them, + * and handle the old interface just here. * * NOTA BENE: for many drivers "eh" is a pointer into the first mbuf or * cluster, right before m_data. So be very careful when working on m, * as you could destroy *eh !! - * A (probably) more convenient and efficient interface to ether_input - * is to have the whole packet (with the ethernet header) into the mbuf: - * modules which do not need the ethernet header can easily drop it, while - * others (most noticeably bridge and ng_ether) do not need to do additional - * work to put the ethernet header back into the mbuf. * * First we perform any link layer operations, then continue * to the upper layers with ether_demux(). */ void -ether_input(ifp, eh, m) - struct ifnet *ifp; - struct ether_header *eh; - struct mbuf *m; +ether_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m) { struct ether_header save_eh; + if (eh == NULL) { + if (m->m_len < sizeof(struct ether_header)) { + /* XXX error in the caller. */ + m_freem(m); + return; + } + m->m_pkthdr.rcvif = ifp; + eh = mtod(m, struct ether_header *); + m->m_data += sizeof(struct ether_header); + m->m_len -= sizeof(struct ether_header); + m->m_pkthdr.len = m->m_len; + } + #ifdef MAC mac_create_mbuf_from_ifnet(ifp, m); #endif |