Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net/npf Don't reassemble ipv6 fragments, instead treat t...



details:   https://anonhg.NetBSD.org/src/rev/f7af63b3979e
branches:  trunk
changeset: 821852:f7af63b3979e
user:      christos <christos%NetBSD.org@localhost>
date:      Sun Feb 19 20:27:22 2017 +0000

description:
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.

diffstat:

 sys/net/npf/npf_handler.c |  18 +++++++++++++-----
 sys/net/npf/npf_inet.c    |  20 +++++++++++++++++---
 2 files changed, 30 insertions(+), 8 deletions(-)

diffs (96 lines):

diff -r ab8a821c95f0 -r f7af63b3979e sys/net/npf/npf_handler.c
--- a/sys/net/npf/npf_handler.c Sun Feb 19 18:30:05 2017 +0000
+++ b/sys/net/npf/npf_handler.c Sun Feb 19 20:27:22 2017 +0000
@@ -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_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 @@
        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) {
diff -r ab8a821c95f0 -r f7af63b3979e sys/net/npf/npf_inet.c
--- a/sys/net/npf/npf_inet.c    Sun Feb 19 18:30:05 2017 +0000
+++ b/sys/net/npf/npf_inet.c    Sun Feb 19 20:27:22 2017 +0000
@@ -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 @@
        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 @@
                                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;



Home | Main Index | Thread Index | Old Index