The branch main has been updated by emaste:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=51f798e761b1b30fc2432cce4295271c0689bd1f

commit 51f798e761b1b30fc2432cce4295271c0689bd1f
Author:     Gleb Smirnoff <gleb...@freebsd.org>
AuthorDate: 2022-01-27 05:58:50 +0000
Commit:     Ed Maste <ema...@freebsd.org>
CommitDate: 2022-05-05 18:38:07 +0000

    netisr: serialize/restore m_pkthdr.rcvif when queueing mbufs
    
    Reviewed by:            kp
    Differential revision:  https://reviews.freebsd.org/D33268
    
    (cherry picked from commit 6871de9363e559fef6765f0e49acc47f77544999)
---
 sys/net/netisr.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/sys/net/netisr.c b/sys/net/netisr.c
index e4abea317440..4d0bce3bedfc 100644
--- a/sys/net/netisr.c
+++ b/sys/net/netisr.c
@@ -700,9 +700,11 @@ netisr_register_vnet(const struct netisr_handler *nhp)
 static void
 netisr_drain_proto_vnet(struct vnet *vnet, u_int proto)
 {
+       struct epoch_tracker et;
        struct netisr_workstream *nwsp;
        struct netisr_work *npwp;
        struct mbuf *m, *mp, *n, *ne;
+       struct ifnet *ifp;
        u_int i;
 
        KASSERT(vnet != NULL, ("%s: vnet is NULL", __func__));
@@ -723,11 +725,14 @@ netisr_drain_proto_vnet(struct vnet *vnet, u_int proto)
                 */
                m = npwp->nw_head;
                n = ne = NULL;
+               NET_EPOCH_ENTER(et);
                while (m != NULL) {
                        mp = m;
                        m = m->m_nextpkt;
                        mp->m_nextpkt = NULL;
-                       if (mp->m_pkthdr.rcvif->if_vnet != vnet) {
+                       if ((ifp = ifnet_byindexgen(mp->m_pkthdr.rcvidx,
+                           mp->m_pkthdr.rcvgen)) != NULL &&
+                           ifp->if_vnet != vnet) {
                                if (n == NULL) {
                                        n = ne = mp;
                                } else {
@@ -736,10 +741,12 @@ netisr_drain_proto_vnet(struct vnet *vnet, u_int proto)
                                }
                                continue;
                        }
-                       /* This is a packet in the selected vnet. Free it. */
+                       /* This is a packet in the selected vnet, or belongs
+                          to destroyed interface. Free it. */
                        npwp->nw_len--;
                        m_freem(mp);
                }
+               NET_EPOCH_EXIT(et);
                npwp->nw_head = n;
                npwp->nw_tail = ne;
                NWS_UNLOCK(nwsp);
@@ -913,8 +920,10 @@ netisr_process_workstream_proto(struct netisr_workstream 
*nwsp, u_int proto)
                if (local_npw.nw_head == NULL)
                        local_npw.nw_tail = NULL;
                local_npw.nw_len--;
-               VNET_ASSERT(m->m_pkthdr.rcvif != NULL,
-                   ("%s:%d rcvif == NULL: m=%p", __func__, __LINE__, m));
+               if (__predict_false(m_rcvif_restore(m) == NULL)) {
+                       m_freem(m);
+                       continue;
+               }
                CURVNET_SET(m->m_pkthdr.rcvif->if_vnet);
                netisr_proto[proto].np_handler(m);
                CURVNET_RESTORE();
@@ -986,6 +995,7 @@ netisr_queue_workstream(struct netisr_workstream *nwsp, 
u_int proto,
 
        *dosignalp = 0;
        if (npwp->nw_len < npwp->nw_qlimit) {
+               m_rcvif_serialize(m);
                m->m_nextpkt = NULL;
                if (npwp->nw_head == NULL) {
                        npwp->nw_head = m;

Reply via email to