Source-Changes-HG archive

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

[src/trunk]: src NPF: Major rework -- migrate NPF to the libnv library.



details:   https://anonhg.NetBSD.org/src/rev/4af0018f9e74
branches:  trunk
changeset: 836146:4af0018f9e74
user:      rmind <rmind%NetBSD.org@localhost>
date:      Sat Sep 29 14:41:35 2018 +0000

description:
NPF: Major rework -- migrate NPF to the libnv library.
- This conversion significantly simplifies the code and moves NPF to
  a binary serialisation format (replacing the XML-like format).
- Fix some memory/reference leaks and possibly use-after-free bugs.
- Bump NPF_VERSION as this change makes libnpf incompatible with the
  previous versions.  Also, different serialisation format means NPF
  connection/config saving and loading is not compatible with the
  previous versions either.

Thanks to christos@ for extra testing.

diffstat:

 lib/libnpf/Makefile                              |    11 +-
 lib/libnpf/libnpf.3                              |    19 +-
 lib/libnpf/npf.c                                 |  1443 +++++++++------------
 lib/libnpf/npf.h                                 |    14 +-
 lib/npf/ext_log/npfext_log.c                     |     5 +-
 lib/npf/ext_normalize/npfext_normalize.c         |     5 +-
 lib/npf/ext_rndblock/npfext_rndblock.c           |     5 +-
 lib/npf/mod.mk                                   |     5 +-
 libexec/identd/Makefile                          |    10 +-
 sys/compat/netbsd32/netbsd32_ioctl.c             |    61 +-
 sys/compat/netbsd32/netbsd32_ioctl.h             |    24 +-
 sys/modules/if_npflog/Makefile                   |     4 +-
 sys/modules/npf/Makefile                         |     6 +-
 sys/modules/npf_alg_icmp/Makefile                |     3 +-
 sys/modules/npf_ext_log/Makefile                 |     4 +-
 sys/modules/npf_ext_normalize/Makefile           |     4 +-
 sys/modules/npf_ext_rndblock/Makefile            |     4 +-
 sys/net/npf/README                               |     2 +
 sys/net/npf/files.npf                            |     4 +-
 sys/net/npf/if_npflog.c                          |     4 +-
 sys/net/npf/if_npflog.h                          |     2 -
 sys/net/npf/lpm.c                                |   107 +-
 sys/net/npf/lpm.h                                |     1 +
 sys/net/npf/npf.c                                |    17 +-
 sys/net/npf/npf.h                                |    41 +-
 sys/net/npf/npf_alg.c                            |    21 +-
 sys/net/npf/npf_alg_icmp.c                       |     4 +-
 sys/net/npf/npf_bpf.c                            |     4 +-
 sys/net/npf/npf_conf.c                           |     4 +-
 sys/net/npf/npf_conn.c                           |   158 +-
 sys/net/npf/npf_conn.h                           |     9 +-
 sys/net/npf/npf_conndb.c                         |    25 +-
 sys/net/npf/npf_ctl.c                            |   818 +++++-------
 sys/net/npf/npf_ext_log.c                        |    11 +-
 sys/net/npf/npf_ext_normalize.c                  |    14 +-
 sys/net/npf/npf_ext_rndblock.c                   |    10 +-
 sys/net/npf/npf_handler.c                        |     4 +-
 sys/net/npf/npf_if.c                             |     4 +-
 sys/net/npf/npf_ifaddr.c                         |     8 +-
 sys/net/npf/npf_impl.h                           |    60 +-
 sys/net/npf/npf_inet.c                           |     4 +-
 sys/net/npf/npf_mbuf.c                           |     4 +-
 sys/net/npf/npf_nat.c                            |    91 +-
 sys/net/npf/npf_os.c                             |     4 +-
 sys/net/npf/npf_rproc.c                          |    32 +-
 sys/net/npf/npf_ruleset.c                        |   144 +-
 sys/net/npf/npf_sendpkt.c                        |    50 +-
 sys/net/npf/npf_state.c                          |     4 +-
 sys/net/npf/npf_state_tcp.c                      |     4 +-
 sys/net/npf/npf_tableset.c                       |    74 +-
 sys/net/npf/npf_worker.c                         |     4 +-
 sys/net/npf/npfkern.h                            |     1 +
 sys/rump/net/lib/libnpf/Makefile                 |     4 +-
 usr.bin/kdump/Makefile.ioctl-c                   |     3 +-
 usr.bin/kdump/mkioctls                           |     3 +-
 usr.sbin/npf/README                              |     2 +
 usr.sbin/npf/npfctl/Makefile                     |     9 +-
 usr.sbin/npf/npfctl/npf_bpf_comp.c               |     4 +-
 usr.sbin/npf/npfctl/npf_build.c                  |   117 +-
 usr.sbin/npf/npfctl/npf_data.c                   |    10 +-
 usr.sbin/npf/npfctl/npf_extmod.c                 |     4 +-
 usr.sbin/npf/npfctl/npf_parse.y                  |     2 -
 usr.sbin/npf/npfctl/npf_scan.l                   |     2 -
 usr.sbin/npf/npfctl/npf_show.c                   |    12 +-
 usr.sbin/npf/npfctl/npf_var.c                    |     4 +-
 usr.sbin/npf/npfctl/npf_var.h                    |     2 -
 usr.sbin/npf/npfctl/npfctl.c                     |    21 +-
 usr.sbin/npf/npfctl/npfctl.h                     |     5 +-
 usr.sbin/npf/npfd/Makefile                       |     5 +-
 usr.sbin/npf/npftest/Makefile                    |     6 +-
 usr.sbin/npf/npftest/README                      |    12 +-
 usr.sbin/npf/npftest/libnpftest/Makefile         |     2 +
 usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c   |     6 +-
 usr.sbin/npf/npftest/libnpftest/npf_mbuf_subr.c  |     3 +-
 usr.sbin/npf/npftest/libnpftest/npf_perf_test.c  |     6 +-
 usr.sbin/npf/npftest/libnpftest/npf_rule_test.c  |    23 +-
 usr.sbin/npf/npftest/libnpftest/npf_table_test.c |    32 +-
 usr.sbin/npf/npftest/libnpftest/npf_test.h       |     2 +-
 usr.sbin/npf/npftest/libnpftest/npf_test_subr.c  |    48 +-
 usr.sbin/npf/npftest/npftest.c                   |    69 +-
 usr.sbin/npf/npftest/npftest.h                   |     2 +-
 81 files changed, 1660 insertions(+), 2135 deletions(-)

