Source-Changes-HG archive

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

[src/trunk]: src/usr.sbin/npf/npfctl npfctl: implement table replace subcommand.



details:   https://anonhg.NetBSD.org/src/rev/0e039885eae3
branches:  trunk
changeset: 459875:0e039885eae3
user:      rmind <rmind%NetBSD.org@localhost>
date:      Sun Sep 29 16:58:35 2019 +0000

description:
npfctl: implement table replace subcommand.
Contributed by Timshel Knoll-Miller.

diffstat:

 usr.sbin/npf/npfctl/npfctl.8 |   49 ++++++++++++++---
 usr.sbin/npf/npfctl/npfctl.c |  116 ++++++++++++++++++++++++++++++++++++++++--
 usr.sbin/npf/npfctl/npfctl.h |    4 +
 3 files changed, 151 insertions(+), 18 deletions(-)

diffs (284 lines):

diff -r 98f3885667b0 -r 0e039885eae3 usr.sbin/npf/npfctl/npfctl.8
--- a/usr.sbin/npf/npfctl/npfctl.8      Sun Sep 29 12:07:52 2019 +0000
+++ b/usr.sbin/npf/npfctl/npfctl.8      Sun Sep 29 16:58:35 2019 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: npfctl.8,v 1.21 2019/01/19 21:19:32 rmind Exp $
+.\"    $NetBSD: npfctl.8,v 1.22 2019/09/29 16:58:35 rmind Exp $
 .\"
 .\" Copyright (c) 2009-2014 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 December 10, 2017
+.Dd August 26, 2019
 .Dt NPFCTL 8
 .Os
 .Sh NAME
@@ -114,28 +114,50 @@
 Remove all rules from the dynamic ruleset specified by
 .Ar name .
 .\" ---
-.It Ic table Ar tid Ic add Aq Ar addr/mask
+.It Ic table Ar name Ic add Aq Ar addr/mask
 In table
-.Ar tid ,
+.Ar name ,
 add the IP address and optionally netmask, specified by
 .Aq Ar addr/mask .
 Only the tables of type "lpm" support masks.
-.It Ic table Ar tid Ic rem Aq Ar addr/mask
+.It Ic table Ar name Ic rem Aq Ar addr/mask
 In table
-.Ar tid ,
+.Ar name ,
 remove the IP address and optionally netmask, specified by
 .Aq Ar addr/mask .
 Only the tables of type "lpm" support masks.
-.It Ic table Ar tid Ic test Aq Ar addr
+.It Ic table Ar name Ic test Aq Ar addr
 Query the table
-.Ar tid
+.Ar name
 for a specific IP address, specified by
 .Ar addr .
 If no mask is specified, a single host is assumed.
-.It Ic table Ar tid Ic list
+.It Ic table Ar name Ic list
 List all entries in the currently loaded table specified by
-.Ar tid .
+.Ar name .
 This operation is expensive and should be used with caution.
+.It Ic table Ar name Ic replace Oo Fl n Ar newname Oc Oo Fl t Ar type Oc Aq Ar path
+Replace the existing table specified by
+.Ar name
+with a new table built from the file specified by
+.Ar path .
+Optionally, the new table will:
+.Bl -tag -width xxxxxxxxxx -compact -offset 3n
+.It Fl n Ar newname
+be named
+.Ar newname ,
+effectively renaming the table.
+If not specified, the name of the table being replaced will be used.
+.It Fl n Ar type
+be of type
+.Ar type ;
+currently supported types are
+.Cm ipset ,
+.Cm lpm ,
+or
+.Cm const .
+If not specified, the type of the table being replaced will be used.
+.El
 .\" ---
 .It Ic save
 Save the active configuration and a snapshot of the current connections.
@@ -201,6 +223,13 @@
 # npfctl table "vip" add 10.0.0.1
 # npfctl table "vip" rem 182.168.0.0/24
 .Ed
+.Pp
+Replacing the existing table which has ID "svr"
+with a new const table populated from file "/tmp/npf_vps_new",
+and renamed to "vps":
+.Bd -literal -offset indent
+# npfctl table "svr" replace -n "vps" -t const "/tmp/npf_vps_new"
+.Ed
 .\" -----
 .Sh SEE ALSO
 .Xr bpf 4 ,
diff -r 98f3885667b0 -r 0e039885eae3 usr.sbin/npf/npfctl/npfctl.c
--- a/usr.sbin/npf/npfctl/npfctl.c      Sun Sep 29 12:07:52 2019 +0000
+++ b/usr.sbin/npf/npfctl/npfctl.c      Sun Sep 29 16:58:35 2019 +0000
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npfctl.c,v 1.61 2019/08/21 21:41:53 rmind Exp $");
+__RCSID("$NetBSD: npfctl.c,v 1.62 2019/09/29 16:58:35 rmind Exp $");
 
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -142,10 +142,14 @@
            "\t%s rule \"rule-name\" { list | flush }\n",
            progname);
        fprintf(stderr,
-           "\t%s table <tid> { add | rem | test } <address/mask>\n",
+           "\t%s table \"table-name\" { add | rem | test } <address/mask>\n",
            progname);
        fprintf(stderr,
-           "\t%s table <tid> { list | flush }\n",
+           "\t%s table \"table-name\" { list | flush }\n",
+           progname);
+       fprintf(stderr,
+           "\t%s table \"table-name\" replace [-n \"name\"]"
+           " [-t <type>] <table-file>\n",
            progname);
        fprintf(stderr,
            "\t%s save | load\n",
@@ -275,7 +279,101 @@
        return buf;
 }
 
