Source-Changes-HG archive

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

[src/trunk]: src NPF improvements:



details:   https://anonhg.NetBSD.org/src/rev/69a0d1f947a9
branches:  trunk
changeset: 457833:69a0d1f947a9
user:      rmind <rmind%NetBSD.org@localhost>
date:      Tue Jul 23 00:52:01 2019 +0000

description:
NPF improvements:
- Add support for dynamic NETMAP algorithm (stateful net-to-net).
- Add most of the support for the dynamic NAT rules; a little bit more
  userland work is needed to finish this up and enable.
- Replace 'stateful-ends' with more permissive 'stateful-all'.
- Add various tunable parameters and document them, see npf-params(7).
- Reduce the memory usage of the connection state table (conndb).
- Portmap rewrite: use memory more efficiently, handle addresses dynamically.
- Bug fix: add splsoftnet()/splx() around the thmap writers and comment.
- npftest: clean up and simplify; fix some memleaks to make ASAN happy.

diffstat:

 lib/libnpf/libnpf.3                              |   19 +-
 lib/libnpf/npf.c                                 |  120 +++-
 lib/libnpf/npf.h                                 |   89 ++-
 sys/net/npf/files.npf                            |    5 +-
 sys/net/npf/npf.c                                |   25 +-
 sys/net/npf/npf.h                                |    7 +-
 sys/net/npf/npf_alg.c                            |   77 ++-
 sys/net/npf/npf_alg_icmp.c                       |   22 +-
 sys/net/npf/npf_conf.c                           |    3 +-
 sys/net/npf/npf_conn.c                           |  389 +++++-----------
 sys/net/npf/npf_conn.h                           |   90 ++-
 sys/net/npf/npf_conndb.c                         |  118 +++-
 sys/net/npf/npf_connkey.c                        |  274 +++++++++++
 sys/net/npf/npf_ctl.c                            |  170 +++++-
 sys/net/npf/npf_handler.c                        |    6 +-
 sys/net/npf/npf_impl.h                           |   70 ++-
 sys/net/npf/npf_inet.c                           |   22 +-
 sys/net/npf/npf_nat.c                            |  347 ++++-----------
 sys/net/npf/npf_os.c                             |   15 +-
 sys/net/npf/npf_params.c                         |  202 ++++++++
 sys/net/npf/npf_portmap.c                        |  528 +++++++++++++++++++++++
 sys/net/npf/npf_rproc.c                          |    2 +-
 sys/net/npf/npf_ruleset.c                        |   41 +-
 sys/net/npf/npf_state.c                          |   70 ++-
 sys/net/npf/npf_state_tcp.c                      |  164 +++++-
 sys/net/npf/npf_tableset.c                       |   37 +-
 sys/net/npf/npfkern.h                            |   10 +
 sys/rump/net/lib/libnpf/Makefile                 |    5 +-
 usr.sbin/npf/npf-params.7                        |  130 +++++
 usr.sbin/npf/npfctl/npf.conf.5                   |   32 +-
 usr.sbin/npf/npfctl/npf_bpf_comp.c               |    2 +-
 usr.sbin/npf/npfctl/npf_build.c                  |   98 +++-
 usr.sbin/npf/npfctl/npf_parse.y                  |   33 +-
 usr.sbin/npf/npfctl/npf_scan.l                   |    8 +-
 usr.sbin/npf/npfctl/npf_show.c                   |   38 +-
 usr.sbin/npf/npfctl/npfctl.c                     |   38 +-
 usr.sbin/npf/npfctl/npfctl.h                     |    2 +
 usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c   |   55 +-
 usr.sbin/npf/npftest/libnpftest/npf_conn_test.c  |   39 +-
 usr.sbin/npf/npftest/libnpftest/npf_mbuf_subr.c  |   74 +++
 usr.sbin/npf/npftest/libnpftest/npf_nat_test.c   |   55 +-
 usr.sbin/npf/npftest/libnpftest/npf_nbuf_test.c  |   41 +-
 usr.sbin/npf/npftest/libnpftest/npf_perf_test.c  |   26 +-
 usr.sbin/npf/npftest/libnpftest/npf_rule_test.c  |  139 +++--
 usr.sbin/npf/npftest/libnpftest/npf_state_test.c |   18 +-
 usr.sbin/npf/npftest/libnpftest/npf_table_test.c |    3 -
 usr.sbin/npf/npftest/libnpftest/npf_test.h       |   10 +
 usr.sbin/npf/npftest/libnpftest/npf_test_subr.c  |    5 +-
 usr.sbin/npf/npftest/npfstream.c                 |    4 +-
 usr.sbin/npf/npftest/npftest.c                   |    4 +-
 usr.sbin/npf/npftest/npftest.conf                |    3 +-
 51 files changed, 2583 insertions(+), 1201 deletions(-)

