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 *);
 

Reply via email to