svn commit: r225030 - head/sys/netinet/ipfw

Bjoern A. Zeeb bz at FreeBSD.org
Sat Aug 20 12:40:18 UTC 2011


Author: bz
Date: Sat Aug 20 12:40:17 2011
New Revision: 225030
URL: http://svn.freebsd.org/changeset/base/225030

Log:
  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 under discussion to clarify and allow this.
  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.
  
  PR:		kern/145733
  Submitted by:	Matthew Luckie (mjl luckie.org.nz) (original version)
  Tested by:	Matthew Luckie (mjl luckie.org.nz)
  MFC after:	2 weeks
  Approved by:	re (kib)

Modified:
  head/sys/netinet/ipfw/ip_fw2.c

Modified: head/sys/netinet/ipfw/ip_fw2.c
==============================================================================
--- head/sys/netinet/ipfw/ip_fw2.c	Sat Aug 20 12:08:53 2011	(r225029)
+++ head/sys/netinet/ipfw/ip_fw2.c	Sat Aug 20 12:40:17 2011	(r225030)
@@ -107,6 +107,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
@@ -182,6 +185,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
@@ -871,10 +877,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;
@@ -1037,10 +1047,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)


More information about the svn-src-all mailing list