svn commit: r349927 - in stable: 10/sys/contrib/ipfilter/netinet 11/sys/contrib/ipfilter/netinet 12/sys/contrib/ipfilter/netinet

Cy Schubert cy at FreeBSD.org
Fri Jul 12 00:50:35 UTC 2019


Author: cy
Date: Fri Jul 12 00:50:33 2019
New Revision: 349927
URL: https://svnweb.freebsd.org/changeset/base/349927

Log:
  MFC r348987, r348989:
  
  Resolve IPv6 checksum errors with stateful inspection. According to
  PR/203585 this appears to have been broken by r235959, which predates
  the ipfilter 5.1.2 import into FreeBSD.
  
  The IPv6 checksum calculation is incorrect. To resolve this we call
  in6_cksum() to do the the heavy lifting for us, through a new function
  ipf_pcksum6(). Should we need to revisit this area again, a DTrace probe
  is added to aid with future debugging.
  
  Plus whitespace adjustments (r348989).
  
  PR:		203275, 203585
  Differential Revision:	https://reviews.freebsd.org/D20583

Modified:
  stable/11/sys/contrib/ipfilter/netinet/fil.c
  stable/11/sys/contrib/ipfilter/netinet/ip_fil.h
  stable/11/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
Directory Properties:
  stable/11/   (props changed)

Changes in other areas also in this revision:
Modified:
  stable/10/sys/contrib/ipfilter/netinet/fil.c
  stable/10/sys/contrib/ipfilter/netinet/ip_fil.h
  stable/10/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
  stable/12/sys/contrib/ipfilter/netinet/fil.c
  stable/12/sys/contrib/ipfilter/netinet/ip_fil.h
  stable/12/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
Directory Properties:
  stable/10/   (props changed)
  stable/12/   (props changed)

Modified: stable/11/sys/contrib/ipfilter/netinet/fil.c
==============================================================================
--- stable/11/sys/contrib/ipfilter/netinet/fil.c	Fri Jul 12 00:35:43 2019	(r349926)
+++ stable/11/sys/contrib/ipfilter/netinet/fil.c	Fri Jul 12 00:50:33 2019	(r349927)
@@ -3426,35 +3426,21 @@ fr_cksum(fin, ip, l4proto, l4hdr)
 		sum += *sp++;
 		sum += *sp++;	/* ip_dst */
 		sum += *sp++;
+		slen = fin->fin_plen - off;
+		sum += htons(slen);
 #ifdef	USE_INET6
 	} else if (IP_V(ip) == 6) {
+		mb_t *m;
+
+		m = fin->fin_m;
 		ip6 = (ip6_t *)ip;
-		hlen = sizeof(*ip6);
-		off = ((char *)fin->fin_dp - (char *)fin->fin_ip);
-		sp = (u_short *)&ip6->ip6_src;
-		sum += *sp++;	/* ip6_src */
-		sum += *sp++;
-		sum += *sp++;
-		sum += *sp++;
-		sum += *sp++;
-		sum += *sp++;
-		sum += *sp++;
-		sum += *sp++;
-		/* This needs to be routing header aware. */
-		sum += *sp++;	/* ip6_dst */
-		sum += *sp++;
-		sum += *sp++;
-		sum += *sp++;
-		sum += *sp++;
-		sum += *sp++;
-		sum += *sp++;
-		sum += *sp++;
+		off = ((caddr_t)ip6 - m->m_data) + sizeof(struct ip6_hdr);
+		int len = ntohs(ip6->ip6_plen) - (off - sizeof(*ip6));
+		return(ipf_pcksum6(fin, ip6, off, len));
 	} else {
 		return 0xffff;
 	}
 #endif