diffs (truncated from 6430 to 300 lines):

diff -r 050cd0f73476 -r 69a0d1f947a9 lib/libnpf/libnpf.3
--- a/lib/libnpf/libnpf.3       Tue Jul 23 00:49:16 2019 +0000
+++ b/lib/libnpf/libnpf.3       Tue Jul 23 00:52:01 2019 +0000
@@ -1,6 +1,6 @@
-.\"    $NetBSD: libnpf.3,v 1.7 2019/01/19 21:19:31 rmind Exp $
+.\"    $NetBSD: libnpf.3,v 1.8 2019/07/23 00:52:01 rmind Exp $
 .\"
-.\" Copyright (c) 2011-2018 The NetBSD Foundation, Inc.
+.\" Copyright (c) 2011-2019 The NetBSD Foundation, Inc.
 .\" All rights reserved.
 .\"
 .\" This material is based upon work partially supported by The
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd December 29, 2018
+.Dd April 14, 2019
 .Dt LIBNPF 3
 .Os
 .Sh NAME
@@ -95,10 +95,10 @@
 .Ft int
 .Fn npf_nat_setport "nl_nat_t *nt" "in_port_t port"
 .Ft int
-.Fn npf_nat_insert "nl_config_t *ncf" "nl_nat_t *nt" "pri_t pri"
+.Fn npf_nat_insert "nl_config_t *ncf" "nl_nat_t *nt"
 .\" ---
 .Ft nl_table_t *
-.Fn npf_table_create "const char *name" "u_int id" "int type"
+.Fn npf_table_create "const char *name" "unsigned id" "int type"
 .Ft int
 .Fn npf_table_add_entry "nl_table_t *tl" "int af" \
 "const npf_addr_t *addr" "const npf_netmask_t mask"
@@ -178,8 +178,11 @@
 backwards stream (the returning packets) without the ruleset inspection.
 The state is uniquely identified by a 5-tuple (source and destination
 IP addresses, port numbers and an interface identifier).
-.It Dv NPF_RULE_MULTIENDS
+.It Dv NPF_RULE_GSTATEFUL
 Exclude the interface identifier from the state key i.e. use a 4-tuple.
+This makes the state global with the respect network interfaces.
+The state is also picked on packet travelling different direction that
+originally.
 .It Dv NPF_RULE_RETRST
 Return TCP RST packet in a case of packet block.
 .It Dv NPF_RULE_RETICMP
@@ -373,8 +376,8 @@
 IPv6-to-IPv6 Network Prefix Translation (NPTv6, defined in RFC 6296).
 .El
 .\" ---
-.It Fn npf_nat_insert "ncf" "nt" "pri"
-Insert NAT policy, its rule, into the specified configuration.
+.It Fn npf_nat_insert "ncf" "nt"
+Insert the NAT policy, its rule, into the specified configuration.
 The NAT rule must not be referenced after insertion.
 .El
 .\" -----
diff -r 050cd0f73476 -r 69a0d1f947a9 lib/libnpf/npf.c
--- a/lib/libnpf/npf.c  Tue Jul 23 00:49:16 2019 +0000
+++ b/lib/libnpf/npf.c  Tue Jul 23 00:52:01 2019 +0000
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2010-2018 The NetBSD Foundation, Inc.
+ * Copyright (c) 2010-2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This material is based upon work partially supported by The
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.45 2019/01/19 21:19:31 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.46 2019/07/23 00:52:01 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/mman.h>
@@ -80,16 +80,11 @@
        unsigned        ncf_rule_count;
 
        /* Iterators. */
