Source-Changes-HG archive

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

[src/trunk]: src NPF: add support for "stateful-ends".



details:   https://anonhg.NetBSD.org/src/rev/50a7bfcadd0b
branches:  trunk
changeset: 794431:50a7bfcadd0b
user:      rmind <rmind%NetBSD.org@localhost>
date:      Fri Mar 14 11:29:44 2014 +0000

description:
NPF: add support for "stateful-ends".

diffstat:

 sys/net/npf/npf.h               |   3 +-
 sys/net/npf/npf_handler.c       |   7 +++--
 sys/net/npf/npf_impl.h          |   4 +-
 sys/net/npf/npf_nat.c           |   6 ++--
 sys/net/npf/npf_session.c       |  43 +++++++++++++++++++++-------------------
 usr.sbin/npf/npfctl/npf_parse.y |   4 ++-
 usr.sbin/npf/npfctl/npf_scan.l  |   3 +-
 usr.sbin/npf/npfctl/npf_show.c  |   8 ++++--
 8 files changed, 44 insertions(+), 34 deletions(-)

diffs (300 lines):

diff -r 47372184c6b2 -r 50a7bfcadd0b sys/net/npf/npf.h
--- a/sys/net/npf/npf.h Fri Mar 14 11:27:36 2014 +0000
+++ b/sys/net/npf/npf.h Fri Mar 14 11:29:44 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf.h,v 1.37 2014/02/13 03:34:40 rmind Exp $   */
+/*     $NetBSD: npf.h,v 1.38 2014/03/14 11:29:44 rmind Exp $   */
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -210,6 +210,7 @@
 #define        NPF_RULE_RETRST                 0x0010
 #define        NPF_RULE_RETICMP                0x0020
 #define        NPF_RULE_DYNAMIC                0x0040
+#define        NPF_RULE_MULTIENDS              0x0080
 
 #define        NPF_DYNAMIC_GROUP               (NPF_RULE_GROUP | NPF_RULE_DYNAMIC)
 
