summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorrmind <rmind@NetBSD.org>2019-08-21 21:45:47 +0000
committerrmind <rmind@NetBSD.org>2019-08-21 21:45:47 +0000
commit1065c38dd3a58d2bfdb1e60e77eea0626cbdf2bb (patch)
tree165fb237e29a13d6dbcf8600a5256f7544608167 /lib
parente4709b50ba046650a66baef592c3e510f1341f4f (diff)
npfkern/libnpf: Add support for the table replace/swap operation.
Contributed by Timshel Knoll-Miller.
Diffstat (limited to 'lib')
-rw-r--r--lib/libnpf/libnpf.326
-rw-r--r--lib/libnpf/npf.c71
-rw-r--r--lib/libnpf/npf.h2
3 files changed, 78 insertions, 21 deletions
diff --git a/lib/libnpf/libnpf.3 b/lib/libnpf/libnpf.3
index bfe25621080..ea87386e54b 100644
--- a/lib/libnpf/libnpf.3
+++ b/lib/libnpf/libnpf.3
@@ -1,4 +1,4 @@
-.\" $NetBSD: libnpf.3,v 1.9 2019/07/23 14:18:20 wiz Exp $
+.\" $NetBSD: libnpf.3,v 1.10 2019/08/21 21:45:47 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 April 14, 2019
+.Dd August 21, 2019
.Dt LIBNPF 3
.Os
.Sh NAME
@@ -41,7 +41,7 @@
.Ft nl_config_t *
.Fn npf_config_create "void"
.Ft int
-.Fn npf_config_submit "nl_config_t *ncf" "int fd" "nl_error_t *errinfo"
+.Fn npf_config_submit "nl_config_t *ncf" "int fd" "npf_error_t *errinfo"
.Ft nl_config_t *
.Fn npf_config_retrieve "int fd"
.Ft int
@@ -104,6 +104,8 @@
"const npf_addr_t *addr" "const npf_netmask_t mask"
.Ft int
.Fn npf_table_insert "nl_config_t *ncf" "nl_table_t *tl"
+.Ft int
+.Fn npf_table_replace "int fd" "nl_table_t *tl" "npf_error_t *errinfo"
.Ft void
.Fn npf_table_destroy "nl_table_t *tl"
.\" -----
@@ -347,7 +349,9 @@ for IPv4 or
for IPv6 address.
Additionally,
.Fa mask
-may be specified to indicate the translation network.
+may be specified to indicate the translation network;
+otherwise, it should be set to
+.Dv NPF_NO_NETMASK .
In such case, a custom algorithm may need to be specified using the
.Fn npf_nat_setalgo
function.
@@ -423,11 +427,25 @@ must be either
for IPv4 or
.Dv AF_INET6
for IPv6 address.
+If there is no mask, then
+.Fa mask
+should be set to
+.Dv NPF_NO_NETMASK .
+.\" ---
.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_replace "fd" "tl" "errinfo"
+Submit the table object, specified by
+.Fa tl ,
+to the kernel, to replace the existing table with the
+corresponding table name and ID.
+On failure, the error information is written into the structure
+specified by
+.Fa errinfo .
+.\" ---
.It Fn npf_table_destroy "tl"
Destroy the specified table.
.El
diff --git a/lib/libnpf/npf.c b/lib/libnpf/npf.c
index 827da748446..780a2bf260b 100644
--- a/lib/libnpf/npf.c
+++ b/lib/libnpf/npf.c
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.46 2019/07/23 00:52:01 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.47 2019/08/21 21:45:47 rmind Exp $");
#include <sys/types.h>
#include <sys/mman.h>
@@ -203,6 +203,30 @@ _npf_rules_process(nl_config_t *ncf, nvlist_t *dict, const char *key)
}
/*
+ * _npf_extract_error: check the error number field and extract the
+ * error details into the npf_error_t structure.
+ */
+static int
+_npf_extract_error(nvlist_t *resp, npf_error_t *errinfo)
+{
+ int error;
+
+ error = dnvlist_get_number(resp, "errno", 0);
+ if (error && errinfo) {
+ memset(errinfo, 0, sizeof(npf_error_t));
+
+ errinfo->id = dnvlist_get_number(resp, "id", 0);
+ errinfo->error_msg =
+ dnvlist_take_string(resp, "error-msg", NULL);
+ errinfo->source_file =
+ dnvlist_take_string(resp, "source-file", NULL);
+ errinfo->source_line =
+ dnvlist_take_number(resp, "source-line", 0);
+ }
+ return error;
+}
+
+/*
* CONFIGURATION INTERFACE.
*/
@@ -233,17 +257,7 @@ npf_config_submit(nl_config_t *ncf, int fd, npf_error_t *errinfo)
assert(errnv == NULL);
return errno;
}
- error = dnvlist_get_number(errnv, "errno", 0);
- if (error && errinfo) {
- memset(errinfo, 0, sizeof(npf_error_t));
- errinfo->id = dnvlist_get_number(errnv, "id", 0);
- errinfo->error_msg =
- dnvlist_take_string(errnv, "error-msg", NULL);
- errinfo->source_file =
- dnvlist_take_string(errnv, "source-file", NULL);
- errinfo->source_line =
- dnvlist_take_number(errnv, "source-line", 0);
- }
+ error = _npf_extract_error(errnv, errinfo);
nvlist_destroy(errnv);
return error;
}
@@ -949,7 +963,7 @@ npf_table_add_entry(nl_table_t *tl, int af, const npf_addr_t *addr,
}
static inline int
-_npf_table_build(nl_table_t *tl)
+_npf_table_build_const(nl_table_t *tl)
{
struct cdbw *cdbw;
const nvlist_t * const *entries;
@@ -959,6 +973,10 @@ _npf_table_build(nl_table_t *tl)
struct stat sb;
char sfn[32];
+ if (dnvlist_get_number(tl->table_dict, "type", 0) != NPF_TABLE_CONST) {
+ return 0;
+ }
+
if (!nvlist_exists_nvlist_array(tl->table_dict, "entries")) {
return 0;
}
@@ -1050,10 +1068,8 @@ npf_table_insert(nl_config_t *ncf, nl_table_t *tl)
if (_npf_dataset_lookup(ncf->ncf_dict, "tables", "name", name)) {
return EEXIST;
}
- if (dnvlist_get_number(tl->table_dict, "type", 0) == NPF_TABLE_CONST) {
- if ((error = _npf_table_build(tl)) != 0) {
- return error;
- }
+ if ((error = _npf_table_build_const(tl)) != 0) {
+ return error;
}
nvlist_append_nvlist_array(ncf->ncf_dict, "tables", tl->table_dict);
nvlist_destroy(tl->table_dict);
@@ -1061,6 +1077,27 @@ npf_table_insert(nl_config_t *ncf, nl_table_t *tl)
return 0;
}
+int
+npf_table_replace(int fd, nl_table_t *tl, npf_error_t *errinfo)
+{
+ nvlist_t *errnv = NULL;
+ int error;
+
+ /* Ensure const tables are built. */
+ if ((error = _npf_table_build_const(tl)) != 0) {
+ return error;
+ }
+
+ if (nvlist_xfer_ioctl(fd, IOC_NPF_TABLE_REPLACE,
+ tl->table_dict, &errnv) == -1) {
+ assert(errnv == NULL);
+ return errno;
+ }
+ error = _npf_extract_error(errnv, errinfo);
+ nvlist_destroy(errnv);
+ return error;
+}
+
nl_table_t *
npf_table_iterate(nl_config_t *ncf, nl_iter_t *iter)
{
diff --git a/lib/libnpf/npf.h b/lib/libnpf/npf.h
index f24243271be..61ef2c01ecf 100644
--- a/lib/libnpf/npf.h
+++ b/lib/libnpf/npf.h
@@ -146,6 +146,8 @@ int npf_table_add_entry(nl_table_t *, int,
int npf_table_insert(nl_config_t *, nl_table_t *);
void npf_table_destroy(nl_table_t *);
+int npf_table_replace(int, nl_table_t *, npf_error_t *);
+
#ifdef _NPF_PRIVATE
#include <ifaddrs.h>