diffs (truncated from 7112 to 300 lines):

diff -r c4bd51196a0e -r 4af0018f9e74 lib/libnpf/Makefile
--- a/lib/libnpf/Makefile       Sat Sep 29 13:19:38 2018 +0000
+++ b/lib/libnpf/Makefile       Sat Sep 29 14:41:35 2018 +0000
@@ -1,9 +1,11 @@
-# $NetBSD: Makefile,v 1.6 2016/01/05 13:07:47 christos Exp $
+# $NetBSD: Makefile,v 1.7 2018/09/29 14:41:36 rmind Exp $
+
+USE_SHLIBDIR=   yes
+
+NOLINT=                # disabled deliberately
 
 .include <bsd.own.mk>
 
-USE_SHLIBDIR=   yes
-
 LIB=           npf
 MAN=           libnpf.3
 
@@ -12,9 +14,8 @@
 INCS=          npf.h
 INCSDIR=       /usr/include
 
-LIBDPLIBS+=    prop ${.CURDIR}/../libprop
+CPPFLAGS+=     -I ${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
 
 WARNS=         5
-NOLINT=                # disabled deliberately
 
 .include <bsd.lib.mk>
diff -r c4bd51196a0e -r 4af0018f9e74 lib/libnpf/libnpf.3
--- a/lib/libnpf/libnpf.3       Sat Sep 29 13:19:38 2018 +0000
+++ b/lib/libnpf/libnpf.3       Sat Sep 29 14:41:35 2018 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: libnpf.3,v 1.5 2017/12/07 00:22:06 rmind Exp $
+.\"    $NetBSD: libnpf.3,v 1.6 2018/09/29 14:41:36 rmind Exp $
 .\"
 .\" Copyright (c) 2011-2017 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -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 7, 2017
+.Dd June 10, 2018
 .Dt LIBNPF 3
 .Os
 .Sh NAME
@@ -256,6 +256,7 @@
 is
 .Dv NULL ,
 then insert into the main ruleset.
+The rule must not be referenced after insertion.
 .\" ---
 .It Fn npf_rule_export "rl" "length"
 Serialize the rule (including the byte-code), return a binary object
@@ -276,6 +277,7 @@
 Thr name must be unique for each procedure.
 .It Fn npf_rproc_insert "ncf" "rp"
 Insert the rule procedure into the specified configuration object.
+The rule procedure must not be referenced after insertion.
 .El
 .\" -----
 .Ss Translation interface
@@ -331,6 +333,7 @@
 .\" ---
 .It Fn npf_nat_insert "ncf" "nt" "pri"
 Insert NAT policy, its rule, into the specified configuration.
+The NAT rule must not be referenced after insertion.
 .El
 .\" -----
 .Ss Table interface
@@ -342,7 +345,7 @@
 and
 .Fa index ,
 which should be in the range between 1 and
-.Dv NPF_MAX_TABLE_ID .
+.Dv NPF_MAX_TABLES .
 .Pp
 The following types are supported:
 .Bl -tag -width "NPF_TABLE_HASH"
@@ -353,12 +356,9 @@
 prefix match.
 .It Dv NPF_TABLE_CDB
 Indicates to use constant database for storage, typically using
-a perfect hash table.
-In such case, the database produced by
-.Xr cdbw 3
-should be set using the
-.Fn npf_table_setdata
-function.
+a perfect hash table, which will be generated on table insertion
+into the configuration.
+Such table will be immutable.
 .El
 .\" ---
 .It Fn npf_table_add_entry "tl" "af" "addr" "mask"
@@ -378,6 +378,7 @@
 .It Fn npf_table_insert "ncf" "tl"
 Add the table to the configuration object.
 This routine performs a check for duplicate table IDs.
+The table must not be referenced after insertion.
 .\" ---
 .It Fn npf_table_destroy "tl"
 Destroy the specified table.
diff -r c4bd51196a0e -r 4af0018f9e74 lib/libnpf/npf.c
--- a/lib/libnpf/npf.c  Sat Sep 29 13:19:38 2018 +0000
+++ b/lib/libnpf/npf.c  Sat Sep 29 14:41:35 2018 +0000
@@ -1,7 +1,5 @@
-/*     $NetBSD: npf.c,v 1.43 2017/01/03 00:59:31 christos Exp $        */
-
 /*-
- * Copyright (c) 2010-2015 The NetBSD Foundation, Inc.
+ * Copyright (c) 2010-2018 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This material is based upon work partially supported by The
@@ -30,79 +28,77 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.43 2017/01/03 00:59:31 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.44 2018/09/29 14:41:36 rmind Exp $");
 
 #include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
 #include <net/if.h>
-#include <prop/proplib.h>
 
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#include <unistd.h>
 #include <errno.h>
 #include <err.h>
 
+#include <nv.h>
+#include <dnv.h>
+
+#include <cdbw.h>
+
 #define        _NPF_PRIVATE
 #include "npf.h"
 
 struct nl_rule {
-       prop_dictionary_t       nrl_dict;
+       nvlist_t *      rule_dict;
 };
 
 struct nl_rproc {
-       prop_dictionary_t       nrp_dict;
+       nvlist_t *      rproc_dict;
 };
 
 struct nl_table {
-       prop_dictionary_t       ntl_dict;
+       nvlist_t *      table_dict;
 };
 
 struct nl_alg {
-       prop_dictionary_t       nal_dict;
+       nvlist_t *      alg_dict;
 };
 
 struct nl_ext {
-       const char *            nxt_name;
-       prop_dictionary_t       nxt_dict;
+       nvlist_t *      ext_dict;
 };
 
 struct nl_config {
-       /* Rules, translations, procedures, tables, connections. */
-       prop_dictionary_t       ncf_dict;
-       prop_array_t            ncf_alg_list;
-       prop_array_t            ncf_rules_list;
-       prop_array_t            ncf_rproc_list;
-       prop_array_t            ncf_table_list;
-       prop_array_t            ncf_nat_list;
-       prop_array_t            ncf_conn_list;
+       nvlist_t *      ncf_dict;
+
+       /* Temporary rule list. */
+       nvlist_t **     ncf_rule_list;
+       unsigned        ncf_rule_count;
 
        /* Iterators. */
-       prop_object_iterator_t  ncf_rule_iter;
-       unsigned                ncf_reduce[16];
-       unsigned                ncf_nlevel;
-       unsigned                ncf_counter;
-       nl_rule_t               ncf_cur_rule;
-
-       prop_object_iterator_t  ncf_table_iter;
-       nl_table_t              ncf_cur_table;
+       unsigned        ncf_rule_iter;
+       unsigned        ncf_reduce[16];
+       unsigned        ncf_nlevel;
+       unsigned        ncf_counter;
+       nl_rule_t       ncf_cur_rule;
 
-       prop_object_iterator_t  ncf_rproc_iter;
-       nl_rproc_t              ncf_cur_rproc;
+       unsigned        ncf_table_iter;
+       nl_table_t      ncf_cur_table;
 
-       /* Error report and debug information. */
-       prop_dictionary_t       ncf_err;
-       prop_dictionary_t       ncf_debug;
-
-       bool                    ncf_flush;
+       unsigned        ncf_rproc_iter;
+       nl_rproc_t      ncf_cur_rproc;
 };
 