-	slen = fin->fin_plen - off;
-	sum += htons(slen);
 
 	switch (l4proto)
 	{
@@ -6649,6 +6635,12 @@ ipf_checkl4sum(fin)
 	if ((fin->fin_flx & (FI_FRAG|FI_SHORT|FI_BAD)) != 0)
 		return 1;
 
+	DT2(l4sumo, int, fin->fin_out, int, (int)fin->fin_p);
+	if (fin->fin_out == 1) {
+		fin->fin_cksum = FI_CK_SUMOK;
+		return 0;
+	}
+
 	csump = NULL;
 	hdrsum = 0;
 	dosum = 0;
@@ -6700,7 +6692,11 @@ ipf_checkl4sum(fin)
 	}
 #endif
 	DT2(l4sums, u_short, hdrsum, u_short, sum);
+#ifdef USE_INET6
+	if (hdrsum == sum || (sum == 0 && fin->fin_p == IPPROTO_ICMPV6)) {
+#else
 	if (hdrsum == sum) {
+#endif
 		fin->fin_cksum = FI_CK_SUMOK;
 		return 0;
 	}

Modified: stable/11/sys/contrib/ipfilter/netinet/ip_fil.h
==============================================================================
--- stable/11/sys/contrib/ipfilter/netinet/ip_fil.h	Fri Jul 12 00:35:43 2019	(r349926)
+++ stable/11/sys/contrib/ipfilter/netinet/ip_fil.h	Fri Jul 12 00:50:33 2019	(r349927)
@@ -1835,6 +1835,10 @@ extern	int		ipf_matchicmpqueryreply __P((int, icmpinfo
 						     struct icmp *, int));
 extern	u_32_t		ipf_newisn __P((fr_info_t *));
 extern	u_int		ipf_pcksum __P((fr_info_t *, int, u_int));
+#ifdef	USE_INET6
+extern	u_int		ipf_pcksum6 __P((fr_info_t *, ip6_t *,
+						u_int32_t, u_int32_t));
+#endif
 extern	void		ipf_rule_expire __P((ipf_main_softc_t *));
 extern	int		ipf_scanlist __P((fr_info_t *, u_32_t));
 extern	frentry_t 	*ipf_srcgrpmap __P((fr_info_t *, u_32_t *));

Modified: stable/11/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
==============================================================================
--- stable/11/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c	Fri Jul 12 00:35:43 2019	(r349926)
+++ stable/11/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c	Fri Jul 12 00:50:33 2019	(r349927)
@@ -1447,3 +1447,56 @@ ipf_pcksum(fin, hlen, sum)
 	sum2 = ~sum & 0xffff;
 	return sum2;
 }
+
+#ifdef  USE_INET6
+#ifdef	_KERNEL
+u_int
+ipf_pcksum6(fin, ip6, off, len)
+	fr_info_t *fin;
+	ip6_t *ip6;
+	u_int32_t off;
+	u_int32_t len;
+{
+	struct mbuf *m;
+	int sum;
+
+	m = fin->fin_m;
+	if (m->m_len < sizeof(struct ip6_hdr)) {
+		return 0xffff;
+	}
+
+	sum = in6_cksum(m, ip6->ip6_nxt, off, len);
+	return(sum);
+}
+#else
+u_int
+ipf_pcksum6(fin, ip6, off, len)
+	fr_info_t *fin;
+	ip6_t *ip6;
+	u_int32_t off;
+	u_int32_t len;
+{
+	u_short *sp;
+	u_int sum;
+
+	sp = (u_short *)&ip6->ip6_src;
+	sum = *sp++;   /* ip6_src */
+	sum += *sp++;
+	sum += *sp++;
+	sum += *sp++;
+	sum += *sp++;
+	sum += *sp++;
+	sum += *sp++;
+	sum += *sp++;
+	sum += *sp++;   /* ip6_dst */
+	sum += *sp++;
+	sum += *sp++;
+	sum += *sp++;
+	sum += *sp++;
+	sum += *sp++;
+	sum += *sp++;
+	sum += *sp++;
+	return(ipf_pcksum(fin, off, sum));
+}
+#endif
+#endif


More information about the svn-src-all mailing list