Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Major NPF improvements (merge from upstream):
details: https://anonhg.NetBSD.org/src/rev/8ae67f2203ad
branches: trunk
changeset: 933757:8ae67f2203ad
user: rmind <rmind%NetBSD.org@localhost>
date: Sat May 30 14:16:56 2020 +0000
description:
Major NPF improvements (merge from upstream):
- Switch to the C11-style atomic primitives using atomic_loadstore(9).
- npfkern: introduce the 'state.key.interface' and 'state.key.direction'
settings. Users can now choose whether the connection state should be
strictly per-interface or global at the configuration level. Keep NAT
logic to be always per-interface, though.
- npfkern: rewrite the G/C worker logic and make it self-tuning.
- npfkern and libnpf: multiple bug fixes; add param exporting; introduce
more parameters. Remove npf_nvlist_{copyin,copyout}() functions and
refactor npfctl_load_nvlist() with others; add npfctl_run_op() to have
a single entry point for operations. Introduce npf_flow_t and clean up
some code.
- npfctl: lots of fixes for the 'npfctl show' logic; make 'npfctl list'
more informative; misc usability improvements and more user-friendly
error messages.
- Amend and improve the manual pages.
diffstat:
lib/libnpf/libnpf.3 | 16 +-
lib/libnpf/npf.c | 405 +++++++++---
lib/libnpf/npf.h | 3 +-
sys/net/npf/files.npf | 3 +-
sys/net/npf/npf.c | 34 +-
sys/net/npf/npf.h | 17 +-
sys/net/npf/npf_alg.c | 103 ++-
sys/net/npf/npf_alg_icmp.c | 21 +-
sys/net/npf/npf_conf.c | 48 +-
sys/net/npf/npf_conn.c | 337 ++++++----
sys/net/npf/npf_conn.h | 37 +-
sys/net/npf/npf_conndb.c | 96 ++-
sys/net/npf/npf_connkey.c | 226 +++++-
sys/net/npf/npf_ctl.c | 504 ++++++---------
sys/net/npf/npf_ext_log.c | 45 +-
sys/net/npf/npf_ext_normalize.c | 46 +-
sys/net/npf/npf_ext_rndblock.c | 55 +-
sys/net/npf/npf_handler.c | 47 +-
sys/net/npf/npf_if.c | 21 +-
sys/net/npf/npf_ifaddr.c | 6 +-
sys/net/npf/npf_impl.h | 68 +-
sys/net/npf/npf_inet.c | 8 +-
sys/net/npf/npf_mbuf.c | 37 +-
sys/net/npf/npf_nat.c | 249 ++++++--
sys/net/npf/npf_os.c | 91 +-
sys/net/npf/npf_params.c | 53 +-
sys/net/npf/npf_portmap.c | 28 +-
sys/net/npf/npf_rproc.c | 19 +-
sys/net/npf/npf_ruleset.c | 84 +-
sys/net/npf/npf_sendpkt.c | 4 +-
sys/net/npf/npf_state.c | 22 +-
sys/net/npf/npf_state_tcp.c | 15 +-
sys/net/npf/npf_tableset.c | 18 +-
sys/net/npf/npf_worker.c | 316 ++++++---
sys/net/npf/npfkern.h | 42 +-
usr.sbin/npf/npf-params.7 | 54 +-
usr.sbin/npf/npfctl/Makefile | 6 +-
usr.sbin/npf/npfctl/npf.conf.5 | 54 +-
usr.sbin/npf/npfctl/npf_bpf_comp.c | 150 +++-
usr.sbin/npf/npfctl/npf_build.c | 269 +++++---
usr.sbin/npf/npfctl/npf_cmd.c | 540 +++++++++++++++++
usr.sbin/npf/npfctl/npf_parse.y | 131 ++-
usr.sbin/npf/npfctl/npf_scan.l | 8 +-
usr.sbin/npf/npfctl/npf_show.c | 396 ++++++++----
usr.sbin/npf/npfctl/npf_var.c | 120 +--
usr.sbin/npf/npfctl/npf_var.h | 12 +-
usr.sbin/npf/npfctl/npfctl.8 | 38 +-
usr.sbin/npf/npfctl/npfctl.c | 705 +++++-----------------
usr.sbin/npf/npfctl/npfctl.h | 38 +-
usr.sbin/npf/npftest/libnpftest/Makefile | 4 +-
usr.sbin/npf/npftest/libnpftest/npf_conn_test.c | 173 -----
usr.sbin/npf/npftest/libnpftest/npf_gc_test.c | 267 ++++++++
usr.sbin/npf/npftest/libnpftest/npf_mbuf_subr.c | 6 +-
usr.sbin/npf/npftest/libnpftest/npf_nat_test.c | 9 +-
usr.sbin/npf/npftest/libnpftest/npf_state_test.c | 3 +-
usr.sbin/npf/npftest/libnpftest/npf_test.h | 8 +-
usr.sbin/npf/npftest/libnpftest/npf_test_subr.c | 52 +-
usr.sbin/npf/npftest/npftest.c | 10 +-
usr.sbin/npf/npftest/npftest.conf | 5 +-
usr.sbin/npf/npftest/npftest.h | 6 +-
60 files changed, 3771 insertions(+), 2417 deletions(-)
diffs (truncated from 11286 to 300 lines):
diff -r 0029d1c6d643 -r 8ae67f2203ad lib/libnpf/libnpf.3
--- a/lib/libnpf/libnpf.3 Sat May 30 14:15:43 2020 +0000
+++ b/lib/libnpf/libnpf.3 Sat May 30 14:16:56 2020 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: libnpf.3,v 1.11 2019/09/30 00:37:11 rmind Exp $
+.\" $NetBSD: libnpf.3,v 1.12 2020/05/30 14:16:56 rmind Exp $
.\"
.\" Copyright (c) 2011-2019 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 August 25, 2019
+.Dd May 30, 2020
.Dt LIBNPF 3
.Os
.Sh NAME
@@ -187,13 +187,12 @@
.It Dv NPF_RULE_STATEFUL
Create a state (session) on match, track the connection and pass the
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).
+The state is uniquely identified by an n-tuple key.
.It Dv NPF_RULE_GSTATEFUL
-Exclude the interface identifier from the state key i.e. use a 4-tuple.
+Exclude the interface identifier from the state key (n-tuple).
This makes the state global with respect to the network interfaces.
-The state is also picked for packets travelling different direction than
-originally.
+The state is also picked for packets travelling in different direction
+than originally.
.It Dv NPF_RULE_RETRST
Return TCP RST packet in a case of packet block.
.It Dv NPF_RULE_RETICMP
@@ -281,7 +280,8 @@
is
.Dv NULL ,
then insert into the main ruleset.
-The rule must not be referenced after insertion.
+The rule will be consumed (the relevant resourced will be freed) and it
+must not be referenced after insertion.
.\" ---
.It Fn npf_rule_exists_p "ncf" "name"
Check whether the rule with a given name is already in the configuration.
diff -r 0029d1c6d643 -r 8ae67f2203ad lib/libnpf/npf.c
--- a/lib/libnpf/npf.c Sat May 30 14:15:43 2020 +0000
+++ b/lib/libnpf/npf.c Sat May 30 14:16:56 2020 +0000
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2010-2019 The NetBSD Foundation, Inc.
+ * Copyright (c) 2010-2020 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This material is based upon work partially supported by The
@@ -28,11 +28,14 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.48 2019/09/30 00:37:11 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.49 2020/05/30 14:16:56 rmind Exp $");
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#if !defined(_NPF_STANDALONE)
+#include <sys/ioctl.h>
+#endif
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <net/if.h>
@@ -227,6 +230,94 @@
}
/*
+ * npf_xfer_fd: transfer the given request and receive a response.
+ *
+ * => Sets the 'operation' key on the 'req' dictionary.
+ * => On success: returns 0 and valid nvlist in 'resp'.
+ * => On failure: returns an error number.
+ */
+static int
+_npf_xfer_fd(int fd, unsigned long cmd, nvlist_t *req, nvlist_t **resp)
+{
+ struct stat st;
+ int kernver;
+
+ /*
+ * Set the NPF version and operation.
+ */
+ if (!nvlist_exists(req, "version")) {
+ nvlist_add_number(req, "version", NPF_VERSION);
+ }
+ nvlist_add_number(req, "operation", cmd);
+
+ /*
+ * Determine the type of file descriptor:
+ * - If socket, then perform nvlist_send()/nvlist_recv().
+ * - If a character device, then use ioctl.
+ */
+ if (fstat(fd, &st) == -1) {
+ goto err;
+ }
+ switch (st.st_mode & S_IFMT) {
+#if !defined(__NetBSD__)
+ case S_IFSOCK:
+ if (nvlist_send(fd, req) == -1) {
+ goto err;
+ }
+ if (resp && (*resp = nvlist_recv(fd, 0)) == NULL) {
+ goto err;
+ }
+ break;
+#endif
+#if !defined(_NPF_STANDALONE)
+ case S_IFBLK:
+ case S_IFCHR:
+ if (ioctl(fd, IOC_NPF_VERSION, &kernver) == -1) {
+ goto err;
+ }
+ if (kernver != NPF_VERSION) {
+ errno = EPROGMISMATCH;
+ goto err;
+ }
+ if (nvlist_xfer_ioctl(fd, cmd, req, resp) == -1) {
+ goto err;
+ }
+ break;
+#else
+ (void)kernver;
+#endif
+ default:
+ errno = ENOTSUP;
+ goto err;
+ }
+ return 0;
+err:
+ return errno ? errno : EIO;
+}
+
+/*
+ * npf_xfer_fd_errno: same as npf_xfer_fd(), but:
+ *
+ * => After successful retrieval of the response, inspects it, extracts
+ * the 'errno' value (if any) and returns it.
+ * => Destroys the response.
+ */
+static int
+_npf_xfer_fd_errno(int fd, unsigned long cmd, nvlist_t *req)
+{
+ nvlist_t *resp;
+ int error;
+
+ error = _npf_xfer_fd(fd, cmd, req, &resp);
+ if (error) {
+ return error;
+ }
+ error = _npf_extract_error(resp, NULL);
+ nvlist_destroy(resp);
+ return error;
+}
+
+/*
* CONFIGURATION INTERFACE.
*/
@@ -247,18 +338,18 @@
int
npf_config_submit(nl_config_t *ncf, int fd, npf_error_t *errinfo)
{
- nvlist_t *errnv = NULL;
+ nvlist_t *resp = NULL;
int error;
/* Ensure the config is built. */
(void)npf_config_build(ncf);
- if (nvlist_xfer_ioctl(fd, IOC_NPF_LOAD, ncf->ncf_dict, &errnv) == -1) {
- assert(errnv == NULL);
- return errno;
+ error = _npf_xfer_fd(fd, IOC_NPF_LOAD, ncf->ncf_dict, &resp);
+ if (error) {
+ return error;
}
- error = _npf_extract_error(errnv, errinfo);
- nvlist_destroy(errnv);
+ error = _npf_extract_error(resp, errinfo);
+ nvlist_destroy(resp);
return error;
}
@@ -266,15 +357,24 @@
npf_config_retrieve(int fd)
{
nl_config_t *ncf;
+ nvlist_t *req, *resp = NULL;
+ int error;
ncf = calloc(1, sizeof(nl_config_t));
if (!ncf) {
return NULL;
}
- if (nvlist_recv_ioctl(fd, IOC_NPF_SAVE, &ncf->ncf_dict) == -1) {
+
+ req = nvlist_create(0);
+ error = _npf_xfer_fd(fd, IOC_NPF_SAVE, req, &resp);
+ nvlist_destroy(req);
+
+ if (error || _npf_extract_error(resp, NULL) != 0) {
+ nvlist_destroy(resp);
free(ncf);
return NULL;
}
+ ncf->ncf_dict = resp;
return ncf;
}
@@ -332,7 +432,7 @@
return nvlist_exists_nvlist_array(ncf->ncf_dict, "rules");
}
-void *
+const void *
npf_config_build(nl_config_t *ncf)
{
_npf_rules_process(ncf, ncf->ncf_dict, "__rules");
@@ -397,6 +497,43 @@
return 0;
}
+const char *
+npf_param_iterate(nl_config_t *ncf, nl_iter_t *iter, int *val, int *defval)
+{
+ void *cookie = (void *)(intptr_t)*iter;
+ const nvlist_t *params, *dparams;
+ const char *name;
+ int type;
+
+ assert(sizeof(nl_iter_t) >= sizeof(void *));
+
+ params = dnvlist_get_nvlist(ncf->ncf_dict, "params", NULL);
+ if (params == NULL) {
+ return NULL;
+ }
+skip:
+ if ((name = nvlist_next(params, &type, &cookie)) == NULL) {
+ *iter = NPF_ITER_BEGIN;
+ return NULL;
+ }
+ if (type != NV_TYPE_NUMBER) {
+ goto skip; // should never happen, though
+ }
+ if (defval) {
+ dparams = dnvlist_get_nvlist(ncf->ncf_dict,
+ "params-defaults", NULL);
+ if (dparams == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+ *defval = (int)nvlist_get_number(dparams, name);
+ }
+
+ *val = (int)nvlist_get_number(params, name);
+ *iter = (intptr_t)cookie;
+ return name;
+}
+
/*
* DYNAMIC RULESET INTERFACE.
*/
@@ -412,24 +549,26 @@
npf_ruleset_add(int fd, const char *rname, nl_rule_t *rl, uint64_t *id)
{
const bool natset = _npf_nat_ruleset_p(rname);
- nvlist_t *rule_dict = rl->rule_dict;
- nvlist_t *ret_dict;
+ nvlist_t *rule_nvl = rl->rule_dict, *resp;
+ int error;
- nvlist_add_number(rule_dict, "attr",
- NPF_RULE_DYNAMIC | nvlist_take_number(rule_dict, "attr"));
+ nvlist_add_number(rule_nvl, "attr",
+ NPF_RULE_DYNAMIC | nvlist_take_number(rule_nvl, "attr"));
- if (natset && !dnvlist_get_bool(rule_dict, "nat-rule", false)) {
+ if (natset && !dnvlist_get_bool(rule_nvl, "nat-rule", false)) {
errno = EINVAL;
return errno;
}
- nvlist_add_string(rule_dict, "ruleset-name", rname);
- nvlist_add_bool(rule_dict, "nat-ruleset", natset);
- nvlist_add_number(rule_dict, "command", NPF_CMD_RULE_ADD);
+ nvlist_add_string(rule_nvl, "ruleset-name", rname);
+ nvlist_add_bool(rule_nvl, "nat-ruleset", natset);
+ nvlist_add_number(rule_nvl, "command", NPF_CMD_RULE_ADD);
- if (nvlist_xfer_ioctl(fd, IOC_NPF_RULE, rule_dict, &ret_dict) == -1) {
- return errno;
+ error = _npf_xfer_fd(fd, IOC_NPF_RULE, rule_nvl, &resp);
Home |
Main Index |
Thread Index |
Old Index