diff options
Diffstat (limited to 'sys/netinet6/icmp6.c')
-rw-r--r-- | sys/netinet6/icmp6.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 9e3015d..a0bc165 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) { /* |