--- a/sys/net/netmap/netmap_generic.c +++ b/sys/net/netmap/netmap_generic.c @@ -518,6 +518,21 @@ * ring->avail == 0 || j != k */ tx_ret = generic_xmit_frame(ifp, m, addr, len, ring_nr); + /* + * DF-3426: generic_xmit_frame() transfers full ownership of + * the mbuf to ifq_dispatch()/the driver -- the refcount + * retention the original design relied on is #if 0'd out + * in generic_xmit_frame() (netmap_freebsd.c:131-135), and + * on both the success and the failure path the mbuf is + * gone (queued for the driver / dropped by + * ifsq_enqueue_locked). Clear the slot now so the pool + * never aliases driver-owned or already-freed memory. + * The replenish paths (generic_netmap_tx_clean() at :361 + * and the !m branch above) already handle NULL entries, + * and generic_set_tx_event() treats NULL as "event + * already pending". + */ + kring->tx_pool[j] = NULL; if (unlikely(tx_ret)) { RD(5, "start_xmit failed: err %d [%u,%u,%u,%u]", tx_ret, kring->nr_ntc, j, k, kring->nr_hwavail);