==== //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#366 - /data/p4/rwatson/trustedbsd/mac/sys/kern/kern_mac.c ====
@@ -708,18 +708,18 @@
 }
 
 int
-mac_init_mbuf(struct mbuf *m, int flag)
+mac_init_mbuf_tag(struct m_tag *tag, int flag)
 {
+	struct label *label;
 	int error;
 
-	KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf"));
+	label = (struct label *) (tag+1);
+	mac_init_label(label);
 
-	mac_init_label(&m->m_pkthdr.label);
-
-	MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag);
+	MAC_CHECK(init_mbuf_label, label, flag);
 	if (error) {
-		MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label);
-		mac_destroy_label(&m->m_pkthdr.label);
+		MAC_PERFORM(destroy_mbuf_label, label);
+		mac_destroy_label(label);
 	}
 
 #ifdef MAC_DEBUG
@@ -916,11 +916,14 @@
 }
 
 void
-mac_destroy_mbuf(struct mbuf *m)
+mac_destroy_mbuf_tag(struct m_tag *tag)
 {
+	struct label *label;
+
+	label = (struct label *)(tag+1);
 
-	MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label);
-	mac_destroy_label(&m->m_pkthdr.label);
+	MAC_PERFORM(destroy_mbuf_label, label);
+	mac_destroy_label(label);
 #ifdef MAC_DEBUG
 	atomic_subtract_int(&nmacmbufs, 1);
 #endif
@@ -1014,6 +1017,17 @@
 	mac_destroy_vnode_label(&vp->v_label);
 }
 
+void
+mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest)
+{
+	struct label *src_label, *dest_label;
+
+	src_label = (struct label *)(src+1);
+	dest_label = (struct label *)(dest+1);
+
+	MAC_PERFORM(copy_mbuf_label, src_label, dest_label);
+}
+
 static void
 mac_copy_pipe_label(struct label *src, struct label *dest)
 {
@@ -2084,9 +2098,15 @@
 void
 mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
 {
+	struct m_tag *tag;
+	struct label *label;
 
-	MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label,
-	    socket, &socket->so_peerlabel);
+	tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_set_socket_peer_from_mbuf: NULL tag"));
+	label = (struct label *)(tag+1);
+
+	MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket,
+	    &socket->so_peerlabel);
 }
 
 void