diff -r 47372184c6b2 -r 50a7bfcadd0b sys/net/npf/npf_handler.c
--- a/sys/net/npf/npf_handler.c Fri Mar 14 11:27:36 2014 +0000
+++ b/sys/net/npf/npf_handler.c Fri Mar 14 11:29:44 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_handler.c,v 1.28 2013/11/08 00:38:26 rmind Exp $   */
+/*     $NetBSD: npf_handler.c,v 1.29 2014/03/14 11:29:44 rmind Exp $   */
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.28 2013/11/08 00:38:26 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.29 2014/03/14 11:29:44 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -229,7 +229,8 @@
         * if session creation fails (e.g. due to unsupported protocol).
         */
        if ((retfl & NPF_RULE_STATEFUL) != 0 && !se) {
-               se = npf_session_establish(&npc, &nbuf, di);
+               se = npf_session_establish(&npc, &nbuf, di,
+                   (retfl & NPF_RULE_MULTIENDS) == 0);
                if (se) {
                        /*
                         * Note: the reference on the rule procedure is
diff -r 47372184c6b2 -r 50a7bfcadd0b sys/net/npf/npf_impl.h
--- a/sys/net/npf/npf_impl.h    Fri Mar 14 11:27:36 2014 +0000
+++ b/sys/net/npf/npf_impl.h    Fri Mar 14 11:29:44 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_impl.h,v 1.49 2014/02/19 03:51:31 rmind Exp $      */
+/*     $NetBSD: npf_impl.h,v 1.50 2014/03/14 11:29:44 rmind Exp $      */
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -311,7 +311,7 @@
 npf_session_t *        npf_session_lookup(const npf_cache_t *, const nbuf_t *,
                    const int, bool *);
 npf_session_t *        npf_session_inspect(npf_cache_t *, nbuf_t *, const int, int *);
-npf_session_t *        npf_session_establish(npf_cache_t *, nbuf_t *, const int);
+npf_session_t *        npf_session_establish(npf_cache_t *, nbuf_t *, int, bool);
 void           npf_session_release(npf_session_t *);
 void           npf_session_expire(npf_session_t *);
 bool           npf_session_pass(const npf_session_t *, npf_rproc_t **);
diff -r 47372184c6b2 -r 50a7bfcadd0b sys/net/npf/npf_nat.c
--- a/sys/net/npf/npf_nat.c     Fri Mar 14 11:27:36 2014 +0000
+++ b/sys/net/npf/npf_nat.c     Fri Mar 14 11:29:44 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_nat.c,v 1.26 2014/02/19 03:51:31 rmind Exp $       */
+/*     $NetBSD: npf_nat.c,v 1.27 2014/03/14 11:29:44 rmind Exp $       */
 
 /*-
  * Copyright (c) 2014 Mindaugas Rasiukevicius <rmind at netbsd org>
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.26 2014/02/19 03:51:31 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.27 2014/03/14 11:29:44 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -669,7 +669,7 @@
         * stream depends on other, stateless filtering rules.
         */
        if (se == NULL) {
-               nse = npf_session_establish(npc, nbuf, di);
+               nse = npf_session_establish(npc, nbuf, di, true);
                if (nse == NULL) {
                        atomic_dec_uint(&np->n_refcnt);
                        return ENOMEM;
diff -r 47372184c6b2 -r 50a7bfcadd0b sys/net/npf/npf_session.c
--- a/sys/net/npf/npf_session.c Fri Mar 14 11:27:36 2014 +0000
+++ b/sys/net/npf/npf_session.c Fri Mar 14 11:29:44 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_session.c,v 1.30 2013/12/06 01:33:37 rmind Exp $   */
+/*     $NetBSD: npf_session.c,v 1.31 2014/03/14 11:29:44 rmind Exp $   */
 
 /*-
  * Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
@@ -92,7 +92,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.30 2013/12/06 01:33:37 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.31 2014/03/14 11:29:44 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -260,19 +260,12 @@
        const int sz = sen1->se_alen;
        int ret;
 
-       /*
-        * Ports are expected to vary most, therefore they are first.
-        */
        if (sen1->se_src_id != sen2->se_src_id) {
                return (sen1->se_src_id < sen2->se_src_id) ? -1 : 1;
        }
        if (sen1->se_dst_id != sen2->se_dst_id) {
                return (sen1->se_dst_id < sen2->se_dst_id) ? -1 : 1;
        }
-
-       /*
-        * Note that hash should minimise differentiation on addresses.
-        */
        if (sen1->se_alen != sen2->se_alen) {
                return (sen1->se_alen < sen2->se_alen) ? -1 : 1;
        }
@@ -285,7 +278,19 @@
 
        const npf_secomid_t *id1 = &sen1->se_backptr->s_common_id;
        const npf_secomid_t *id2 = ctx ? ctx : &sen2->se_backptr->s_common_id;
-       return memcmp(id1, id2, sizeof(npf_secomid_t));
+
+       if (id1->proto != id2->proto) {
+               return (id1->proto < id2->proto) ? -1 : 1;
+       }
+
+       /*
+        * Zero interface ID is a special case indicating a global state,
+        * in which case we match straight away.
+        */
+       if (id1->ifid && id1->ifid != id2->ifid) {
+               return (id1->ifid < id2->ifid) ? -1 : 1;
+       }
+       return 0;
 }
 
 static signed int
@@ -312,8 +317,7 @@
        const int sz = sen->se_alen;
        uint32_t hash, mix[2];
 
-       mix[0] = (scid->proto ^ scid->ifid) << 16;
-       mix[0] |= sen->se_src_id ^ sen->se_dst_id;
+       mix[0] = (scid->proto << 16) | (sen->se_src_id ^ sen->se_dst_id);
        mix[1] = npf_addr_mix(sz, &sen->se_src_addr, &sen->se_dst_addr);
        hash = murmurhash2(mix, sizeof(mix), sess_hash_seed);
 
@@ -486,6 +490,7 @@
     const int di, bool *forw)
 {
        const u_int proto = npc->npc_proto;
+       const u_int ifid = nbuf->nb_ifid;
        npf_sentry_t senkey, *sen;
        npf_session_t *se;
        npf_sehash_t *sh;
@@ -505,9 +510,7 @@
         * Note: this is a special case where we use common ID pointer
         * to pass the structure for the key comparator.
         */
-       npf_secomid_t scid;
-       memset(&scid, 0, sizeof(npf_secomid_t));
-       scid = (npf_secomid_t){ .proto = proto, .ifid = nbuf->nb_ifid };
+       npf_secomid_t scid = { .proto = proto, .ifid = ifid };
        senkey.se_common_id = &scid;
 
        /*
@@ -528,7 +531,7 @@
        }
        se = sen->se_backptr;
        KASSERT(se->s_common_id.proto == proto);
-       KASSERT(se->s_common_id.ifid == nbuf->nb_ifid);
+       KASSERT(se->s_common_id.ifid == 0 || se->s_common_id.ifid == ifid);
        flags = se->s_flags;
 
        /* Check if session is active and not expired. */
@@ -597,13 +600,13 @@
 }
 
 /*
- * npf_establish_session: create a new session, insert into the global list.
+ * npf_session_establish: create a new session, insert into the global list.
  *
  * => Session is created with the reference held for the caller.
  * => Session will be activated on the first reference release.
  */
 npf_session_t *
-npf_session_establish(npf_cache_t *npc, nbuf_t *nbuf, const int di)
+npf_session_establish(npf_cache_t *npc, nbuf_t *nbuf, int di, bool per_if)
 {
        npf_sentry_t *fw, *bk;
        npf_sehash_t *sh;
@@ -612,6 +615,7 @@
        bool ok;
 
        KASSERT(!nbuf_flag_p(nbuf, NBUF_DATAREF_RESET));
+
        if (!npf_session_trackable_p(npc)) {
                return NULL;
        }
@@ -644,9 +648,8 @@
        memcpy(&fw->se_dst_addr, npc->npc_ips[NPF_DST], alen);
 
        /* Protocol and interface. */
-       memset(&se->s_common_id, 0, sizeof(npf_secomid_t));
        se->s_common_id.proto = npc->npc_proto;
-       se->s_common_id.ifid = nbuf->nb_ifid;
+       se->s_common_id.ifid = per_if ? nbuf->nb_ifid : 0;
 
        /* Setup "forwards" entry. */
        if (!npf_session_fillent(npc, fw)) {
diff -r 47372184c6b2 -r 50a7bfcadd0b usr.sbin/npf/npfctl/npf_parse.y
--- a/usr.sbin/npf/npfctl/npf_parse.y   Fri Mar 14 11:27:36 2014 +0000
+++ b/usr.sbin/npf/npfctl/npf_parse.y   Fri Mar 14 11:29:44 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_parse.y,v 1.33 2014/02/17 00:45:24 rmind Exp $     */
+/*     $NetBSD: npf_parse.y,v 1.34 2014/03/14 11:29:45 rmind Exp $     */
 
 /*-
  * Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
@@ -136,6 +136,7 @@
 %token                 SEPLINE
 %token                 SLASH
 %token                 STATEFUL
+%token                 STATEFUL_ENDS
 %token                 TABLE
 %token                 TCP
 %token                 TO
@@ -553,6 +554,7 @@
 
 opt_stateful
        : STATEFUL      { $$ = NPF_RULE_STATEFUL; }
+       | STATEFUL_ENDS { $$ = NPF_RULE_STATEFUL | NPF_RULE_MULTIENDS; }
        |               { $$ = 0; }
        ;
 
diff -r 47372184c6b2 -r 50a7bfcadd0b usr.sbin/npf/npfctl/npf_scan.l
--- a/usr.sbin/npf/npfctl/npf_scan.l    Fri Mar 14 11:27:36 2014 +0000
+++ b/usr.sbin/npf/npfctl/npf_scan.l    Fri Mar 14 11:29:44 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_scan.l,v 1.19 2014/02/13 03:34:40 rmind Exp $      */
+/*     $NetBSD: npf_scan.l,v 1.20 2014/03/14 11:29:45 rmind Exp $      */
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -118,6 +118,7 @@
 pass                   return PASS;
 pcap-filter            return PCAP_FILTER;
 stateful               return STATEFUL;
+stateful-ends          return STATEFUL_ENDS;
 apply                  return APPLY;
 final                  return FINAL;
 quick                  return FINAL;
diff -r 47372184c6b2 -r 50a7bfcadd0b usr.sbin/npf/npfctl/npf_show.c
--- a/usr.sbin/npf/npfctl/npf_show.c    Fri Mar 14 11:27:36 2014 +0000
+++ b/usr.sbin/npf/npfctl/npf_show.c    Fri Mar 14 11:29:44 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_show.c,v 1.12 2014/02/19 01:43:16 rmind Exp $      */
+/*     $NetBSD: npf_show.c,v 1.13 2014/03/14 11:29:45 rmind Exp $      */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_show.c,v 1.12 2014/02/19 01:43:16 rmind Exp $");
+__RCSID("$NetBSD: npf_show.c,v 1.13 2014/03/14 11:29:45 rmind Exp $");
 
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -218,6 +218,7 @@
  */
 
 #define        F(name)         __CONCAT(NPF_RULE_, name)
+#define        STATEFUL_ENDS   (NPF_RULE_STATEFUL | NPF_RULE_MULTIENDS)
 #define        NAME_AT         2
 
 static const struct attr_keyword_mapent {
@@ -232,7 +233,8 @@
        { F(RETRST)|F(RETICMP), F(RETRST)|F(RETICMP),   "return"        },
        { F(RETRST)|F(RETICMP), F(RETRST),              "return-rst"    },
        { F(RETRST)|F(RETICMP), F(RETICMP),             "return-icmp"   },
-       { F(STATEFUL),          F(STATEFUL),            "stateful"      },
+       { STATEFUL_ENDS,        F(STATEFUL),            "stateful"      },
+       { STATEFUL_ENDS,        STATEFUL_ENDS,          "stateful-ends" },
        { F(DIMASK),            F(IN),                  "in"            },
        { F(DIMASK),            F(OUT),                 "out"           },
        { F(FINAL),             F(FINAL),               "final"         },



Home | Main Index | Thread Index | Old Index