Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Feb 2012 15:37:35 +0000 (UTC)
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r231206 - stable/8/sys/netinet/ipfw
Message-ID:  <201202081537.q18FbZiq049073@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bz
Date: Wed Feb  8 15:37:34 2012
New Revision: 231206
URL: http://svn.freebsd.org/changeset/base/231206

Log:
  MFC r225030:
  
   While not explicitly allowed by RFC 2460, in case there is no
   translation technology involved (and that section is suggested to
   be removed by Errata 2843), single packet fragments do not harm.
  
   There is another errata and further drafts under discussion to clarify
   on these kinds of packets.
   Meanwhile add a sysctl to allow disabling this behaviour again.
   We will treat single packet fragment (a fragment header added
   when not needed) as if there was no fragment header.
  
   Submitted by:	Matthew Luckie (mjl luckie.org.nz) (original version)
  PR:		kern/145733

Modified:
  stable/8/sys/netinet/ipfw/ip_fw2.c
Directory Properties:
  stable/8/sys/   (props changed)

Modified: stable/8/sys/netinet/ipfw/ip_fw2.c
==============================================================================
--- stable/8/sys/netinet/ipfw/ip_fw2.c	Wed Feb  8 15:19:49 2012	(r231205)
+++ stable/8/sys/netinet/ipfw/ip_fw2.c	Wed Feb  8 15:37:34 2012	(r231206)
@@ -103,6 +103,9 @@ static VNET_DEFINE(int, ipfw_vnet_ready)
 static VNET_DEFINE(int, fw_deny_unknown_exthdrs);
 #define	V_fw_deny_unknown_exthdrs	VNET(fw_deny_unknown_exthdrs)
 
+static VNET_DEFINE(int, fw_permit_single_frag6) = 1;
+#define	V_fw_permit_single_frag6	VNET(fw_permit_single_frag6)
+
 #ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
 static int default_to_accept = 1;
 #else
@@ -177,6 +180,9 @@ SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw
 SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs,
     CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_deny_unknown_exthdrs), 0,
     "Deny packets with unknown IPv6 Extension Headers");
+SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, permit_single_frag6,
+    CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_permit_single_frag6), 0,
+    "Permit single packet IPv6 fragments");
 #endif /* INET6 */
 
 SYSEND
@@ -838,10 +844,14 @@ ipfw_chk(struct ip_fw_args *args)
 	 *	we have a fragment at this offset of an IPv4 packet.
 	 *	offset == 0 means that (if this is an IPv4 packet)
 	 *	this is the first or only fragment.
-	 *	For IPv6 offset == 0 means there is no Fragment Header. 
+	 *	For IPv6 offset == 0 means there is no Fragment Header or there
+	 *	is a single packet fragement (fragement header added without
+	 *	needed).  We will treat a single packet fragment as if there
+	 *	was no fragment header (or log/block depending on the
+	 *	V_fw_permit_single_frag6 sysctl setting).
 	 *	If offset != 0 for IPv6 always use correct mask to
-	 *	get the correct offset because we add IP6F_MORE_FRAG
-	 *	to be able to dectect the first fragment which would
+	 *	get the correct offset because we add IP6F_MORE_FRAG to be able
+	 *	to dectect the first of multiple fragments which would
 	 *	otherwise have offset = 0.
 	 */
 	u_short offset = 0;
@@ -1004,10 +1014,11 @@ do {								\
 				offset = ((struct ip6_frag *)ulp)->ip6f_offlg &
 					IP6F_OFF_MASK;
 				/* Add IP6F_MORE_FRAG for offset of first
-				 * fragment to be != 0. */
+				 * fragment to be != 0 if there shall be more. */
 				offset |= ((struct ip6_frag *)ulp)->ip6f_offlg &
 					IP6F_MORE_FRAG;
-				if (offset == 0) {
+				if (V_fw_permit_single_frag6 == 0 &&
+				    offset == 0) {
 					printf("IPFW2: IPV6 - Invalid Fragment "
 					    "Header\n");
 					if (V_fw_deny_unknown_exthdrs)



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