@@ -2101,85 +2121,157 @@
 void
 mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
 {
+	struct m_tag *tag;
+	struct label *label;
 
+	tag = m_tag_find(datagram, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_datagram_from_ipq: NULL tag"));
+	label = (struct label *)(tag+1);
+
 	MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
-	    datagram, &datagram->m_pkthdr.label);
+	    datagram, label);
 }
 
 void
 mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
 {
+	struct m_tag *tag;
+	struct label *datagramlabel, *fragmentlabel;
+
+	tag = m_tag_find(datagram, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_fragment: NULL tag"));
+	datagramlabel = (struct label *)(tag+1);
+	tag = m_tag_find(fragment, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_fragment: NULL tag"));
+	fragmentlabel = (struct label *)(tag+1);
 
-	MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label,
-	    fragment, &fragment->m_pkthdr.label);
+	MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment,
+	    fragmentlabel);
 }
 
 void
 mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
 {
+	struct m_tag *tag;
+	struct label *label;
+
+	tag = m_tag_find(fragment, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_ipq: NULL tag"));
+	label = (struct label *)(tag+1);
 
-	MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq,
-	    &ipq->ipq_label);
+	MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label);
 }
 
 void
 mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
 {
+	struct m_tag *tag;
+	struct label *oldmbuflabel, *newmbuflabel;
+
+	tag = m_tag_find(oldmbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_mbuf_from_mbuf: NULL tag"));
+	oldmbuflabel = (struct label *)(tag+1);
+	tag = m_tag_find(newmbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_mbuf_from_mbuf: NULL tag"));
+	newmbuflabel = (struct label *)(tag+1);
 
-	MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label,
-	    newmbuf, &newmbuf->m_pkthdr.label);
+	MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf,
+	    newmbuflabel);
 }
 
 void
 mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
 {
+	struct m_tag *tag;
+	struct label *label;
 
+	tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_mbuf_from_bpfdesc: NULL tag"));
+	label = (struct label *)(tag+1);
+
 	MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
-	    &mbuf->m_pkthdr.label);
+	    label);
 }
 
 void
 mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
 {
+	struct m_tag *tag;
+	struct label *label;
+
+	tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_mbuf_linklayer: NULL tag"));
+	label = (struct label *)(tag+1);
 
 	MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
-	    &mbuf->m_pkthdr.label);
+	    label);
 }
 
 void
 mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
 {
+	struct m_tag *tag;
+	struct label *label;
+
+	tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_mbuf_from_ifnet: NULL tag"));
+	label = (struct label *)(tag+1);
 
 	MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
-	    &mbuf->m_pkthdr.label);
+	    label);
 }
 
 void
 mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
     struct mbuf *newmbuf)
 {
+	struct m_tag *tag;
+	struct label *oldmbuflabel, *newmbuflabel;
 
-	MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf,
-	    &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf,
-	    &newmbuf->m_pkthdr.label);
+	tag = m_tag_find(oldmbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_mbuf_multicast_encap: NULL tag"));
+	oldmbuflabel = (struct label *)(tag+1);
+
+	tag = m_tag_find(newmbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_mbuf_multicast_encap: NULL tag"));
+	newmbuflabel = (struct label *)(tag+1);
+
+	MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel,
+	    ifnet, &ifnet->if_label, newmbuf, newmbuflabel);
 }
 
 void
 mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
 {
+	struct m_tag *tag;
+	struct label *oldmbuflabel, *newmbuflabel;
 
-	MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label,
-	    newmbuf, &newmbuf->m_pkthdr.label);
+	tag = m_tag_find(oldmbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_mbuf_netlayer: NULL tag"));
+	oldmbuflabel = (struct label *)(tag+1);
+
+	tag = m_tag_find(newmbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_mbuf_netlayer: NULL tag"));
+	newmbuflabel = (struct label *)(tag+1);
+
+	MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf,
+	    newmbuflabel);
 }
 
 int
 mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
 {
+	struct m_tag *tag;
+	struct label *label;
+
+	tag = m_tag_find(fragment, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_fragment_match: NULL tag"));
+	label = (struct label *)(tag+1);
 	int result;
 
 	result = 1;
-	MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label,
-	    ipq, &ipq->ipq_label);
+	MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq,
+	    &ipq->ipq_label);
 
 	return (result);
 }
@@ -2187,17 +2279,28 @@
 void
 mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
 {
+	struct m_tag *tag;
+	struct label *label;
+
+	tag = m_tag_find(fragment, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_update_ipq: NULL tag"));
+	label = (struct label *)(tag+1);
 
-	MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq,
-	    &ipq->ipq_label);
+	MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label);
 }
 
 void
 mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
 {
+	struct m_tag *tag;
+	struct label *label;
+
+	tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_create_mbuf_from_socket: NULL tag"));
+	label = (struct label *)(tag+1);
 
 	MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
-	    &mbuf->m_pkthdr.label);
+	    label);
 }
 
 void
@@ -2256,17 +2359,21 @@
 int
 mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
 {
+	struct m_tag *tag;
+	struct label *label;
+
+	KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr"));
+
+	tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_check_ifnet_transmit: NULL tag"));
+	label = (struct label *)(tag+1);
 	int error;
 
 	if (!mac_enforce_network)
 		return (0);
 
-	KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr"));
-	if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
-		if_printf(ifnet, "not initialized\n");
-
 	MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
-	    &mbuf->m_pkthdr.label);
+	    label);
 
 	return (error);
 }
