mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-13 10:02:38 +00:00
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
This commit is contained in:
parent
2b5989e943
commit
c939f1aee7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=101345
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user