tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

MBuf leak in nd6_resolve()? (was: MBuf leak in ether_output())



> If nd6_resolve returns nonzero, that means it has taken responsibility
> for m.
Thanks. Embarassingly enough, I remember having found out that myself 
months ago, but forgotten in the meantime.

> At least, that's the contract;
Infortunately, that contract seems only to be documented in a few 
knowledgeable people's heads.

> of course there may be bugs in its implementation of the contract.
Looks like it.

The code I run is actually different from what you quote, because it's 
from before the arp/nd6 merge (actually, I'm on -8, but -9 apparently 
has the same code).
However, that merge was announced as "no functional change".

What I'm doing to investigate this is to deposite magic numbers in an 
unused padding field (if it's in fact unused, what it is in my case) 
whenenver an mbuf is processed (in some sense), then (using a utility 
I wrote and posted here), dump the mbpl pool and dissect it (using an 
sed script I attached, to be used as 
sed -n -f pool.sed mbpl.dump | sort | uniq -c) to see where dangling 
mbufs where last handled.

What I'm now seeing is that dangling mbufs are at c2 or c3, meaning 
nd6_resolve() hast put them on the ln_hold queue, either appended (c2) 
or as first member (c3).
They are /not/ seen in nd6_llinfo_timer() (which would be c4).

Is it possible that the timer got stuck? Have there been fixes since -8?

When the problem appears, mbuf usage starts to ramp up. If I then 
destroy and re-create the vlan interface that owns the lost mbufs, 
ramping stops but the lost mbufs remain lost. Shouldn't destroying the 
vlan instance free any packets queued waiting for LL resolution?
Index: dev/pci/if_wm.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_wm.c,v
retrieving revision 1.508.4.52
diff -u -p -r1.508.4.52 if_wm.c
--- dev/pci/if_wm.c	8 Oct 2023 15:31:17 -0000	1.508.4.52
+++ dev/pci/if_wm.c	22 Apr 2024 11:36:23 -0000
@@ -86,6 +86,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
+#include "opt_mbuftrace.h"	/* MBUFTRACE_POINT */
 #include "opt_if_wm.h"
 #endif
 
@@ -5797,6 +5798,7 @@ wm_add_rxbuf(struct wm_rxqueue *rxq, int
 	if (m == NULL)
 		return ENOBUFS;
 
+	MBUFTRACE_POINT(m, 0x4c);
 	MCLGET(m, M_DONTWAIT);
 	if ((m->m_flags & M_EXT) == 0) {
 		m_freem(m);
@@ -8684,6 +8686,7 @@ wm_transmit(struct ifnet *ifp, struct mb
 	struct wm_softc *sc = ifp->if_softc;
 	struct wm_txqueue *txq;
 
+	MBUFTRACE_POINT(m, 0x41);
 	qid = wm_select_txqueue(ifp, m);
 	txq = &sc->sc_queue[qid].wmq_txq;
 
@@ -8692,6 +8695,7 @@ wm_transmit(struct ifnet *ifp, struct mb
 		WM_Q_EVCNT_INCR(txq, pcqdrop);
 		return ENOBUFS;
 	}
+	MBUFTRACE_POINT(m, 0x42);
 
 	/* XXX NOMPSAFE: ifp->if_data should be percpu. */
 	ifp->if_obytes += m->m_pkthdr.len;
@@ -8786,6 +8790,7 @@ wm_send_common_locked(struct ifnet *ifp,
 			IFQ_DEQUEUE(&ifp->if_snd, m0);
 		if (m0 == NULL)
 			break;
+		MBUFTRACE_POINT(m0, 0x45);
 
 		DPRINTF(sc, WM_DEBUG_TX,
 		    ("%s: TX: have packet to transmit: %p\n",
@@ -8918,6 +8923,7 @@ retry:
 		 * incremented by 1 if we do checksum offload (a descriptor
 		 * is used to set the checksum context).
 		 */
+		MBUFTRACE_POINT(m0, 0x46);
 		txs->txs_mbuf = m0;
 		txs->txs_firstdesc = txq->txq_next;
 		txs->txs_ndesc = segs_needed;
@@ -9033,6 +9039,7 @@ retry:
 
 		/* Pass the packet to any BPF listeners. */
 		bpf_mtap(ifp, m0);
+		MBUFTRACE_POINT(m0, 0x47);
 	}
 
 	if (m0 != NULL) {
@@ -9042,6 +9049,7 @@ retry:
 		WM_Q_EVCNT_INCR(txq, descdrop);
 		DPRINTF(sc, WM_DEBUG_TX, ("%s: TX: error after IFQ_DEQUEUE\n",
 			__func__));
+		MBUFTRACE_POINT(m0, 0x4b);
 		m_freem(m0);
 	}
 
@@ -9303,6 +9311,7 @@ wm_nq_transmit(struct ifnet *ifp, struct
 	struct wm_softc *sc = ifp->if_softc;
 	struct wm_txqueue *txq;
 
+	MBUFTRACE_POINT(m, 0x43);
 	qid = wm_select_txqueue(ifp, m);
 	txq = &sc->sc_queue[qid].wmq_txq;
 
@@ -9311,6 +9320,7 @@ wm_nq_transmit(struct ifnet *ifp, struct
 		WM_Q_EVCNT_INCR(txq, pcqdrop);
 		return ENOBUFS;
 	}
+	MBUFTRACE_POINT(m, 0x44);
 
 	/* XXX NOMPSAFE: ifp->if_data should be percpu. */
 	ifp->if_obytes += m->m_pkthdr.len;
@@ -9412,6 +9422,7 @@ wm_nq_send_common_locked(struct ifnet *i
 			IFQ_DEQUEUE(&ifp->if_snd, m0);
 		if (m0 == NULL)
 			break;
+		MBUFTRACE_POINT(m0, 0x48);
 
 		DPRINTF(sc, WM_DEBUG_TX,
 		    ("%s: TX: have packet to transmit: %p\n",
@@ -9505,6 +9516,7 @@ retry:
 		 * incremented by 1 if we do checksum offload (a descriptor
 		 * is used to set the checksum context).
 		 */
+		MBUFTRACE_POINT(m0, 0x49);
 		txs->txs_mbuf = m0;
 		txs->txs_firstdesc = txq->txq_next;
 		txs->txs_ndesc = segs_needed;
@@ -9630,6 +9642,7 @@ retry:
 
 		/* Pass the packet to any BPF listeners. */
 		bpf_mtap(ifp, m0);
+		MBUFTRACE_POINT(m0, 0x4a);
 	}
 
 	if (m0 != NULL) {
@@ -10158,6 +10171,7 @@ wm_rxeof(struct wm_rxqueue *rxq, u_int l
 		    ("%s: RX: have entire packet, len -> %d\n",
 			device_xname(sc->sc_dev), len));
 
+		MBUFTRACE_POINT(m, 0x4d);
 		/* If an error occurred, update stats and drop the packet. */
 		if (wm_rxdesc_has_errors(rxq, errors)) {
 			m_freem(m);
@@ -10179,6 +10193,7 @@ wm_rxeof(struct wm_rxqueue *rxq, u_int l
 		 * If VLANs are enabled, VLAN packets have been unwrapped
 		 * for us.  Associate the tag with the packet.
 		 */
+		MBUFTRACE_POINT(m, 0x4e);
 		if (!wm_rxdesc_input_vlantag(rxq, status, vlantag, m))
 			continue;
 
@@ -10187,6 +10202,7 @@ wm_rxeof(struct wm_rxqueue *rxq, u_int l
 
 		rxq->rxq_packets++;
 		rxq->rxq_bytes += len;
+		MBUFTRACE_POINT(m, 0x4f);
 		/* Pass it on. */
 		if_percpuq_enqueue(sc->sc_ipq, m);
 
Index: kern/uipc_mbuf.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_mbuf.c,v
retrieving revision 1.172.6.6
diff -u -p -r1.172.6.6 uipc_mbuf.c
--- kern/uipc_mbuf.c	25 Oct 2021 15:49:49 -0000	1.172.6.6
+++ kern/uipc_mbuf.c	22 Apr 2024 11:36:33 -0000
@@ -142,6 +142,9 @@ do {									\
 	KASSERT(((n)->m_flags & M_EXT) == 0);				\
 	KASSERT((o)->m_ext.ext_refcnt >= 1);				\
 	(n)->m_flags |= ((o)->m_flags & M_EXTCOPYFLAGS);		\
+	MBUFTRACE_FLAG((o), 0x80);					\
+	MBUFTRACE_FLAG((n), 0x08);					\
+	(n)->m_ext_storage.ext_refcnt = 0;				\
 	atomic_inc_uint(&(o)->m_ext.ext_refcnt);			\
 	(n)->m_ext_ref = (o)->m_ext_ref;				\
 	mowner_ref((n), (n)->m_flags);					\
@@ -1688,6 +1691,7 @@ m_getptr(struct mbuf *m, int loc, int *o
 
 void
 m_ext_free(struct mbuf *m)
+#if 0
 {
 	bool embedded = MEXT_ISEMBEDDED(m);
 	bool dofree = true;
@@ -1699,18 +1703,22 @@ m_ext_free(struct mbuf *m)
 	KASSERT((m->m_flags & M_EXT_CLUSTER) ==
 	    (m->m_ext_ref->m_flags & M_EXT_CLUSTER));
 
+	MBUFTRACE_FLAG(m, 0x01);
 	if (__predict_true(m->m_ext.ext_refcnt == 1)) {
 		refcnt = m->m_ext.ext_refcnt = 0;
 	} else {
 		refcnt = atomic_dec_uint_nv(&m->m_ext.ext_refcnt);
 	}
 	if (refcnt > 0) {
+		MBUFTRACE_FLAG(m, 0x02);
 		if (embedded) {
 			/*
 			 * other mbuf's m_ext_ref still points to us.
 			 */
+			MBUFTRACE_FLAG(m, 0x04);
 			dofree = false;
 		} else {
+			MBUFTRACE_FLAG(m->m_ext_ref, 0x10);
 			m->m_ext_ref = m;
 		}
 	} else {
@@ -1719,6 +1727,7 @@ m_ext_free(struct mbuf *m)
 		 */
 		if (!embedded) {
 			m->m_ext.ext_refcnt++; /* XXX */
+			MBUFTRACE_FLAG(m->m_ext_ref, 0x20);
 			m_ext_free(m->m_ext_ref);
 			m->m_ext_ref = m;
 		} else if ((m->m_flags & M_EXT_CLUSTER) != 0) {
@@ -1742,6 +1751,54 @@ m_ext_free(struct mbuf *m)
 		pool_cache_put(mb_cache, m);
 	}
 }
+#else
+{
+	struct mbuf *m1 = m->m_ext_ref; /* may well be m itself */
+	u_int refcnt;
+
+	KASSERT((m->m_flags & M_EXT) != 0);
+	KASSERT(MEXT_ISEMBEDDED(m1));
+	KASSERT((m1->m_flags & M_EXT) != 0);
+	KASSERT((m->m_flags & M_EXT_CLUSTER) ==
+	    (m1->m_flags & M_EXT_CLUSTER));
+
+	MBUFTRACE_FLAG(m, 0x01);
+	MBUFTRACE_FLAG(m1, 0x10);
+	if (__predict_true(m1->m_ext_storage.ext_refcnt == 1)) {
+		refcnt = m1->m_ext_storage.ext_refcnt = 0;
+	} else {
+		refcnt = atomic_dec_uint_nv(&m1->m_ext_storage.ext_refcnt);
+	}
+	if (refcnt == 0) {
+		if ((m1->m_flags & M_EXT_CLUSTER) != 0) {
+			pool_cache_put_paddr((struct pool_cache *)
+			    m1->m_ext_storage.ext_arg,
+			    m1->m_ext_storage.ext_buf, m1->m_ext_storage.ext_paddr);
+			m1->m_type = MT_FREE;
+			pool_cache_put(mb_cache, m1);
+		} else if (m1->m_ext_storage.ext_free) {
+			(*m1->m_ext_storage.ext_free)(m1,
+			    m1->m_ext_storage.ext_buf, m1->m_ext_storage.ext_size,
+			    m1->m_ext_storage.ext_arg);
+			/*
+			 * m1 is already freed by the ext_free callback.
+			 */
+			MBUFTRACE_FLAG(m1, 0x08);
+		} else {
+			free(m1->m_ext_storage.ext_buf, m1->m_ext_storage.ext_type);
+			m1->m_type = MT_FREE;
+			pool_cache_put(mb_cache, m1);
+		}
+	} else {
+		MBUFTRACE_FLAG(m1, 0x20);
+	}
+	if (__predict_false(m1 != m)) {
+		KASSERT(m->m_ext_storage.ext_refcnt == 0);
+		m->m_type = MT_FREE;
+		pool_cache_put(mb_cache, m);
+	}
+}
+#endif
 
 #if defined(DDB)
 void
Index: net/if.c
===================================================================
RCS file: /cvsroot/src/sys/net/if.c,v
retrieving revision 1.394.2.19
diff -u -p -r1.394.2.19 if.c
--- net/if.c	17 Jul 2020 15:28:07 -0000	1.394.2.19
+++ net/if.c	22 Apr 2024 11:36:35 -0000
@@ -100,6 +100,7 @@ __KERNEL_RCSID(0, "$NetBSD: if.c,v 1.394
 #include "opt_wlan.h"
 #include "opt_net_mpsafe.h"
 #include "opt_mrouting.h"
+#include "opt_mbuftrace.h"	/* MBUFTRACE_POINT */
 #endif
 
 #include <sys/param.h>
@@ -825,7 +826,9 @@ if_percpuq_softint(void *arg)
 
 	while ((m = if_percpuq_dequeue(ipq)) != NULL) {
 		ifp->if_ipackets++;
+		MBUFTRACE_POINT(m, 0x27);
 		bpf_mtap(ifp, m);
+		MBUFTRACE_POINT(m, 0x28);
 
 		ifp->_if_input(ifp, m);
 	}
@@ -905,6 +908,7 @@ if_percpuq_enqueue(struct if_percpuq *ip
 
 	KASSERT(ipq != NULL);
 
+	MBUFTRACE_POINT(m, 0x23);
 	s = splnet();
 	ifq = percpu_getref(ipq->ipq_ifqs);
 	if (IF_QFULL(ifq)) {
@@ -913,6 +917,7 @@ if_percpuq_enqueue(struct if_percpuq *ip
 		m_freem(m);
 		goto out;
 	}
+	MBUFTRACE_POINT(m, 0x24);
 	IF_ENQUEUE(ifq, m);
 	percpu_putref(ipq->ipq_ifqs);
 
@@ -1118,7 +1123,9 @@ if_input(struct ifnet *ifp, struct mbuf 
 	KASSERT(!cpu_intr_p());
 
 	ifp->if_ipackets++;
+	MBUFTRACE_POINT(m, 0x25);
 	bpf_mtap(ifp, m);
+	MBUFTRACE_POINT(m, 0x26);
 
 	ifp->_if_input(ifp, m);
 }
@@ -3517,6 +3524,7 @@ if_transmit(struct ifnet *ifp, struct mb
 
 	s = splnet();
 
+	MBUFTRACE_POINT(m, 0x21);
 	IFQ_ENQUEUE(&ifp->if_snd, m, error);
 	if (error != 0) {
 		/* mbuf is already freed */
@@ -3540,6 +3548,7 @@ if_transmit_lock(struct ifnet *ifp, stru
 {
 	int error;
 
+	MBUFTRACE_POINT(m, 0x22);
 #ifdef ALTQ
 	KERNEL_LOCK(1, NULL);
 	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
Index: net/if_ethersubr.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_ethersubr.c,v
retrieving revision 1.242.6.10
diff -u -p -r1.242.6.10 if_ethersubr.c
--- net/if_ethersubr.c	10 Oct 2022 16:09:12 -0000	1.242.6.10
+++ net/if_ethersubr.c	22 Apr 2024 11:36:36 -0000
@@ -204,6 +204,7 @@ ether_output(struct ifnet * const ifp0, 
 	struct at_ifaddr *aa;
 #endif /* NETATALK */
 
+	MBUFTRACE_POINT(m, 0xb1);
 #ifdef MBUFTRACE
 	m_claimm(m, ifp->if_mowner);
 #endif
@@ -232,6 +233,7 @@ ether_output(struct ifnet * const ifp0, 
 	}
 #endif /* NCARP > 0 */
 
+	MBUFTRACE_POINT(m, 0xb2);
 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING))
 		senderr(ENETDOWN);
 
@@ -239,6 +241,7 @@ ether_output(struct ifnet * const ifp0, 
 
 #ifdef INET
 	case AF_INET:
+		MBUFTRACE_POINT(m, 0xb2);
 		if (m->m_flags & M_BCAST)
 			(void)memcpy(edst, etherbroadcastaddr, sizeof(edst));
 		else if (m->m_flags & M_MCAST)
@@ -250,10 +253,12 @@ ether_output(struct ifnet * const ifp0, 
 		/* If broadcasting on a simplex interface, loopback a copy */
 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
 			mcopy = m_copy(m, 0, (int)M_COPYALL);
+		if (mcopy) MBUFTRACE_POINT(mcopy, 0xb3);
 		etype = htons(ETHERTYPE_IP);
 		break;
 
 	case AF_ARP:
+		MBUFTRACE_POINT(m, 0xb4);
 		ah = mtod(m, struct arphdr *);
 		if (m->m_flags & M_BCAST)
 			(void)memcpy(edst, etherbroadcastaddr, sizeof(edst));
@@ -286,6 +291,7 @@ ether_output(struct ifnet * const ifp0, 
 #endif
 #ifdef INET6
 	case AF_INET6:
+		MBUFTRACE_POINT(m, 0xb5);
 		if (m->m_flags & M_BCAST)
 			(void)memcpy(edst, etherbroadcastaddr, sizeof(edst));
 		else if (m->m_flags & M_MCAST) {
@@ -369,6 +375,8 @@ ether_output(struct ifnet * const ifp0, 
 			dst->sa_family);
 		senderr(EAFNOSUPPORT);
 	}
+	MBUFTRACE_POINT(m, 0xb6);
+	if (mcopy) MBUFTRACE_POINT(mcopy, 0xb7);
 
 #ifdef MPLS
 	KERNEL_LOCK(1, NULL);
@@ -398,6 +406,7 @@ ether_output(struct ifnet * const ifp0, 
 	M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
 	if (m == 0)
 		senderr(ENOBUFS);
+	MBUFTRACE_POINT(m, 0xb8);
 	eh = mtod(m, struct ether_header *);
 	/* Note: etype is already in network byte order. */
 	(void)memcpy(&eh->ether_type, &etype, sizeof(eh->ether_type));
@@ -417,6 +426,7 @@ ether_output(struct ifnet * const ifp0, 
 
 	if ((error = pfil_run_hooks(ifp->if_pfil, &m, ifp, PFIL_OUT)) != 0)
 		return (error);
+	if (m) MBUFTRACE_POINT(m, 0xb9);
 	if (m == NULL)
 		return (0);
 
@@ -445,6 +455,7 @@ ether_output(struct ifnet * const ifp0, 
 		altq_etherclassify(&ifp->if_snd, m);
 	KERNEL_UNLOCK_ONE(NULL);
 #endif
+	MBUFTRACE_POINT(m, 0xba);
 	return ifq_enqueue(ifp, m);
 
 bad:
@@ -573,12 +584,14 @@ ether_input(struct ifnet *ifp, struct mb
 #endif
 
 	KASSERT(!cpu_intr_p());
+	MBUFTRACE_POINT(m, 0x51);
 
 	if ((ifp->if_flags & IFF_UP) == 0) {
 		m_freem(m);
 		return;
 	}
 
+	MBUFTRACE_POINT(m, 0x52);
 #ifdef MBUFTRACE
 	m_claimm(m, &ec->ec_rx_mowner);
 #endif
@@ -607,6 +620,7 @@ ether_input(struct ifnet *ifp, struct mb
 		m_freem(m);
 		return;
 	}
+	MBUFTRACE_POINT(m, 0x53);
 
 	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
 		/*
@@ -627,6 +641,7 @@ ether_input(struct ifnet *ifp, struct mb
 			m->m_flags |= M_MCAST;
 		ifp->if_imcasts++;
 	}
+	MBUFTRACE_POINT(m, 0x54);
 
 	/* If the CRC is still on the packet, trim it off. */
 	if (m->m_flags & M_HASFCS) {
@@ -666,6 +681,7 @@ ether_input(struct ifnet *ifp, struct mb
 		etype = ntohs(eh->ether_type);
 		ehlen = sizeof(*eh);
 	}
+	MBUFTRACE_POINT(m, 0x55);
 
 #if NAGR > 0
 	if (ifp->if_agrprivate &&
@@ -693,6 +709,7 @@ ether_input(struct ifnet *ifp, struct mb
 #endif
 		return;
 	}
+	MBUFTRACE_POINT(m, 0x56);
 
 	/*
 	 * Handle protocols that expect to have the Ethernet header
@@ -777,6 +794,7 @@ ether_input(struct ifnet *ifp, struct mb
 			return;
 		}
 	}
+	MBUFTRACE_POINT(m, 0x57);
 
 	/* If the CRC is still on the packet, trim it off. */
 	if (m->m_flags & M_HASFCS) {
@@ -894,6 +912,7 @@ ether_input(struct ifnet *ifp, struct mb
 		return;
 #endif /* LLC || NETATALK */
 	}
+	MBUFTRACE_POINT(m, 0x58);
 
 	if (__predict_true(pktq)) {
 #ifdef NET_MPSAFE
@@ -906,12 +925,14 @@ ether_input(struct ifnet *ifp, struct mb
 		}
 		return;
 	}
+	MBUFTRACE_POINT(m, 0x59);
 
 	if (__predict_false(!inq)) {
 		/* Should not happen. */
 		m_freem(m);
 		return;
 	}
+	MBUFTRACE_POINT(m, 0x5a);
 
 	IFQ_LOCK(inq);
 	if (IF_QFULL(inq)) {
Index: net/if_vlan.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_vlan.c,v
retrieving revision 1.97.2.18
diff -u -p -r1.97.2.18 if_vlan.c
--- net/if_vlan.c	13 Nov 2019 12:53:34 -0000	1.97.2.18
+++ net/if_vlan.c	22 Apr 2024 11:36:37 -0000
@@ -83,6 +83,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
 #include "opt_net_mpsafe.h"
+#include "opt_mbuftrace.h"	/* MBUFTRACE_POINT */
 #endif
 
 #include <sys/param.h>
@@ -1395,11 +1396,13 @@ vlan_start(struct ifnet *ifp)
 #endif
 			}
 		}
+		MBUFTRACE_POINT(m, 0x11);
 
 		if ((p->if_flags & IFF_RUNNING) == 0) {
 			m_freem(m);
 			continue;
 		}
+		MBUFTRACE_POINT(m, 0x12);
 
 		error = if_transmit_lock(p, m);
 		if (error) {
@@ -1407,6 +1410,7 @@ vlan_start(struct ifnet *ifp)
 			ifp->if_oerrors++;
 			continue;
 		}
+		MBUFTRACE_POINT(m, 0x13);
 		ifp->if_opackets++;
 	}
 
@@ -1522,19 +1526,21 @@ vlan_transmit(struct ifnet *ifp, struct 
 #endif
 		}
 	}
+	MBUFTRACE_POINT(m, 0x14);
 
 	if ((p->if_flags & IFF_RUNNING) == 0) {
 		m_freem(m);
 		error = ENETDOWN;
 		goto out;
 	}
+	MBUFTRACE_POINT(m, 0x15);
 
 	error = if_transmit_lock(p, m);
 	if (error) {
 		/* mbuf is already freed */
 		ifp->if_oerrors++;
 	} else {
-
+		MBUFTRACE_POINT(m, 0x16);
 		ifp->if_opackets++;
 		ifp->if_obytes += pktlen;
 		if (mcast)
@@ -1564,6 +1570,7 @@ vlan_input(struct ifnet *ifp, struct mbu
 	struct psref psref;
 	bool have_vtag;
 
+	MBUFTRACE_POINT(m, 0x17);
 	have_vtag = vlan_has_tag(m);
 	if (have_vtag) {
 		vid = EVL_VLANOFTAG(vlan_get_tag(m));
@@ -1603,6 +1610,7 @@ vlan_input(struct ifnet *ifp, struct mbu
 		}
 	}
 
+	MBUFTRACE_POINT(m, 0x18);
 	mib = vlan_lookup_tag_psref(ifp, vid, &psref);
 	if (mib == NULL) {
 		m_freem(m);
@@ -1610,6 +1618,7 @@ vlan_input(struct ifnet *ifp, struct mbu
 		return;
 	}
 
+	MBUFTRACE_POINT(m, 0x19);
 	ifv = mib->ifvm_ifvlan;
 	if ((ifv->ifv_if.if_flags & (IFF_UP|IFF_RUNNING)) !=
 	    (IFF_UP|IFF_RUNNING)) {
@@ -1630,11 +1639,13 @@ vlan_input(struct ifnet *ifp, struct mbu
 
 	m_set_rcvif(m, &ifv->ifv_if);
 
+	MBUFTRACE_POINT(m, 0x1a);
 	if (pfil_run_hooks(ifp->if_pfil, &m, ifp, PFIL_IN) != 0)
 		goto out;
 	if (m == NULL)
 		goto out;
 
+	MBUFTRACE_POINT(m, 0x1b);
 	m->m_flags &= ~M_PROMISC;
 	if_input(&ifv->ifv_if, m);
 out:
Index: net/pktqueue.c
===================================================================
RCS file: /cvsroot/src/sys/net/pktqueue.c,v
retrieving revision 1.9
diff -u -p -r1.9 pktqueue.c
--- net/pktqueue.c	1 Jun 2017 02:45:14 -0000	1.9
+++ net/pktqueue.c	22 Apr 2024 11:36:38 -0000
@@ -38,6 +38,10 @@
 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: pktqueue.c,v 1.9 2017/06/01 02:45:14 chs Exp $");
 
+#if defined(_KERNEL_OPT)
+#include "opt_mbuftrace.h"	/* MBUFTRACE_POINT */
+#endif
+
 #include <sys/param.h>
 #include <sys/types.h>
 
@@ -214,10 +218,12 @@ pktq_enqueue(pktqueue_t *pq, struct mbuf
 
 	KASSERT(kpreempt_disabled());
 
+	MBUFTRACE_POINT(m, 0x61);
 	if (__predict_false(!pcq_put(pq->pq_queue[cpuid], m))) {
 		pktq_inc_count(pq, PQCNT_DROP);
 		return false;
 	}
+	MBUFTRACE_POINT(m, 0x62);
 	softint_schedule_cpu(pq->pq_sih, cpu_lookup(cpuid));
 	pktq_inc_count(pq, PQCNT_ENQUEUE);
 	return true;
@@ -244,6 +250,7 @@ pktq_dequeue(pktqueue_t *pq)
 	}
 	if (__predict_true(m != NULL)) {
 		pktq_inc_count(pq, PQCNT_DEQUEUE);
+		MBUFTRACE_POINT(m, 0x63);
 	}
 	return m;
 }
Index: netinet/ip_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_input.c,v
retrieving revision 1.355.2.9
diff -u -p -r1.355.2.9 ip_input.c
--- netinet/ip_input.c	7 Mar 2021 19:13:24 -0000	1.355.2.9
+++ netinet/ip_input.c	22 Apr 2024 11:36:38 -0000
@@ -440,6 +440,7 @@ ipintr(void *arg __unused)
 
 	SOFTNET_KERNEL_LOCK_UNLESS_NET_MPSAFE();
 	while ((m = pktq_dequeue(ip_pktq)) != NULL) {
+		MBUFTRACE_POINT(m, 0x71);
 		ip_input(m);
 	}
 	SOFTNET_KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
@@ -468,6 +469,7 @@ ip_input(struct mbuf *m)
 	KASSERT((m->m_flags & M_PKTHDR) != 0);
 
 	ifp = m_get_rcvif_psref(m, &psref);
+	MBUFTRACE_POINT(m, 0x72);
 	if (__predict_false(ifp == NULL))
 		goto out;
 
@@ -671,6 +673,7 @@ ip_input(struct mbuf *m)
 	}
 #endif
 
+	MBUFTRACE_POINT(m, 0x73);
 	/*
 	 * Process options and, if not destined for us,
 	 * ship it on.  ip_dooptions returns 1 when an
@@ -682,6 +685,7 @@ ip_input(struct mbuf *m)
 		goto out;
 	}
 
+	MBUFTRACE_POINT(m, 0x74);
 	/*
 	 * Check our list of addresses, to see if the packet is for us.
 	 *
@@ -788,9 +792,11 @@ ip_input(struct mbuf *m)
 		ip_forward(m, srcrt, ifp);
 		m_put_rcvif_psref(ifp, &psref);
 	}
+	MBUFTRACE_POINT(m, 0x75);
 	return;
 
 ours:
+	MBUFTRACE_POINT(m, 0x76);
 	m_put_rcvif_psref(ifp, &psref);
 	ifp = NULL;
 
@@ -816,6 +822,7 @@ ours:
 		ip = mtod(m, struct ip *);
 		hlen = ip->ip_hl << 2;
 	}
+	MBUFTRACE_POINT(m, 0x77);
 
 #ifdef IPSEC
 	/*
@@ -851,6 +858,7 @@ ours:
 
 	const int off = hlen, nh = ip->ip_p;
 
+	MBUFTRACE_POINT(m, 0x78);
 	(*inetsw[ip_protox[nh]].pr_input)(m, off, nh);
 	return;
 
Index: netinet6/ip6_etherip.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/Attic/ip6_etherip.c,v
retrieving revision 1.21.8.1
diff -u -p -r1.21.8.1 ip6_etherip.c
--- netinet6/ip6_etherip.c	5 Apr 2018 14:31:19 -0000	1.21.8.1
+++ netinet6/ip6_etherip.c	22 Apr 2024 11:36:42 -0000
@@ -63,6 +63,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_etherip.
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
+#include "opt_mbuftrace.h"	/* MBUFTRACE_POINT */
 #endif
 
 #include <sys/param.h>
@@ -111,6 +112,7 @@ ip6_etherip_output(struct ifnet *ifp, st
 		struct sockaddr_in6	dst6;
 	} u;
 
+	MBUFTRACE_POINT(m, 0xb1);
 	sin6_src = (struct sockaddr_in6 *)sc->sc_src;
 	sin6_dst = (struct sockaddr_in6 *)sc->sc_dst;
 
@@ -128,6 +130,7 @@ ip6_etherip_output(struct ifnet *ifp, st
 	KASSERT((m->m_flags & M_PKTHDR) != 0);
 	proto = IPPROTO_ETHERIP;
 
+	MBUFTRACE_POINT(m, 0xb2);
 	/* fill and prepend Ethernet-in-IP header */
 	eiphdr.eip_ver = ETHERIP_VERSION & ETHERIP_VER_VERS_MASK;
 	eiphdr.eip_pad = 0;
@@ -142,6 +145,7 @@ ip6_etherip_output(struct ifnet *ifp, st
 	memcpy(mtod(m, struct etherip_header *), &eiphdr,
 	    sizeof(struct etherip_header));
 
+	MBUFTRACE_POINT(m, 0xb3);
 	/* prepend new IP header */
 	M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
 	if (m && m->m_len < sizeof(struct ip6_hdr))
@@ -149,6 +153,7 @@ ip6_etherip_output(struct ifnet *ifp, st
 	if (m == NULL)
 		return ENOBUFS;
 
+	MBUFTRACE_POINT(m, 0xb4);
 	ip6 = mtod(m, struct ip6_hdr *);
 	ip6->ip6_flow = 0;
 	ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
@@ -184,6 +189,7 @@ ip6_etherip_output(struct ifnet *ifp, st
 	 * it is too painful to ask for resend of inner packet, to achieve
 	 * path MTU discovery for encapsulated packets.
 	 */
+	MBUFTRACE_POINT(m, 0xb5);
 	error = ip6_output(m, 0, &sc->sc_ro, IPV6_MINMTU, NULL, NULL, NULL);
 
 	return error;
Index: netinet6/ip6_forward.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_forward.c,v
retrieving revision 1.87.2.4
diff -u -p -r1.87.2.4 ip6_forward.c
--- netinet6/ip6_forward.c	24 Sep 2019 18:27:09 -0000	1.87.2.4
+++ netinet6/ip6_forward.c	22 Apr 2024 11:36:42 -0000
@@ -36,6 +36,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_forward.
 #ifdef _KERNEL_OPT
 #include "opt_gateway.h"
 #include "opt_ipsec.h"
+#include "opt_mbuftrace.h"	/* MBUFTRACE_POINT */
 #endif
 
 #include <sys/param.h>
@@ -139,6 +140,7 @@ ip6_forward(struct mbuf *m, int srcrt)
 	struct secpolicy *sp = NULL;
 #endif
 
+	MBUFTRACE_POINT(m, 0x91);
 	/*
 	 * Clear any in-bound checksum flags for this packet.
 	 */
@@ -164,6 +166,7 @@ ip6_forward(struct mbuf *m, int srcrt)
 		goto drop;
 	}
 
+	MBUFTRACE_POINT(m, 0x92);
 	if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
 		/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */
 		icmp6_error(m, ICMP6_TIME_EXCEEDED,
@@ -171,6 +174,7 @@ ip6_forward(struct mbuf *m, int srcrt)
 		goto out;
 	}
 	ip6->ip6_hlim -= IPV6_HLIMDEC;
+	MBUFTRACE_POINT(m, 0x93);
 
 	/*
 	 * Save at most ICMPV6_PLD_MAXLEN (= the min IPv6 MTU -
@@ -182,6 +186,7 @@ ip6_forward(struct mbuf *m, int srcrt)
 	 * processing may modify the mbuf.
 	 */
 	mcopy = m_copy(m, 0, imin(m->m_pkthdr.len, ICMPV6_PLD_MAXLEN));
+	if (mcopy) MBUFTRACE_POINT(mcopy, 0x94);
 
 #ifdef IPSEC
 	if (ipsec_used) {
@@ -237,6 +242,8 @@ ip6_forward(struct mbuf *m, int srcrt)
 	}
 	dst = satocsin6(rtcache_getdst(ro));
 
+	MBUFTRACE_POINT(m, 0x95);
+	if (mcopy) MBUFTRACE_POINT(mcopy, 0x96);
 	/*
 	 * Source scope check: if a packet can't be delivered to its
 	 * destination for the reason that the destination is beyond the scope
@@ -276,6 +283,8 @@ ip6_forward(struct mbuf *m, int srcrt)
 	}
 #endif   
 
+	MBUFTRACE_POINT(m, 0x97);
+	if (mcopy) MBUFTRACE_POINT(mcopy, 0x98);
 	/*
 	 * Destination scope check: if a packet is going to break the scope
 	 * zone of packet's destination address, discard it.  This case should
@@ -297,6 +306,8 @@ ip6_forward(struct mbuf *m, int srcrt)
 		goto drop;
 	}
 
+	MBUFTRACE_POINT(m, 0x99);
+	if (mcopy) MBUFTRACE_POINT(mcopy, 0x9a);
 	if (m->m_pkthdr.len > IN6_LINKMTU(rt->rt_ifp)) {
 		in6_ifstat_inc(rt->rt_ifp, ifs6_in_toobig);
 		if (mcopy) {
@@ -311,6 +322,8 @@ ip6_forward(struct mbuf *m, int srcrt)
 	if (rt->rt_flags & RTF_GATEWAY)
 		dst = (struct sockaddr_in6 *)rt->rt_gateway;
 
+	MBUFTRACE_POINT(m, 0x9b);
+	if (mcopy) MBUFTRACE_POINT(mcopy, 0x9c);
 	/*
 	 * If we are to forward the packet using the same interface
 	 * as one we got the packet from, perhaps we should send a redirect
@@ -347,6 +360,8 @@ ip6_forward(struct mbuf *m, int srcrt)
 		type = ND_REDIRECT;
 	}
 
+	MBUFTRACE_POINT(m, 0x9d);
+	if (mcopy) MBUFTRACE_POINT(mcopy, 0x9e);
 	/*
 	 * Fake scoped addresses. Note that even link-local source or
 	 * destinaion can appear, if the originating node just sends the
@@ -404,6 +419,8 @@ ip6_forward(struct mbuf *m, int srcrt)
 		goto freecopy;
 	ip6 = mtod(m, struct ip6_hdr *);
 
+	MBUFTRACE_POINT(m, 0x9f);
+	if (mcopy) MBUFTRACE_POINT(mcopy, 0x9a);
 	error = ip6_if_output(rt->rt_ifp, origifp, m, dst, rt);
 	if (error) {
 		in6_ifstat_inc(rt->rt_ifp, ifs6_out_discard);
@@ -454,6 +471,7 @@ ip6_forward(struct mbuf *m, int srcrt)
 		code = ICMP6_DST_UNREACH_ADDR;
 		break;
 	}
+	MBUFTRACE_POINT(mcopy, 0x9b);
 	icmp6_error(mcopy, type, code, 0);
 	goto out;
 
Index: netinet6/ip6_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.178.2.9
diff -u -p -r1.178.2.9 ip6_input.c
--- netinet6/ip6_input.c	24 Sep 2019 18:27:09 -0000	1.178.2.9
+++ netinet6/ip6_input.c	22 Apr 2024 11:36:43 -0000
@@ -71,6 +71,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_input.c,
 #include "opt_ipsec.h"
 #include "opt_compat_netbsd.h"
 #include "opt_net_mpsafe.h"
+#include "opt_mbuftrace.h"	/* MBUFTRACE_POINT */
 #endif
 
 #include <sys/param.h>
@@ -233,6 +234,7 @@ ip6intr(void *arg __unused)
 		struct psref psref;
 		struct ifnet *rcvif = m_get_rcvif_psref(m, &psref);
 
+		MBUFTRACE_POINT(m, 0x81);
 		if (rcvif == NULL) {
 			m_freem(m);
 			continue;
@@ -268,6 +270,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 	} u;
 	struct route *ro;
 
+	MBUFTRACE_POINT(m, 0x82);
 	/*
 	 * make sure we don't have onion peering information into m_tag.
 	 */
@@ -320,6 +323,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 		}
 	}
 
+	MBUFTRACE_POINT(m, 0x83);
 	ip6 = mtod(m, struct ip6_hdr *);
 
 	if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
@@ -328,6 +332,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 		goto bad;
 	}
 
+	MBUFTRACE_POINT(m, 0x84);
 	/*
 	 * Assume that we can create a fast-forward IP flow entry
 	 * based on this packet.
@@ -368,6 +373,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 		ip6 = mtod(m, struct ip6_hdr *);
 		srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst);
 	}
+	MBUFTRACE_POINT(m, 0x85);
 
 	IP6_STATINC(IP6_STAT_NXTHIST + ip6->ip6_nxt);
 
@@ -383,6 +389,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 	}
 #endif
 
+	MBUFTRACE_POINT(m, 0x86);
 	/*
 	 * Check against address spoofing/corruption.
 	 */
@@ -429,6 +436,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 	}
 #endif
 
+	MBUFTRACE_POINT(m, 0x87);
 	/*
 	 * Disambiguate address scope zones (if there is ambiguity).
 	 * We first make sure that the original source or destination address
@@ -453,6 +461,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 		goto bad;
 	}
 
+	MBUFTRACE_POINT(m, 0x88);
 	ro = rtcache_percpu_getref(ip6_forward_rt_percpu);
 	/*
 	 * Multicast check
@@ -479,6 +488,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 		deliverifp = rcvif;
 		goto hbhcheck;
 	}
+	MBUFTRACE_POINT(m, 0x89);
 
 	sockaddr_in6_init(&u.dst6, &ip6->ip6_dst, 0, 0, 0);
 
@@ -557,6 +567,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 		}
 	}
 
+	MBUFTRACE_POINT(m, 0x8a);
 	/*
 	 * FAITH (Firewall Aided Internet Translator)
 	 */
@@ -592,6 +603,7 @@ ip6_input(struct mbuf *m, struct ifnet *
     }
 #endif
 
+	MBUFTRACE_POINT(m, 0x8b);
 	/*
 	 * Now there is no reason to process the packet if it's not our own
 	 * and we're not a router.
@@ -601,6 +613,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 		in6_ifstat_inc(rcvif, ifs6_in_discard);
 		goto bad_unref;
 	}
+	MBUFTRACE_POINT(m, 0x8c);
 
   hbhcheck:
 	/*
@@ -687,6 +700,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 	} else
 		nxt = ip6->ip6_nxt;
 
+	MBUFTRACE_POINT(m, 0x8d);
 	/*
 	 * Check that the amount of data in the buffers
 	 * is as at least much as the IPv6 header would have us expect.
@@ -706,6 +720,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 			m_adj(m, sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len);
 	}
 
+	MBUFTRACE_POINT(m, 0x8e);
 	/*
 	 * Forward if desirable.
 	 */
@@ -741,6 +756,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 		return;
 	}
 
+	MBUFTRACE_POINT(m, 0x8f);
 	ip6 = mtod(m, struct ip6_hdr *);
 
 	/*
@@ -833,6 +849,7 @@ ip6_input(struct mbuf *m, struct ifnet *
 		}
 #endif /* IPSEC */
 
+		MBUFTRACE_POINT(m, 0x80);
 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
 	}
 	return;
Index: netinet6/ip6_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.191.6.6
diff -u -p -r1.191.6.6 ip6_output.c
--- netinet6/ip6_output.c	4 Aug 2023 14:38:09 -0000	1.191.6.6
+++ netinet6/ip6_output.c	22 Apr 2024 11:36:44 -0000
@@ -68,6 +68,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_output.c
 #include "opt_inet.h"
 #include "opt_inet6.h"
 #include "opt_ipsec.h"
+#include "opt_mbuftrace.h"	/* MBUFTRACE_POINT */
 #endif
 
 #include <sys/param.h>
@@ -189,6 +190,7 @@ ip6_if_output(struct ifnet * const ifp, 
 {
 	int error = 0;
 
+	MBUFTRACE_POINT(m, 0xa1);
 	if (rt != NULL) {
 		error = rt_check_reject_route(rt, ifp);
 		if (error != 0) {
@@ -197,12 +199,14 @@ ip6_if_output(struct ifnet * const ifp, 
 		}
 	}
 
+	MBUFTRACE_POINT(m, 0xa2);
 	/* discard the packet if IPv6 operation is disabled on the interface */
 	if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) {
 		m_freem(m);
 		return ENETDOWN; /* better error? */
 	}
 
+	MBUFTRACE_POINT(m, 0xa3);
 	if ((ifp->if_flags & IFF_LOOPBACK) != 0)
 		error = if_output_lock(ifp, origifp, m, sin6tocsa(dst), rt);
 	else
@@ -259,6 +263,7 @@ ip6_output(
 	int bound = curlwp_bind();
 	bool release_psref_ia = false;
 
+	MBUFTRACE_POINT(m, 0xa4);
 #ifdef  DIAGNOSTIC
 	if ((m->m_flags & M_PKTHDR) == 0)
 		panic("ip6_output: no HDR");
@@ -527,6 +532,7 @@ ip6_output(
 	}
 #endif /* IPSEC */    
 
+	MBUFTRACE_POINT(m, 0xa5);
 	/* adjust pointer */
 	ip6 = mtod(m, struct ip6_hdr *);
 
@@ -610,6 +616,7 @@ ip6_output(
 
 	/* scope check is done. */
 
+	MBUFTRACE_POINT(m, 0xa6);
 	/* Ensure we only send from a valid address. */
 	if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
 	    (error = ip6_ifaddrvalid(&src0, &dst0)) != 0)
@@ -638,6 +645,7 @@ ip6_output(
 	else
 		dst = satocsin6(rtcache_getdst(ro));
 
+	MBUFTRACE_POINT(m, 0xa7);
 	/*
 	 * XXXXXX: original code follows:
 	 */
@@ -704,6 +712,7 @@ ip6_output(
 		}
 	}
 
+	MBUFTRACE_POINT(m, 0xa8);
 	/*
 	 * Fill the outgoing inteface to tell the upper layer
 	 * to increment per-interface statistics.
@@ -765,6 +774,7 @@ ip6_output(
 	in6_clearscope(&ip6->ip6_src);
 	in6_clearscope(&ip6->ip6_dst);
 
+	MBUFTRACE_POINT(m, 0xa9);
 	/*
 	 * If the outgoing packet contains a hop-by-hop options header,
 	 * it must be examined and processed even by the source node.
@@ -784,6 +794,7 @@ ip6_output(
 		ip6 = mtod(m, struct ip6_hdr *);
 	}
 
+	MBUFTRACE_POINT(m, 0xaa);
 	/*
 	 * Run through list of hooks for output packets.
 	 */
@@ -792,6 +803,7 @@ ip6_output(
 	if (m == NULL)
 		goto done;
 	ip6 = mtod(m, struct ip6_hdr *);
+	MBUFTRACE_POINT(m, 0xab);
 
 	/*
 	 * Send the packet to the outgoing interface.
@@ -874,6 +886,7 @@ ip6_output(
 		}
 
 		KASSERT(dst != NULL);
+		MBUFTRACE_POINT(m, 0xac);
 		if (__predict_true(!tso ||
 		    (ifp->if_capenable & IFCAP_TSOv6) != 0)) {
 			error = ip6_if_output(ifp, origifp, m, dst, rt);
@@ -1062,6 +1075,7 @@ sendorfree:
 			}
 			pserialize_read_exit(s);
 			KASSERT(dst != NULL);
+			MBUFTRACE_POINT(m, 0xad);
 			error = ip6_if_output(ifp, origifp, m, dst, rt);
 		} else
 			m_freem(m);
Index: netinet6/nd6.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/nd6.c,v
retrieving revision 1.232.2.14
diff -u -p -r1.232.2.14 nd6.c
--- netinet6/nd6.c	20 Aug 2021 19:34:49 -0000	1.232.2.14
+++ netinet6/nd6.c	22 Apr 2024 11:36:44 -0000
@@ -34,6 +34,7 @@
 __KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.232.2.14 2021/08/20 19:34:49 martin Exp $");
 
 #ifdef _KERNEL_OPT
+#include "opt_mbuftrace.h"	/* MBUFTRACE_POINT */
 #include "opt_net_mpsafe.h"
 #endif
 
@@ -489,6 +490,7 @@ nd6_llinfo_timer(void *arg)
 		} else {
 			struct mbuf *m = ln->ln_hold;
 			if (m) {
+				MBUFTRACE_POINT(m, 0xc4);
 				struct mbuf *m0;
 
 				/*
@@ -497,6 +499,7 @@ nd6_llinfo_timer(void *arg)
 				 */
 				m0 = m->m_nextpkt;
 				m->m_nextpkt = NULL;
+				if (m0) MBUFTRACE_POINT(m0, 0xc5);
 				ln->ln_hold = m0;
 				clear_llinfo_pqueue(ln);
  			}
@@ -504,6 +507,7 @@ nd6_llinfo_timer(void *arg)
 			nd6_free(ln, 0);
 			ln = NULL;
 			if (m != NULL) {
+				MBUFTRACE_POINT(m, 0xc6);
 				icmp6_error2(m, ICMP6_DST_UNREACH,
 				    ICMP6_DST_UNREACH_ADDR, 0, ifp);
 			}
@@ -2025,6 +2029,7 @@ nd6_llinfo_release_pkts(struct llentry *
 		 * just set the 2nd argument as the 
 		 * 1st one.
 		 */
+		MBUFTRACE_POINT(m_hold, 0xc7);
 		ip6_if_output(ifp, ifp, m_hold, &sin6, NULL);
 	}
 	LLE_WLOCK(ln);
@@ -2306,6 +2311,7 @@ nd6_resolve(struct ifnet *ifp, const str
 	bool created = false;
 	const struct sockaddr_in6 *dst = satocsin6(_dst);
 
+	MBUFTRACE_POINT(m, 0xc1);
 	/* discard the packet if IPv6 operation is disabled on the interface */
 	if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) {
 		m_freem(m);
@@ -2415,6 +2421,7 @@ nd6_resolve(struct ifnet *ifp, const str
 			i++;
 			if (m_hold->m_nextpkt == NULL) {
 				m_hold->m_nextpkt = m;
+				MBUFTRACE_POINT(m, 0xc2);
 				break;
 			}
 		}
@@ -2426,6 +2433,7 @@ nd6_resolve(struct ifnet *ifp, const str
 		}
 	} else {
 		ln->ln_hold = m;
+		MBUFTRACE_POINT(m, 0xc3);
 	}
 
 	/*
Index: sys/mbuf.h
===================================================================
RCS file: /cvsroot/src/sys/sys/mbuf.h,v
retrieving revision 1.170.2.3
diff -u -p -r1.170.2.3 mbuf.h
--- sys/mbuf.h	5 Apr 2018 14:33:41 -0000	1.170.2.3
+++ sys/mbuf.h	22 Apr 2024 11:36:47 -0000
@@ -438,6 +438,10 @@ void mowner_revoke(struct mbuf *, bool, 
 void mowner_attach(struct mowner *);
 void mowner_detach(struct mowner *);
 void m_claimm(struct mbuf *, struct mowner *);
+
+/* m_pkthdr.pad0 is only available if M_PKTHDR or M_EXT is set, otherwise M_databuf aka m_dat uses that space */
+#define MBUFTRACE_POINT(m, p)		do { if ((m)->m_flags & (M_PKTHDR | M_EXT)) (m)->m_pkthdr.pad0 = ((m)->m_pkthdr.pad0 & 0xff00) | (p); } while (/* CONSTCOND */ 0)
+#define MBUFTRACE_FLAG(m, f)		do { if ((m)->m_flags & (M_PKTHDR | M_EXT)) (m)->m_pkthdr.pad0 = (m)->m_pkthdr.pad0 | ((f) << 8); } while (/* CONSTCOND */ 0)
 #else
 #define mowner_init(m, type)		do { } while (/* CONSTCOND */ 0)
 #define	mowner_ref(m, flags)		do { } while (/* CONSTCOND */ 0)
@@ -446,6 +450,9 @@ void m_claimm(struct mbuf *, struct mown
 #define	mowner_attach(mo)		do { } while (/* CONSTCOND */ 0)
 #define	mowner_detach(mo)		do { } while (/* CONSTCOND */ 0)
 #define	m_claimm(m, mo)			do { } while (/* CONSTCOND */ 0)
+
+#define MBUFTRACE_POINT(m, p)		do { } while (/* CONSTCOND */ 0)
+#define MBUFTRACE_FLAG(m, f)		do { } while (/* CONSTCOND */ 0)
 #endif
 
 #define	MCLAIM(m, mo)		m_claim((m), (mo))
@@ -1009,6 +1016,10 @@ m_pkthdr_init(struct mbuf *m)
 	m->m_pkthdr.pattr_class = NULL;
 	m->m_pkthdr.pattr_af = AF_UNSPEC;
 	m->m_pkthdr.pattr_hdr = NULL;
+
+#ifdef MBUFTRACE
+	m->m_pkthdr.pad0 = 0;
+#endif
 }
 
 void m_print(const struct mbuf *, const char *, void (*)(const char *, ...)
1a\
PT FL fl ty rc
/^0020/{ s/^0020  .. .. .. .. \(..\) .*$/\1/
h
}
/^0030  0[^0]/{ s/^0030  \(..\).*$/\1/
H
n
n
s/^0050  .. .. .. .. .. .. .. ..  .. .. \(..\) \(..\) .. .. .. ..$/\1 \2/
tx
b
:x
G
h
n
n
s/^0070  .. .. .. .. .. .. .. ..  \(..\).*$/\1/
H
g
s/\n/ /g
p
}


Home | Main Index | Thread Index | Old Index