@@ -2547,13 +2654,19 @@
 int
 mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
 {
+	struct m_tag *tag;
+	struct label *label;
+
+	tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
+	KASSERT(tag != NULL, ("mac_check_socket_deliver: NULL tag"));
+	label = (struct label *)(tag+1);
 	int error;
 
 	if (!mac_enforce_socket)
 		return (0);
 
 	MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
-	    &mbuf->m_pkthdr.label);
+	    label);
 
 	return (error);
 }
==== //depot/projects/trustedbsd/mac/sys/kern/subr_mbuf.c#23 - /data/p4/rwatson/trustedbsd/mac/sys/kern/subr_mbuf.c ====
@@ -1252,16 +1252,27 @@
 struct mbuf *
 m_gethdr(int how, short type)
 {
+#ifdef MAC
+	struct m_tag *tag;
+#endif
 	struct mbuf *mb;
 
 	mb = (struct mbuf *)mb_alloc(&mb_list_mbuf, how, type, 0, NULL);
 	if (mb != NULL) {
 		_mbhdr_setup(mb, type);
 #ifdef MAC
-		if (mac_init_mbuf(mb, how) != 0) {
+		tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
+		    how);
+		if (tag == NULL) {
 			m_free(mb);
-			return NULL;
+			return (NULL);
 		}
+		if (mac_init_mbuf_tag(tag, how) != 0) {
+			m_tag_free(tag);
+			m_free(mb);
+			return (NULL);
+		} else
+			m_tag_prepend(mb, tag);
 #endif
 	}
 	return (mb);
@@ -1299,18 +1310,29 @@
  *  - type: the type of the mbuf being allocated.
  */
 struct mbuf *
-m_gethdr_clrd(int how, short type)
+m_gethdr_clrd(int  how, short type)
 {
+#ifdef MAC
+	struct m_tag *tag;
+#endif
 	struct mbuf *mb;
 
 	mb = (struct mbuf *)mb_alloc(&mb_list_mbuf, how, type, 0, NULL);
 	if (mb != NULL) {
 		_mbhdr_setup(mb, type);
 #ifdef MAC
-		if (mac_init_mbuf(mb, how) != 0) {
+		tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
+		    how);
+		if (tag == NULL) {
 			m_free(mb);
-			return NULL;
+			return (NULL);
 		}
+		if (mac_init_mbuf_tag(tag, how) != 0) {
+			m_tag_free(tag);
+			m_free(mb);
+			return (NULL);
+		} else
+			m_tag_prepend(mb, tag);
 #endif
 		bzero(mtod(mb, caddr_t), MHLEN);
 	}
@@ -1335,11 +1357,6 @@
 
 	if ((mb->m_flags & M_PKTHDR) != 0)
 		m_tag_delete_chain(mb, NULL);
-#ifdef MAC
-	if ((mb->m_flags & M_PKTHDR) &&
-	    (mb->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
-		mac_destroy_mbuf(mb);
-#endif
 	nb = mb->m_next;
 	if ((mb->m_flags & M_EXT) != 0) {
 		MEXT_REM_REF(mb);
@@ -1382,11 +1399,6 @@
 	while (mb != NULL) {
 		if ((mb->m_flags & M_PKTHDR) != 0)
 			m_tag_delete_chain(mb, NULL);
-#ifdef MAC
-		if ((mb->m_flags & M_PKTHDR) &&
-		    (mb->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
-			mac_destroy_mbuf(mb);
-#endif
 		persist = 0;
 		m = mb;
 		mb = mb->m_next;
@@ -1427,6 +1439,9 @@
 struct mbuf *
 m_getcl(int how, short type, int flags)
 {
+#ifdef MAC
+	struct m_tag *tag;
+#endif
 	struct mbuf *mb;
 	int cchnum;
 
@@ -1454,9 +1469,19 @@
 		_mext_init_ref(mb, &cl_refcntmap[cl2ref(mb->m_ext.ext_buf)]);
 	}
 #ifdef MAC
-	if ((flags & M_PKTHDR) && (mac_init_mbuf(mb, how) != 0)) {
-		m_free(mb);
-		return NULL;
+	if (flags & M_PKTHDR) {
+		tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
+		    how);
+		if (tag == NULL) {
+			m_free(mb);
+			return (NULL);
+		}
+		if (mac_init_mbuf_tag(tag, how) != 0) {
+			m_tag_free(tag);
+			m_free(mb);
+			return (NULL);
+		} else
+			m_tag_prepend(mb, tag);
 	}
 #endif
 	return (mb);
==== //depot/projects/trustedbsd/mac/sys/kern/uipc_mbuf.c#15 - /data/p4/rwatson/trustedbsd/mac/sys/kern/uipc_mbuf.c ====
@@ -78,18 +78,29 @@
 	KASSERT(to->m_flags & M_PKTHDR,
 	    ("m_copy_pkthdr() called on non-header"));
 #endif
-#ifdef MAC
 	if (to->m_flags & M_PKTHDR)
-		mac_destroy_mbuf(to);
+		m_tag_delete_chain(to, NULL);
+	to->m_data = to->m_pktdat;
+	to->m_flags = from->m_flags & M_COPYFLAGS;
+	to->m_pkthdr = from->m_pkthdr;
+	SLIST_INIT(&from->m_pkthdr.tags);
+}
+
+int
+m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how)
+{
+
+#if 0
+	KASSERT(to->m_flags & M_PKTHDR,
+	    ("m_dup_pkthdr() called on a non-header"));
 #endif
+	if (to->m_flags & M_PKTHDR)
+		m_tag_delete_chain(to, NULL);
 	to->m_data = to->m_pktdat;
 	to->m_flags = from->m_flags & M_COPYFLAGS;
 	to->m_pkthdr = from->m_pkthdr;
-#ifdef MAC
-	mac_init_mbuf(to, 1);			/* XXXMAC no way to fail */
-	mac_create_mbuf_from_mbuf(from, to);
-#endif
-	SLIST_INIT(&from->m_pkthdr.tags);
+	SLIST_INIT(&to->m_pkthdr.tags);
+	return (m_tag_copy_chain(to, from, how));
 }
 
 /*
@@ -109,9 +120,6 @@
 	}
 	if (m->m_flags & M_PKTHDR) {
 		M_COPY_PKTHDR(mn, m);
-#ifdef MAC
-		mac_destroy_mbuf(m);
-#endif
 		m->m_flags &= ~M_PKTHDR;
 	}
 	mn->m_next = m;
@@ -161,7 +169,8 @@
 		if (n == NULL)
 			goto nospace;
 		if (copyhdr) {
-			M_COPY_PKTHDR(n, m);
+			if (!m_dup_pkthdr(n, m, wait))
+				goto nospace;
 			if (len == M_COPYALL)
 				n->m_pkthdr.len -= off0;
 			else
@@ -212,7 +221,8 @@
 	if (n == NULL)
 		goto nospace;
 
-	M_COPY_PKTHDR(n, m);
+	if (!m_dup_pkthdr(n, m, how))
+		goto nospace;
 	n->m_len = m->m_len;
 	if (m->m_flags & M_EXT) {
 		n->m_data = m->m_data;
@@ -309,7 +319,8 @@
 		if (n == NULL)
 			goto nospace;
 		if (top == NULL) {		/* first one, must be PKTHDR */
-			M_COPY_PKTHDR(n, m);
+			if (!m_dup_pkthdr(n, m, how))
+				goto nospace;
 			nsize = MHLEN;
 		} else				/* not the first one */
 			nsize = MLEN;
==== //depot/projects/trustedbsd/mac/sys/kern/uipc_mbuf2.c#7 - /data/p4/rwatson/trustedbsd/mac/sys/kern/uipc_mbuf2.c ====
@@ -68,10 +68,13 @@
 
 /*#define PULLDOWN_DEBUG*/
 
+#include "opt_mac.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
+#include <sys/mac.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/mutex.h>
@@ -298,8 +301,12 @@
 	if (!n)
 		return NULL;
 
-	if (copyhdr)
-		M_COPY_PKTHDR(n, m);
+	if (copyhdr) {
+		if (!m_dup_pkthdr(n, m, wait)) {
+			m_free(n);
+			return NULL;
+		}
+	}
 	m_copydata(m, off, len, mtod(n, caddr_t));
 	return n;
 }
@@ -325,6 +332,10 @@
 void
 m_tag_free(struct m_tag *t)
 {
+#ifdef MAC
+	if (t->m_tag_id == PACKET_TAG_MACLABEL)
+		mac_destroy_mbuf_tag(t);
+#endif
 	free(t, M_PACKET_TAGS);
 }
 
@@ -392,15 +403,24 @@
 
 /* Copy a single tag. */
 struct m_tag *
-m_tag_copy(struct m_tag *t)
+m_tag_copy(struct m_tag *t, int how)
 {
 	struct m_tag *p;
 
 	KASSERT(t, ("m_tag_copy: null tag"));
-	p = m_tag_alloc(t->m_tag_cookie, t->m_tag_id, t->m_tag_len, M_NOWAIT);
+	p = m_tag_alloc(t->m_tag_cookie, t->m_tag_id, t->m_tag_len, how);
 	if (p == NULL)
 		return (NULL);
-	bcopy(t + 1, p + 1, t->m_tag_len); /* Copy the data */
+#ifdef MAC
+	if (t->m_tag_id == PACKET_TAG_MACLABEL) {
+		if (mac_init_mbuf_tag(p, how) != 0) {
+			m_tag_free(p);
+			return (NULL);
+		}
+		mac_copy_mbuf_tag(t, p);
+	} else
+#endif
+		bcopy(t + 1, p + 1, t->m_tag_len); /* Copy the data */
 	return p;
 }
 
@@ -411,7 +431,7 @@
  * destination mbuf.
  */
 int
-m_tag_copy_chain(struct mbuf *to, struct mbuf *from)
+m_tag_copy_chain(struct mbuf *to, struct mbuf *from, int how)
 {
 	struct m_tag *p, *t, *tprev = NULL;
 
@@ -419,7 +439,7 @@
 		("m_tag_copy: null argument, to %p from %p", to, from));
 	m_tag_delete_chain(to, NULL);
 	SLIST_FOREACH(p, &from->m_pkthdr.tags, m_tag_link) {
-		t = m_tag_copy(p);
+		t = m_tag_copy(p, how);
 		if (t == NULL) {
 			m_tag_delete_chain(to, NULL);
 			return 0;
==== //depot/projects/trustedbsd/mac/sys/net/if_loop.c#12 - /data/p4/rwatson/trustedbsd/mac/sys/net/if_loop.c ====
==== //depot/projects/trustedbsd/mac/sys/netinet/ip_input.c#22 - /data/p4/rwatson/trustedbsd/mac/sys/netinet/ip_input.c ====
@@ -1757,17 +1757,14 @@
 	 */
 	MGET(mcopy, M_DONTWAIT, m->m_type);
 	if (mcopy != NULL) {
-		M_COPY_PKTHDR(mcopy, m);
-		mcopy->m_len = imin((ip->ip_hl << 2) + 8,
-		    (int)ip->ip_len);
-		m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t));
-#ifdef MAC
-		/*
-		 * XXXMAC: This will eventually become an explicit
-		 * labeling point.
-		 */
-		mac_create_mbuf_from_mbuf(m, mcopy);
-#endif
+		if (m_dup_pkthdr(mcopy, m, M_DONTWAIT)) {
+			mcopy->m_len = imin((ip->ip_hl << 2) + 8,
+			    (int)ip->ip_len);
+			m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t));
+		} else {
+			m_freem(mcopy);
+			mcopy = NULL;
+		}
 	}
 
 #ifdef IPSTEALTH
==== //depot/projects/trustedbsd/mac/sys/netinet6/esp_input.c#8 - /data/p4/rwatson/trustedbsd/mac/sys/netinet6/esp_input.c ====
@@ -812,8 +812,12 @@
 
 			MGETHDR(n, M_DONTWAIT, MT_HEADER);
 			maxlen = MHLEN;
-			if (n)
-				M_COPY_PKTHDR(n, m);
+			if (n) {
+				if (!m_dup_pkthdr(n, m)) {
+					m_free(n);
+					n = NULL;
+				}
+			}
 			if (n && m->m_pkthdr.len > maxlen) {
 				MCLGET(n, M_DONTWAIT);
 				maxlen = MCLBYTES;
==== //depot/projects/trustedbsd/mac/sys/netinet6/ip6_output.c#11 - /data/p4/rwatson/trustedbsd/mac/sys/netinet6/ip6_output.c ====
@@ -2575,7 +2575,11 @@
 			m_freem(m);
 			return ENOBUFS;
 		}
-		M_COPY_PKTHDR(mh, m);
+		if (!m_dup_pkthdr(mh, m, M_DONTWAIT)) {
+			m_freem(mh);
+			m_freem(m);
+			return ENOBUFS;
+		}
 		MH_ALIGN(mh, sizeof(*ip6));
 		m->m_flags &= ~M_PKTHDR;
 		m->m_len -= sizeof(*ip6);
==== //depot/projects/trustedbsd/mac/sys/netinet6/ipsec.c#5 - /data/p4/rwatson/trustedbsd/mac/sys/netinet6/ipsec.c ====
@@ -3124,7 +3124,11 @@
 			m_freem(m);
 			return NULL;
 		}
-		M_COPY_PKTHDR(mh, m);
+		if (!m_dup_pkthdr(mh, m, M_DONTWAIT)) {
+			m_freem(mh);
+			m_freem(m);
+			return NULL;
+		}
 		MH_ALIGN(mh, hlen);
 		m->m_flags &= ~M_PKTHDR;
 		m->m_len -= hlen;
@@ -3161,7 +3165,11 @@
 			m_freem(m);
 			return NULL;
 		}
