summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2015-09-11 15:12:30 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2015-09-11 15:12:30 +0000
commita54df8ef8a12563d8397a4ce12c43a638e28f768 (patch)
tree43f37308105aadaa46913ad7d4b2152ef6964dcf
parentc6881f5e14705f60ed4d6c879bf66648d71ebecc (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@
-rw-r--r--sys/netinet/ip_icmp.c4
-rw-r--r--sys/netinet6/icmp6.c6
2 files changed, 5 insertions, 5 deletions
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 518583717f5..e472c4d9372 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_icmp.c,v 1.139 2015/09/10 12:10:52 dlg Exp $ */
+/* $OpenBSD: ip_icmp.c,v 1.140 2015/09/11 15:12:29 bluhm Exp $ */
/* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */
/*
@@ -846,7 +846,7 @@ icmp_send(struct mbuf *m, struct mbuf *opts)
hlen = ip->ip_hl << 2;
icp = (struct icmp *)(mtod(m, caddr_t) + hlen);
icp->icmp_cksum = 0;
- m->m_pkthdr.csum_flags |= M_ICMP_CSUM_OUT;
+ m->m_pkthdr.csum_flags = M_ICMP_CSUM_OUT;
#ifdef ICMPPRINTFS
if (icmpprintfs) {
char dst[INET_ADDRSTRLEN], src[INET_ADDRSTRLEN];
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);