Here's a preview of what will happen to "struct pkthdr". Do not store a pointer since ifp might disappear. That will allow us to stop garbage collecting the various queues when an interface is destroy/detached and since the per-ifp lists might also need some concurrent protection, we can easily fold that around if_get().
But before talking about pkthdr, let's remove the related ifp pointer in the "struct mbuf_ext", diff below, ok? Index: share/man/man9/mbuf.9 =================================================================== RCS file: /home/ncvs/src/share/man/man9/mbuf.9,v retrieving revision 1.69 diff -u -p -r1.69 mbuf.9 --- share/man/man9/mbuf.9 19 Mar 2014 10:09:19 -0000 1.69 +++ share/man/man9/mbuf.9 26 Mar 2014 15:26:36 -0000 @@ -140,7 +140,7 @@ struct mbuf_ext { void *ext_arg; u_int ext_size; int ext_type; - struct ifnet* ext_ifp; + u_short ext_ifidx; int ext_backend; struct mbuf *ext_nextref; struct mbuf *ext_prevref; Index: sys/kern/uipc_mbuf.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_mbuf.c,v retrieving revision 1.178 diff -u -p -r1.178 uipc_mbuf.c --- sys/kern/uipc_mbuf.c 19 Jan 2014 03:04:54 -0000 1.178 +++ sys/kern/uipc_mbuf.c 26 Mar 2014 15:26:36 -0000 @@ -402,15 +402,18 @@ void m_cluncount(struct mbuf *m, int all) { struct mbuf_ext *me; + struct ifnet *ifp; do { me = &m->m_ext; if (((m->m_flags & (M_EXT|M_CLUSTER)) != (M_EXT|M_CLUSTER)) || - (me->ext_ifp == NULL)) + (me->ext_ifidx == 0)) continue; - me->ext_ifp->if_data.ifi_mclpool[me->ext_backend].mcl_alive--; - me->ext_ifp = NULL; + ifp = if_get(me->ext_ifidx); + if (ifp != NULL) + ifp->if_data.ifi_mclpool[me->ext_backend].mcl_alive--; + me->ext_ifidx = 0; } while (all && (m = m->m_next)); } @@ -460,7 +463,10 @@ m_clget(struct mbuf *m, int how, struct m->m_ext.ext_free = NULL; m->m_ext.ext_arg = NULL; m->m_ext.ext_backend = pi; - m->m_ext.ext_ifp = ifp; + if (ifp != NULL) + m->m_ext.ext_ifidx = ifp->if_index; + else + m->m_ext.ext_ifidx = 0; MCLINITREFERENCE(m); return (m); } @@ -1375,7 +1381,7 @@ m_print(void *v, m->m_ext.ext_buf, m->m_ext.ext_size); (*pr)("m_ext.ext_type: %x\tm_ext.ext_backend: %i\n", m->m_ext.ext_type, m->m_ext.ext_backend); - (*pr)("m_ext.ext_ifp: %p\n", m->m_ext.ext_ifp); + (*pr)("m_ext.ext_ifidx: %u\n", m->m_ext.ext_ifidx); (*pr)("m_ext.ext_free: %p\tm_ext.ext_arg: %p\n", m->m_ext.ext_free, m->m_ext.ext_arg); (*pr)("m_ext.ext_nextref: %p\tm_ext.ext_prevref: %p\n", Index: sys/sys/mbuf.h =================================================================== RCS file: /home/ncvs/src/sys/sys/mbuf.h,v retrieving revision 1.173 diff -u -p -r1.173 mbuf.h --- sys/sys/mbuf.h 19 Mar 2014 10:09:20 -0000 1.173 +++ sys/sys/mbuf.h 26 Mar 2014 15:26:36 -0000 @@ -130,7 +130,7 @@ struct mbuf_ext { void *ext_arg; /* argument for ext_free */ u_int ext_size; /* size of buffer, for ext_free */ int ext_type; - struct ifnet* ext_ifp; + u_short ext_ifidx; /* index of the interface */ int ext_backend; /* backend pool the storage came from */ struct mbuf *ext_nextref; struct mbuf *ext_prevref;