-       unsigned        ncf_rule_iter;
        unsigned        ncf_reduce[16];
        unsigned        ncf_nlevel;
-       unsigned        ncf_counter;
+
        nl_rule_t       ncf_cur_rule;
-
-       unsigned        ncf_table_iter;
        nl_table_t      ncf_cur_table;
-
-       unsigned        ncf_rproc_iter;
        nl_rproc_t      ncf_cur_rproc;
 };
 
@@ -242,6 +237,8 @@
        if (error && errinfo) {
                memset(errinfo, 0, sizeof(npf_error_t));
                errinfo->id = dnvlist_get_number(errnv, "id", 0);
+               errinfo->error_msg =
+                   dnvlist_take_string(errnv, "error-msg", NULL);
                errinfo->source_file =
                    dnvlist_take_string(errnv, "source-file", NULL);
                errinfo->source_line =
@@ -346,6 +343,47 @@
 }
 
 /*
+ * PARAMETERS.
+ */
+
+int
+npf_param_get(nl_config_t *ncf, const char *name, int *valp)
+{
+       const nvlist_t *params;
+
+       params = dnvlist_get_nvlist(ncf->ncf_dict, "params", NULL);
+       if (params == NULL || !nvlist_exists(params, name)) {
+               return ENOENT;
+       }
+       *valp = (int)dnvlist_get_number(params, name, 0);
+       return 0;
+}
+
+int
+npf_param_set(nl_config_t *ncf, const char *name, int val)
+{
+       nvlist_t *params;
+
+       /* Ensure params dictionary. */
+       if (nvlist_exists(ncf->ncf_dict, "params")) {
+               params = nvlist_take_nvlist(ncf->ncf_dict, "params");
+       } else {
+               params = nvlist_create(0);
+       }
+
+       /*
+        * If the parameter is already set, then free it first.
+        * Set the parameter.  Note: values can be negative.
+        */
+       if (nvlist_exists(params, name)) {
+               nvlist_free_number(params, name);
+       }
+       nvlist_add_number(params, name, (uint64_t)val);
+       nvlist_add_nvlist(ncf->ncf_dict, "params", params);
+       return 0;
+}
+
+/*
  * DYNAMIC RULESET INTERFACE.
  */
 
@@ -539,9 +577,10 @@
 }
 
 static nl_rule_t *
-_npf_rule_iterate1(nl_config_t *ncf, const char *key, unsigned *level)
+_npf_rule_iterate1(nl_config_t *ncf, const char *key,
+    nl_iter_t *iter, unsigned *level)
 {
-       unsigned i = ncf->ncf_rule_iter++;
+       unsigned i = *iter;
        const nvlist_t *rule_dict;
        uint32_t skipto;
 
@@ -549,16 +588,14 @@
                /* Initialise the iterator. */
                ncf->ncf_nlevel = 0;
                ncf->ncf_reduce[0] = 0;
-               ncf->ncf_counter = 0;
        }
 
        rule_dict = _npf_dataset_getelement(ncf->ncf_dict, key, i);
        if (!rule_dict) {
-               /* Reset the iterator. */
-               ncf->ncf_rule_iter = 0;
+               *iter = NPF_ITER_BEGIN;
                return NULL;
        }
-       ncf->ncf_cur_rule.rule_dict = __UNCONST(rule_dict); // XXX
+       *iter = i + 1; // next
        *level = ncf->ncf_nlevel;
 
        skipto = dnvlist_get_number(rule_dict, "skip-to", 0);
@@ -566,17 +603,19 @@
                ncf->ncf_nlevel++;
                ncf->ncf_reduce[ncf->ncf_nlevel] = skipto;
        }
-       if (ncf->ncf_reduce[ncf->ncf_nlevel] == ++ncf->ncf_counter) {
+       if (ncf->ncf_reduce[ncf->ncf_nlevel] == (i + 1)) {
                assert(ncf->ncf_nlevel > 0);
                ncf->ncf_nlevel--;
        }
+
+       ncf->ncf_cur_rule.rule_dict = __UNCONST(rule_dict); // XXX
        return &ncf->ncf_cur_rule;
 }
 
 nl_rule_t *
