mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-14 10:09:48 +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;
|
* Process a received Ethernet packet. We have two different interfaces:
|
||||||
* the packet is in the mbuf chain m without
|
* one (conventional) assumes the packet in the mbuf, with the ethernet
|
||||||
* the ether header, which is provided separately.
|
* 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
|
* 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,
|
* cluster, right before m_data. So be very careful when working on m,
|
||||||
* as you could destroy *eh !!
|
* 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
|
* First we perform any link layer operations, then continue
|
||||||
* to the upper layers with ether_demux().
|
* to the upper layers with ether_demux().
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ether_input(ifp, eh, m)
|
ether_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
|
||||||
struct ifnet *ifp;
|
|
||||||
struct ether_header *eh;
|
|
||||||
struct mbuf *m;
|
|
||||||
{
|
{
|
||||||
struct ether_header save_eh;
|
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
|
#ifdef MAC
|
||||||
mac_create_mbuf_from_ifnet(ifp, m);
|
mac_create_mbuf_from_ifnet(ifp, m);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user