aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/awi/awi.c2
-rw-r--r--sys/dev/awi/awi_wep.c2
-rw-r--r--sys/dev/en/midway.c2
-rw-r--r--sys/dev/hifn/hifn7751.c7
-rw-r--r--sys/dev/ubsec/ubsec.c6
-rw-r--r--sys/kern/uipc_mbuf.c68
-rw-r--r--sys/kern/uipc_mbuf2.c14
-rw-r--r--sys/net/if_loop.c20
-rw-r--r--sys/netatm/port.h3
-rw-r--r--sys/netinet/ip_input.c11
-rw-r--r--sys/netinet6/esp_input.c3
-rw-r--r--sys/netinet6/icmp6.c17
-rw-r--r--sys/netinet6/ip6_input.c2
-rw-r--r--sys/netinet6/ip6_output.c2
-rw-r--r--sys/netinet6/ipsec.c16
-rw-r--r--sys/netipsec/ipsec_mbuf.c2
-rw-r--r--sys/netipsec/ipsec_output.c2
-rw-r--r--sys/sys/mbuf.h14
18 files changed, 126 insertions, 67 deletions
diff --git a/sys/dev/awi/awi.c b/sys/dev/awi/awi.c
index 37181981fead..e77fae6d601a 100644
--- a/sys/dev/awi/awi.c
+++ b/sys/dev/awi/awi.c
@@ -1326,7 +1326,7 @@ awi_fix_rxhdr(sc, m0)
m_freem(m0);
return NULL;
}
- M_COPY_PKTHDR(n, m0);
+ M_MOVE_PKTHDR(n, m0);
n->m_len = MHLEN;
} else {
MGET(n, M_DONTWAIT, MT_DATA);
diff --git a/sys/dev/awi/awi_wep.c b/sys/dev/awi/awi_wep.c
index b24bd9f567f3..ecaf548b4ce0 100644
--- a/sys/dev/awi/awi_wep.c
+++ b/sys/dev/awi/awi_wep.c
@@ -323,7 +323,7 @@ awi_wep_encrypt(sc, m0, txflag)
n0 = n;
if (n == NULL)
goto fail;
- M_COPY_PKTHDR(n, m);
+ M_MOVE_PKTHDR(n, m);
len = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
if (txflag) {
n->m_pkthdr.len += len;
diff --git a/sys/dev/en/midway.c b/sys/dev/en/midway.c
index 915fd14ca1e7..ffcc6c96dfda 100644
--- a/sys/dev/en/midway.c
+++ b/sys/dev/en/midway.c
@@ -1843,7 +1843,7 @@ STATIC int en_makeexclusive(sc, mm, prev)
return(0);
}
if (m->m_flags & M_PKTHDR)
- M_COPY_PKTHDR(new, m);
+ M_MOVE_PKTHDR(new, m);
MCLGET(new, M_DONTWAIT);
if ((new->m_flags & M_EXT) == 0) {
m_free(new);
diff --git a/sys/dev/hifn/hifn7751.c b/sys/dev/hifn/hifn7751.c
index ea87bd6f9ac3..accb5312c454 100644
--- a/sys/dev/hifn/hifn7751.c
+++ b/sys/dev/hifn/hifn7751.c
@@ -1668,6 +1668,10 @@ hifn_crypto(
if (cmd->src_m->m_flags & M_PKTHDR) {
len = MHLEN;
MGETHDR(m0, M_DONTWAIT, MT_DATA);
+ if (m0 && !m_dup_pkthdr(m0, cmd->src_m, M_DONTWAIT)) {
+ m_free(m0);
+ m0 = NULL;
+ }
} else {
len = MLEN;
MGET(m0, M_DONTWAIT, MT_DATA);
@@ -1677,9 +1681,6 @@ hifn_crypto(
err = dma->cmdu ? ERESTART : ENOMEM;
goto err_srcmap;
}
- if (len == MHLEN) {
- M_COPY_PKTHDR(m0, cmd->src_m);
- }
if (totlen >= MINCLSIZE) {
MCLGET(m0, M_DONTWAIT);
if ((m0->m_flags & M_EXT) == 0) {
diff --git a/sys/dev/ubsec/ubsec.c b/sys/dev/ubsec/ubsec.c
index 37cb37e3b708..b62a425085db 100644
--- a/sys/dev/ubsec/ubsec.c
+++ b/sys/dev/ubsec/ubsec.c
@@ -1269,6 +1269,10 @@ ubsec_process(void *arg, struct cryptop *crp, int hint)
if (q->q_src_m->m_flags & M_PKTHDR) {
len = MHLEN;
MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m && !m_dup_pkthdr(m, q->q_src_m, M_DONTWAIT)) {
+ m_free(m);
+ m = NULL;
+ }
} else {
len = MLEN;
MGET(m, M_DONTWAIT, MT_DATA);
@@ -1278,8 +1282,6 @@ ubsec_process(void *arg, struct cryptop *crp, int hint)
err = sc->sc_nqueue ? ERESTART : ENOMEM;
goto errout;
}
- if (len == MHLEN)
- M_COPY_PKTHDR(m, q->q_src_m);
if (totlen >= MINCLSIZE) {
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 6aedd110b677..bc6aa71e683c 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -66,30 +66,70 @@ SYSCTL_INT(_kern_ipc, KIPC_MAX_DATALEN, max_datalen, CTLFLAG_RW,
&max_datalen, 0, "");
/*
- * Copy mbuf pkthdr from "from" to "to".
+ * "Move" mbuf pkthdr from "from" to "to".
* "from" must have M_PKTHDR set, and "to" must be empty.
- * aux pointer will be moved to "to".
*/
void
-m_copy_pkthdr(struct mbuf *to, struct mbuf *from)
+m_move_pkthdr(struct mbuf *to, struct mbuf *from)
{
#if 0
+ /* see below for why these are not enabled */
KASSERT(to->m_flags & M_PKTHDR,
- ("m_copy_pkthdr() called on non-header"));
+ ("m_move_pkthdr: called on non-header"));
+ KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags),
+ ("m_move_pkthdr: to has tags"));
#endif
+ KASSERT((to->m_flags & M_EXT) == 0, ("m_move_pkthdr: to has cluster"));
#ifdef MAC
if (to->m_flags & M_PKTHDR)
mac_destroy_mbuf(to);
#endif
+ to->m_flags = from->m_flags & M_COPYFLAGS;
to->m_data = to->m_pktdat;
+ to->m_pkthdr = from->m_pkthdr; /* especially tags */
+#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); /* purge tags from src */
+ from->m_flags &= ~M_PKTHDR;
+}
+
+/*
+ * Duplicate "from"'s mbuf pkthdr in "to".
+ * "from" must have M_PKTHDR set, and "to" must be empty.
+ * In particular, this does a deep copy of the packet tags.
+ */
+int
+m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how)
+{
+
+#if 0
+ /*
+ * The mbuf allocator only initializes the pkthdr
+ * when the mbuf is allocated with MGETHDR. Many users
+ * (e.g. m_copy*, m_prepend) use MGET and then
+ * smash the pkthdr as needed causing these
+ * assertions to trip. For now just disable them.
+ */
+ KASSERT(to->m_flags & M_PKTHDR, ("m_dup_pkthdr: called on non-header"));
+ KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags), ("m_dup_pkthdr: to has tags"));
+#endif
+ KASSERT((to->m_flags & M_EXT) == 0, ("m_dup_pkthdr: to has cluster"));
+#ifdef MAC
+ if (to->m_flags & M_PKTHDR)
+ mac_destroy_mbuf(to);
+#endif
to->m_flags = from->m_flags & M_COPYFLAGS;
+ to->m_data = to->m_pktdat;
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));
}
/*
@@ -108,11 +148,10 @@ m_prepend(struct mbuf *m, int len, int how)
return (NULL);
}
if (m->m_flags & M_PKTHDR) {
- M_COPY_PKTHDR(mn, m);
+ M_MOVE_PKTHDR(mn, m);
#ifdef MAC
mac_destroy_mbuf(m);
#endif
- m->m_flags &= ~M_PKTHDR;
}
mn->m_next = m;
m = mn;
@@ -161,7 +200,8 @@ m_copym(struct mbuf *m, int off0, int len, int wait)
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 +252,8 @@ m_copypacket(struct mbuf *m, int how)
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 +350,8 @@ m_dup(struct mbuf *m, int how)
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;
@@ -484,10 +526,8 @@ m_pullup(struct mbuf *n, int len)
if (m == NULL)
goto bad;
m->m_len = 0;
- if (n->m_flags & M_PKTHDR) {
- M_COPY_PKTHDR(m, n);
- n->m_flags &= ~M_PKTHDR;
- }
+ if (n->m_flags & M_PKTHDR)
+ M_MOVE_PKTHDR(m, n);
}
space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
do {
diff --git a/sys/kern/uipc_mbuf2.c b/sys/kern/uipc_mbuf2.c
index 63d86b7bf974..9dbb7a32fee4 100644
--- a/sys/kern/uipc_mbuf2.c
+++ b/sys/kern/uipc_mbuf2.c
@@ -298,8 +298,10 @@ m_dup1(struct mbuf *m, int off, int len, int wait)
if (!n)
return NULL;
- if (copyhdr)
- M_COPY_PKTHDR(n, m);
+ if (copyhdr && !m_dup_pkthdr(n, m, wait)) {
+ m_free(n);
+ return NULL;
+ }
m_copydata(m, off, len, mtod(n, caddr_t));
return n;
}
@@ -392,12 +394,12 @@ m_tag_locate(struct mbuf *m, u_int32_t cookie, int type, struct m_tag *t)
/* 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 */
@@ -411,7 +413,7 @@ m_tag_copy(struct m_tag *t)
* 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 +421,7 @@ m_tag_copy_chain(struct mbuf *to, struct mbuf *from)
("m_tag_copy_chain: 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;
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 9c3affca973c..7c07931bf228 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -214,19 +214,11 @@ looutput(ifp, m, dst, rt)
if (m && m->m_next != NULL && m->m_pkthdr.len < MCLBYTES) {
struct mbuf *n;
+ /* XXX MT_HEADER should be m->m_type */
MGETHDR(n, M_DONTWAIT, MT_HEADER);
if (!n)
goto contiguousfail;
- MCLGET(n, M_DONTWAIT);
- if (! (n->m_flags & M_EXT)) {
- m_freem(n);
- goto contiguousfail;
- }
-
- m_copydata(m, 0, m->m_pkthdr.len, mtod(n, caddr_t));
- n->m_pkthdr = m->m_pkthdr;
- n->m_len = m->m_pkthdr.len;
- SLIST_INIT(&m->m_pkthdr.tags);
+ M_MOVE_PKTHDR(n, m);
#ifdef MAC
/*
* XXXMAC: Once we put labels in tags and proper
@@ -235,6 +227,14 @@ looutput(ifp, m, dst, rt)
*/
m->m_pkthdr.label.l_flags &= ~MAC_FLAG_INITIALIZED;
#endif
+ MCLGET(n, M_DONTWAIT);
+ if (! (n->m_flags & M_EXT)) {
+ m_freem(n);
+ goto contiguousfail;
+ }
+
+ m_copydata(m, 0, m->m_pkthdr.len, mtod(n, caddr_t));
+ n->m_len = m->m_pkthdr.len;
m_freem(m);
m = n;
}
diff --git a/sys/netatm/port.h b/sys/netatm/port.h
index 83e065476526..df599adf1cbc 100644
--- a/sys/netatm/port.h
+++ b/sys/netatm/port.h
@@ -178,8 +178,7 @@ typedef struct mbuf KBuffer;
}
#define KB_LINKHEAD(new, head) { \
if ((head) && KB_ISPKT(new) && KB_ISPKT(head)) {\
- M_COPY_PKTHDR((new), (head)); \
- (head)->m_flags &= ~M_PKTHDR; \
+ M_MOVE_PKTHDR((new), (head)); \
} \
(new)->m_next = (head); \
}
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 90f54e0c9230..51332a5eee99 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1763,8 +1763,17 @@ ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop)
* data in a cluster may change before we reach icmp_error().
*/
MGET(mcopy, M_DONTWAIT, m->m_type);
+ if (mcopy != NULL && !m_dup_pkthdr(mcopy, m, M_DONTWAIT)) {
+ /*
+ * It's probably ok if the pkthdr dup fails (because
+ * the deep copy of the tag chain failed), but for now
+ * be conservative and just discard the copy since
+ * code below may some day want the tags.
+ */
+ m_free(mcopy);
+ mcopy = NULL;
+ }
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));
diff --git a/sys/netinet6/esp_input.c b/sys/netinet6/esp_input.c
index b038f6c3826b..ad40e648c067 100644
--- a/sys/netinet6/esp_input.c
+++ b/sys/netinet6/esp_input.c
@@ -813,7 +813,7 @@ noreplaycheck:
MGETHDR(n, M_DONTWAIT, MT_HEADER);
maxlen = MHLEN;
if (n)
- M_COPY_PKTHDR(n, m);
+ M_MOVE_PKTHDR(n, m);
if (n && m->m_pkthdr.len > maxlen) {
MCLGET(n, M_DONTWAIT);
maxlen = MCLBYTES;
@@ -839,7 +839,6 @@ noreplaycheck:
n->m_pkthdr.len = m->m_pkthdr.len;
n->m_next = m;
m_adj(m, maxlen);
- m->m_flags &= ~M_PKTHDR;
}
m = n;
}
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 9e3015dc5503..a0bc16544f67 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -574,7 +574,7 @@ icmp6_input(mp, offp, proto)
m_freem(n0);
break;
}
- M_COPY_PKTHDR(n, n0);
+ M_MOVE_PKTHDR(n, n0);
/*
* Copy IPv6 and ICMPv6 only.
*/
@@ -592,7 +592,6 @@ icmp6_input(mp, offp, proto)
m_adj(n0, off + sizeof(struct icmp6_hdr));
n->m_pkthdr.len += n0->m_pkthdr.len;
n->m_next = n0;
- n0->m_flags &= ~M_PKTHDR;
} else {
nip6 = mtod(n, struct ip6_hdr *);
nicmp6 = (struct icmp6_hdr *)((caddr_t)nip6 + off);
@@ -690,6 +689,17 @@ icmp6_input(mp, offp, proto)
n = NULL;
}
}
+ if (!m_dup_pkthdr(n, m, M_DONTWAIT)) {
+ /*
+ * Previous code did a blind M_COPY_PKTHDR
+ * and said "just for rcvif". If true, then
+ * we could tolerate the dup failing (due to
+ * the deep copy of the tag chain). For now
+ * be conservative and just fail.
+ */
+ m_free(n);
+ n = NULL;
+ }
if (n == NULL) {
/* Give up remote */
break;
@@ -710,7 +720,6 @@ icmp6_input(mp, offp, proto)
bzero(p, 4);
bcopy(hostname, p + 4, maxhlen); /* meaningless TTL */
noff = sizeof(struct ip6_hdr);
- M_COPY_PKTHDR(n, m); /* just for rcvif */
n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) +
sizeof(struct icmp6_hdr) + 4 + maxhlen;
nicmp6->icmp6_type = ICMP6_WRUREPLY;
@@ -1387,7 +1396,7 @@ ni6_input(m, off)
m_freem(m);
return(NULL);
}
- M_COPY_PKTHDR(n, m); /* just for recvif */
+ M_MOVE_PKTHDR(n, m); /* just for recvif */
if (replylen > MHLEN) {
if (replylen > MCLBYTES) {
/*
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index e76727fa1bbd..15a44bbc8c5b 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -319,7 +319,7 @@ ip6_input(m)
MGETHDR(n, M_DONTWAIT, MT_HEADER);
if (n)
- M_COPY_PKTHDR(n, m);
+ M_MOVE_PKTHDR(n, m);
if (n && m->m_pkthdr.len > MHLEN) {
MCLGET(n, M_DONTWAIT);
if ((n->m_flags & M_EXT) == 0) {
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 94be84aae108..75ed4dc9df30 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -2575,7 +2575,7 @@ ip6_splithdr(m, exthdrs)
m_freem(m);
return ENOBUFS;
}
- M_COPY_PKTHDR(mh, m);
+ M_MOVE_PKTHDR(mh, m);
MH_ALIGN(mh, sizeof(*ip6));
m->m_flags &= ~M_PKTHDR;
m->m_len -= sizeof(*ip6);
diff --git a/sys/netinet6/ipsec.c b/sys/netinet6/ipsec.c
index b91470e504df..c25b1bf6d485 100644
--- a/sys/netinet6/ipsec.c
+++ b/sys/netinet6/ipsec.c
@@ -3124,7 +3124,7 @@ ipsec4_splithdr(m)
m_freem(m);
return NULL;
}
- M_COPY_PKTHDR(mh, m);
+ M_MOVE_PKTHDR(mh, m);
MH_ALIGN(mh, hlen);
m->m_flags &= ~M_PKTHDR;
m->m_len -= hlen;
@@ -3161,7 +3161,7 @@ ipsec6_splithdr(m)
m_freem(m);
return NULL;
}
- M_COPY_PKTHDR(mh, m);
+ M_MOVE_PKTHDR(mh, m);
MH_ALIGN(mh, hlen);
m->m_flags &= ~M_PKTHDR;
m->m_len -= hlen;
@@ -3371,16 +3371,10 @@ ipsec_copypkt(m)
MGETHDR(mnew, M_DONTWAIT, MT_HEADER);
if (mnew == NULL)
goto fail;
- mnew->m_pkthdr = n->m_pkthdr;
-#if 0
- if (n->m_pkthdr.aux) {
- mnew->m_pkthdr.aux =
- m_copym(n->m_pkthdr.aux,
- 0, M_COPYALL, M_DONTWAIT);
+ if (!m_dup_pkthdr(mnew, n, M_DONTWAIT)) {
+ m_free(mnew);
+ goto fail;
}
-#endif
- M_COPY_PKTHDR(mnew, n);
- mnew->m_flags = n->m_flags & M_COPYFLAGS;
}
else {
MGET(mnew, M_DONTWAIT, MT_DATA);
diff --git a/sys/netipsec/ipsec_mbuf.c b/sys/netipsec/ipsec_mbuf.c
index 4cf1c7c84e66..b2969ae7138a 100644
--- a/sys/netipsec/ipsec_mbuf.c
+++ b/sys/netipsec/ipsec_mbuf.c
@@ -101,7 +101,7 @@ m_clone(struct mbuf *m0)
m_freem(m0);
return (NULL);
}
- M_COPY_PKTHDR(n, m);
+ M_MOVE_PKTHDR(n, m);
MCLGET(n, M_DONTWAIT);
if ((n->m_flags & M_EXT) == 0) {
m_free(n);
diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c
index 836e17bd33dc..3748747abe9e 100644
--- a/sys/netipsec/ipsec_output.c
+++ b/sys/netipsec/ipsec_output.c
@@ -474,7 +474,7 @@ ipsec6_splithdr(struct mbuf *m)
m_freem(m);
return NULL;
}
- M_COPY_PKTHDR(mh, m);
+ M_MOVE_PKTHDR(mh, m);
MH_ALIGN(mh, hlen);
m->m_len -= hlen;
m->m_data += hlen;
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 69821f7f7a61..adc48325ecd1 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -177,8 +177,9 @@ struct mbuf {
/*
* Flags copied when copying m_pkthdr.
*/
-#define M_COPYFLAGS (M_PKTHDR|M_EOR|M_PROTO1|M_PROTO1|M_PROTO2|M_PROTO3 | \
- M_PROTO4|M_PROTO5|M_BCAST|M_MCAST|M_FRAG|M_RDONLY)
+#define M_COPYFLAGS (M_PKTHDR|M_EOR|M_RDONLY|M_PROTO1|M_PROTO1|M_PROTO2|\
+ M_PROTO3|M_PROTO4|M_PROTO5|M_BCAST|M_MCAST|\
+ M_FRAG|M_FIRSTFRAG|M_LASTFRAG)
/*
* Flags indicating hw checksum support and sw checksum requirements.
@@ -294,7 +295,8 @@ struct mbstat {
* mbuf, cluster, and external object allocation macros
* (for compatibility purposes).
*/
-#define M_COPY_PKTHDR(to, from) m_copy_pkthdr((to), (from))
+/* NB: M_COPY_PKTHDR is deprecated, use M_MOVE_PKTHDR or m_dup_pktdr */
+#define M_MOVE_PKTHDR(to, from) m_move_pkthdr((to), (from))
#define m_getclr(how, type) m_get_clrd((how), (type))
#define MGET(m, how, type) ((m) = m_get((how), (type)))
#define MGETHDR(m, how, type) ((m) = m_gethdr((how), (type)))
@@ -428,6 +430,7 @@ void m_copy_pkthdr(struct mbuf *, struct mbuf *);
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 *);
@@ -438,6 +441,7 @@ struct mbuf *m_gethdr(int, short);
struct mbuf *m_gethdr_clrd(int, short);
struct mbuf *m_getm(struct mbuf *, int, int, short);
u_int m_length(struct mbuf *, struct mbuf **);
+void m_move_pkthdr(struct mbuf *, struct mbuf *);
struct mbuf *m_prepend(struct mbuf *, int, int);
void m_print(const struct mbuf *);
struct mbuf *m_pulldown(struct mbuf *, int, int, int *);
@@ -528,8 +532,8 @@ void m_tag_unlink(struct mbuf *, struct m_tag *);
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 *);