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;