Module Name: src
Committed By: rmind
Date: Sun Aug 25 13:21:04 UTC 2019
Modified Files:
src/sys/net/npf: npf.c 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/usr.sbin/npf/npfctl: npf_bpf_comp.c
src/usr.sbin/npf/npftest/libnpftest: npf_rule_test.c
Log Message:
- 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.
To generate a diff of this commit:
cvs rdiff -u -r1.40 -r1.41 src/sys/net/npf/npf.c
cvs rdiff -u -r1.20 -r1.21 src/sys/net/npf/npf_alg.c
cvs rdiff -u -r1.14 -r1.15 src/sys/net/npf/npf_conf.c
cvs rdiff -u -r1.56 -r1.57 src/sys/net/npf/npf_ctl.c
cvs rdiff -u -r1.47 -r1.48 src/sys/net/npf/npf_handler.c \
src/sys/net/npf/npf_nat.c
cvs rdiff -u -r1.5 -r1.6 src/sys/net/npf/npf_ifaddr.c
cvs rdiff -u -r1.77 -r1.78 src/sys/net/npf/npf_impl.h
cvs rdiff -u -r1.15 -r1.16 src/sys/net/npf/npf_os.c
cvs rdiff -u -r1.14 -r1.15 src/usr.sbin/npf/npfctl/npf_bpf_comp.c
cvs rdiff -u -r1.18 -r1.19 \
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.40 src/sys/net/npf/npf.c:1.41
--- src/sys/net/npf/npf.c:1.40 Sun Aug 11 20:26:33 2019
+++ src/sys/net/npf/npf.c Sun Aug 25 13:21:03 2019
@@ -33,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.40 2019/08/11 20:26:33 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.41 2019/08/25 13:21:03 rmind 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_alg.c
diff -u src/sys/net/npf/npf_alg.c:1.20 src/sys/net/npf/npf_alg.c:1.21
--- src/sys/net/npf/npf_alg.c:1.20 Tue Jul 23 00:52:01 2019
+++ src/sys/net/npf/npf_alg.c Sun Aug 25 13:21:03 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.21 2019/08/25 13:21:03 rmind 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.14 src/sys/net/npf/npf_conf.c:1.15
--- src/sys/net/npf/npf_conf.c:1.14 Sun Aug 11 20:26:33 2019
+++ src/sys/net/npf/npf_conf.c Sun Aug 25 13:21:03 2019
@@ -47,53 +47,57 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.14 2019/08/11 20:26:33 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.15 2019/08/25 13:21:03 rmind 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.56 src/sys/net/npf/npf_ctl.c:1.57
--- src/sys/net/npf/npf_ctl.c:1.56 Wed Aug 21 21:45:47 2019
+++ src/sys/net/npf/npf_ctl.c Sun Aug 25 13:21:03 2019
@@ -36,7 +36,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.56 2019/08/21 21:45:47 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.57 2019/08/25 13:21:03 rmind Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@@ -237,7 +237,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 +267,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 +305,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 +333,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 +435,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 +458,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 +472,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 +527,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 +553,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 +569,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 +586,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 +608,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 +628,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 +696,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 +706,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;
}
@@ -763,19 +750,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 +828,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 +845,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 +855,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 +937,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 +946,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.47 src/sys/net/npf/npf_handler.c:1.48
--- src/sys/net/npf/npf_handler.c:1.47 Sun Aug 11 20:26:33 2019
+++ src/sys/net/npf/npf_handler.c Sun Aug 25 13:21:03 2019
@@ -35,7 +35,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.47 2019/08/11 20:26:33 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.48 2019/08/25 13:21:03 rmind 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.47 src/sys/net/npf/npf_nat.c:1.48
--- src/sys/net/npf/npf_nat.c:1.47 Sun Aug 11 20:26:34 2019
+++ src/sys/net/npf/npf_nat.c Sun Aug 25 13:21:03 2019
@@ -67,7 +67,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.47 2019/08/11 20:26:34 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.48 2019/08/25 13:21:03 rmind 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.6
--- src/sys/net/npf/npf_ifaddr.c:1.5 Sat Jan 19 21:19:32 2019
+++ src/sys/net/npf/npf_ifaddr.c Sun Aug 25 13:21:03 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.6 2019/08/25 13:21:03 rmind 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.77 src/sys/net/npf/npf_impl.h:1.78
--- src/sys/net/npf/npf_impl.h:1.77 Wed Aug 21 21:45:47 2019
+++ src/sys/net/npf/npf_impl.h Sun Aug 25 13:21:03 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,19 +275,19 @@ 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 *);
int npf_worker_sysinit(unsigned);
@@ -503,6 +513,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 +534,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.15 src/sys/net/npf/npf_os.c:1.16
--- src/sys/net/npf/npf_os.c:1.15 Wed Aug 21 21:45:47 2019
+++ src/sys/net/npf/npf_os.c Sun Aug 25 13:21:03 2019
@@ -33,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_os.c,v 1.15 2019/08/21 21:45:47 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_os.c,v 1.16 2019/08/25 13:21:03 rmind 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>
@@ -494,3 +495,58 @@ npf_pfil_registered_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/usr.sbin/npf/npfctl/npf_bpf_comp.c
diff -u src/usr.sbin/npf/npfctl/npf_bpf_comp.c:1.14 src/usr.sbin/npf/npfctl/npf_bpf_comp.c:1.15
--- src/usr.sbin/npf/npfctl/npf_bpf_comp.c:1.14 Thu Aug 8 21:29:15 2019
+++ src/usr.sbin/npf/npfctl/npf_bpf_comp.c Sun Aug 25 13:21:03 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.14 2019/08/08 21:29:15 rmind Exp $");
+__RCSID("$NetBSD: npf_bpf_comp.c,v 1.15 2019/08/25 13:21:03 rmind 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.18 src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.19
--- src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.18 Sun Aug 11 20:26:34 2019
+++ src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c Sun Aug 25 13:21:03 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;