Module Name: src Committed By: rmind Date: Sun Feb 10 23:47:38 UTC 2013
Modified Files: src/lib/libnpf: npf.c npf.h src/sys/net/npf: npf.h npf_conf.c npf_ctl.c npf_impl.h npf_ruleset.c src/usr.sbin/npf/npfctl: npf_build.c npf_disassemble.c npfctl.c npfctl.h Log Message: - Fix NPF config reload with dynamic rules present. - Implement list and flush commands on a dynamic ruleset. To generate a diff of this commit: cvs rdiff -u -r1.16 -r1.17 src/lib/libnpf/npf.c cvs rdiff -u -r1.13 -r1.14 src/lib/libnpf/npf.h cvs rdiff -u -r1.26 -r1.27 src/sys/net/npf/npf.h src/sys/net/npf/npf_impl.h cvs rdiff -u -r1.1 -r1.2 src/sys/net/npf/npf_conf.c cvs rdiff -u -r1.21 -r1.22 src/sys/net/npf/npf_ctl.c cvs rdiff -u -r1.17 -r1.18 src/sys/net/npf/npf_ruleset.c cvs rdiff -u -r1.18 -r1.19 src/usr.sbin/npf/npfctl/npf_build.c cvs rdiff -u -r1.15 -r1.16 src/usr.sbin/npf/npfctl/npf_disassemble.c cvs rdiff -u -r1.29 -r1.30 src/usr.sbin/npf/npfctl/npfctl.c cvs rdiff -u -r1.25 -r1.26 src/usr.sbin/npf/npfctl/npfctl.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libnpf/npf.c diff -u src/lib/libnpf/npf.c:1.16 src/lib/libnpf/npf.c:1.17 --- src/lib/libnpf/npf.c:1.16 Sat Feb 9 03:35:33 2013 +++ src/lib/libnpf/npf.c Sun Feb 10 23:47:37 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npf.c,v 1.16 2013/02/09 03:35:33 rmind Exp $ */ +/* $NetBSD: npf.c,v 1.17 2013/02/10 23:47:37 rmind Exp $ */ /*- * Copyright (c) 2010-2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.16 2013/02/09 03:35:33 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.17 2013/02/10 23:47:37 rmind Exp $"); #include <sys/types.h> #include <netinet/in_systm.h> @@ -320,6 +320,20 @@ npf_ruleset_remkey(int fd, const char *r return prop_dictionary_send_ioctl(rldict, fd, IOC_NPF_RULE); } +int +npf_ruleset_flush(int fd, const char *rname) +{ + prop_dictionary_t rldict; + + rldict = prop_dictionary_create(); + if (rldict == NULL) { + return ENOMEM; + } + prop_dictionary_set_cstring(rldict, "ruleset-name", rname); + prop_dictionary_set_uint32(rldict, "command", NPF_CMD_RULE_FLUSH); + return prop_dictionary_send_ioctl(rldict, fd, IOC_NPF_RULE); +} + /* * _npf_ruleset_transform: transform the ruleset representing nested * rules with lists into an array. @@ -569,6 +583,32 @@ _npf_rule_foreach(nl_config_t *ncf, nl_r return _npf_rule_foreach1(ncf->ncf_rules_list, func); } +int +_npf_ruleset_list(int fd, const char *rname, nl_config_t *ncf) +{ + prop_dictionary_t rldict, ret; + int error; + + rldict = prop_dictionary_create(); + if (rldict == NULL) { + return ENOMEM; + } + prop_dictionary_set_cstring(rldict, "ruleset-name", rname); + prop_dictionary_set_uint32(rldict, "command", NPF_CMD_RULE_LIST); + error = prop_dictionary_sendrecv_ioctl(rldict, fd, IOC_NPF_RULE, &ret); + if (!error) { + prop_array_t rules; + + rules = prop_dictionary_get(ret, "rules"); + if (rules == NULL) { + return EINVAL; + } + prop_object_release(ncf->ncf_rules_list); + ncf->ncf_rules_list = rules; + } + return error; +} + pri_t _npf_rule_getinfo(nl_rule_t *nrl, const char **rname, uint32_t *attr, u_int *if_idx) Index: src/lib/libnpf/npf.h diff -u src/lib/libnpf/npf.h:1.13 src/lib/libnpf/npf.h:1.14 --- src/lib/libnpf/npf.h:1.13 Sat Feb 9 03:35:33 2013 +++ src/lib/libnpf/npf.h Sun Feb 10 23:47:38 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npf.h,v 1.13 2013/02/09 03:35:33 rmind Exp $ */ +/* $NetBSD: npf.h,v 1.14 2013/02/10 23:47:38 rmind Exp $ */ /*- * Copyright (c) 2011-2013 The NetBSD Foundation, Inc. @@ -82,6 +82,7 @@ int npf_config_flush(int); int npf_ruleset_add(int, const char *, nl_rule_t *, uintptr_t *); int npf_ruleset_remove(int, const char *, uintptr_t); int npf_ruleset_remkey(int, const char *, const void *, size_t); +int npf_ruleset_flush(int, const char *); nl_ext_t * npf_ext_construct(const char *name); void npf_ext_param_u32(nl_ext_t *, const char *, uint32_t); @@ -121,6 +122,7 @@ int npf_sessions_recv(int, const char * void _npf_config_error(nl_config_t *, nl_error_t *); void _npf_config_setsubmit(nl_config_t *, const char *); +int _npf_ruleset_list(int, const char *, nl_config_t *); int _npf_rule_foreach(nl_config_t *, nl_rule_callback_t); pri_t _npf_rule_getinfo(nl_rule_t *, const char **, uint32_t *, u_int *); Index: src/sys/net/npf/npf.h diff -u src/sys/net/npf/npf.h:1.26 src/sys/net/npf/npf.h:1.27 --- src/sys/net/npf/npf.h:1.26 Sat Feb 9 03:35:31 2013 +++ src/sys/net/npf/npf.h Sun Feb 10 23:47:37 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npf.h,v 1.26 2013/02/09 03:35:31 rmind Exp $ */ +/* $NetBSD: npf.h,v 1.27 2013/02/10 23:47:37 rmind Exp $ */ /*- * Copyright (c) 2009-2013 The NetBSD Foundation, Inc. @@ -235,7 +235,8 @@ bool npf_autounload_p(void); #define NPF_CMD_RULE_INSERT 2 #define NPF_CMD_RULE_REMOVE 3 #define NPF_CMD_RULE_REMKEY 4 -#define NPF_CMD_RULE_FLUSH 5 +#define NPF_CMD_RULE_LIST 5 +#define NPF_CMD_RULE_FLUSH 6 /* * NPF ioctl(2): table commands and structures. Index: src/sys/net/npf/npf_impl.h diff -u src/sys/net/npf/npf_impl.h:1.26 src/sys/net/npf/npf_impl.h:1.27 --- src/sys/net/npf/npf_impl.h:1.26 Sat Feb 9 03:35:32 2013 +++ src/sys/net/npf/npf_impl.h Sun Feb 10 23:47:37 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_impl.h,v 1.26 2013/02/09 03:35:32 rmind Exp $ */ +/* $NetBSD: npf_impl.h,v 1.27 2013/02/10 23:47:37 rmind Exp $ */ /*- * Copyright (c) 2009-2013 The NetBSD Foundation, Inc. @@ -130,6 +130,7 @@ void npf_config_fini(void); void npf_config_enter(void); void npf_config_exit(void); +void npf_config_sync(void); bool npf_config_locked_p(void); int npf_config_read_enter(void); void npf_config_read_exit(int); @@ -231,9 +232,12 @@ npf_rule_t * npf_ruleset_sharepm(npf_rul void npf_ruleset_freealg(npf_ruleset_t *, npf_alg_t *); int npf_ruleset_add(npf_ruleset_t *, const char *, npf_rule_t *); -npf_rule_t * npf_ruleset_remove(npf_ruleset_t *, const char *, uintptr_t); -npf_rule_t * npf_ruleset_remkey(npf_ruleset_t *, const char *, +int npf_ruleset_remove(npf_ruleset_t *, const char *, uintptr_t); +int npf_ruleset_remkey(npf_ruleset_t *, const char *, const void *, size_t); +prop_dictionary_t npf_ruleset_list(npf_ruleset_t *, const char *); +int npf_ruleset_flush(npf_ruleset_t *, const char *); +void npf_ruleset_gc(npf_ruleset_t *); npf_rule_t * npf_ruleset_inspect(npf_cache_t *, nbuf_t *, const npf_ruleset_t *, const int, const int); Index: src/sys/net/npf/npf_conf.c diff -u src/sys/net/npf/npf_conf.c:1.1 src/sys/net/npf/npf_conf.c:1.2 --- src/sys/net/npf/npf_conf.c:1.1 Sat Feb 9 03:35:31 2013 +++ src/sys/net/npf/npf_conf.c Sun Feb 10 23:47:37 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_conf.c,v 1.1 2013/02/09 03:35:31 rmind Exp $ */ +/* $NetBSD: npf_conf.c,v 1.2 2013/02/10 23:47:37 rmind Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -48,7 +48,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.1 2013/02/09 03:35:31 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.2 2013/02/10 23:47:37 rmind Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -185,6 +185,13 @@ npf_config_locked_p(void) return mutex_owned(&npf_config_lock); } +void +npf_config_sync(void) +{ + KASSERT(npf_config_locked_p()); + pserialize_perform(npf_config_psz); +} + /* * Reader-side synchronisation routines. */ Index: src/sys/net/npf/npf_ctl.c diff -u src/sys/net/npf/npf_ctl.c:1.21 src/sys/net/npf/npf_ctl.c:1.22 --- src/sys/net/npf/npf_ctl.c:1.21 Sat Feb 9 03:35:31 2013 +++ src/sys/net/npf/npf_ctl.c Sun Feb 10 23:47:37 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_ctl.c,v 1.21 2013/02/09 03:35:31 rmind Exp $ */ +/* $NetBSD: npf_ctl.c,v 1.22 2013/02/10 23:47:37 rmind Exp $ */ /*- * Copyright (c) 2009-2013 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.21 2013/02/09 03:35:31 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.22 2013/02/10 23:47:37 rmind Exp $"); #include <sys/param.h> #include <sys/conf.h> @@ -581,10 +581,7 @@ npfctl_rule(u_long cmd, void *data) error = EINVAL; break; } - rl = npf_ruleset_remove(rlset, ruleset_name, (uintptr_t)id64); - if (rl == NULL) { - error = ENOENT; - } + error = npf_ruleset_remove(rlset, ruleset_name, (uintptr_t)id64); break; } case NPF_CMD_RULE_REMKEY: { @@ -596,16 +593,27 @@ npfctl_rule(u_long cmd, void *data) error = EINVAL; break; } - rl = npf_ruleset_remkey(rlset, ruleset_name, key, len); - if (rl == NULL) { - error = ENOENT; - } + error = npf_ruleset_remkey(rlset, ruleset_name, key, len); + break; + } + case NPF_CMD_RULE_LIST: { + retdict = npf_ruleset_list(rlset, ruleset_name); + break; + } + case NPF_CMD_RULE_FLUSH: { + error = npf_ruleset_flush(rlset, ruleset_name); break; } default: error = EINVAL; break; } + + /* Destroy any removed rules. */ + if (!error && rcmd != NPF_CMD_RULE_ADD && rcmd != NPF_CMD_RULE_LIST) { + npf_config_sync(); + npf_ruleset_gc(rlset); + } npf_config_exit(); if (rl) { Index: src/sys/net/npf/npf_ruleset.c diff -u src/sys/net/npf/npf_ruleset.c:1.17 src/sys/net/npf/npf_ruleset.c:1.18 --- src/sys/net/npf/npf_ruleset.c:1.17 Sat Feb 9 03:35:32 2013 +++ src/sys/net/npf/npf_ruleset.c Sun Feb 10 23:47:37 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_ruleset.c,v 1.17 2013/02/09 03:35:32 rmind Exp $ */ +/* $NetBSD: npf_ruleset.c,v 1.18 2013/02/10 23:47:37 rmind Exp $ */ /*- * Copyright (c) 2009-2013 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.17 2013/02/09 03:35:32 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.18 2013/02/10 23:47:37 rmind Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -52,9 +52,14 @@ __KERNEL_RCSID(0, "$NetBSD: npf_ruleset. #include "npf_impl.h" struct npf_ruleset { - /* List of all rules and dynamic (i.e. named) rules. */ + /* + * - List of all rules. + * - Dynamic (i.e. named) rules. + * - G/C list for convenience. + */ LIST_HEAD(, npf_rule) rs_all; LIST_HEAD(, npf_rule) rs_dynamic; + LIST_HEAD(, npf_rule) rs_gc; /* Number of array slots and active rules. */ u_int rs_slots; @@ -95,6 +100,9 @@ struct npf_rule { npf_rule_t * r_parent; } /* C11 */; + /* Dictionary. */ + prop_dictionary_t r_dict; + /* Rule name and all-list entry. */ char r_name[NPF_RULE_MAXNAMELEN]; LIST_ENTRY(npf_rule) r_aentry; @@ -143,6 +151,7 @@ npf_ruleset_destroy(npf_ruleset_t *rlset npf_rule_free(rl); } KASSERT(LIST_EMPTY(&rlset->rs_dynamic)); + KASSERT(LIST_EMPTY(&rlset->rs_gc)); kmem_free(rlset, len); } @@ -238,25 +247,26 @@ npf_ruleset_add(npf_ruleset_t *rlset, co return 0; } -npf_rule_t * +int npf_ruleset_remove(npf_ruleset_t *rlset, const char *rname, uintptr_t id) { npf_rule_t *rg, *rl; if ((rg = npf_ruleset_lookup(rlset, rname)) == NULL) { - return NULL; + return ENOENT; } TAILQ_FOREACH(rl, &rg->r_subset, r_entry) { /* Compare ID. On match, remove and return. */ if ((uintptr_t)rl == id) { npf_ruleset_unlink(rlset, rl); + LIST_INSERT_HEAD(&rlset->rs_gc, rl, r_aentry); break; } } - return rl; + return 0; } -npf_rule_t * +int npf_ruleset_remkey(npf_ruleset_t *rlset, const char *rname, const void *key, size_t len) { @@ -265,17 +275,77 @@ npf_ruleset_remkey(npf_ruleset_t *rlset, KASSERT(len && len <= NPF_RULE_MAXKEYLEN); if ((rg = npf_ruleset_lookup(rlset, rname)) == NULL) { - return NULL; + return ENOENT; } + /* Find the last in the list. */ TAILQ_FOREACH_REVERSE(rl, &rg->r_subset, npf_ruleq, r_entry) { /* Compare the key. On match, remove and return. */ if (memcmp(rl->r_key, key, len) == 0) { npf_ruleset_unlink(rlset, rl); + LIST_INSERT_HEAD(&rlset->rs_gc, rl, r_aentry); break; } } - return rl; + return 0; +} + +prop_dictionary_t +npf_ruleset_list(npf_ruleset_t *rlset, const char *rname) +{ + prop_dictionary_t rldict; + prop_array_t rules; + npf_rule_t *rg, *rl; + + if ((rg = npf_ruleset_lookup(rlset, rname)) == NULL) { + return NULL; + } + if ((rldict = prop_dictionary_create()) == NULL) { + return NULL; + } + if ((rules = prop_array_create()) == NULL) { + prop_object_release(rldict); + return NULL; + } + + TAILQ_FOREACH(rl, &rg->r_subset, r_entry) { + if (rl->r_dict && !prop_array_add(rules, rl->r_dict)) { + prop_object_release(rldict); + return NULL; + } + } + if (!prop_dictionary_set(rldict, "rules", rules)) { + prop_object_release(rldict); + rldict = NULL; + } + prop_object_release(rules); + return rldict; +} + +int +npf_ruleset_flush(npf_ruleset_t *rlset, const char *rname) +{ + npf_rule_t *rg, *rl; + + if ((rg = npf_ruleset_lookup(rlset, rname)) == NULL) { + return ENOENT; + } + while ((rl = TAILQ_FIRST(&rg->r_subset)) != NULL) { + npf_ruleset_unlink(rlset, rl); + LIST_INSERT_HEAD(&rlset->rs_gc, rl, r_aentry); + } + return 0; +} + +void +npf_ruleset_gc(npf_ruleset_t *rlset) +{ + npf_rule_t *rl; + + while ((rl = LIST_FIRST(&rlset->rs_gc)) != NULL) { + LIST_REMOVE(rl, r_aentry); + npf_rule_free(rl); + } } /* @@ -284,17 +354,30 @@ npf_ruleset_remkey(npf_ruleset_t *rlset, * => Active ruleset should be exclusively locked. */ void -npf_ruleset_reload(npf_ruleset_t *nrlset, npf_ruleset_t *arlset) +npf_ruleset_reload(npf_ruleset_t *rlset, npf_ruleset_t *arlset) { - npf_rule_t *rl, *arl; + npf_rule_t *rl; KASSERT(npf_config_locked_p()); - LIST_FOREACH(rl, &nrlset->rs_dynamic, r_dentry) { + LIST_FOREACH(rl, &rlset->rs_dynamic, r_dentry) { + npf_rule_t *arl, *it; + if ((arl = npf_ruleset_lookup(arlset, rl->r_name)) == NULL) { continue; } + + /* + * Copy the list-head structure and move the rules from the + * old ruleset to the new by reinserting to a new all-rules + * list. Note that the rules are still active and therefore + * accessible for inspection via the old ruleset. + */ memcpy(&rl->r_subset, &arl->r_subset, sizeof(rl->r_subset)); + TAILQ_FOREACH(it, &rl->r_subset, r_entry) { + LIST_REMOVE(rl, r_aentry); + LIST_INSERT_HEAD(&rlset->rs_all, rl, r_aentry); + } } } @@ -422,6 +505,11 @@ npf_rule_alloc(prop_dictionary_t rldict) } memcpy(rl->r_key, key, len); } + + if ((rl->r_attr & NPF_DYNAMIC_GROUP) == NPF_RULE_DYNAMIC) { + rl->r_dict = prop_dictionary_copy(rldict); + } + return rl; } @@ -469,6 +557,10 @@ npf_rule_free(npf_rule_t *rl) /* Free n-code. */ kmem_free(rl->r_code, rl->r_clen); } + if (rl->r_dict) { + /* Destroy the dictionary. */ + prop_object_release(rl->r_dict); + } kmem_free(rl, sizeof(npf_rule_t)); } Index: src/usr.sbin/npf/npfctl/npf_build.c diff -u src/usr.sbin/npf/npfctl/npf_build.c:1.18 src/usr.sbin/npf/npfctl/npf_build.c:1.19 --- src/usr.sbin/npf/npfctl/npf_build.c:1.18 Sat Feb 9 03:35:32 2013 +++ src/usr.sbin/npf/npfctl/npf_build.c Sun Feb 10 23:47:37 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_build.c,v 1.18 2013/02/09 03:35:32 rmind Exp $ */ +/* $NetBSD: npf_build.c,v 1.19 2013/02/10 23:47:37 rmind Exp $ */ /*- * Copyright (c) 2011-2013 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npf_build.c,v 1.18 2013/02/09 03:35:32 rmind Exp $"); +__RCSID("$NetBSD: npf_build.c,v 1.19 2013/02/10 23:47:37 rmind Exp $"); #include <sys/types.h> #include <sys/ioctl.h> @@ -502,6 +502,7 @@ npfctl_build_rule(int attr, u_int if_idx { nl_rule_t *rl; + attr |= (npf_conf ? 0 : NPF_RULE_DYNAMIC); rl = npf_rule_create(NULL, attr, if_idx); npfctl_build_ncode(rl, family, op, fopts, false); if (rproc) { Index: src/usr.sbin/npf/npfctl/npf_disassemble.c diff -u src/usr.sbin/npf/npfctl/npf_disassemble.c:1.15 src/usr.sbin/npf/npfctl/npf_disassemble.c:1.16 --- src/usr.sbin/npf/npfctl/npf_disassemble.c:1.15 Sat Feb 9 03:35:32 2013 +++ src/usr.sbin/npf/npfctl/npf_disassemble.c Sun Feb 10 23:47:37 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_disassemble.c,v 1.15 2013/02/09 03:35:32 rmind Exp $ */ +/* $NetBSD: npf_disassemble.c,v 1.16 2013/02/10 23:47:37 rmind Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ * FIXME: config generation should be redesigned.. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npf_disassemble.c,v 1.15 2013/02/09 03:35:32 rmind Exp $"); +__RCSID("$NetBSD: npf_disassemble.c,v 1.16 2013/02/10 23:47:37 rmind Exp $"); #include <stdio.h> #include <stdlib.h> @@ -742,3 +742,18 @@ npfctl_config_show(int fd) npf_config_destroy(ncf); return error; } + +int +npfctl_ruleset_show(int fd, const char *ruleset_name) +{ + nl_config_t *ncf; + int error; + + ncf = npf_config_create(); + if ((error = _npf_ruleset_list(fd, ruleset_name, ncf)) != 0) { + return error; + } + error = _npf_rule_foreach(ncf, npfctl_show_rule); + npf_config_destroy(ncf); + return error; +} Index: src/usr.sbin/npf/npfctl/npfctl.c diff -u src/usr.sbin/npf/npfctl/npfctl.c:1.29 src/usr.sbin/npf/npfctl/npfctl.c:1.30 --- src/usr.sbin/npf/npfctl/npfctl.c:1.29 Sat Feb 9 03:35:33 2013 +++ src/usr.sbin/npf/npfctl/npfctl.c Sun Feb 10 23:47:37 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npfctl.c,v 1.29 2013/02/09 03:35:33 rmind Exp $ */ +/* $NetBSD: npfctl.c,v 1.30 2013/02/10 23:47:37 rmind Exp $ */ /*- * Copyright (c) 2009-2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npfctl.c,v 1.29 2013/02/09 03:35:33 rmind Exp $"); +__RCSID("$NetBSD: npfctl.c,v 1.30 2013/02/10 23:47:37 rmind Exp $"); #include <sys/ioctl.h> #include <sys/stat.h> @@ -403,6 +403,8 @@ npfctl_rule(int fd, int argc, char **arg { "rem", NPF_CMD_RULE_REMKEY }, { "del", NPF_CMD_RULE_REMKEY }, { "rem-id", NPF_CMD_RULE_REMOVE }, + { "list", NPF_CMD_RULE_LIST }, + { "flush", NPF_CMD_RULE_FLUSH }, { NULL, 0 } }; uint8_t key[NPF_RULE_MAXKEYLEN]; @@ -419,7 +421,8 @@ npfctl_rule(int fd, int argc, char **arg } } - if (!action || argc < 3) { + bool narg = action == NPF_CMD_RULE_LIST || action == NPF_CMD_RULE_FLUSH; + if (!action || (argc < 3 && !narg)) { usage(); } argc -= 2; @@ -441,6 +444,12 @@ npfctl_rule(int fd, int argc, char **arg rule_id = (uintptr_t)strtoull(argv[0], NULL, 16); error = npf_ruleset_remove(fd, ruleset_name, rule_id); break; + case NPF_CMD_RULE_LIST: + error = npfctl_ruleset_show(fd, ruleset_name); + break; + case NPF_CMD_RULE_FLUSH: + error = npf_ruleset_flush(fd, ruleset_name); + break; default: assert(false); } Index: src/usr.sbin/npf/npfctl/npfctl.h diff -u src/usr.sbin/npf/npfctl/npfctl.h:1.25 src/usr.sbin/npf/npfctl/npfctl.h:1.26 --- src/usr.sbin/npf/npfctl/npfctl.h:1.25 Sat Feb 9 03:35:33 2013 +++ src/usr.sbin/npf/npfctl/npfctl.h Sun Feb 10 23:47:37 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npfctl.h,v 1.25 2013/02/09 03:35:33 rmind Exp $ */ +/* $NetBSD: npfctl.h,v 1.26 2013/02/10 23:47:37 rmind Exp $ */ /*- * Copyright (c) 2009-2013 The NetBSD Foundation, Inc. @@ -187,6 +187,8 @@ void npfctl_config_init(bool); int npfctl_config_send(int, const char *); nl_config_t * npfctl_config_ref(void); int npfctl_config_show(int); +int npfctl_ruleset_show(int, const char *); + nl_rule_t * npfctl_rule_ref(void); unsigned long npfctl_debug_addif(const char *);