Source-Changes-HG archive

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

[src/trunk]: src npfkern/libnpf: Add support for the table replace/swap opera...



details:   https://anonhg.NetBSD.org/src/rev/d19a14271ce6
branches:  trunk
changeset: 964907:d19a14271ce6
user:      rmind <rmind%NetBSD.org@localhost>
date:      Wed Aug 21 21:45:47 2019 +0000

description:
npfkern/libnpf: Add support for the table replace/swap operation.
Contributed by Timshel Knoll-Miller.

diffstat:

 lib/libnpf/libnpf.3        |   26 ++++++-
 lib/libnpf/npf.c           |   71 +++++++++++++++-----
 lib/libnpf/npf.h           |    2 +
 sys/net/npf/npf.h          |    1 +
 sys/net/npf/npf_ctl.c      |  152 ++++++++++++++++++++++++++++++++++----------
 sys/net/npf/npf_impl.h     |    3 +-
 sys/net/npf/npf_os.c       |    5 +-
 sys/net/npf/npf_tableset.c |   15 ++-
 8 files changed, 211 insertions(+), 64 deletions(-)

diffs (truncated from 495 to 300 lines):

diff -r c3a397f4c72e -r d19a14271ce6 lib/libnpf/libnpf.3
--- a/lib/libnpf/libnpf.3       Wed Aug 21 21:41:53 2019 +0000
+++ b/lib/libnpf/libnpf.3       Wed Aug 21 21:45:47 2019 +0000
@@ -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 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 @@
 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 -r c3a397f4c72e -r d19a14271ce6 lib/libnpf/npf.c
--- a/lib/libnpf/npf.c  Wed Aug 21 21:41:53 2019 +0000
+++ b/lib/libnpf/npf.c  Wed Aug 21 21:45:47 2019 +0000
@@ -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_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 @@
                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 @@
 }
 
 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 @@
        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 @@
        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 @@
        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 -r c3a397f4c72e -r d19a14271ce6 lib/libnpf/npf.h
--- a/lib/libnpf/npf.h  Wed Aug 21 21:41:53 2019 +0000
+++ b/lib/libnpf/npf.h  Wed Aug 21 21:45:47 2019 +0000
@@ -146,6 +146,8 @@
 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>
diff -r c3a397f4c72e -r d19a14271ce6 sys/net/npf/npf.h
--- a/sys/net/npf/npf.h Wed Aug 21 21:41:53 2019 +0000
+++ b/sys/net/npf/npf.h Wed Aug 21 21:45:47 2019 +0000
@@ -310,6 +310,7 @@
 #define        IOC_NPF_SAVE            _IOR('N', 105, nvlist_ref_t)
 #define        IOC_NPF_RULE            _IOWR('N', 107, nvlist_ref_t)
 #define        IOC_NPF_CONN_LOOKUP     _IOWR('N', 108, nvlist_ref_t)
+#define        IOC_NPF_TABLE_REPLACE   _IOWR('N', 109, nvlist_ref_t)
 
 /*
  * NPF error report.
diff -r c3a397f4c72e -r d19a14271ce6 sys/net/npf/npf_ctl.c
--- a/sys/net/npf/npf_ctl.c     Wed Aug 21 21:41:53 2019 +0000
+++ b/sys/net/npf/npf_ctl.c     Wed Aug 21 21:45:47 2019 +0000
@@ -36,7 +36,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.55 2019/08/11 20:26:33 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.56 2019/08/21 21:45:47 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -178,6 +178,63 @@
        return error;
 }
 
+/*
+ * npf_mk_table: create a table from provided nvlist.
+ */
+static int __noinline
+npf_mk_table(npf_t *npf, const nvlist_t *tbl_dict, nvlist_t *errdict,
+    npf_tableset_t *tblset, npf_table_t **tblp, bool replacing)
+{
+       npf_table_t *t;
+       const char *name;
+       const void *blob;
+       uint64_t tid;
+       size_t size;
+       int type;
+       int error = 0;
+
+       KASSERT(tblp != NULL);
+
+       /* Table name, ID and type.  Validate them. */
+       name = dnvlist_get_string(tbl_dict, "name", NULL);
+       if (!name) {
+               NPF_ERR_DEBUG(errdict);
+               error = EINVAL;
+               goto out;
+       }
+       tid = dnvlist_get_number(tbl_dict, "id", UINT64_MAX);
+       type = dnvlist_get_number(tbl_dict, "type", UINT64_MAX);
+       error = npf_table_check(tblset, name, tid, type, replacing);
+       if (error) {
+               NPF_ERR_DEBUG(errdict);
+               goto out;
+       }
+
+       /* Get the entries or binary data. */
+       blob = dnvlist_get_binary(tbl_dict, "data", &size, NULL, 0);
+       if (type == NPF_TABLE_CONST && (blob == NULL || size == 0)) {
+               NPF_ERR_DEBUG(errdict);
+               error = EINVAL;
+               goto out;
+       }
+
+       t = npf_table_create(name, (u_int)tid, type, blob, size);
+       if (t == NULL) {
+               NPF_ERR_DEBUG(errdict);
+               error = ENOMEM;
+               goto out;
+       }
+
+       if ((error = npf_mk_table_entries(t, tbl_dict, errdict)) != 0) {
+               npf_table_destroy(t);
+               goto out;
+       }
+
+       *tblp = t;
+out:
+       return error;
+}
+
 static int __noinline
 npf_mk_tables(npf_t *npf, nvlist_t *npf_dict, nvlist_t *errdict,
     npf_tableset_t **tblsetp)
@@ -200,49 +257,15 @@
        tblset = npf_tableset_create(nitems);
        for (unsigned i = 0; i < nitems; i++) {
                const nvlist_t *table = tables[i];
-               const char *name;



Home | Main Index | Thread Index | Old Index