-__dead static void
+static int
+npfctl_table_type(const char *typename)
+{
+       int i;
+
+       static const struct tbltype_s {
+               const char *name;
+               u_int type;
+       } tbltypes[] = {
+               { "ipset",      NPF_TABLE_IPSET },
+               { "lpm",        NPF_TABLE_LPM   },
+               { "const",      NPF_TABLE_CONST },
+               { NULL,         0               }
+       };
+
+       for (i = 0; tbltypes[i].name != NULL; i++) {
+               if (strcmp(typename, tbltypes[i].name) == 0) {
+                       return tbltypes[i].type;
+               }
+       }
+
+       return 0;
+}
+
+static void
+npfctl_table_replace(int fd, int argc, char **argv)
+{
+       const char *name, *newname, *path, *typename = NULL;
+       int c, tid = -1;
+       FILE *fp;
+       nl_config_t *ncf;
+       nl_table_t *t;
+       u_int type = 0;
+
+       name = newname = argv[0];
+       optind = 2;
+       while ((c = getopt(argc, argv, "n:t:")) != -1) {
+               switch (c) {
+               case 't':
+                       typename = optarg;
+                       break;
+               case 'n':
+                       newname = optarg;
+                       break;
+               default:
+                       fprintf(stderr,
+                           "Usage: %s table \"table-name\" replace "
+                           "[-n \"name\"] [-t <type>] <table-file>\n",
+                           getprogname());
+                       exit(EXIT_FAILURE);
+               }
+       }
+       argc -= optind;
+       argv += optind;
+
+       if (typename && (type = npfctl_table_type(typename)) == 0) {
+               errx(EXIT_FAILURE, "unsupported table type '%s'", typename);
+       }
+
+       if (argc != 1) {
+               usage();
+       }
+
+       path = argv[0];
+       if (strcmp(path, "-") == 0) {
+               path = "stdin";
+               fp = stdin;
+       } else if ((fp = fopen(path, "r")) == NULL) {
+               err(EXIT_FAILURE, "open '%s'", path);
+       }
+
+       /* Get existing config to lookup ID of existing table */
+       if ((ncf = npf_config_retrieve(fd)) == NULL) {
+               err(EXIT_FAILURE, "npf_config_retrieve()");
+       }
+       if ((t = npfctl_table_getbyname(ncf, name)) == NULL) {
+               errx(EXIT_FAILURE,
+                   "table '%s' not found in the active configuration", name);
+       }
+       tid = npf_table_getid(t);
+       if (!type) {
+               type = npf_table_gettype(t);
+       }
+       npf_config_destroy(ncf);
+
+       if ((t = npfctl_load_table(newname, tid, type, path, fp)) == NULL) {
+               err(EXIT_FAILURE, "table load failed");
+       }
+
+       if (npf_table_replace(fd, t, NULL)) {
+               err(EXIT_FAILURE, "npf_table_replace(<%s>)", name);
+       }
+}
+
+static void
 npfctl_table(int fd, int argc, char **argv)
 {
        static const struct tblops_s {
@@ -383,7 +481,6 @@
                    nct.nct_cmd == NPF_CMD_TABLE_LOOKUP ?
                    "match" : "success");
        }
-       exit(EXIT_SUCCESS);
 }
 
 static nl_rule_t *
@@ -431,7 +528,7 @@
        free(meta);
 }
 
-__dead static void
+static void
 npfctl_rule(int fd, int argc, char **argv)
 {
        static const struct ruleops_s {
@@ -509,7 +606,6 @@
        if (action == NPF_CMD_RULE_ADD) {
                printf("OK %" PRIx64 "\n", rule_id);
        }
-       exit(EXIT_SUCCESS);
 }
 
 static bool bpfjit = true;
@@ -754,7 +850,11 @@
                        usage();
                }
                argv += 2;
-               npfctl_table(fd, argc, argv);
+               if (strcmp(argv[1], "replace") == 0) {
+                       npfctl_table_replace(fd, argc, argv);
+               } else {
+                       npfctl_table(fd, argc, argv);
+               }
                break;
        case NPFCTL_RULE:
                if ((argc -= 2) < 2) {
diff -r 98f3885667b0 -r 0e039885eae3 usr.sbin/npf/npfctl/npfctl.h
--- a/usr.sbin/npf/npfctl/npfctl.h      Sun Sep 29 12:07:52 2019 +0000
+++ b/usr.sbin/npf/npfctl/npfctl.h      Sun Sep 29 16:58:35 2019 +0000
@@ -117,6 +117,7 @@
 char *         npfctl_print_addrmask(int, const char *, const npf_addr_t *,
                    npf_netmask_t);
 void           npfctl_note_interface(const char *);
+nl_table_t *   npfctl_table_getbyname(nl_config_t *, const char *);
 unsigned       npfctl_table_getid(const char *);
 const char *   npfctl_table_getname(nl_config_t *, unsigned, bool *);
 int            npfctl_protono(const char *);
@@ -196,8 +197,11 @@
 int            npfctl_ruleset_show(int, const char *);
 
 nl_rule_t *    npfctl_rule_ref(void);
+nl_table_t *   npfctl_table_ref(void);
 bool           npfctl_debug_addif(const char *);
 
+nl_table_t *   npfctl_load_table(const char *, int, u_int, const char *, FILE *);
+
 void           npfctl_build_alg(const char *);
 void           npfctl_build_rproc(const char *, npfvar_t *);
 void           npfctl_build_group(const char *, int, const char *, bool);



Home | Main Index | Thread Index | Old Index