Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Dec 2015 15:12:54 +0000 (UTC)
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r292732 - in stable/9/sys: contrib/pf/net netinet6
Message-ID:  <201512251512.tBPFCs4H027650@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kp
Date: Fri Dec 25 15:12:54 2015
New Revision: 292732
URL: https://svnweb.freebsd.org/changeset/base/292732

Log:
  pf: Fix IPv6 checksums with route-to.
  
  When using route-to (or reply-to) pf sends the packet directly to the output
  interface. If that interface doesn't support checksum offloading the checksum
  has to be calculated in software.
  That was already done in the IPv4 case, but not for the IPv6 case. As a result
  we'd emit packets with pseudo-header checksums (i.e. incorrect checksums).
  
  This issue was exposed by the changes in r289316 when pf stopped performing full
  checksum calculations for all packets.
  
  Submitted by:   Luoqi Chen

Modified:
  stable/9/sys/contrib/pf/net/pf.c
  stable/9/sys/netinet6/ip6_output.c
  stable/9/sys/netinet6/ip6_var.h

Modified: stable/9/sys/contrib/pf/net/pf.c
==============================================================================
--- stable/9/sys/contrib/pf/net/pf.c	Fri Dec 25 15:12:11 2015	(r292731)
+++ stable/9/sys/contrib/pf/net/pf.c	Fri Dec 25 15:12:54 2015	(r292732)
@@ -6340,6 +6340,13 @@ pf_route6(struct mbuf **m, struct pf_rul
 		ip6 = mtod(m0, struct ip6_hdr *);
 	}
 
+	if (m0->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6 &
+	    ~ifp->if_hwassist) {
+		uint32_t plen = m0->m_pkthdr.len - sizeof(*ip6);
+		in6_delayed_cksum(m0, plen, sizeof(struct ip6_hdr));
+		m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6;
+	}
+
 	/*
 	 * If the packet is too large for the outgoing interface,
 	 * send back an icmp6 error.

Modified: stable/9/sys/netinet6/ip6_output.c
==============================================================================
--- stable/9/sys/netinet6/ip6_output.c	Fri Dec 25 15:12:11 2015	(r292731)
+++ stable/9/sys/netinet6/ip6_output.c	Fri Dec 25 15:12:54 2015	(r292732)
@@ -184,7 +184,7 @@ static int copypktopts(struct ip6_pktopt
 	}\
     } while (/*CONSTCOND*/ 0)
 
-static void
+void
 in6_delayed_cksum(struct mbuf *m, uint32_t plen, u_short offset)
 {
 	u_short csum;

Modified: stable/9/sys/netinet6/ip6_var.h
==============================================================================
--- stable/9/sys/netinet6/ip6_var.h	Fri Dec 25 15:12:11 2015	(r292731)
+++ stable/9/sys/netinet6/ip6_var.h	Fri Dec 25 15:12:54 2015	(r292732)
@@ -455,6 +455,7 @@ int	in6_selectroute_fib(struct sockaddr_
 	    struct rtentry **, u_int);
 u_int32_t ip6_randomid(void);
 u_int32_t ip6_randomflowlabel(void);
+void in6_delayed_cksum(struct mbuf *m, uint32_t plen, u_short offset);
 #endif /* _KERNEL */
 
 #endif /* !_NETINET6_IP6_VAR_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512251512.tBPFCs4H027650>