-npf_rule_iterate(nl_config_t *ncf, unsigned *level)
+npf_rule_iterate(nl_config_t *ncf, nl_iter_t *iter, unsigned *level)
 {
-       return _npf_rule_iterate1(ncf, "rules", level);
+       return _npf_rule_iterate1(ncf, "rules", iter, level);
 }
 
 const char *
@@ -710,17 +749,17 @@
 }
 
 nl_rproc_t *
-npf_rproc_iterate(nl_config_t *ncf)
+npf_rproc_iterate(nl_config_t *ncf, nl_iter_t *iter)
 {
        const nvlist_t *rproc_dict;
-       unsigned i = ncf->ncf_rproc_iter++;
+       unsigned i = *iter;
 
        rproc_dict = _npf_dataset_getelement(ncf->ncf_dict, "rprocs", i);
        if (!rproc_dict) {
-               /* Reset the iterator. */
-               ncf->ncf_rproc_iter = 0;
+               *iter = NPF_ITER_BEGIN;
                return NULL;
        }
+       *iter = i + 1; // next
        ncf->ncf_cur_rproc.rproc_dict = __UNCONST(rproc_dict); // XXX
        return &ncf->ncf_cur_rproc;
 }
@@ -755,13 +794,13 @@
        /* Translation type and flags. */
        nvlist_add_number(rule_dict, "type", type);
        nvlist_add_number(rule_dict, "flags", flags);
+       nvlist_add_bool(rule_dict, "nat-rule", true);
        return (nl_nat_t *)rl;
 }
 
 int
-npf_nat_insert(nl_config_t *ncf, nl_nat_t *nt, int pri __unused)
+npf_nat_insert(nl_config_t *ncf, nl_nat_t *nt)
 {
-       nvlist_add_number(nt->rule_dict, "prio", (uint64_t)NPF_PRI_LAST);
        nvlist_append_nvlist_array(ncf->ncf_dict, "nat", nt->rule_dict);
        nvlist_destroy(nt->rule_dict);
        free(nt);
@@ -769,17 +808,17 @@
 }
 
 nl_nat_t *
-npf_nat_iterate(nl_config_t *ncf)
+npf_nat_iterate(nl_config_t *ncf, nl_iter_t *iter)
 {
        unsigned level;
-       return _npf_rule_iterate1(ncf, "nat", &level);
+       return _npf_rule_iterate1(ncf, "nat", iter, &level);
 }
 
 int
 npf_nat_setaddr(nl_nat_t *nt, int af, npf_addr_t *addr, npf_netmask_t mask)
 {
        /* Translation IP and mask. */
-       if (!_npf_add_addr(nt->rule_dict, "nat-ip", af, addr)) {
+       if (!_npf_add_addr(nt->rule_dict, "nat-addr", af, addr)) {
                return nvlist_error(nt->rule_dict);
        }
        nvlist_add_number(nt->rule_dict, "nat-mask", (uint32_t)mask);
@@ -797,6 +836,9 @@
 int
 npf_nat_settable(nl_nat_t *nt, unsigned tid)
 {
+       /*
+        * Translation table ID; the address/mask will then serve as a filter.
+        */
        nvlist_add_number(nt->rule_dict, "nat-table-id", tid);
        return nvlist_error(nt->rule_dict);
 }
@@ -843,8 +885,8 @@
 {
        const void *data;
 
-       if (nvlist_exists(nt->rule_dict, "nat-ip")) {
-               data = nvlist_get_binary(nt->rule_dict, "nat-ip", alen);
+       if (nvlist_exists(nt->rule_dict, "nat-addr")) {
+               data = nvlist_get_binary(nt->rule_dict, "nat-addr", alen);
                *mask = nvlist_get_number(nt->rule_dict, "nat-mask");
        } else {
                data = NULL;
@@ -892,7 +934,6 @@
 {
        nvlist_t *entry;
 
-       /* Create the table entry. */
        entry = nvlist_create(0);
        if (!entry) {
                return ENOMEM;
@@ -946,7 +987,7 @@
        }
 
        /*
-        * Produce the constant database into a temporary file.



Home | Main Index | Thread Index | Old Index