diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2015-09-11 15:12:30 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2015-09-11 15:12:30 +0000 |
commit | a54df8ef8a12563d8397a4ce12c43a638e28f768 (patch) | |
tree | 43f37308105aadaa46913ad7d4b2152ef6964dcf /sys/netinet6 | |
parent | c6881f5e14705f60ed4d6c879bf66648d71ebecc (diff) |
When pf modifies a TCP packet, it sets the M_TCP_CSUM_OUT flag in
the mbuf packet header. If the packet and is later dropped in
ip6_forward(), the TCP mbuf is copied and passed to icmp6_error().
IPv6 uses m_copym() and M_PREPEND() which preserve the packet header.
The inherited M_TCP_CSUM_OUT flag generates ICMP6 packets with an
incorrect checksum. So reset the csum_flags when packets are
generated by icmp6_reflect() or icmp6_redirect_output().
IPv4 does m_copydata() into a fresh mbuf. There m_inithdr() clears
the packet header, so the problem does not occur. But setting the
csum_flags explicitly also makes sense for icmp_send(). Do not or
M_ICMP_CSUM_OUT to a value that is 0 because of some function calls
before.
OK mpi@ lteo@
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/icmp6.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index dac1e9a988c..ea170130fed 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.c,v 1.168 2015/09/11 09:14:06 claudio Exp $ */ +/* $OpenBSD: icmp6.c,v 1.169 2015/09/11 15:12:29 bluhm Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -1283,7 +1283,7 @@ icmp6_reflect(struct mbuf *m, size_t off) ip6->ip6_hlim = ip6_defhlim; icmp6->icmp6_cksum = 0; - m->m_pkthdr.csum_flags |= M_ICMP_CSUM_OUT; + m->m_pkthdr.csum_flags = M_ICMP_CSUM_OUT; /* * XXX option handling @@ -1789,7 +1789,7 @@ noredhdropt: ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr)); nd_rd->nd_rd_cksum = 0; - m->m_pkthdr.csum_flags |= M_ICMP_CSUM_OUT; + m->m_pkthdr.csum_flags = M_ICMP_CSUM_OUT; /* send the packet to outside... */ ip6_output(m, NULL, NULL, 0, NULL, NULL); |