-static prop_array_t    _npf_ruleset_transform(prop_array_t);
+/*
+ * Various helper routines.
+ */
 
 static bool
-_npf_add_addr(prop_dictionary_t dict, const char *name, int af,
-    const npf_addr_t *addr)
+_npf_add_addr(nvlist_t *nvl, const char *name, int af, const npf_addr_t *addr)
 {
        size_t sz;
 
@@ -113,33 +109,102 @@
        } else {
                return false;
        }
-       prop_data_t addrdat = prop_data_create_data(addr, sz);
-       if (addrdat == NULL) {
-               return false;
-       }
-       prop_dictionary_set(dict, name, addrdat);
-       prop_object_release(addrdat);
-       return true;
+       nvlist_add_binary(nvl, name, addr, sz);
+       return nvlist_error(nvl) == 0;
 }
 
 static unsigned
-_npf_get_addr(prop_dictionary_t dict, const char *name, npf_addr_t *addr)
+_npf_get_addr(const nvlist_t *nvl, const char *name, npf_addr_t *addr)
 {
-       prop_object_t obj = prop_dictionary_get(dict, name);
-       const void *d = prop_data_data_nocopy(obj);
+       const void *d;
+       size_t sz = 0;
 
-       if (d == NULL)
-               return false;
-
-       size_t sz = prop_data_size(obj);
+       d = nvlist_get_binary(nvl, name, &sz);
        switch (sz) {
        case sizeof(struct in_addr):
        case sizeof(struct in6_addr):
                memcpy(addr, d, sz);
                return (unsigned)sz;
-       default:
-               return 0;
+       }
+       return 0;
+}
+
+static bool
+_npf_dataset_lookup(const nvlist_t *dict, const char *dataset,
+    const char *key, const char *name)
+{
+       const nvlist_t * const *items;
+       size_t nitems;
+
+       if (!nvlist_exists_nvlist_array(dict, dataset)) {
+               return false;
+       }
+       items = nvlist_get_nvlist_array(dict, dataset, &nitems);
+       for (unsigned i = 0; i < nitems; i++) {
+               const char *item_name;
+
+               item_name = dnvlist_get_string(items[i], key, NULL);
+               if (item_name && strcmp(item_name, name) == 0) {
+                       return true;
+               }
+       }
+       return false;
+}
+
+static const nvlist_t *
+_npf_dataset_getelement(nvlist_t *dict, const char *dataset, unsigned i)
+{
+       const nvlist_t * const *items;
+       size_t nitems;
+
+       if (!nvlist_exists_nvlist_array(dict, dataset)) {
+               return NULL;
+       }
+       items = nvlist_get_nvlist_array(dict, dataset, &nitems);



Home | Main Index | Thread Index | Old Index