Module Name:    src
Committed By:   christos
Date:           Sun Feb 19 20:27:22 UTC 2017

Modified Files:
        src/sys/net/npf: npf_handler.c npf_inet.c

Log Message:
Don't reassemble ipv6 fragments, instead treat the first fragment as a regular
packet (subject to filtering rules), and pass subsequent fragments in the
same group unconditionally.


To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/sys/net/npf/npf_handler.c \
    src/sys/net/npf/npf_inet.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/npf/npf_handler.c
diff -u src/sys/net/npf/npf_handler.c:1.36 src/sys/net/npf/npf_handler.c:1.37
--- src/sys/net/npf/npf_handler.c:1.36	Sat Jan 28 19:15:54 2017
+++ src/sys/net/npf/npf_handler.c	Sun Feb 19 15:27:22 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_handler.c,v 1.36 2017/01/29 00:15:54 christos Exp $	*/
+/*	$NetBSD: npf_handler.c,v 1.37 2017/02/19 20:27:22 christos Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.36 2017/01/29 00:15:54 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.37 2017/02/19 20:27:22 christos Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -129,7 +129,7 @@ npf_packet_handler(npf_t *npf, struct mb
 	npf_conn_t *con;
 	npf_rule_t *rl;
 	npf_rproc_t *rp;
-	int error, decision;
+	int error, decision, flags;
 	uint32_t ntag;
 	npf_match_info_t mi;
 
@@ -155,9 +155,17 @@ npf_packet_handler(npf_t *npf, struct mb
 	rp = NULL;
 
 	/* Cache everything.  Determine whether it is an IP fragment. */
-	if (__predict_false(npf_cache_all(&npc) & NPC_IPFRAG)) {
+	flags = npf_cache_all(&npc);
+	if (__predict_false(flags & NPC_IPFRAG)) {
 		/*
-		 * Pass to IPv4 or IPv6 reassembly mechanism.
+		 * We pass IPv6 fragments unconditionally
+		 * The first IPv6 fragment is not marked as such
+		 * and passes through the filter
+		 */
+		if (flags & NPC_IP6)
+			return 0;
+		/*
+		 * Pass to IPv4 reassembly mechanism.
 		 */
 		error = npf_reassembly(npf, &npc, mp);
 		if (error) {
Index: src/sys/net/npf/npf_inet.c
diff -u src/sys/net/npf/npf_inet.c:1.36 src/sys/net/npf/npf_inet.c:1.37
--- src/sys/net/npf/npf_inet.c:1.36	Mon Dec 26 18:05:06 2016
+++ src/sys/net/npf/npf_inet.c	Sun Feb 19 15:27:22 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_inet.c,v 1.36 2016/12/26 23:05:06 christos Exp $	*/
+/*	$NetBSD: npf_inet.c,v 1.37 2017/02/19 20:27:22 christos Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -40,7 +40,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.36 2016/12/26 23:05:06 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.37 2017/02/19 20:27:22 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -355,6 +355,7 @@ npf_cache_ip(npf_cache_t *npc, nbuf_t *n
 	case (IPV6_VERSION >> 4): {
 		struct ip6_hdr *ip6;
 		struct ip6_ext *ip6e;
+		struct ip6_frag *ip6f;
 		size_t off, hlen;
 
 		ip6 = nbuf_ensure_contig(nbuf, sizeof(struct ip6_hdr));
@@ -387,8 +388,21 @@ npf_cache_ip(npf_cache_t *npc, nbuf_t *n
 				hlen = (ip6e->ip6e_len + 1) << 3;
 				break;
 			case IPPROTO_FRAGMENT:
+				ip6f = nbuf_ensure_contig(nbuf, sizeof(*ip6f));
+				if (ip6f == NULL)
+					return 0;
+				/*
+				 * We treat the first fragment as a regular
+				 * packet and then we pass the rest of the
+				 * fragments unconditionally. This way if
+				 * the first packet passes the rest will
+				 * be able to reassembled, if not they will
+				 * be ignored. We can do better later.
+				 */
+				if (ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK) != 0)
+					flags |= NPC_IPFRAG;
+
 				hlen = sizeof(struct ip6_frag);
-				flags |= NPC_IPFRAG;
 				break;
 			case IPPROTO_AH:
 				hlen = (ip6e->ip6e_len + 2) << 2;

Reply via email to