mbuf(9): Implement a leaf network interface field in the mbuf packet header.

When packets are received they may traverse several network interfaces like
vlan(4) and lagg(9). When doing receive side offloads it is important to
know the first network interface entry point, because that is where all
offloading is taking place. This makes it possible to track receive
side route changes for multiport setups, for example when lagg(9) receives
traffic from more than one port. This avoids having to install multiple
offloading rules for the same stream.

This field works similar to the existing "rcvif" mbuf packet header field.

Submitted by:	jhb@
Reviewed by:	gallatin@ and gnn@
Differential revision:	https://reviews.freebsd.org/D35339
Sponsored by:	NVIDIA Networking
Sponsored by:	Netflix
This commit is contained in:
Hans Petter Selasky 2022-05-25 14:08:50 +02:00
parent 892eded5b8
commit 4d88d81c31
3 changed files with 34 additions and 6 deletions

View File

@ -1645,12 +1645,21 @@ m_rcvif_serialize(struct mbuf *m)
gen = m->m_pkthdr.rcvif->if_idxgen;
m->m_pkthdr.rcvidx = idx;
m->m_pkthdr.rcvgen = gen;
if (__predict_false(m->m_pkthdr.leaf_rcvif != NULL)) {
idx = m->m_pkthdr.leaf_rcvif->if_index;
gen = m->m_pkthdr.leaf_rcvif->if_idxgen;
} else {
idx = -1;
gen = 0;
}
m->m_pkthdr.leaf_rcvidx = idx;
m->m_pkthdr.leaf_rcvgen = gen;
}
struct ifnet *
m_rcvif_restore(struct mbuf *m)
{
struct ifnet *ifp;
struct ifnet *ifp, *leaf_ifp;
M_ASSERTPKTHDR(m);
NET_EPOCH_ASSERT();
@ -1659,7 +1668,19 @@ m_rcvif_restore(struct mbuf *m)
if (ifp == NULL || (ifp->if_flags & IFF_DYING))
return (NULL);
return (m->m_pkthdr.rcvif = ifp);
if (__predict_true(m->m_pkthdr.leaf_rcvidx == (u_short)-1)) {
leaf_ifp = NULL;
} else {
leaf_ifp = ifnet_byindexgen(m->m_pkthdr.leaf_rcvidx,
m->m_pkthdr.leaf_rcvgen);
if (__predict_false(leaf_ifp != NULL && (leaf_ifp->if_flags & IFF_DYING)))
leaf_ifp = NULL;
}
m->m_pkthdr.leaf_rcvif = leaf_ifp;
m->m_pkthdr.rcvif = ifp;
return (ifp);
}
/*

View File

@ -180,11 +180,11 @@ CTASSERT(offsetof(struct mbuf, m_pktdat) % 8 == 0);
*/
#if defined(__LP64__)
CTASSERT(offsetof(struct mbuf, m_dat) == 32);
CTASSERT(sizeof(struct pkthdr) == 56);
CTASSERT(sizeof(struct pkthdr) == 64);
CTASSERT(sizeof(struct m_ext) == 160);
#else
CTASSERT(offsetof(struct mbuf, m_dat) == 24);
CTASSERT(sizeof(struct pkthdr) == 48);
CTASSERT(sizeof(struct pkthdr) == 52);
#if defined(__powerpc__) && defined(BOOKE)
/* PowerPC booke has 64-bit physical pointers. */
CTASSERT(sizeof(struct m_ext) == 184);

View File

@ -150,8 +150,8 @@ struct m_snd_tag {
/*
* Record/packet header in first mbuf of chain; valid only if M_PKTHDR is set.
* Size ILP32: 48
* LP64: 56
* Size ILP32: 52
* LP64: 64
* Compile-time assertions in uipc_mbuf.c test these values to ensure that
* they are correct.
*/
@ -164,6 +164,13 @@ struct pkthdr {
uint16_t rcvgen; /* ... and generation count */
};
};
union {
struct ifnet *leaf_rcvif; /* leaf rcv interface */
struct {
uint16_t leaf_rcvidx; /* leaf rcv interface index ... */
uint16_t leaf_rcvgen; /* ... and generation count */
};
};
SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
int32_t len; /* total packet length */