Module Name:    src
Committed By:   martin
Date:           Sun Sep  1 13:21:39 UTC 2019

Modified Files:
        src/sys/net/npf [netbsd-9]: npf.c npf.h npf_alg.c npf_conf.c npf_ctl.c
            npf_handler.c npf_ifaddr.c npf_impl.h npf_nat.c npf_os.c
        src/sys/sys [netbsd-9]: mbuf.h
        src/usr.sbin/npf/npfctl [netbsd-9]: npf_bpf_comp.c
        src/usr.sbin/npf/npftest/libnpftest [netbsd-9]: npf_rule_test.c

Log Message:
Pull up following revision(s) (requested by rmind in ticket #141):

        usr.sbin/npf/npfctl/npf_bpf_comp.c: revision 1.15
        sys/net/npf/npf_alg.c: revision 1.21
        sys/net/npf/npf.h: revision 1.62
        sys/net/npf/npf_ctl.c: revision 1.57
        sys/net/npf/npf_ctl.c: revision 1.58
        sys/net/npf/npf_os.c: revision 1.16
        sys/net/npf/npf_os.c: revision 1.17
        sys/net/npf/npf_conf.c: revision 1.15
        sys/net/npf/npf_impl.h: revision 1.78
        sys/sys/mbuf.h: revision 1.220
        sys/net/npf/npf_impl.h: revision 1.79
        sys/net/npf/npf.c: revision 1.41
        usr.sbin/npf/npftest/libnpftest/npf_rule_test.c: revision 1.19
        sys/net/npf/npf_nat.c: revision 1.48
        sys/net/npf/npf_handler.c: revision 1.48
        sys/net/npf/npf_ifaddr.c: revision 1.6

- npfctl_load_nvlist: simplify the config loading logic.
- Fix a small race condition in npf_nat_getaddr().
- Rework pserialize/EBR wrappers, make it easier to maintain.
Move PACKET_TAG_NPF where it belongs to.
Make npfctl_switch() and pfil private to OS-specific module.


To generate a diff of this commit:
cvs rdiff -u -r1.38.2.2 -r1.38.2.3 src/sys/net/npf/npf.c
cvs rdiff -u -r1.60.2.1 -r1.60.2.2 src/sys/net/npf/npf.h
cvs rdiff -u -r1.20 -r1.20.2.1 src/sys/net/npf/npf_alg.c
cvs rdiff -u -r1.13.2.1 -r1.13.2.2 src/sys/net/npf/npf_conf.c
cvs rdiff -u -r1.54.2.2 -r1.54.2.3 src/sys/net/npf/npf_ctl.c
cvs rdiff -u -r1.46.2.1 -r1.46.2.2 src/sys/net/npf/npf_handler.c \
    src/sys/net/npf/npf_nat.c
cvs rdiff -u -r1.5 -r1.5.4.1 src/sys/net/npf/npf_ifaddr.c
cvs rdiff -u -r1.75.2.2 -r1.75.2.3 src/sys/net/npf/npf_impl.h
cvs rdiff -u -r1.12.2.2 -r1.12.2.3 src/sys/net/npf/npf_os.c
cvs rdiff -u -r1.219 -r1.219.4.1 src/sys/sys/mbuf.h
cvs rdiff -u -r1.13.2.1 -r1.13.2.2 src/usr.sbin/npf/npfctl/npf_bpf_comp.c
cvs rdiff -u -r1.17.2.1 -r1.17.2.2 \
    src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.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.c
diff -u src/sys/net/npf/npf.c:1.38.2.2 src/sys/net/npf/npf.c:1.38.2.3
--- src/sys/net/npf/npf.c:1.38.2.2	Tue Aug 13 14:35:55 2019
+++ src/sys/net/npf/npf.c	Sun Sep  1 13:21:39 2019
@@ -33,7 +33,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.38.2.2 2019/08/13 14:35:55 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.38.2.3 2019/09/01 13:21:39 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -72,7 +72,7 @@ npfk_create(int flags, const npf_mbufops
 	npf_t *npf;
 
 	npf = kmem_zalloc(sizeof(npf_t), KM_SLEEP);
-	npf->qsbr = pserialize_create();
+	npf->ebr = npf_ebr_create();
 	npf->stats_percpu = percpu_alloc(NPF_STATS_SIZE);
 	npf->mbufops = mbufops;
 
@@ -111,7 +111,7 @@ npfk_destroy(npf_t *npf)
 	npf_state_sysfini(npf);
 	npf_param_fini(npf);
 
-	pserialize_destroy(npf->qsbr);
+	npf_ebr_destroy(npf->ebr);
 	percpu_free(npf->stats_percpu, NPF_STATS_SIZE);
 	kmem_free(npf, sizeof(npf_t));
 }
@@ -131,14 +131,14 @@ npfk_gc(npf_t *npf)
 __dso_public void
 npfk_thread_register(npf_t *npf)
 {
-	pserialize_register(npf->qsbr);
+	npf_ebr_register(npf->ebr);
 }
 
 __dso_public void
 npfk_thread_unregister(npf_t *npf)
 {
-	pserialize_perform(npf->qsbr);
-	pserialize_unregister(npf->qsbr);
+	npf_ebr_full_sync(npf->ebr);
+	npf_ebr_unregister(npf->ebr);
 }
 
 void

Index: src/sys/net/npf/npf.h
diff -u src/sys/net/npf/npf.h:1.60.2.1 src/sys/net/npf/npf.h:1.60.2.2
--- src/sys/net/npf/npf.h:1.60.2.1	Sun Sep  1 13:13:14 2019
+++ src/sys/net/npf/npf.h	Sun Sep  1 13:21:39 2019
@@ -253,8 +253,9 @@ bool		npf_autounload_p(void);
 #define	NPF_LAYER_2			2
 #define	NPF_LAYER_3			3
 
-/* XXX mbuf.h: just for now. */
-#define	PACKET_TAG_NPF			10
+/*
+ * Flags passed via nbuf tags.
+ */
 #define	NPF_NTAG_PASS			0x0001
 
 /*

Index: src/sys/net/npf/npf_alg.c
diff -u src/sys/net/npf/npf_alg.c:1.20 src/sys/net/npf/npf_alg.c:1.20.2.1
--- src/sys/net/npf/npf_alg.c:1.20	Tue Jul 23 00:52:01 2019
+++ src/sys/net/npf/npf_alg.c	Sun Sep  1 13:21:39 2019
@@ -33,13 +33,12 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.20 2019/07/23 00:52:01 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.20.2.1 2019/09/01 13:21:39 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
 
 #include <sys/kmem.h>
-#include <sys/pserialize.h>
 #include <sys/module.h>
 #endif
 
@@ -185,7 +184,7 @@ npf_alg_unregister(npf_t *npf, npf_alg_t
 	afuncs->match = NULL;
 	afuncs->translate = NULL;
 	afuncs->inspect = NULL;
-	pserialize_perform(npf->qsbr);
+	npf_ebr_full_sync(npf->ebr);
 
 	/* Finally, unregister the ALG. */
 	npf_ruleset_freealg(npf_config_natset(npf), alg);
@@ -210,13 +209,14 @@ npf_alg_unregister(npf_t *npf, npf_alg_t
 bool
 npf_alg_match(npf_cache_t *npc, npf_nat_t *nt, int di)
 {
-	npf_algset_t *aset = npc->npc_ctx->algset;
+	npf_t *npf = npc->npc_ctx;
+	npf_algset_t *aset = npf->algset;
 	bool match = false;
 	int s;
 
 	KASSERTMSG(npf_iscached(npc, NPC_IP46), "expecting protocol number");
 
-	s = pserialize_read_enter();
+	s = npf_ebr_enter(npf->ebr);
 	for (unsigned i = 0; i < aset->alg_count; i++) {
 		const npfa_funcs_t *f = &aset->alg_funcs[i];
 
@@ -225,7 +225,7 @@ npf_alg_match(npf_cache_t *npc, npf_nat_
 			break;
 		}
 	}
-	pserialize_read_exit(s);
+	npf_ebr_exit(npf->ebr, s);
 	return match;
 }
 
@@ -243,12 +243,13 @@ npf_alg_match(npf_cache_t *npc, npf_nat_
 void
 npf_alg_exec(npf_cache_t *npc, npf_nat_t *nt, bool forw)
 {
-	npf_algset_t *aset = npc->npc_ctx->algset;
+	npf_t *npf = npc->npc_ctx;
+	npf_algset_t *aset = npf->algset;
 	int s;
 
 	KASSERTMSG(npf_iscached(npc, NPC_IP46), "expecting protocol number");
 
-	s = pserialize_read_enter();
+	s = npf_ebr_enter(npf->ebr);
 	for (unsigned i = 0; i < aset->alg_count; i++) {
 		const npfa_funcs_t *f = &aset->alg_funcs[i];
 
@@ -256,11 +257,11 @@ npf_alg_exec(npf_cache_t *npc, npf_nat_t
 			f->translate(npc, nt, forw);
 		}
 	}
-	pserialize_read_exit(s);
+	npf_ebr_exit(npf->ebr, s);
 }
 
 /*
- * npf_alg_conn: query ALGs giving which may perform a custom state lookup.
+ * npf_alg_conn: query ALGs which may perform a custom state lookup.
  *
  *	The purpose of ALG connection inspection function is to provide
  *	ALGs with a mechanism to override the regular connection state
@@ -279,11 +280,12 @@ npf_alg_exec(npf_cache_t *npc, npf_nat_t
 npf_conn_t *
 npf_alg_conn(npf_cache_t *npc, int di)
 {
-	npf_algset_t *aset = npc->npc_ctx->algset;
+	npf_t *npf = npc->npc_ctx;
+	npf_algset_t *aset = npf->algset;
 	npf_conn_t *con = NULL;
 	int s;
 
-	s = pserialize_read_enter();
+	s = npf_ebr_enter(npf->ebr);
 	for (unsigned i = 0; i < aset->alg_count; i++) {
 		const npfa_funcs_t *f = &aset->alg_funcs[i];
 
@@ -292,7 +294,7 @@ npf_alg_conn(npf_cache_t *npc, int di)
 		if ((con = f->inspect(npc, di)) != NULL)
 			break;
 	}
-	pserialize_read_exit(s);
+	npf_ebr_exit(npf->ebr, s);
 	return con;
 }
 

Index: src/sys/net/npf/npf_conf.c
diff -u src/sys/net/npf/npf_conf.c:1.13.2.1 src/sys/net/npf/npf_conf.c:1.13.2.2
--- src/sys/net/npf/npf_conf.c:1.13.2.1	Tue Aug 13 14:35:55 2019
+++ src/sys/net/npf/npf_conf.c	Sun Sep  1 13:21:39 2019
@@ -47,53 +47,57 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.13.2.1 2019/08/13 14:35:55 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.13.2.2 2019/09/01 13:21:39 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
 
 #include <sys/atomic.h>
 #include <sys/kmem.h>
-#include <sys/pserialize.h>
 #include <sys/mutex.h>
 #endif
 
 #include "npf_impl.h"
 #include "npf_conn.h"
 
-struct npf_config {
-	npf_ruleset_t *		n_rules;
-	npf_tableset_t *	n_tables;
-	npf_ruleset_t *		n_nat_rules;
-	npf_rprocset_t *	n_rprocs;
-	bool			n_default_pass;
-};
-
 void
 npf_config_init(npf_t *npf)
 {
-	npf_ruleset_t *rlset, *nset;
-	npf_rprocset_t *rpset;
-	npf_tableset_t *tset;
+	npf_config_t *nc;
 
 	mutex_init(&npf->config_lock, MUTEX_DEFAULT, IPL_SOFTNET);
+	nc = npf_config_create();
+
+	/*
+	 * Load an empty configuration.
+	 */
+	nc->ruleset = npf_ruleset_create(0);
+	nc->nat_ruleset = npf_ruleset_create(0);
+	nc->rule_procs = npf_rprocset_create();
+	nc->tableset = npf_tableset_create(0);
+	nc->default_pass = true;
 
-	/* Load the empty configuration. */
-	tset = npf_tableset_create(0);
-	rpset = npf_rprocset_create();
-	rlset = npf_ruleset_create(0);
-	nset = npf_ruleset_create(0);
-	npf_config_load(npf, rlset, tset, nset, rpset, NULL, true);
+	npf_config_load(npf, nc, NULL, true);
 	KASSERT(npf->config != NULL);
 }
 
-static void
+npf_config_t *
+npf_config_create(void)
+{
+	return kmem_zalloc(sizeof(npf_config_t), KM_SLEEP);
+}
+
+void
 npf_config_destroy(npf_config_t *nc)
 {
-	npf_ruleset_destroy(nc->n_rules);
-	npf_ruleset_destroy(nc->n_nat_rules);
-	npf_rprocset_destroy(nc->n_rprocs);
-	npf_tableset_destroy(nc->n_tables);
+	/*
+	 * Note: the rulesets must be destroyed first, in order to drop
+	 * any references to the tableset.
+	 */
+	npf_ruleset_destroy(nc->ruleset);
+	npf_ruleset_destroy(nc->nat_ruleset);
+	npf_rprocset_destroy(nc->rule_procs);
+	npf_tableset_destroy(nc->tableset);
 	kmem_free(nc, sizeof(npf_config_t));
 }
 
@@ -105,7 +109,7 @@ npf_config_fini(npf_t *npf)
 	/* Flush the connections. */
 	mutex_enter(&npf->config_lock);
 	npf_conn_tracking(npf, false);
-	pserialize_perform(npf->qsbr);
+	npf_ebr_full_sync(npf->ebr);
 	npf_conn_load(npf, cd, false);
 	npf_ifmap_flush(npf);
 	mutex_exit(&npf->config_lock);
@@ -119,19 +123,12 @@ npf_config_fini(npf_t *npf)
  * Performs the necessary synchronisation and destroys the old config.
  */
 void
-npf_config_load(npf_t *npf, npf_ruleset_t *rset, npf_tableset_t *tset,
-    npf_ruleset_t *nset, npf_rprocset_t *rpset,
-    npf_conndb_t *conns, bool flush)
+npf_config_load(npf_t *npf, npf_config_t *nc, npf_conndb_t *conns, bool flush)
 {
 	const bool load = conns != NULL;
-	npf_config_t *nc, *onc;
+	npf_config_t *onc;
 
-	nc = kmem_zalloc(sizeof(npf_config_t), KM_SLEEP);
-	nc->n_rules = rset;
-	nc->n_tables = tset;
-	nc->n_nat_rules = nset;
-	nc->n_rprocs = rpset;
-	nc->n_default_pass = flush;
+	nc->default_pass = flush;
 
 	/*
 	 * Acquire the lock and perform the first phase:
@@ -140,9 +137,9 @@ npf_config_load(npf_t *npf, npf_ruleset_
 	 */
 	mutex_enter(&npf->config_lock);
 	if ((onc = npf->config) != NULL) {
-		npf_ruleset_reload(npf, rset, onc->n_rules, load);
-		npf_tableset_reload(npf, tset, onc->n_tables);
-		npf_ruleset_reload(npf, nset, onc->n_nat_rules, load);
+		npf_ruleset_reload(npf, nc->ruleset, onc->ruleset, load);
+		npf_tableset_reload(npf, nc->tableset, onc->tableset);
+		npf_ruleset_reload(npf, nc->nat_ruleset, onc->nat_ruleset, load);
 	}
 
 	/*
@@ -167,7 +164,7 @@ npf_config_load(npf_t *npf, npf_ruleset_
 	}
 
 	/* Synchronise: drain all references. */
-	pserialize_perform(npf->qsbr);
+	npf_ebr_full_sync(npf->ebr);
 	if (flush) {
 		npf_portmap_flush(npf->portmap);
 		npf_ifmap_flush(npf);
@@ -191,10 +188,11 @@ done:
  * Writer-side exclusive locking.
  */
 
-void
+npf_config_t *
 npf_config_enter(npf_t *npf)
 {
 	mutex_enter(&npf->config_lock);
+	return npf->config;
 }
 
 void
@@ -213,7 +211,7 @@ void
 npf_config_sync(npf_t *npf)
 {
 	KASSERT(npf_config_locked_p(npf));
-	pserialize_perform(npf->qsbr);
+	npf_ebr_full_sync(npf->ebr);
 }
 
 /*
@@ -221,15 +219,15 @@ npf_config_sync(npf_t *npf)
  */
 
 int
-npf_config_read_enter(void)
+npf_config_read_enter(npf_t *npf)
 {
-	return pserialize_read_enter();
+	return npf_ebr_enter(npf->ebr);
 }
 
 void
-npf_config_read_exit(int s)
+npf_config_read_exit(npf_t *npf, int s)
 {
-	pserialize_read_exit(s);
+	npf_ebr_exit(npf->ebr, s);
 }
 
 /*
@@ -239,29 +237,27 @@ npf_config_read_exit(int s)
 npf_ruleset_t *
 npf_config_ruleset(npf_t *npf)
 {
-	return npf->config->n_rules;
+	KASSERT(npf_config_locked_p(npf) || npf_ebr_incrit_p(npf->ebr));
+	return npf->config->ruleset;
 }
 
 npf_ruleset_t *
 npf_config_natset(npf_t *npf)
 {
-	return npf->config->n_nat_rules;
+	KASSERT(npf_config_locked_p(npf) || npf_ebr_incrit_p(npf->ebr));
+	return npf->config->nat_ruleset;
 }
 
 npf_tableset_t *
 npf_config_tableset(npf_t *npf)
 {
-	return npf->config->n_tables;
-}
-
-npf_rprocset_t *
-npf_config_rprocs(npf_t *npf)
-{
-	return npf->config->n_rprocs;
+	KASSERT(npf_config_locked_p(npf) || npf_ebr_incrit_p(npf->ebr));
+	return npf->config->tableset;
 }
 
 bool
 npf_default_pass(npf_t *npf)
 {
-	return npf->config->n_default_pass;
+	KASSERT(npf_config_locked_p(npf) || npf_ebr_incrit_p(npf->ebr));
+	return npf->config->default_pass;
 }

Index: src/sys/net/npf/npf_ctl.c
diff -u src/sys/net/npf/npf_ctl.c:1.54.2.2 src/sys/net/npf/npf_ctl.c:1.54.2.3
--- src/sys/net/npf/npf_ctl.c:1.54.2.2	Sun Sep  1 13:13:14 2019
+++ src/sys/net/npf/npf_ctl.c	Sun Sep  1 13:21:39 2019
@@ -36,7 +36,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.54.2.2 2019/09/01 13:13:14 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.54.2.3 2019/09/01 13:21:39 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -53,28 +53,6 @@ __KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 
 	nvlist_add_string((e), "source-file", __FILE__); \
 	nvlist_add_number((e), "source-line", __LINE__);
 
-#ifdef _KERNEL
-/*
- * npfctl_switch: enable or disable packet inspection.
- */
-int
-npfctl_switch(void *data)
-{
-	const bool onoff = *(int *)data ? true : false;
-	int error;
-
-	if (onoff) {
-		/* Enable: add pfil hooks. */
-		error = npf_pfil_register(false);
-	} else {
-		/* Disable: remove pfil hooks. */
-		npf_pfil_unregister(false);
-		error = 0;
-	}
-	return error;
-}
-#endif
-
 static int
 npf_nvlist_copyin(npf_t *npf, void *data, nvlist_t **nvl)
 {
@@ -237,7 +215,7 @@ out:
 
 static int __noinline
 npf_mk_tables(npf_t *npf, nvlist_t *npf_dict, nvlist_t *errdict,
-    npf_tableset_t **tblsetp)
+    npf_config_t *nc)
 {
 	const nvlist_t * const *tables;
 	npf_tableset_t *tblset;
@@ -267,7 +245,7 @@ npf_mk_tables(npf_t *npf, nvlist_t *npf_
 		error = npf_tableset_insert(tblset, t);
 		KASSERT(error == 0);
 	}
-	*tblsetp = tblset;
+	nc->tableset = tblset;
 	return error;
 }
 
@@ -305,7 +283,7 @@ npf_mk_singlerproc(npf_t *npf, const nvl
 
 static int __noinline
 npf_mk_rprocs(npf_t *npf, nvlist_t *npf_dict, nvlist_t *errdict,
-    npf_rprocset_t **rpsetp)
+    npf_config_t *nc)
 {
 	const nvlist_t * const *rprocs;
 	npf_rprocset_t *rpset;
@@ -333,7 +311,7 @@ npf_mk_rprocs(npf_t *npf, nvlist_t *npf_
 		}
 		npf_rprocset_insert(rpset, rp);
 	}
-	*rpsetp = rpset;
+	nc->rule_procs = rpset;
 	return error;
 }
 
@@ -435,7 +413,7 @@ err:
 
 static int __noinline
 npf_mk_rules(npf_t *npf, nvlist_t *npf_dict, nvlist_t *errdict,
-     npf_rprocset_t *rpset, npf_ruleset_t **rlsetp)
+    npf_config_t *nc)
 {
 	const nvlist_t * const *rules;
 	npf_ruleset_t *rlset;
@@ -458,7 +436,8 @@ npf_mk_rules(npf_t *npf, nvlist_t *npf_d
 		npf_rule_t *rl = NULL;
 		const char *name;
 
-		error = npf_mk_singlerule(npf, rule, rpset, &rl, errdict);
+		error = npf_mk_singlerule(npf, rule, nc->rule_procs, &rl,
+		    errdict);
 		if (error) {
 			break;
 		}
@@ -471,7 +450,7 @@ npf_mk_rules(npf_t *npf, nvlist_t *npf_d
 		}
 		npf_ruleset_insert(rlset, rl);
 	}
-	*rlsetp = rlset;
+	nc->ruleset = rlset;
 	return error;
 }
 
@@ -526,8 +505,8 @@ out:
 }
 
 static int __noinline
-npf_mk_natlist(npf_t *npf, nvlist_t *npf_dict, npf_tableset_t *tblset,
-    nvlist_t *errdict, npf_ruleset_t **ntsetp)
+npf_mk_natlist(npf_t *npf, nvlist_t *npf_dict, nvlist_t *errdict,
+    npf_config_t *nc)
 {
 	const nvlist_t * const *nat_rules;
 	npf_ruleset_t *ntset;
@@ -552,13 +531,14 @@ npf_mk_natlist(npf_t *npf, nvlist_t *npf
 		const nvlist_t *nat = nat_rules[i];
 		npf_rule_t *rl = NULL;
 
-		error = npf_mk_singlenat(npf, nat, ntset, tblset, errdict, &rl);
+		error = npf_mk_singlenat(npf, nat, ntset, nc->tableset,
+		    errdict, &rl);
 		if (error) {
 			break;
 		}
 		npf_ruleset_insert(ntset, rl);
 	}
-	*ntsetp = ntset;
+	nc->nat_ruleset = ntset;
 	return error;
 }
 
@@ -567,7 +547,7 @@ npf_mk_natlist(npf_t *npf, nvlist_t *npf
  */
 static int __noinline
 npf_mk_connlist(npf_t *npf, nvlist_t *npf_dict, nvlist_t *errdict,
-    npf_ruleset_t *natlist, npf_conndb_t **conndb)
+    npf_config_t *nc, npf_conndb_t **conndb)
 {
 	const nvlist_t * const *conns;
 	npf_conndb_t *cd;
@@ -584,7 +564,7 @@ npf_mk_connlist(npf_t *npf, nvlist_t *np
 		const nvlist_t *conn = conns[i];
 
 		/* Construct and insert the connection. */
-		error = npf_conn_import(npf, cd, conn, natlist);
+		error = npf_conn_import(npf, cd, conn, nc->nat_ruleset);
 		if (error) {
 			NPF_ERR_DEBUG(errdict);
 			break;
@@ -606,15 +586,13 @@ npf_mk_connlist(npf_t *npf, nvlist_t *np
 static int
 npfctl_load_nvlist(npf_t *npf, nvlist_t *npf_dict, nvlist_t *errdict)
 {
-	npf_tableset_t *tblset = NULL;
-	npf_ruleset_t *ntset = NULL;
-	npf_rprocset_t *rpset = NULL;
-	npf_ruleset_t *rlset = NULL;
+	npf_config_t *nc;
 	npf_conndb_t *conndb = NULL;
 	uint64_t ver;
 	bool flush;
 	int error;
 
+	nc = npf_config_create();
 	ver = dnvlist_get_number(npf_dict, "version", UINT64_MAX);
 	if (ver != NPF_VERSION) {
 		error = EPROGMISMATCH;
@@ -628,55 +606,41 @@ npfctl_load_nvlist(npf_t *npf, nvlist_t 
 	if (error) {
 		goto fail;
 	}
-	error = npf_mk_tables(npf, npf_dict, errdict, &tblset);
+	error = npf_mk_tables(npf, npf_dict, errdict, nc);
 	if (error) {
 		goto fail;
 	}
-	error = npf_mk_rprocs(npf, npf_dict, errdict, &rpset);
+	error = npf_mk_rprocs(npf, npf_dict, errdict, nc);
 	if (error) {
 		goto fail;
 	}
-	error = npf_mk_natlist(npf, npf_dict, tblset, errdict, &ntset);
+	error = npf_mk_natlist(npf, npf_dict, errdict, nc);
 	if (error) {
 		goto fail;
 	}
-	error = npf_mk_rules(npf, npf_dict, errdict, rpset, &rlset);
+	error = npf_mk_rules(npf, npf_dict, errdict, nc);
 	if (error) {
 		goto fail;
 	}
-	error = npf_mk_connlist(npf, npf_dict, errdict, ntset, &conndb);
+	error = npf_mk_connlist(npf, npf_dict, errdict, nc, &conndb);
 	if (error) {
 		goto fail;
 	}
 
+	flush = dnvlist_get_bool(npf_dict, "flush", false);
+	nc->default_pass = flush;
+
 	/*
 	 * Finally - perform the load.
 	 */
-	flush = dnvlist_get_bool(npf_dict, "flush", false);
-	npf_config_load(npf, rlset, tblset, ntset, rpset, conndb, flush);
+	npf_config_load(npf, nc, conndb, flush);
 	npf_mk_params(npf, npf_dict, errdict, true /* set the params */);
 
 	/* Done.  Since data is consumed now, we shall not destroy it. */
-	tblset = NULL;
-	rpset = NULL;
-	rlset = NULL;
-	ntset = NULL;
+	nc = NULL;
 fail:
-	/*
-	 * Note: the rulesets must be destroyed first, in order to drop
-	 * any references to the tableset.
-	 */
-	if (rlset) {
-		npf_ruleset_destroy(rlset);
-	}
-	if (ntset) {
-		npf_ruleset_destroy(ntset);
-	}
-	if (rpset) {
-		npf_rprocset_destroy(rpset);
-	}
-	if (tblset) {
-		npf_tableset_destroy(tblset);
+	if (nc) {
+		npf_config_destroy(nc);
 	}
 	nvlist_destroy(npf_dict);
 	return error;
@@ -710,6 +674,7 @@ npfctl_load(npf_t *npf, u_long cmd, void
 int
 npfctl_save(npf_t *npf, u_long cmd, void *data)
 {
+	npf_config_t *nc;
 	nvlist_t *npf_dict;
 	int error;
 
@@ -719,24 +684,24 @@ npfctl_save(npf_t *npf, u_long cmd, void
 	/*
 	 * Serialise the whole NPF config, including connections.
 	 */
-	npf_config_enter(npf);
+	nc = npf_config_enter(npf);
 	error = npf_conndb_export(npf, npf_dict);
 	if (error) {
 		goto out;
 	}
-	error = npf_ruleset_export(npf, npf_config_ruleset(npf), "rules", npf_dict);
+	error = npf_ruleset_export(npf, nc->ruleset, "rules", npf_dict);
 	if (error) {
 		goto out;
 	}
-	error = npf_ruleset_export(npf, npf_config_natset(npf), "nat", npf_dict);
+	error = npf_ruleset_export(npf, nc->nat_ruleset, "nat", npf_dict);
 	if (error) {
 		goto out;
 	}
-	error = npf_tableset_export(npf, npf_config_tableset(npf), npf_dict);
+	error = npf_tableset_export(npf, nc->tableset, npf_dict);
 	if (error) {
 		goto out;
 	}
-	error = npf_rprocset_export(npf_config_rprocs(npf), npf_dict);
+	error = npf_rprocset_export(nc->rule_procs, npf_dict);
 	if (error) {
 		goto out;
 	}
@@ -744,7 +709,7 @@ npfctl_save(npf_t *npf, u_long cmd, void
 	if (error) {
 		goto out;
 	}
-	nvlist_add_bool(npf_dict, "active", npf_pfil_registered_p());
+	nvlist_add_bool(npf_dict, "active", npf_active_p());
 	error = npf_nvlist_copyout(npf, data, npf_dict);
 	npf_dict = NULL;
 out:
@@ -763,19 +728,15 @@ static int __noinline
 npfctl_table_replace_nvlist(npf_t *npf, nvlist_t *npf_dict, nvlist_t *errdict)
 {
 	npf_table_t *tbl, *gc_tbl = NULL;
-	npf_tableset_t *tblset;
+	npf_config_t *nc;
 	int error = 0;
 
-	npf_config_enter(npf);
-	tblset = npf_config_tableset(npf);
-
-	/* Get the entries or binary data. */
-	error = npf_mk_table(npf, npf_dict, errdict, tblset, &tbl, true);
+	nc = npf_config_enter(npf);
+	error = npf_mk_table(npf, npf_dict, errdict, nc->tableset, &tbl, true);
 	if (error) {
 		goto err;
 	}
-
-	gc_tbl = npf_tableset_swap(tblset, tbl);
+	gc_tbl = npf_tableset_swap(nc->tableset, tbl);
 	if (gc_tbl == NULL) {
 		error = EINVAL;
 		gc_tbl = tbl;
@@ -845,6 +806,7 @@ npfctl_rule(npf_t *npf, u_long cmd, void
 	npf_ruleset_t *rlset;
 	npf_rule_t *rl = NULL;
 	const char *ruleset_name;
+	npf_config_t *nc;
 	uint32_t rcmd;
 	int error = 0;
 	bool natset;
@@ -861,8 +823,8 @@ npfctl_rule(npf_t *npf, u_long cmd, void
 		goto out;
 	}
 
-	npf_config_enter(npf);
-	rlset = natset ? npf_config_natset(npf) : npf_config_ruleset(npf);
+	nc = npf_config_enter(npf);
+	rlset = natset ? nc->nat_ruleset : nc->ruleset;
 	switch (rcmd) {
 	case NPF_CMD_RULE_ADD: {
 		retdict = nvlist_create(0);
@@ -871,7 +833,7 @@ npfctl_rule(npf_t *npf, u_long cmd, void
 			 * Translation rule.
 			 */
 			error = npf_mk_singlenat(npf, npf_rule, rlset,
-			    npf_config_tableset(npf), retdict, &rl);
+			    nc->tableset, retdict, &rl);
 		} else {
 			/*
 			 * Standard rule.
@@ -953,7 +915,7 @@ npfctl_table(npf_t *npf, void *data)
 {
 	const npf_ioctl_table_t *nct = data;
 	char tname[NPF_TABLE_MAXNAMELEN];
-	npf_tableset_t *ts;
+	npf_config_t *nc;
 	npf_table_t *t;
 	int error;
 
@@ -962,9 +924,8 @@ npfctl_table(npf_t *npf, void *data)
 		return error;
 	}
 
-	npf_config_enter(npf);
-	ts = npf_config_tableset(npf);
-	if ((t = npf_tableset_getbyname(ts, tname)) == NULL) {
+	nc = npf_config_enter(npf);
+	if ((t = npf_tableset_getbyname(nc->tableset, tname)) == NULL) {
 		npf_config_exit(npf);
 		return EINVAL;
 	}

Index: src/sys/net/npf/npf_handler.c
diff -u src/sys/net/npf/npf_handler.c:1.46.2.1 src/sys/net/npf/npf_handler.c:1.46.2.2
--- src/sys/net/npf/npf_handler.c:1.46.2.1	Tue Aug 13 14:35:55 2019
+++ src/sys/net/npf/npf_handler.c	Sun Sep  1 13:21:39 2019
@@ -35,7 +35,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.46.2.1 2019/08/13 14:35:55 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.46.2.2 2019/09/01 13:21:39 martin Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -193,13 +193,13 @@ npfk_packet_handler(npf_t *npf, struct m
 	}
 
 	/* Acquire the lock, inspect the ruleset using this packet. */
-	int slock = npf_config_read_enter();
+	int slock = npf_config_read_enter(npf);
 	npf_ruleset_t *rlset = npf_config_ruleset(npf);
 
 	rl = npf_ruleset_inspect(&npc, rlset, di, NPF_LAYER_3);
 	if (__predict_false(rl == NULL)) {
 		const bool pass = npf_default_pass(npf);
-		npf_config_read_exit(slock);
+		npf_config_read_exit(npf, slock);
 
 		if (pass) {
 			npf_stats_inc(npf, NPF_STAT_PASS_DEFAULT);
@@ -218,7 +218,7 @@ npfk_packet_handler(npf_t *npf, struct m
 
 	/* Conclude with the rule and release the lock. */
 	error = npf_rule_conclude(rl, &mi);
-	npf_config_read_exit(slock);
+	npf_config_read_exit(npf, slock);
 
 	if (error) {
 		npf_stats_inc(npf, NPF_STAT_BLOCK_RULESET);
@@ -246,6 +246,7 @@ npfk_packet_handler(npf_t *npf, struct m
 pass:
 	decision = NPF_DECISION_PASS;
 	KASSERT(error == 0);
+
 	/*
 	 * Perform NAT.
 	 */
Index: src/sys/net/npf/npf_nat.c
diff -u src/sys/net/npf/npf_nat.c:1.46.2.1 src/sys/net/npf/npf_nat.c:1.46.2.2
--- src/sys/net/npf/npf_nat.c:1.46.2.1	Tue Aug 13 14:35:55 2019
+++ src/sys/net/npf/npf_nat.c	Sun Sep  1 13:21:39 2019
@@ -67,7 +67,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.46.2.1 2019/08/13 14:35:55 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.46.2.2 2019/09/01 13:21:39 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -381,19 +381,20 @@ npf_nat_which(const unsigned type, bool 
 static npf_natpolicy_t *
 npf_nat_inspect(npf_cache_t *npc, const int di)
 {
-	int slock = npf_config_read_enter();
-	npf_ruleset_t *rlset = npf_config_natset(npc->npc_ctx);
+	npf_t *npf = npc->npc_ctx;
+	int slock = npf_config_read_enter(npf);
+	npf_ruleset_t *rlset = npf_config_natset(npf);
 	npf_natpolicy_t *np;
 	npf_rule_t *rl;
 
 	rl = npf_ruleset_inspect(npc, rlset, di, NPF_LAYER_3);
 	if (rl == NULL) {
-		npf_config_read_exit(slock);
+		npf_config_read_exit(npf, slock);
 		return NULL;
 	}
 	np = npf_rule_getnat(rl);
 	atomic_inc_uint(&np->n_refcnt);
-	npf_config_read_exit(slock);
+	npf_config_read_exit(npf, slock);
 	return np;
 }
 
@@ -444,6 +445,7 @@ npf_nat_create(npf_cache_t *npc, npf_nat
 {
 	const int proto = npc->npc_proto;
 	const unsigned alen = npc->npc_alen;
+	npf_t *npf = npc->npc_ctx;
 	npf_addr_t *taddr;
 	npf_nat_t *nt;
 
@@ -455,7 +457,7 @@ npf_nat_create(npf_cache_t *npc, npf_nat
 	if (__predict_false(!nt)) {
 		return NULL;
 	}
-	npf_stats_inc(npc->npc_ctx, NPF_STAT_NAT_CREATE);
+	npf_stats_inc(npf, NPF_STAT_NAT_CREATE);
 	nt->nt_natpolicy = np;
 	nt->nt_conn = con;
 	nt->nt_alg = NULL;
@@ -464,12 +466,16 @@ npf_nat_create(npf_cache_t *npc, npf_nat
 	 * Select the translation address.
 	 */
 	if (np->n_flags & NPF_NAT_USETABLE) {
+		int slock = npf_config_read_enter(npf);
 		taddr = npf_nat_getaddr(npc, np, alen);
 		if (__predict_false(!taddr)) {
+			npf_config_read_exit(npf, slock);
 			pool_cache_put(nat_cache, nt);
 			return NULL;
 		}
 		memcpy(&nt->nt_taddr, taddr, alen);
+		npf_config_read_exit(npf, slock);
+
 	} else if (np->n_algo == NPF_ALGO_NETMAP) {
 		const unsigned which = npf_nat_which(np->n_type, true);
 		npf_nat_algo_netmap(npc, np, which, &nt->nt_taddr);

Index: src/sys/net/npf/npf_ifaddr.c
diff -u src/sys/net/npf/npf_ifaddr.c:1.5 src/sys/net/npf/npf_ifaddr.c:1.5.4.1
--- src/sys/net/npf/npf_ifaddr.c:1.5	Sat Jan 19 21:19:32 2019
+++ src/sys/net/npf/npf_ifaddr.c	Sun Sep  1 13:21:39 2019
@@ -33,7 +33,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ifaddr.c,v 1.5 2019/01/19 21:19:32 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ifaddr.c,v 1.5.4.1 2019/09/01 13:21:39 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -51,8 +51,8 @@ lookup_ifnet_table(npf_t *npf, ifnet_t *
 {
 	const npf_ifops_t *ifops = npf->ifops;
 	char tname[NPF_TABLE_MAXNAMELEN];
-	npf_tableset_t *ts;
 	const char *ifname;
+	npf_config_t *nc;
 	npf_table_t *t;
 	u_int tid;
 
@@ -61,13 +61,12 @@ lookup_ifnet_table(npf_t *npf, ifnet_t *
 	snprintf(tname, sizeof(tname), ".ifnet-%s", ifname);
 
 	KERNEL_LOCK(1, NULL);
-	npf_config_enter(npf);
-	ts = npf_config_tableset(npf);
+	nc = npf_config_enter(npf);
 
 	/*
 	 * Check whether this interface is of any interest to us.
 	 */
-	t = npf_tableset_getbyname(ts, tname);
+	t = npf_tableset_getbyname(nc->tableset, tname);
 	if (!t) {
 		goto out;
 	}
@@ -88,7 +87,7 @@ out:
 static void
 replace_ifnet_table(npf_t *npf, npf_table_t *newt)
 {
-	npf_tableset_t *ts = npf_config_tableset(npf);
+	npf_tableset_t *ts = npf->config->tableset;
 	npf_table_t *oldt;
 
 	KERNEL_UNLOCK_ONE(NULL);

Index: src/sys/net/npf/npf_impl.h
diff -u src/sys/net/npf/npf_impl.h:1.75.2.2 src/sys/net/npf/npf_impl.h:1.75.2.3
--- src/sys/net/npf/npf_impl.h:1.75.2.2	Sun Sep  1 13:13:14 2019
+++ src/sys/net/npf/npf_impl.h	Sun Sep  1 13:21:39 2019
@@ -75,7 +75,6 @@ struct npf_rprocset;
 struct npf_portmap;
 struct npf_nat;
 struct npf_conn;
-struct npf_config;
 
 typedef struct npf_ruleset	npf_ruleset_t;
 typedef struct npf_rule		npf_rule_t;
@@ -85,7 +84,6 @@ typedef struct npf_rprocset	npf_rprocset
 typedef struct npf_alg		npf_alg_t;
 typedef struct npf_natpolicy	npf_natpolicy_t;
 typedef struct npf_conn		npf_conn_t;
-typedef struct npf_config	npf_config_t;
 
 struct npf_conndb;
 struct npf_table;
@@ -98,10 +96,22 @@ typedef struct npf_table	npf_table_t;
 typedef struct npf_tableset	npf_tableset_t;
 typedef struct npf_algset	npf_algset_t;
 
+#ifdef __NetBSD__
+typedef void			ebr_t;
+#endif
+
 /*
  * DEFINITIONS.
  */
 
+typedef struct {
+	npf_ruleset_t *		ruleset;
+	npf_ruleset_t *		nat_ruleset;
+	npf_rprocset_t *	rule_procs;
+	npf_tableset_t *	tableset;
+	bool			default_pass;
+} npf_config_t;
+
 typedef void (*npf_workfunc_t)(npf_t *);
 
 typedef struct {
@@ -195,7 +205,7 @@ typedef enum {
 struct npf {
 	/* Active NPF configuration. */
 	kmutex_t		config_lock;
-	pserialize_t		qsbr;
+	ebr_t *			ebr;
 	npf_config_t *		config;
 
 	/* BPF byte-code context. */
@@ -265,20 +275,21 @@ void		npf_rproc_assign(npf_rproc_t *, vo
 void		npf_config_init(npf_t *);
 void		npf_config_fini(npf_t *);
 
-void		npf_config_enter(npf_t *);
+npf_config_t *	npf_config_enter(npf_t *);
 void		npf_config_exit(npf_t *);
 void		npf_config_sync(npf_t *);
 bool		npf_config_locked_p(npf_t *);
-int		npf_config_read_enter(void);
-void		npf_config_read_exit(int s);
+int		npf_config_read_enter(npf_t *);
+void		npf_config_read_exit(npf_t *, int);
 
-void		npf_config_load(npf_t *, npf_ruleset_t *, npf_tableset_t *,
-		    npf_ruleset_t *, npf_rprocset_t *, npf_conndb_t *, bool);
+npf_config_t *	npf_config_create(void);
+void		npf_config_destroy(npf_config_t *);
+void		npf_config_load(npf_t *, npf_config_t *, npf_conndb_t *, bool);
 npf_ruleset_t *	npf_config_ruleset(npf_t *npf);
 npf_ruleset_t *	npf_config_natset(npf_t *npf);
 npf_tableset_t *npf_config_tableset(npf_t *npf);
-npf_rprocset_t *npf_config_rprocs(npf_t *);
 bool		npf_default_pass(npf_t *);
+bool		npf_active_p(void);
 
 int		npf_worker_sysinit(unsigned);
 void		npf_worker_sysfini(void);
@@ -286,8 +297,6 @@ void		npf_worker_signal(npf_t *);
 void		npf_worker_register(npf_t *, npf_workfunc_t);
 void		npf_worker_unregister(npf_t *, npf_workfunc_t);
 
-int		npfctl_switch(void *);
-int		npfctl_reload(u_long, void *);
 int		npfctl_save(npf_t *, u_long, void *);
 int		npfctl_load(npf_t *, u_long, void *);
 int		npfctl_rule(npf_t *, u_long, void *);
@@ -317,11 +326,6 @@ void		npf_ifaddr_sync(npf_t *, ifnet_t *
 void		npf_ifaddr_flush(npf_t *, ifnet_t *);
 void		npf_ifaddr_syncall(npf_t *);
 
-/* Packet filter hooks. */
-int		npf_pfil_register(bool);
-void		npf_pfil_unregister(bool);
-bool		npf_pfil_registered_p(void);
-
 /* Protocol helpers. */
 int		npf_cache_all(npf_cache_t *);
 void		npf_recache(npf_cache_t *);
@@ -503,6 +507,16 @@ void		npf_alg_exec(npf_cache_t *, npf_na
 npf_conn_t *	npf_alg_conn(npf_cache_t *, int);
 int		npf_alg_export(npf_t *, nvlist_t *);
 
+/* Wrappers for the reclamation mechanism. */
+ebr_t *		npf_ebr_create(void);
+void		npf_ebr_destroy(ebr_t *);
+void		npf_ebr_register(ebr_t *);
+void		npf_ebr_unregister(ebr_t *);
+int		npf_ebr_enter(ebr_t *);
+void		npf_ebr_exit(ebr_t *, int);
+void		npf_ebr_full_sync(ebr_t *);
+bool		npf_ebr_incrit_p(ebr_t *);
+
 /* Debugging routines. */
 const char *	npf_addr_dump(const npf_addr_t *, int);
 void		npf_state_dump(const npf_state_t *);
@@ -514,10 +528,4 @@ void		npf_state_setsampler(void (*)(npf_
 void		npf_setkernctx(npf_t *);
 npf_t *		npf_getkernctx(void);
 
-#ifdef __NetBSD__
-#define	pserialize_register(x)
-#define	pserialize_checkpoint(x)
-#define	pserialize_unregister(x)
-#endif
-
 #endif	/* _NPF_IMPL_H_ */

Index: src/sys/net/npf/npf_os.c
diff -u src/sys/net/npf/npf_os.c:1.12.2.2 src/sys/net/npf/npf_os.c:1.12.2.3
--- src/sys/net/npf/npf_os.c:1.12.2.2	Sun Sep  1 13:13:14 2019
+++ src/sys/net/npf/npf_os.c	Sun Sep  1 13:21:39 2019
@@ -33,7 +33,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_os.c,v 1.12.2.2 2019/09/01 13:13:14 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_os.c,v 1.12.2.3 2019/09/01 13:21:39 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "pf.h"
@@ -50,6 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: npf_os.c,v 1
 #include <sys/kmem.h>
 #include <sys/lwp.h>
 #include <sys/module.h>
+#include <sys/pserialize.h>
 #include <sys/socketvar.h>
 #include <sys/uio.h>
 
@@ -83,6 +84,9 @@ MODULE(MODULE_CLASS_MISC, npf, "bpf");
 MODULE(MODULE_CLASS_DRIVER, npf, "bpf");
 #endif
 
+static int	npf_pfil_register(bool);
+static void	npf_pfil_unregister(bool);
+
 static int	npf_dev_open(dev_t, int, int, lwp_t *);
 static int	npf_dev_close(dev_t, int, int, lwp_t *);
 static int	npf_dev_ioctl(dev_t, u_long, void *, int, lwp_t *);
@@ -225,6 +229,26 @@ npf_stats_export(npf_t *npf, void *data)
 	return error;
 }
 
+/*
+ * npfctl_switch: enable or disable packet inspection.
+ */
+static int
+npfctl_switch(void *data)
+{
+	const bool onoff = *(int *)data ? true : false;
+	int error;
+
+	if (onoff) {
+		/* Enable: add pfil hooks. */
+		error = npf_pfil_register(false);
+	} else {
+		/* Disable: remove pfil hooks. */
+		npf_pfil_unregister(false);
+		error = 0;
+	}
+	return error;
+}
+
 static int
 npf_dev_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
 {
@@ -289,7 +313,7 @@ bool
 npf_autounload_p(void)
 {
 	npf_t *npf = npf_getkernctx();
-	return !npf_pfil_registered_p() && npf_default_pass(npf);
+	return !npf_active_p() && npf_default_pass(npf);
 }
 
 /*
@@ -393,7 +417,7 @@ npf_ifaddrhook(void *arg, u_long cmd, vo
 /*
  * npf_pfil_register: register pfil(9) hooks.
  */
-int
+static int
 npf_pfil_register(bool init)
 {
 	npf_t *npf = npf_getkernctx();
@@ -462,7 +486,7 @@ out:
 /*
  * npf_pfil_unregister: unregister pfil(9) hooks.
  */
-void
+static void
 npf_pfil_unregister(bool fini)
 {
 	npf_t *npf = npf_getkernctx();
@@ -489,8 +513,64 @@ npf_pfil_unregister(bool fini)
 }
 
 bool
-npf_pfil_registered_p(void)
+npf_active_p(void)
 {
 	return pfil_registered;
 }
+
+#endif
+
+#ifdef __NetBSD__
+
+ebr_t *
+npf_ebr_create(void)
+{
+	return pserialize_create();
+}
+
+void
+npf_ebr_destroy(ebr_t *ebr)
+{
+	pserialize_destroy(ebr);
+}
+
+void
+npf_ebr_register(ebr_t *ebr)
+{
+	KASSERT(ebr != NULL); (void)ebr;
+}
+
+void
+npf_ebr_unregister(ebr_t *ebr)
+{
+	KASSERT(ebr != NULL); (void)ebr;
+}
+
+int
+npf_ebr_enter(ebr_t *ebr)
+{
+	KASSERT(ebr != NULL); (void)ebr;
+	return pserialize_read_enter();
+}
+
+void
+npf_ebr_exit(ebr_t *ebr, int s)
+{
+	KASSERT(ebr != NULL); (void)ebr;
+	pserialize_read_exit(s);
+}
+
+void
+npf_ebr_full_sync(ebr_t *ebr)
+{
+	pserialize_perform(ebr);
+}
+
+bool
+npf_ebr_incrit_p(ebr_t *ebr)
+{
+	KASSERT(ebr != NULL); (void)ebr;
+	return pserialize_in_read_section();
+}
+
 #endif

Index: src/sys/sys/mbuf.h
diff -u src/sys/sys/mbuf.h:1.219 src/sys/sys/mbuf.h:1.219.4.1
--- src/sys/sys/mbuf.h:1.219	Thu Jan 17 02:47:15 2019
+++ src/sys/sys/mbuf.h	Sun Sep  1 13:21:39 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: mbuf.h,v 1.219 2019/01/17 02:47:15 knakahara Exp $	*/
+/*	$NetBSD: mbuf.h,v 1.219.4.1 2019/09/01 13:21:39 martin Exp $	*/
 
 /*
  * Copyright (c) 1996, 1997, 1999, 2001, 2007 The NetBSD Foundation, Inc.
@@ -799,6 +799,7 @@ int	m_tag_copy_chain(struct mbuf *, stru
 /* Packet tag types */
 #define PACKET_TAG_NONE			0  /* Nothing */
 #define PACKET_TAG_SO			4  /* sending socket pointer */
+#define PACKET_TAG_NPF			10 /* packet filter */
 #define PACKET_TAG_PF			11 /* packet filter */
 #define PACKET_TAG_ALTQ_QID		12 /* ALTQ queue id */
 #define PACKET_TAG_IPSEC_OUT_DONE	18

Index: src/usr.sbin/npf/npfctl/npf_bpf_comp.c
diff -u src/usr.sbin/npf/npfctl/npf_bpf_comp.c:1.13.2.1 src/usr.sbin/npf/npfctl/npf_bpf_comp.c:1.13.2.2
--- src/usr.sbin/npf/npfctl/npf_bpf_comp.c:1.13.2.1	Sun Aug 11 10:10:23 2019
+++ src/usr.sbin/npf/npfctl/npf_bpf_comp.c	Sun Sep  1 13:21:39 2019
@@ -32,14 +32,14 @@
  *
  * Overview
  *
- *	Each NPF rule is compiled into BPF micro-program.  There is a
+ *	Each NPF rule is compiled into a BPF micro-program.  There is a
  *	BPF byte-code fragment for each higher-level filtering logic,
  *	e.g. to match L4 protocol, IP/mask, etc.  The generation process
  *	combines multiple BPF-byte code fragments into one program.
  *
  * Basic case
  *
- *	Consider a basic case, where all filters should match.  They
+ *	Consider a basic case where all filters should match.  They
  *	are expressed as logical conjunction, e.g.:
  *
  *		A and B and C and D
@@ -56,8 +56,8 @@
  *	Once all byte-code fragments are combined into one, then there
  *	are two additional steps:
  *
- *	- Two instructions are appended at the end of the program: return
- *	"success" followed by return "failure".
+ *	- Two instructions are appended at the end of the program: "return
+ *	success" followed by "return failure".
  *
  *	- All jumps with the JUMP_MAGIC value are patched to point to the
  *	"return failure" instruction.
@@ -65,11 +65,11 @@
  *	Therefore, if all filter criteria will match, then the first
  *	instruction will be reached, indicating a successful match of the
  *	rule.  Otherwise, if any of the criteria will not match, it will
- *	take the failure path and the rule will not matching.
+ *	take the failure path and the rule will not be matching.
  *
  * Grouping
  *
- *	Filters can have groups, which are have a meaning of logical
+ *	Filters can have groups, which have a meaning of logical
  *	disjunction, e.g.:
  *
  *		A and B and (C or D)
@@ -82,7 +82,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_bpf_comp.c,v 1.13.2.1 2019/08/11 10:10:23 martin Exp $");
+__RCSID("$NetBSD: npf_bpf_comp.c,v 1.13.2.2 2019/09/01 13:21:39 martin Exp $");
 
 #include <stdlib.h>
 #include <stdbool.h>

Index: src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c
diff -u src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.17.2.1 src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.17.2.2
--- src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.17.2.1	Tue Aug 13 14:35:55 2019
+++ src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c	Sun Sep  1 13:21:39 2019
@@ -68,7 +68,7 @@ run_raw_testcase(unsigned i)
 	m = mbuf_get_pkt(AF_INET, IPPROTO_UDP, t->src, t->dst, 9000, 9000);
 	npc = get_cached_pkt(m, t->ifname);
 
-	slock = npf_config_read_enter();
+	slock = npf_config_read_enter(npf);
 	rl = npf_ruleset_inspect(npc, npf_config_ruleset(npf), t->di, NPF_LAYER_3);
 	if (rl) {
 		npf_match_info_t mi;
@@ -76,7 +76,7 @@ run_raw_testcase(unsigned i)
 	} else {
 		error = ENOENT;
 	}
-	npf_config_read_exit(slock);
+	npf_config_read_exit(npf, slock);
 
 	put_cached_pkt(npc);
 	return error;

Reply via email to