aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2022-05-25 12:08:50 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2022-06-07 10:54:42 +0000
commit4d88d81c3166a80df8098d23a3cc26c2463da33d (patch)
tree9533d218f70eed0b2e420819dc8de0e6a53f4393
parent892eded5b8b0723043577b971ac7be7edeb8df7a (diff)
downloadsrc-4d88d81c3166a80df8098d23a3cc26c2463da33d.tar.gz
src-4d88d81c3166a80df8098d23a3cc26c2463da33d.zip
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
-rw-r--r--sys/kern/kern_mbuf.c25
-rw-r--r--sys/kern/uipc_mbuf.c4
-rw-r--r--sys/sys/mbuf.h11
3 files changed, 34 insertions, 6 deletions
diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c
index 23050e991418..2e307975b9ca 100644
--- a/sys/kern/kern_mbuf.c
+++ b/sys/kern/kern_mbuf.c
@@ -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);
}
/*
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index dab068894f54..4a5bb45e9573 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -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);
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 61da52c6e67c..c9b3df075105 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -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 */