diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c --- a/sys/kern/kern_mbuf.c +++ b/sys/kern/kern_mbuf.c @@ -1645,12 +1645,21 @@ 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 @@ 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 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -180,11 +180,11 @@ */ #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 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -150,8 +150,8 @@ /* * 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 @@ 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 */