aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet6/icmp6.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6/icmp6.c')
-rw-r--r--sys/netinet6/icmp6.c17
1 files changed, 13 insertions, 4 deletions
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) {
/*