Index: sys/net/netisr.c =================================================================== --- sys/net/netisr.c +++ sys/net/netisr.c @@ -700,6 +700,7 @@ 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; @@ -723,11 +724,14 @@ */ 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 (m_rcvif_restore(mp) != NULL && + mp->m_pkthdr.rcvif->if_vnet != vnet) { + m_rcvif_serialize(m); if (n == NULL) { n = ne = mp; } else { @@ -740,6 +744,7 @@ npwp->nw_len--; m_freem(mp); } + NET_EPOCH_EXIT(et); npwp->nw_head = n; npwp->nw_tail = ne; NWS_UNLOCK(nwsp); @@ -913,8 +918,10 @@ 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 +993,7 @@ *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;