-		M_COPY_PKTHDR(mh, m);
+		if (!m_dup_pkthdr(mh, m, M_DONTWAIT)) {
+			m_freem(mh);
+			m_freem(m);
+			return NULL;
+		}
 		MH_ALIGN(mh, hlen);
 		m->m_flags &= ~M_PKTHDR;
 		m->m_len -= hlen;
@@ -3379,7 +3387,12 @@
 						    0, M_COPYALL, M_DONTWAIT);
 					}
 #endif
-					M_COPY_PKTHDR(mnew, n);
+					if (!m_dup_pkthdr(mnew, m,
+					    M_DONTWAIT)) {
+						m_freem(mnew);
+						mnew = NULL;
+						goto fail;
+					}
 					mnew->m_flags = n->m_flags & M_COPYFLAGS;
 				}
 				else {
==== //depot/projects/trustedbsd/mac/sys/sys/mac.h#220 - /data/p4/rwatson/trustedbsd/mac/sys/sys/mac.h ====
@@ -117,6 +117,7 @@
 struct ifreq;
 struct image_params;
 struct ipq;
+struct m_tag;
 struct mbuf;
 struct mount;
 struct proc;
@@ -144,11 +145,12 @@
 void	mac_init_ipq(struct ipq *);
 int	mac_init_socket(struct socket *, int flag);
 void	mac_init_pipe(struct pipe *);
-int	mac_init_mbuf(struct mbuf *m, int flag);
+int	mac_init_mbuf_tag(struct m_tag *, int flag);
 void	mac_init_mount(struct mount *);
 void	mac_init_proc(struct proc *);
 void	mac_init_vnode(struct vnode *);
 void	mac_init_vnode_label(struct label *);
+void	mac_copy_mbuf_tag(struct m_tag *, struct m_tag *);
 void	mac_copy_vnode_label(struct label *, struct label *label);
 void	mac_destroy_bpfdesc(struct bpf_d *);
 void	mac_destroy_cred(struct ucred *);
@@ -158,7 +160,7 @@
 void	mac_destroy_socket(struct socket *);
 void	mac_destroy_pipe(struct pipe *);
 void	mac_destroy_proc(struct proc *);
-void	mac_destroy_mbuf(struct mbuf *);
+void	mac_destroy_mbuf_tag(struct m_tag *);
 void	mac_destroy_mount(struct mount *);
 void	mac_destroy_vnode(struct vnode *);
 void	mac_destroy_vnode_label(struct label *);
==== //depot/projects/trustedbsd/mac/sys/sys/mac_policy.h#174 - /data/p4/rwatson/trustedbsd/mac/sys/sys/mac_policy.h ====
@@ -95,6 +95,8 @@
 	void	(*mpo_destroy_pipe_label)(struct label *label);
 	void	(*mpo_destroy_proc_label)(struct label *label);
 	void	(*mpo_destroy_vnode_label)(struct label *label);
+	void	(*mpo_copy_mbuf_label)(struct label *src,
+		    struct label *dest);
 	void	(*mpo_copy_pipe_label)(struct label *src,
 		    struct label *dest);
 	void	(*mpo_copy_vnode_label)(struct label *src,
==== //depot/projects/trustedbsd/mac/sys/sys/mbuf.h#20 - /data/p4/rwatson/trustedbsd/mac/sys/sys/mbuf.h ====
@@ -37,7 +37,6 @@
 #ifndef _SYS_MBUF_H_
 #define	_SYS_MBUF_H_
 
-#include <sys/_label.h>
 #include <sys/queue.h>
 
 /*
@@ -98,7 +97,6 @@
 	int	csum_flags;		/* flags regarding checksum */
 	int	csum_data;		/* data field used by csum routines */
 	SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
-	struct	label label;		/* MAC label of data in packet */
 };
 
 /*
@@ -428,6 +426,7 @@
 struct	mbuf	*m_devget(char *, int, int, struct ifnet *,
 		    void (*)(char *, caddr_t, u_int));
 struct	mbuf	*m_dup(struct mbuf *, int);
+int		 m_dup_pkthdr(struct mbuf *, struct mbuf *, int);
 u_int		 m_fixhdr(struct mbuf *);
 struct	mbuf	*m_free(struct mbuf *);
 void		 m_freem(struct mbuf *);
@@ -519,6 +518,7 @@
 #define	PACKET_TAG_IPFW				16 /* ipfw classification */
 #define	PACKET_TAG_DIVERT			17 /* divert info */
 #define	PACKET_TAG_IPFORWARD			18 /* ipforward info */
+#define	PACKET_TAG_MACLABEL			19 /* MAC label */
 
 /* Packet tag routines */
 struct	m_tag 	*m_tag_alloc(u_int32_t, int, int, int);
@@ -528,8 +528,8 @@
 void		 m_tag_delete(struct mbuf *, struct m_tag *);
 void		 m_tag_delete_chain(struct mbuf *, struct m_tag *);
 struct	m_tag	*m_tag_locate(struct mbuf *, u_int32_t, int, struct m_tag *);
-struct	m_tag	*m_tag_copy(struct m_tag *);
-int		 m_tag_copy_chain(struct mbuf *, struct mbuf *);
+struct	m_tag	*m_tag_copy(struct m_tag *, int);
+int		 m_tag_copy_chain(struct mbuf *, struct mbuf *, int);
 void		 m_tag_init(struct mbuf *);
 struct	m_tag	*m_tag_first(struct mbuf *);
 struct	m_tag	*m_tag_next(struct mbuf *, struct m_tag *);
