Module Name:    src
Committed By:   rmind
Date:           Tue Nov 12 00:46:34 UTC 2013

Modified Files:
        src/lib/libnpf: npf.3 npf.c npf.h
        src/sys/net/npf: npf.h npf_bpf.c npf_conf.c npf_ctl.c npf_impl.h
            npf_tableset.c
        src/usr.sbin/npf/npfctl: npf.conf.5 npf_build.c npf_scan.l npf_show.c
            npfctl.c
        src/usr.sbin/npf/npftest/libnpftest: npf_table_test.c

Log Message:
NPF: add support for table naming and remove NPF_TABLE_SLOTS (there is
just an arbitrary sanity limit of NPF_MAX_TABLES currently set to 128).

Few misc fixes.  Bump NPF_VERSION.


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/lib/libnpf/npf.3
cvs rdiff -u -r1.22 -r1.23 src/lib/libnpf/npf.c
cvs rdiff -u -r1.19 -r1.20 src/lib/libnpf/npf.h
cvs rdiff -u -r1.32 -r1.33 src/sys/net/npf/npf.h
cvs rdiff -u -r1.1 -r1.2 src/sys/net/npf/npf_bpf.c
cvs rdiff -u -r1.3 -r1.4 src/sys/net/npf/npf_conf.c
cvs rdiff -u -r1.31 -r1.32 src/sys/net/npf/npf_ctl.c
cvs rdiff -u -r1.37 -r1.38 src/sys/net/npf/npf_impl.h
cvs rdiff -u -r1.18 -r1.19 src/sys/net/npf/npf_tableset.c
cvs rdiff -u -r1.32 -r1.33 src/usr.sbin/npf/npfctl/npf.conf.5
cvs rdiff -u -r1.28 -r1.29 src/usr.sbin/npf/npfctl/npf_build.c
cvs rdiff -u -r1.13 -r1.14 src/usr.sbin/npf/npfctl/npf_scan.l
cvs rdiff -u -r1.3 -r1.4 src/usr.sbin/npf/npfctl/npf_show.c
cvs rdiff -u -r1.39 -r1.40 src/usr.sbin/npf/npfctl/npfctl.c
cvs rdiff -u -r1.6 -r1.7 src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c

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.3
diff -u src/lib/libnpf/npf.3:1.11 src/lib/libnpf/npf.3:1.12
--- src/lib/libnpf/npf.3:1.11	Fri Nov  8 13:17:45 2013
+++ src/lib/libnpf/npf.3	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-.\"	$NetBSD: npf.3,v 1.11 2013/11/08 13:17:45 wiz Exp $
+.\"	$NetBSD: npf.3,v 1.12 2013/11/12 00:46:34 rmind Exp $
 .\"
 .\" Copyright (c) 2011-2013 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 November 7, 2013
+.Dd November 12, 2013
 .Dt NPF 3
 .Os
 .Sh NAME
@@ -78,7 +78,7 @@
 .Fn npf_nat_insert "nl_config_t *ncf" "nl_nat_t *nt" "pri_t pri"
 .\" ---
 .Ft nl_table_t *
-.Fn npf_table_create "u_int id" "int type"
+.Fn npf_table_create "const char *name", "u_int id" "int type"
 .Ft int
 .Fn npf_table_add_entry "nl_table_t *tl" "int af" \
 "in_addr_t addr" "in_addr_t mask"
@@ -261,7 +261,7 @@ Insert NAT policy, its rule, into the sp
 .\" -----
 .Ss Table interface
 .Bl -tag -width 4n
-.It Fn npf_table_create "index" "type"
+.It Fn npf_table_create "name" "index" "type"
 Create NPF table of specified type.
 The following types are supported:
 .Bl -tag -width "NPF_TABLE_TREE "
@@ -269,7 +269,9 @@ The following types are supported:
 Indicates to use hash table for storage.
 .It Dv NPF_TABLE_TREE
 Indicates to use red-black tree for storage.
-Table is identified by
+Table is identified by the
+.Fa name
+and
 .Fa index ,
 which should be in the range between 1 and
 .Dv NPF_MAX_TABLE_ID .

Index: src/lib/libnpf/npf.c
diff -u src/lib/libnpf/npf.c:1.22 src/lib/libnpf/npf.c:1.23
--- src/lib/libnpf/npf.c:1.22	Fri Nov  8 00:38:27 2013
+++ src/lib/libnpf/npf.c	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf.c,v 1.22 2013/11/08 00:38:27 rmind Exp $	*/
+/*	$NetBSD: npf.c,v 1.23 2013/11/12 00:46:34 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.22 2013/11/08 00:38:27 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.23 2013/11/12 00:46:34 rmind Exp $");
 
 #include <sys/types.h>
 #include <netinet/in_systm.h>
@@ -892,7 +892,7 @@ npf_nat_getmap(nl_nat_t *nt, npf_addr_t 
  */
 
 nl_table_t *
-npf_table_create(u_int id, int type)
+npf_table_create(const char *name, u_int id, int type)
 {
 	prop_dictionary_t tldict;
 	prop_array_t tblents;
@@ -907,6 +907,7 @@ npf_table_create(u_int id, int type)
 		free(tl);
 		return NULL;
 	}
+	prop_dictionary_set_cstring(tldict, "name", name);
 	prop_dictionary_set_uint32(tldict, "id", id);
 	prop_dictionary_set_int32(tldict, "type", type);
 
@@ -1014,12 +1015,22 @@ unsigned
 npf_table_getid(nl_table_t *tl)
 {
 	prop_dictionary_t tldict = tl->ntl_dict;
-	u_int id = 0;
+	unsigned id = (unsigned)-1;
 
 	prop_dictionary_get_uint32(tldict, "id", &id);
 	return id;
 }
 
+const char *
+npf_table_getname(nl_table_t *tl)
+{
+	prop_dictionary_t tldict = tl->ntl_dict;
+	const char *tname = NULL;
+
+	prop_dictionary_get_cstring_nocopy(tldict, "name", &tname);
+	return tname;
+}
+
 int
 npf_table_gettype(nl_table_t *tl)
 {

Index: src/lib/libnpf/npf.h
diff -u src/lib/libnpf/npf.h:1.19 src/lib/libnpf/npf.h:1.20
--- src/lib/libnpf/npf.h:1.19	Fri Nov  8 00:38:27 2013
+++ src/lib/libnpf/npf.h	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf.h,v 1.19 2013/11/08 00:38:27 rmind Exp $	*/
+/*	$NetBSD: npf.h,v 1.20 2013/11/12 00:46:34 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2011-2013 The NetBSD Foundation, Inc.
@@ -108,7 +108,7 @@ nl_nat_t *	npf_nat_create(int, u_int, co
 		    npf_addr_t *, int, in_port_t);
 int		npf_nat_insert(nl_config_t *, nl_nat_t *, pri_t);
 
-nl_table_t *	npf_table_create(u_int, int);
+nl_table_t *	npf_table_create(const char *, u_int, int);
 int		npf_table_add_entry(nl_table_t *, int,
 		    const npf_addr_t *, const npf_netmask_t);
 bool		npf_table_exists_p(nl_config_t *, u_int);
@@ -130,6 +130,7 @@ const void *	npf_rule_getinfo(nl_rule_t 
 const char *	npf_rule_getproc(nl_rule_t *);
 
 nl_table_t *	npf_table_iterate(nl_config_t *);
+const char *	npf_table_getname(nl_table_t *);
 unsigned	npf_table_getid(nl_table_t *);
 int		npf_table_gettype(nl_table_t *);
 

Index: src/sys/net/npf/npf.h
diff -u src/sys/net/npf/npf.h:1.32 src/sys/net/npf/npf.h:1.33
--- src/sys/net/npf/npf.h:1.32	Fri Nov  8 00:38:26 2013
+++ src/sys/net/npf/npf.h	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf.h,v 1.32 2013/11/08 00:38:26 rmind Exp $	*/
+/*	$NetBSD: npf.h,v 1.33 2013/11/12 00:46:34 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -45,7 +45,7 @@
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
 
-#define	NPF_VERSION		11
+#define	NPF_VERSION		12
 
 /*
  * Public declarations and definitions.
@@ -231,6 +231,8 @@ bool		npf_autounload_p(void);
 #define	NPF_TABLE_HASH			1
 #define	NPF_TABLE_TREE			2
 
+#define	NPF_TABLE_MAXNAMELEN		32
+
 /* Layers. */
 #define	NPF_LAYER_2			2
 #define	NPF_LAYER_3			3
@@ -272,7 +274,7 @@ typedef struct npf_ioctl_buf {
 
 typedef struct npf_ioctl_table {
 	int			nct_cmd;
-	u_int			nct_tid;
+	const char *		nct_name;
 	union {
 		npf_ioctl_ent_t	ent;
 		npf_ioctl_buf_t	buf;

Index: src/sys/net/npf/npf_bpf.c
diff -u src/sys/net/npf/npf_bpf.c:1.1 src/sys/net/npf/npf_bpf.c:1.2
--- src/sys/net/npf/npf_bpf.c:1.1	Thu Sep 19 01:04:46 2013
+++ src/sys/net/npf/npf_bpf.c	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_bpf.c,v 1.1 2013/09/19 01:04:46 rmind Exp $	*/
+/*	$NetBSD: npf_bpf.c,v 1.2 2013/11/12 00:46:34 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_bpf.c,v 1.1 2013/09/19 01:04:46 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_bpf.c,v 1.2 2013/11/12 00:46:34 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -145,11 +145,15 @@ npf_cop_table(const struct mbuf *pkt, vo
 	npf_tableset_t *tblset = npf_config_tableset();
 	const uint32_t tid = A & (SRC_FLAG_BIT - 1);
 	const npf_addr_t *addr;
+	npf_table_t *t;
 
 	KASSERT(npc != NULL);
 	KASSERT(npf_iscached(npc, NPC_IP46));
 	memset(M, 0, sizeof(uint32_t) * BPF_MEMWORDS);
 
+	if ((t = npf_tableset_getbyid(tblset, tid)) == NULL) {
+		return 0;
+	}
 	addr = (A & SRC_FLAG_BIT) ? npc->npc_srcip : npc->npc_dstip;
-	return npf_table_lookup(tblset, tid, npc->npc_alen, addr) == 0;
+	return npf_table_lookup(t, npc->npc_alen, addr) == 0;
 }

Index: src/sys/net/npf/npf_conf.c
diff -u src/sys/net/npf/npf_conf.c:1.3 src/sys/net/npf/npf_conf.c:1.4
--- src/sys/net/npf/npf_conf.c:1.3	Fri Nov  8 00:38:26 2013
+++ src/sys/net/npf/npf_conf.c	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_conf.c,v 1.3 2013/11/08 00:38:26 rmind Exp $	*/
+/*	$NetBSD: npf_conf.c,v 1.4 2013/11/12 00:46:34 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.3 2013/11/08 00:38:26 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.4 2013/11/12 00:46:34 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -86,7 +86,7 @@ npf_config_init(void)
 
 	/* Load the empty configuration. */
 	dict = prop_dictionary_create();
-	tset = npf_tableset_create();
+	tset = npf_tableset_create(0);
 	rpset = npf_rprocset_create();
 	rlset = npf_ruleset_create(0);
 	nset = npf_ruleset_create(0);

Index: src/sys/net/npf/npf_ctl.c
diff -u src/sys/net/npf/npf_ctl.c:1.31 src/sys/net/npf/npf_ctl.c:1.32
--- src/sys/net/npf/npf_ctl.c:1.31	Fri Nov  8 00:38:26 2013
+++ src/sys/net/npf/npf_ctl.c	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_ctl.c,v 1.31 2013/11/08 00:38:26 rmind Exp $	*/
+/*	$NetBSD: npf_ctl.c,v 1.32 2013/11/12 00:46:34 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.31 2013/11/08 00:38:26 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.32 2013/11/12 00:46:34 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -95,6 +95,7 @@ npf_mk_tables(npf_tableset_t *tblset, pr
 		prop_dictionary_t ent;
 		prop_object_iterator_t eit;
 		prop_array_t entries;
+		const char *name;
 		npf_table_t *t;
 		u_int tid;
 		int type;
@@ -106,17 +107,22 @@ npf_mk_tables(npf_tableset_t *tblset, pr
 			break;
 		}
 
-		/* Table ID and type. */
+		/* Table name, ID and type.  Validate them. */
+		if (!prop_dictionary_get_cstring_nocopy(tbldict, "name", &name)) {
+			NPF_ERR_DEBUG(errdict);
+			error = EINVAL;
+			break;
+		}
 		prop_dictionary_get_uint32(tbldict, "id", &tid);
 		prop_dictionary_get_int32(tbldict, "type", &type);
-
-		/* Validate them, check for duplicate IDs. */
-		error = npf_table_check(tblset, tid, type);
-		if (error)
+		error = npf_table_check(tblset, name, tid, type);
+		if (error) {
+			NPF_ERR_DEBUG(errdict);
 			break;
+		}
 
 		/* Create and insert the table. */
-		t = npf_table_create(tid, type, 1024);	/* XXX */
+		t = npf_table_create(name, tid, type, 1024);	/* XXX */
 		if (t == NULL) {
 			NPF_ERR_DEBUG(errdict);
 			error = ENOMEM;
@@ -144,7 +150,7 @@ npf_mk_tables(npf_tableset_t *tblset, pr
 			prop_dictionary_get_uint8(ent, "mask", &mask);
 			alen = prop_data_size(obj);
 
-			error = npf_table_insert(tblset, tid, alen, addr, mask);
+			error = npf_table_insert(t, alen, addr, mask);
 			if (error)
 				break;
 		}
@@ -478,16 +484,22 @@ npfctl_reload(u_long cmd, void *data)
 	}
 
 	/* Tables. */
-	tblset = npf_tableset_create();
 	tables = prop_dictionary_get(npf_dict, "tables");
+	if ((nitems = prop_array_count(tables)) > NPF_MAX_TABLES) {
+		goto fail;
+	}
+	tblset = npf_tableset_create(nitems);
 	error = npf_mk_tables(tblset, tables, errdict);
 	if (error) {
 		goto fail;
 	}
 
 	/* Rule procedures. */
-	rpset = npf_rprocset_create();
 	rprocs = prop_dictionary_get(npf_dict, "rprocs");
+	if ((nitems = prop_array_count(rprocs)) > NPF_MAX_RPROCS) {
+		goto fail;
+	}
+	rpset = npf_rprocset_create();
 	error = npf_mk_rprocs(rpset, rprocs, errdict);
 	if (error) {
 		goto fail;
@@ -778,39 +790,48 @@ int
 npfctl_table(void *data)
 {
 	const npf_ioctl_table_t *nct = data;
-	npf_tableset_t *tblset;
-	int error;
+	char tname[NPF_TABLE_MAXNAMELEN];
+	npf_tableset_t *ts;
+	npf_table_t *t;
+	int s, error;
 
-	//npf_config_ref();
-	tblset = npf_config_tableset();
+	error = copyinstr(nct->nct_name, tname, sizeof(tname), NULL);
+	if (error) {
+		return error;
+	}
+
+	s = npf_config_read_enter(); /* XXX */
+	ts = npf_config_tableset();
+	if ((t = npf_tableset_getbyname(ts, tname)) == NULL) {
+		npf_config_read_exit(s);
+		return EINVAL;
+	}
 
 	switch (nct->nct_cmd) {
 	case NPF_CMD_TABLE_LOOKUP:
-		error = npf_table_lookup(tblset, nct->nct_tid,
-		    nct->nct_data.ent.alen, &nct->nct_data.ent.addr);
+		error = npf_table_lookup(t, nct->nct_data.ent.alen,
+		    &nct->nct_data.ent.addr);
 		break;
 	case NPF_CMD_TABLE_ADD:
-		error = npf_table_insert(tblset, nct->nct_tid,
-		    nct->nct_data.ent.alen, &nct->nct_data.ent.addr,
-		    nct->nct_data.ent.mask);
+		error = npf_table_insert(t, nct->nct_data.ent.alen,
+		    &nct->nct_data.ent.addr, nct->nct_data.ent.mask);
 		break;
 	case NPF_CMD_TABLE_REMOVE:
-		error = npf_table_remove(tblset, nct->nct_tid,
-		    nct->nct_data.ent.alen, &nct->nct_data.ent.addr,
-		    nct->nct_data.ent.mask);
+		error = npf_table_remove(t, nct->nct_data.ent.alen,
+		    &nct->nct_data.ent.addr, nct->nct_data.ent.mask);
 		break;
 	case NPF_CMD_TABLE_LIST:
-		error = npf_table_list(tblset, nct->nct_tid,
-		    nct->nct_data.buf.buf, nct->nct_data.buf.len);
+		error = npf_table_list(t, nct->nct_data.buf.buf,
+		    nct->nct_data.buf.len);
 		break;
 	case NPF_CMD_TABLE_FLUSH:
-		error = npf_table_flush(tblset, nct->nct_tid);
+		error = npf_table_flush(t);
 		break;
 	default:
 		error = EINVAL;
 		break;
 	}
-	//npf_config_unref();
+	npf_config_read_exit(s);
 
 	return error;
 }

Index: src/sys/net/npf/npf_impl.h
diff -u src/sys/net/npf/npf_impl.h:1.37 src/sys/net/npf/npf_impl.h:1.38
--- src/sys/net/npf/npf_impl.h:1.37	Fri Nov  8 00:38:26 2013
+++ src/sys/net/npf/npf_impl.h	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_impl.h,v 1.37 2013/11/08 00:38:26 rmind Exp $	*/
+/*	$NetBSD: npf_impl.h,v 1.38 2013/11/12 00:46:34 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -86,11 +86,11 @@ typedef struct npf_session	npf_session_t
 
 struct npf_sehash;
 struct npf_table;
+struct npf_tableset;
 
 typedef struct npf_sehash	npf_sehash_t;
 typedef struct npf_table	npf_table_t;
-
-typedef npf_table_t *		npf_tableset_t;
+typedef struct npf_tableset	npf_tableset_t;
 
 /*
  * DEFINITIONS.
@@ -101,8 +101,9 @@ typedef npf_session_t *(*npf_alg_sfunc_t
 typedef void (*npf_workfunc_t)(void);
 
 /* Some artificial limits. */
-#define	NPF_TABLE_SLOTS		32
 #define	NPF_MAX_RULES		(1024 * 1024)
+#define	NPF_MAX_TABLES		128
+#define	NPF_MAX_RPROCS		128
 #define	NPF_MAX_IFMAP		64
 
 /*
@@ -216,23 +217,24 @@ void		npf_tableset_sysfini(void);
 
 extern const pt_tree_ops_t npf_table_ptree_ops;
 
-npf_tableset_t *npf_tableset_create(void);
+npf_tableset_t *npf_tableset_create(u_int);
 void		npf_tableset_destroy(npf_tableset_t *);
 int		npf_tableset_insert(npf_tableset_t *, npf_table_t *);
+npf_table_t *	npf_tableset_getbyname(npf_tableset_t *, const char *);
+npf_table_t *	npf_tableset_getbyid(npf_tableset_t *, u_int);
 void		npf_tableset_reload(npf_tableset_t *, npf_tableset_t *);
 
-npf_table_t *	npf_table_create(u_int, int, size_t);
+npf_table_t *	npf_table_create(const char *, u_int, int, size_t);
 void		npf_table_destroy(npf_table_t *);
 
-int		npf_table_check(const npf_tableset_t *, u_int, int);
-int		npf_table_insert(npf_tableset_t *, u_int,
-		    const int, const npf_addr_t *, const npf_netmask_t);
-int		npf_table_remove(npf_tableset_t *, u_int,
-		    const int, const npf_addr_t *, const npf_netmask_t);
-int		npf_table_lookup(npf_tableset_t *, u_int,
-		    const int, const npf_addr_t *);
-int		npf_table_list(npf_tableset_t *, u_int, void *, size_t);
-int		npf_table_flush(npf_tableset_t *, u_int);
+int		npf_table_check(npf_tableset_t *, const char *, u_int, int);
+int		npf_table_insert(npf_table_t *, const int,
+		    const npf_addr_t *, const npf_netmask_t);
+int		npf_table_remove(npf_table_t *, const int,
+		    const npf_addr_t *, const npf_netmask_t);
+int		npf_table_lookup(npf_table_t *, const int, const npf_addr_t *);
+int		npf_table_list(npf_table_t *, void *, size_t);
+int		npf_table_flush(npf_table_t *);
 
 /* Ruleset interface. */
 npf_ruleset_t *	npf_ruleset_create(size_t);

Index: src/sys/net/npf/npf_tableset.c
diff -u src/sys/net/npf/npf_tableset.c:1.18 src/sys/net/npf/npf_tableset.c:1.19
--- src/sys/net/npf/npf_tableset.c:1.18	Sun May 19 20:45:34 2013
+++ src/sys/net/npf/npf_tableset.c	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_tableset.c,v 1.18 2013/05/19 20:45:34 rmind Exp $	*/
+/*	$NetBSD: npf_tableset.c,v 1.19 2013/11/12 00:46:34 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.18 2013/05/19 20:45:34 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.19 2013/11/12 00:46:34 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -57,10 +57,6 @@ __KERNEL_RCSID(0, "$NetBSD: npf_tableset
 
 #include "npf_impl.h"
 
-/*
- * Table structures.
- */
-
 typedef struct npf_tblent {
 	union {
 		LIST_ENTRY(npf_tblent) hashq;
@@ -73,22 +69,36 @@ typedef struct npf_tblent {
 LIST_HEAD(npf_hashl, npf_tblent);
 
 struct npf_table {
-	char			t_name[16];
-	/* Lock and reference count. */
-	krwlock_t		t_lock;
-	u_int			t_refcnt;
-	/* Total number of items. */
-	u_int			t_nitems;
-	/* Table ID. */
-	u_int			t_id;
-	/* The storage type can be: a) hash b) tree. */
-	int			t_type;
+	/*
+	 * The storage type can be: a) hash b) tree.
+	 * There are separate trees for IPv4 and IPv6.
+	 */
 	struct npf_hashl *	t_hashl;
 	u_long			t_hashmask;
-	/* Separate trees for IPv4 and IPv6. */
 	pt_tree_t		t_tree[2];
+
+	/*
+	 * Table ID, type and lock.  The ID may change during the
+	 * config reload, it is protected by the npf_config_lock.
+	 */
+	int			t_type;
+	u_int			t_id;
+	krwlock_t		t_lock;
+
+	/* The number of items, reference count and table name. */
+	u_int			t_nitems;
+	u_int			t_refcnt;
+	char			t_name[NPF_TABLE_MAXNAMELEN];
+};
+
+struct npf_tableset {
+	u_int			ts_nitems;
+	npf_table_t *		ts_map[];
 };
 
+#define	NPF_TABLESET_SIZE(n)	\
+    (offsetof(npf_tableset_t, ts_map[n]) * sizeof(npf_table_t *))
+
 #define	NPF_ADDRLEN2TREE(alen)	((alen) >> 4)
 
 static pool_cache_t		tblent_cache	__read_mostly;
@@ -99,7 +109,6 @@ static pool_cache_t		tblent_cache	__read
 void
 npf_tableset_sysinit(void)
 {
-
 	tblent_cache = pool_cache_init(sizeof(npf_tblent_t), coherency_unit,
 	    0, 0, "npftblpl", NULL, IPL_NONE, NULL, NULL, NULL);
 }
@@ -107,36 +116,32 @@ npf_tableset_sysinit(void)
 void
 npf_tableset_sysfini(void)
 {
-
 	pool_cache_destroy(tblent_cache);
 }
 
 npf_tableset_t *
-npf_tableset_create(void)
+npf_tableset_create(u_int nitems)
 {
-	const size_t sz = NPF_TABLE_SLOTS * sizeof(npf_table_t *);
-
-	return kmem_zalloc(sz, KM_SLEEP);
+	npf_tableset_t *ts = kmem_zalloc(NPF_TABLESET_SIZE(nitems), KM_SLEEP);
+	ts->ts_nitems = nitems;
+	return ts;
 }
 
 void
-npf_tableset_destroy(npf_tableset_t *tblset)
+npf_tableset_destroy(npf_tableset_t *ts)
 {
-	const size_t sz = NPF_TABLE_SLOTS * sizeof(npf_table_t *);
-	npf_table_t *t;
-	u_int tid;
-
 	/*
-	 * Destroy all tables (no references should be held, as ruleset
-	 * should be destroyed before).
+	 * Destroy all tables (no references should be held, since the
+	 * ruleset should be destroyed before).
 	 */
-	for (tid = 0; tid < NPF_TABLE_SLOTS; tid++) {
-		t = tblset[tid];
+	for (u_int tid = 0; tid < ts->ts_nitems; tid++) {
+		npf_table_t *t = ts->ts_map[tid];
+
 		if (t && atomic_dec_uint_nv(&t->t_refcnt) == 0) {
 			npf_table_destroy(t);
 		}
 	}
-	kmem_free(tblset, sz);
+	kmem_free(ts, NPF_TABLESET_SIZE(ts->ts_nitems));
 }
 
 /*
@@ -145,16 +150,16 @@ npf_tableset_destroy(npf_tableset_t *tbl
  * => Returns 0 on success.  Fails and returns error if ID is already used.
  */
 int
-npf_tableset_insert(npf_tableset_t *tblset, npf_table_t *t)
+npf_tableset_insert(npf_tableset_t *ts, npf_table_t *t)
 {
 	const u_int tid = t->t_id;
 	int error;
 
-	KASSERT((u_int)tid < NPF_TABLE_SLOTS);
+	KASSERT((u_int)tid < ts->ts_nitems);
 
-	if (tblset[tid] == NULL) {
+	if (ts->ts_map[tid] == NULL) {
 		atomic_inc_uint(&t->t_refcnt);
-		tblset[tid] = t;
+		ts->ts_map[tid] = t;
 		error = 0;
 	} else {
 		error = EEXIST;
@@ -163,32 +168,76 @@ npf_tableset_insert(npf_tableset_t *tbls
 }
 
 /*
+ * npf_tableset_getbyname: look for a table in the set given the name.
+ */
+npf_table_t *
+npf_tableset_getbyname(npf_tableset_t *ts, const char *name)
+{
+	npf_table_t *t;
+
+	for (u_int tid = 0; tid < ts->ts_nitems; tid++) {
+		if ((t = ts->ts_map[tid]) == NULL)
+			continue;
+		if (strcmp(name, t->t_name) == 0)
+			return t;
+	}
+	return NULL;
+}
+
+npf_table_t *
+npf_tableset_getbyid(npf_tableset_t *ts, u_int tid)
+{
+	if (__predict_true(tid < ts->ts_nitems)) {
+		return ts->ts_map[tid];
+	}
+	return NULL;
+}
+
+/*
  * npf_tableset_reload: iterate all tables and if the new table is of the
  * same type and has no items, then we preserve the old one and its entries.
  *
  * => The caller is responsible for providing synchronisation.
  */
 void
-npf_tableset_reload(npf_tableset_t *ntset, npf_tableset_t *otset)
+npf_tableset_reload(npf_tableset_t *nts, npf_tableset_t *ots)
 {
-	for (int i = 0; i < NPF_TABLE_SLOTS; i++) {
-		npf_table_t *t = ntset[i], *ot = otset[i];
+	for (u_int tid = 0; tid < nts->ts_nitems; tid++) {
+		npf_table_t *t, *ot;
+
+		if ((t = nts->ts_map[tid]) == NULL) {
+			continue;
+		}
 
-		if (t == NULL || ot == NULL) {
+		/* If our table has entries, just load it. */
+		if (t->t_nitems) {
 			continue;
 		}
-		if (t->t_nitems || t->t_type != ot->t_type) {
+
+		/* Look for a currently existing table with such name. */
+		ot = npf_tableset_getbyname(ots, t->t_name);
+		if (ot == NULL) {
+			/* Not found: we have a new table. */
+			continue;
+		}
+
+		/* Found.  Did the type change? */
+		if (t->t_type != ot->t_type) {
+			/* Yes, load the new. */
 			continue;
 		}
 
 		/*
-		 * Acquire a reference since the table has to be kept
-		 * in the old tableset.
+		 * Preserve the current table.  Acquire a reference since
+		 * we are keeping it in the old table set.  Update its ID.
 		 */
 		atomic_inc_uint(&ot->t_refcnt);
-		ntset[i] = ot;
+		nts->ts_map[tid] = ot;
+
+		KASSERT(npf_config_locked_p());
+		ot->t_id = tid;
 
-		/* Only reference, never been visible. */
+		/* Destroy the new table (we hold only reference). */
 		t->t_refcnt--;
 		npf_table_destroy(t);
 	}
@@ -250,13 +299,13 @@ table_tree_destroy(pt_tree_t *tree)
  * npf_table_create: create table with a specified ID.
  */
 npf_table_t *
-npf_table_create(u_int tid, int type, size_t hsize)
+npf_table_create(const char *name, u_int tid, int type, size_t hsize)
 {
 	npf_table_t *t;
 
-	KASSERT((u_int)tid < NPF_TABLE_SLOTS);
-
 	t = kmem_zalloc(sizeof(npf_table_t), KM_SLEEP);
+	strlcpy(t->t_name, name, NPF_TABLE_MAXNAMELEN);
+
 	switch (type) {
 	case NPF_TABLE_TREE:
 		ptree_init(&t->t_tree[0], &npf_table_ptree_ops,
@@ -310,21 +359,26 @@ npf_table_destroy(npf_table_t *t)
 }
 
 /*
- * npf_table_check: validate ID and type.
+ * npf_table_check: validate the name, ID and type.
  */
 int
-npf_table_check(const npf_tableset_t *tset, u_int tid, int type)
+npf_table_check(npf_tableset_t *ts, const char *name, u_int tid, int type)
 {
-
-	if ((u_int)tid >= NPF_TABLE_SLOTS) {
+	if ((u_int)tid >= ts->ts_nitems) {
 		return EINVAL;
 	}
-	if (tset[tid] != NULL) {
+	if (ts->ts_map[tid] != NULL) {
 		return EEXIST;
 	}
 	if (type != NPF_TABLE_TREE && type != NPF_TABLE_HASH) {
 		return EINVAL;
 	}
+	if (strlen(name) >= NPF_TABLE_MAXNAMELEN) {
+		return ENAMETOOLONG;
+	}
+	if (npf_tableset_getbyname(ts, name)) {
+		return EINVAL;
+	}
 	return 0;
 }
 
@@ -332,11 +386,10 @@ static int
 table_cidr_check(const u_int aidx, const npf_addr_t *addr,
     const npf_netmask_t mask)
 {
-
-	if (mask > NPF_MAX_NETMASK && mask != NPF_NO_NETMASK) {
+	if (aidx > 1) {
 		return EINVAL;
 	}
-	if (aidx > 1) {
+	if (mask > NPF_MAX_NETMASK && mask != NPF_NO_NETMASK) {
 		return EINVAL;
 	}
 
@@ -354,18 +407,13 @@ table_cidr_check(const u_int aidx, const
  * npf_table_insert: add an IP CIDR entry into the table.
  */
 int
-npf_table_insert(npf_tableset_t *tset, u_int tid, const int alen,
+npf_table_insert(npf_table_t *t, const int alen,
     const npf_addr_t *addr, const npf_netmask_t mask)
 {
 	const u_int aidx = NPF_ADDRLEN2TREE(alen);
 	npf_tblent_t *ent;
-	npf_table_t *t;
 	int error;
 
-	if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
-		return EINVAL;
-	}
-
 	error = table_cidr_check(aidx, addr, mask);
 	if (error) {
 		return error;
@@ -430,12 +478,11 @@ npf_table_insert(npf_tableset_t *tset, u
  * npf_table_remove: remove the IP CIDR entry from the table.
  */
 int
-npf_table_remove(npf_tableset_t *tset, u_int tid, const int alen,
+npf_table_remove(npf_table_t *t, const int alen,
     const npf_addr_t *addr, const npf_netmask_t mask)
 {
 	const u_int aidx = NPF_ADDRLEN2TREE(alen);
 	npf_tblent_t *ent;
-	npf_table_t *t;
 	int error;
 
 	error = table_cidr_check(aidx, addr, mask);
@@ -443,10 +490,6 @@ npf_table_remove(npf_tableset_t *tset, u
 		return error;
 	}
 
-	if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
-		return EINVAL;
-	}
-
 	rw_enter(&t->t_lock, RW_WRITER);
 	switch (t->t_type) {
 	case NPF_TABLE_HASH: {
@@ -487,21 +530,15 @@ npf_table_remove(npf_tableset_t *tset, u
  * the contents with the specified IP address.
  */
 int
-npf_table_lookup(npf_tableset_t *tset, u_int tid,
-    const int alen, const npf_addr_t *addr)
+npf_table_lookup(npf_table_t *t, const int alen, const npf_addr_t *addr)
 {
 	const u_int aidx = NPF_ADDRLEN2TREE(alen);
 	npf_tblent_t *ent;
-	npf_table_t *t;
 
 	if (__predict_false(aidx > 1)) {
 		return EINVAL;
 	}
 
-	if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
-		return EINVAL;
-	}
-
 	rw_enter(&t->t_lock, RW_READER);
 	switch (t->t_type) {
 	case NPF_TABLE_HASH: {
@@ -563,16 +600,11 @@ table_tree_list(pt_tree_t *tree, npf_net
  * npf_table_list: copy a list of all table entries into a userspace buffer.
  */
 int
-npf_table_list(npf_tableset_t *tset, u_int tid, void *ubuf, size_t len)
+npf_table_list(npf_table_t *t, void *ubuf, size_t len)
 {
-	npf_table_t *t;
 	size_t off = 0;
 	int error = 0;
 
-	if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
-		return EINVAL;
-	}
-
 	rw_enter(&t->t_lock, RW_READER);
 	switch (t->t_type) {
 	case NPF_TABLE_HASH:
@@ -603,14 +635,8 @@ npf_table_list(npf_tableset_t *tset, u_i
  * npf_table_flush: remove all table entries.
  */
 int
-npf_table_flush(npf_tableset_t *tset, u_int tid)
+npf_table_flush(npf_table_t *t)
 {
-	npf_table_t *t;
-
-	if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
-		return EINVAL;
-	}
-
 	rw_enter(&t->t_lock, RW_WRITER);
 	switch (t->t_type) {
 	case NPF_TABLE_HASH:
@@ -626,6 +652,5 @@ npf_table_flush(npf_tableset_t *tset, u_
 		KASSERT(false);
 	}
 	rw_exit(&t->t_lock);
-
 	return 0;
 }

Index: src/usr.sbin/npf/npfctl/npf.conf.5
diff -u src/usr.sbin/npf/npfctl/npf.conf.5:1.32 src/usr.sbin/npf/npfctl/npf.conf.5:1.33
--- src/usr.sbin/npf/npfctl/npf.conf.5:1.32	Tue Nov  5 13:09:12 2013
+++ src/usr.sbin/npf/npfctl/npf.conf.5	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-.\"    $NetBSD: npf.conf.5,v 1.32 2013/11/05 13:09:12 kefren Exp $
+.\"    $NetBSD: npf.conf.5,v 1.33 2013/11/12 00:46:34 rmind Exp $
 .\"
 .\" Copyright (c) 2009-2013 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 November 5, 2013
+.Dd November 10, 2013
 .Dt NPF.CONF 5
 .Os
 .Sh NAME
@@ -78,12 +78,11 @@ $var2 = { 10.0.0.1, 10.0.0.2 }
 Common variable definitions are for IP addresses, networks, ports,
 and interfaces.
 .Ss Tables
-Tables are specified using a number between angle brackets
+Tables are specified using a name between angle brackets
 \*[Lt] and \*[Gt].
-The number used to specify a table should be between 0 and 15.
 The following is an example of table definition:
 .Bd -literal
-table <1> type hash dynamic
+table <black> type hash dynamic
 .Pp
 .Ed
 Currently, tables support two storage types: "hash" or "tree".
@@ -115,7 +114,7 @@ Groups may have the following options: n
 They are defined in the following form:
 .Pp
 .Bd -literal
-group "my_group_name" in on wm0 {
+group "my-name" in on wm0 {
 	# List of rules
 }
 .Ed
@@ -146,6 +145,13 @@ specification at present is limited to p
 TCP and UDP understanding source and destination ports, and ICMP and
 IPv6-ICMP understanding icmp-type.
 .Pp
+Alternatively, NPF supports
+.Xr pcap-filter 7
+syntax, for example:
+.Bd -literal
+block out final pcap-filter "tcp and dst 10.1.1.252"
+.Ed
+.Pp
 Fragments are not selectable since NPF always reassembles packets
 before further processing.
 .Ss Map
@@ -216,7 +222,7 @@ var-def		= var "=" ( var-value | "{" val
 
 ; Table definition.  Table ID shall be numeric.  Path is in the double quotes.
 
-table-id	= \*[Lt]tid\*[Gt]
+table-id	= \*[Lt]table-name\*[Gt]
 table-def	= "table" table-id "type" ( "hash" | "tree" )
 		  ( "dynamic" | "file" path )
 
@@ -242,10 +248,13 @@ group		= "group" ( "default" | group-opt
 group-opts	= name-string [ "in" | "out" ] [ "on" interface ]
 rule-list	= [ rule new-line ] rule-list
 
+npf-filter	= [ "family" family-opt ] [ "proto" protocol [ proto-opts ] ]
+		  ( "all" | filt-opts ) 
 static-rule	= ( "block" [ block-opts ] | "pass" ) [ "stateful" ]
 		  [ "in" | out" ] [ "final" ] [ "on" interface ]
-		  [ "family" family-opt ] [ "proto" protocol [ proto-opts ] ]
-		  ( "all" | filt-opts ) [ "apply" proc-name ]
+		  ( npf-filter | "pcap-filter" pcap-filter-expr )
+		  [ "apply" proc-name ]
+
 dynamic-ruleset	= "ruleset" group-opts
 rule		= static-rule | dynamic-ruleset
 
@@ -275,8 +284,8 @@ directory containing further examples
 $ext_if = ifnet(wm0)
 $int_if = ifnet(wm1)
 
-table <1> type hash file "/etc/npf_blacklist"
-table <2> type tree dynamic
+table <black> type hash file "/etc/npf_blacklist"
+table <limited> type tree dynamic
 
 $services_tcp = { http, https, smtp, domain, 6000, 9022 }
 $services_udp = { domain, ntp, 6000 }
@@ -296,7 +305,7 @@ procedure "log" {
 group "external" on $ext_if {
 	pass stateful out final all
 
-	block in final from \*[Lt]1\*[Gt]
+	block in final from \*[Lt]black\*[Gt]
 	pass stateful in final family inet proto tcp to $ext_if port ssh apply "log"
 	pass stateful in final proto tcp to $ext_if port $services_tcp
 	pass stateful in final proto udp to $ext_if port $services_udp
@@ -306,7 +315,7 @@ group "external" on $ext_if {
 
 group "internal" on $int_if {
 	block in all
-	block in final from \*[Lt]2\*[Gt]
+	block in final from \*[Lt]limited\*[Gt]
 
 	# Ingress filtering as per RFC 2827.
 	pass in final from $localnet
@@ -321,6 +330,7 @@ group default {
 .\" -----
 .Sh SEE ALSO
 .Xr bpf 4 ,
+.Xr pcap-filter 7 ,
 .Xr npfctl 8
 .Sh HISTORY
 NPF first appeared in

Index: src/usr.sbin/npf/npfctl/npf_build.c
diff -u src/usr.sbin/npf/npfctl/npf_build.c:1.28 src/usr.sbin/npf/npfctl/npf_build.c:1.29
--- src/usr.sbin/npf/npfctl/npf_build.c:1.28	Fri Nov  8 00:38:26 2013
+++ src/usr.sbin/npf/npfctl/npf_build.c	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_build.c,v 1.28 2013/11/08 00:38:26 rmind Exp $	*/
+/*	$NetBSD: npf_build.c,v 1.29 2013/11/12 00:46:34 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.28 2013/11/08 00:38:26 rmind Exp $");
+__RCSID("$NetBSD: npf_build.c,v 1.29 2013/11/12 00:46:34 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/ioctl.h>
@@ -42,6 +42,7 @@ __RCSID("$NetBSD: npf_build.c,v 1.28 201
 #include <stdlib.h>
 #include <inttypes.h>
 #include <string.h>
+#include <ctype.h>
 #include <errno.h>
 #include <err.h>
 
@@ -658,17 +659,16 @@ npfctl_fill_table(nl_table_t *tl, u_int 
  * if required, fill with contents from a file.
  */
 void
-npfctl_build_table(const char *tid, u_int type, const char *fname)
+npfctl_build_table(const char *tname, u_int type, const char *fname)
 {
+	static unsigned tid = 0;
 	nl_table_t *tl;
-	u_int id;
 
-	id = atoi(tid);
-	tl = npf_table_create(id, type);
+	tl = npf_table_create(tname, tid++, type);
 	assert(tl != NULL);
 
 	if (npf_table_insert(npf_conf, tl)) {
-		errx(EXIT_FAILURE, "table '%d' is already defined\n", id);
+		yyerror("table '%s' is already defined", tname);
 	}
 
 	if (fname) {

Index: src/usr.sbin/npf/npfctl/npf_scan.l
diff -u src/usr.sbin/npf/npfctl/npf_scan.l:1.13 src/usr.sbin/npf/npfctl/npf_scan.l:1.14
--- src/usr.sbin/npf/npfctl/npf_scan.l:1.13	Fri Sep 20 03:03:52 2013
+++ src/usr.sbin/npf/npfctl/npf_scan.l	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_scan.l,v 1.13 2013/09/20 03:03:52 rmind Exp $	*/
+/*	$NetBSD: npf_scan.l,v 1.14 2013/11/12 00:46:34 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -82,7 +82,7 @@ npfctl_parse_string(const char *str)
 %option noyywrap nounput noinput
 
 ID	[a-zA-Z_][a-zA-Z_0-9]*
-NID	[a-zA-Z_0-9]+
+DID	[a-zA-Z_][a-zA-Z_0-9-]*
 NUMBER	[0-9]+
 
 %%
@@ -181,12 +181,12 @@ any			return ANY;
 			return NUM;
 		}
 
-"<"{NID}">"	{
+"<"{DID}">"	{
 			yylval.str = estrndup(yytext + 1, yyleng - 2);
 			return TABLE_ID;
 		}
 
-"$"{NID}	{
+"$"{ID}	{
 			yylval.str = estrndup(yytext + 1, yyleng - 1);
 			return VAR_ID;
 		}

Index: src/usr.sbin/npf/npfctl/npf_show.c
diff -u src/usr.sbin/npf/npfctl/npf_show.c:1.3 src/usr.sbin/npf/npfctl/npf_show.c:1.4
--- src/usr.sbin/npf/npfctl/npf_show.c:1.3	Fri Nov  8 00:38:26 2013
+++ src/usr.sbin/npf/npfctl/npf_show.c	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_show.c,v 1.3 2013/11/08 00:38:26 rmind Exp $	*/
+/*	$NetBSD: npf_show.c,v 1.4 2013/11/12 00:46:34 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_show.c,v 1.3 2013/11/08 00:38:26 rmind Exp $");
+__RCSID("$NetBSD: npf_show.c,v 1.4 2013/11/12 00:46:34 rmind Exp $");
 
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -54,6 +54,7 @@ __RCSID("$NetBSD: npf_show.c,v 1.3 2013/
 #include "npfctl.h"
 
 typedef struct {
+	nl_config_t *	conf;
 	FILE *		fp;
 	long		fpos;
 } npf_conf_info_t;
@@ -104,7 +105,7 @@ tcpflags2string(char *buf, u_int tfl)
 }
 
 static char *
-print_family(const uint32_t *words)
+print_family(npf_conf_info_t *ctx, const uint32_t *words)
 {
 	const int af = words[0];
 
@@ -120,7 +121,7 @@ print_family(const uint32_t *words)
 }
 
 static char *
-print_address(const uint32_t *words)
+print_address(npf_conf_info_t *ctx, const uint32_t *words)
 {
 	const int af = *words++;
 	const u_int mask = *words++;
@@ -142,7 +143,7 @@ print_address(const uint32_t *words)
 }
 
 static char *
-print_number(const uint32_t *words)
+print_number(npf_conf_info_t *ctx, const uint32_t *words)
 {
 	char *p;
 	easprintf(&p, "%u", words[0]);
@@ -150,7 +151,22 @@ print_number(const uint32_t *words)
 }
 
 static char *
-print_proto(const uint32_t *words)
+print_table(npf_conf_info_t *ctx, const uint32_t *words)
+{
+	unsigned tid = words[0];
+	nl_table_t *tl;
+	char *p;
+
+	while ((tl = npf_table_iterate(ctx->conf)) != NULL) {
+		if (npf_table_getid(tl) == tid)
+			break;
+	}
+	easprintf(&p, "%s", npf_table_getname(tl));
+	return p;
+}
+
+static char *
+print_proto(npf_conf_info_t *ctx, const uint32_t *words)
 {
 	switch (words[0]) {
 	case IPPROTO_TCP:
@@ -162,11 +178,11 @@ print_proto(const uint32_t *words)
 	case IPPROTO_ICMPV6:
 		return estrdup("ipv6-icmp");
 	}
-	return print_number(words);
+	return print_number(ctx, words);
 }
 
 static char *
-print_tcpflags(const uint32_t *words)
+print_tcpflags(npf_conf_info_t *ctx, const uint32_t *words)
 {
 	const u_int tf = words[0], tf_mask = words[1];
 	char buf[16];
@@ -180,7 +196,7 @@ print_tcpflags(const uint32_t *words)
 }
 
 static char *
-print_portrange(const uint32_t *words)
+print_portrange(npf_conf_info_t *ctx, const uint32_t *words)
 {
 	u_int fport = words[0], tport = words[1];
 	char *p;
@@ -224,7 +240,7 @@ static const struct mark_keyword_mapent 
 	u_int		mark;
 	const char *	token;
 	const char *	sep;
-	char *		(*printfn)(const uint32_t *);
+	char *		(*printfn)(npf_conf_info_t *, const uint32_t *);
 	u_int		fwords;
 } mark_keyword_map[] = {
 	{ BM_IPVER,	"family %s",	NULL,		print_family,	1 },
@@ -234,11 +250,11 @@ static const struct mark_keyword_mapent 
 	{ BM_ICMP_CODE,	"code %s",	NULL,		print_number,	1 },
 
 	{ BM_SRC_CIDR,	"from %s",	", ",		print_address,	6 },
-	{ BM_SRC_TABLE,	"from <%s>",	NULL,		print_number,	1 },
+	{ BM_SRC_TABLE,	"from <%s>",	NULL,		print_table,	1 },
 	{ BM_SRC_PORTS,	"port %s",	", ",		print_portrange,2 },
 
 	{ BM_DST_CIDR,	"to %s",	", ",		print_address,	6 },
-	{ BM_DST_TABLE,	"to <%s>",	NULL,		print_number,	1 },
+	{ BM_DST_TABLE,	"to <%s>",	NULL,		print_table,	1 },
 	{ BM_DST_PORTS,	"port %s",	", ",		print_portrange,2 },
 };
 
@@ -267,7 +283,7 @@ scan_marks(npf_conf_info_t *ctx, const s
 		if (m == mk->mark) {
 			/* Value is processed by the print function. */
 			assert(mk->fwords == nwords);
-			vals[nvals++] = mk->printfn(marks);
+			vals[nvals++] = mk->printfn(ctx, marks);
 		}
 		marks += nwords;
 		mlen -= nwords;
@@ -401,10 +417,10 @@ npfctl_print_nat(npf_conf_info_t *ctx, n
 static void
 npfctl_print_table(npf_conf_info_t *ctx, nl_table_t *tl)
 {
-	const u_int id = npf_table_getid(tl);
+	const char *name = npf_table_getname(tl);
 	const int type = npf_table_gettype(tl);
 
-	fprintf(ctx->fp, "table <%u> type %s\n", id,
+	fprintf(ctx->fp, "table <%s> type %s\n", name,
 	    (type == NPF_TABLE_HASH) ? "hash" :
 	    (type == NPF_TABLE_TREE) ? "tree" :
 	    "unknown");
@@ -431,6 +447,7 @@ npfctl_config_show(int fd)
 		ncf = npfctl_config_ref();
 		loaded = true;
 	}
+	ctx->conf = ncf;
 
 	if (loaded) {
 		nl_rule_t *rl;
@@ -475,6 +492,8 @@ npfctl_ruleset_show(int fd, const char *
 	int error;
 
 	ncf = npf_config_create();
+	ctx->conf = ncf;
+
 	if ((error = _npf_ruleset_list(fd, ruleset_name, ncf)) != 0) {
 		return error;
 	}

Index: src/usr.sbin/npf/npfctl/npfctl.c
diff -u src/usr.sbin/npf/npfctl/npfctl.c:1.39 src/usr.sbin/npf/npfctl/npfctl.c:1.40
--- src/usr.sbin/npf/npfctl/npfctl.c:1.39	Thu Sep 19 12:05:11 2013
+++ src/usr.sbin/npf/npfctl/npfctl.c	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npfctl.c,v 1.39 2013/09/19 12:05:11 rmind Exp $	*/
+/*	$NetBSD: npfctl.c,v 1.40 2013/11/12 00:46:34 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npfctl.c,v 1.39 2013/09/19 12:05:11 rmind Exp $");
+__RCSID("$NetBSD: npfctl.c,v 1.40 2013/11/12 00:46:34 rmind Exp $");
 
 #include <sys/ioctl.h>
 #include <sys/stat.h>
@@ -274,12 +274,12 @@ npfctl_table(int fd, int argc, char **ar
 	npf_ioctl_table_t nct;
 	fam_addr_mask_t fam;
 	size_t buflen = 512;
-	char *cmd, *arg = NULL; /* XXX gcc */
+	char *cmd, *arg;
 	int n, alen;
 
 	/* Default action is list. */
 	memset(&nct, 0, sizeof(npf_ioctl_table_t));
-	nct.nct_tid = atoi(argv[0]);
+	nct.nct_name = argv[0];
 	cmd = argv[1];
 
 	for (n = 0; tblops[n].cmd != NULL; n++) {
@@ -296,6 +296,7 @@ npfctl_table(int fd, int argc, char **ar
 	switch (nct.nct_cmd) {
 	case NPF_CMD_TABLE_LIST:
 	case NPF_CMD_TABLE_FLUSH:
+		arg = NULL;
 		break;
 	default:
 		if (argc < 3) {

Index: src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c
diff -u src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c:1.6 src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c:1.7
--- src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c:1.6	Mon Oct 29 02:27:11 2012
+++ src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c	Tue Nov 12 00:46:34 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_table_test.c,v 1.6 2012/10/29 02:27:11 rmind Exp $	*/
+/*	$NetBSD: npf_table_test.c,v 1.7 2013/11/12 00:46:34 rmind Exp $	*/
 
 /*
  * NPF tableset test.
@@ -41,8 +41,8 @@ static const uint16_t ip6_list[][8] = {
 	}
 };
 
-#define	HASH_TID		1
-#define	TREE_TID		2
+#define	HASH_TID		"hash-table"
+#define	TREE_TID		"tree-table"
 
 static bool
 npf_table_test_fill4(npf_tableset_t *tblset, npf_addr_t *addr)
@@ -53,18 +53,21 @@ npf_table_test_fill4(npf_tableset_t *tbl
 
 	/* Fill both tables with IP addresses. */
 	for (unsigned i = 0; i < __arraycount(ip_list); i++) {
+		npf_table_t *t;
 		int error;
 
 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
 
-		error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
+		t = npf_tableset_getbyname(tblset, HASH_TID);
+		error = npf_table_insert(t, alen, addr, nm);
 		fail |= !(error == 0);
-		error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
+		error = npf_table_insert(t, alen, addr, nm);
 		fail |= !(error != 0);
 
-		error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
+		t = npf_tableset_getbyname(tblset, TREE_TID);
+		error = npf_table_insert(t, alen, addr, nm);
 		fail |= !(error == 0);
-		error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
+		error = npf_table_insert(t, alen, addr, nm);
 		fail |= !(error != 0);
 	}
 	return fail;
@@ -76,16 +79,16 @@ npf_table_test(bool verbose)
 	npf_addr_t addr_storage, *addr = &addr_storage;
 	const int nm = NPF_NO_NETMASK;
 	npf_tableset_t *tblset;
-	npf_table_t *t1, *t2;
+	npf_table_t *t, *t1, *t2;
 	int error, alen;
 	bool fail = false;
 	u_int i;
 
-	tblset = npf_tableset_create();
+	tblset = npf_tableset_create(2);
 	fail |= !(tblset != NULL);
 
 	/* Table ID 1, using hash table with 256 lists. */
-	t1 = npf_table_create(HASH_TID, NPF_TABLE_HASH, 256);
+	t1 = npf_table_create(HASH_TID, 0, NPF_TABLE_HASH, 256);
 	fail |= !(t1 != NULL);
 	error = npf_tableset_insert(tblset, t1);
 	fail |= !(error == 0);
@@ -94,8 +97,8 @@ npf_table_test(bool verbose)
 	error = npf_tableset_insert(tblset, t1);
 	fail |= !(error != 0);
 
-	/* Table ID 2, using RB-tree. */
-	t2 = npf_table_create(TREE_TID, NPF_TABLE_TREE, 0);
+	/* Table ID 2, using a prefix tree. */
+	t2 = npf_table_create(TREE_TID, 1, NPF_TABLE_TREE, 0);
 	fail |= !(t2 != NULL);
 	error = npf_tableset_insert(tblset, t2);
 	fail |= !(error == 0);
@@ -104,10 +107,12 @@ npf_table_test(bool verbose)
 	addr->s6_addr32[0] = inet_addr(ip_list[0]);
 	alen = sizeof(struct in_addr);
 
-	error = npf_table_lookup(tblset, HASH_TID, alen, addr);
+	t = npf_tableset_getbyname(tblset, HASH_TID);
+	error = npf_table_lookup(t, alen, addr);
 	fail |= !(error != 0);
 
-	error = npf_table_lookup(tblset, TREE_TID, alen, addr);
+	t = npf_tableset_getbyname(tblset, TREE_TID);
+	error = npf_table_lookup(t, alen, addr);
 	fail |= !(error != 0);
 
 	/* Fill both tables with IP addresses. */
@@ -117,20 +122,24 @@ npf_table_test(bool verbose)
 	addr->s6_addr32[0] = inet_addr(ip_list[0]);
 	alen = sizeof(struct in_addr);
 
-	error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
+	t = npf_tableset_getbyname(tblset, HASH_TID);
+	error = npf_table_insert(t, alen, addr, nm);
 	fail |= !(error != 0);
 
-	error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
+	t = npf_tableset_getbyname(tblset, TREE_TID);
+	error = npf_table_insert(t, alen, addr, nm);
 	fail |= !(error != 0);
 
 	/* Match (validate) each IP entry. */
 	for (i = 0; i < __arraycount(ip_list); i++) {
 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
 
-		error = npf_table_lookup(tblset, HASH_TID, alen, addr);
+		t = npf_tableset_getbyname(tblset, HASH_TID);
+		error = npf_table_lookup(t, alen, addr);
 		fail |= !(error == 0);
 
-		error = npf_table_lookup(tblset, TREE_TID, alen, addr);
+		t = npf_tableset_getbyname(tblset, TREE_TID);
+		error = npf_table_lookup(t, alen, addr);
 		fail |= !(error == 0);
 	}
 
@@ -138,18 +147,20 @@ npf_table_test(bool verbose)
 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
 	alen = sizeof(struct in6_addr);
 
-	error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
+	t = npf_tableset_getbyname(tblset, HASH_TID);
+	error = npf_table_insert(t, alen, addr, nm);
 	fail |= !(error == 0);
-	error = npf_table_lookup(tblset, HASH_TID, alen, addr);
+	error = npf_table_lookup(t, alen, addr);
 	fail |= !(error == 0);
-	error = npf_table_remove(tblset, HASH_TID, alen, addr, nm);
+	error = npf_table_remove(t, alen, addr, nm);
 	fail |= !(error == 0);
 
-	error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
+	t = npf_tableset_getbyname(tblset, TREE_TID);
+	error = npf_table_insert(t, alen, addr, nm);
 	fail |= !(error == 0);
-	error = npf_table_lookup(tblset, TREE_TID, alen, addr);
+	error = npf_table_lookup(t, alen, addr);
 	fail |= !(error == 0);
-	error = npf_table_remove(tblset, TREE_TID, alen, addr, nm);
+	error = npf_table_remove(t, alen, addr, nm);
 	fail |= !(error == 0);
 
 	/*
@@ -157,41 +168,41 @@ npf_table_test(bool verbose)
 	 */
 
 	memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
-	error = npf_table_insert(tblset, TREE_TID, alen, addr, 96);
+	error = npf_table_insert(t, alen, addr, 96);
 	fail |= !(error == 0);
 
 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
-	error = npf_table_lookup(tblset, TREE_TID, alen, addr);
+	error = npf_table_lookup(t, alen, addr);
 	fail |= !(error == 0);
 
 	memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
-	error = npf_table_remove(tblset, TREE_TID, alen, addr, 96);
+	error = npf_table_remove(t, alen, addr, 96);
 	fail |= !(error == 0);
 
 
 	memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
-	error = npf_table_insert(tblset, TREE_TID, alen, addr, 32);
+	error = npf_table_insert(t, alen, addr, 32);
 	fail |= !(error == 0);
 
 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
-	error = npf_table_lookup(tblset, TREE_TID, alen, addr);
+	error = npf_table_lookup(t, alen, addr);
 	fail |= !(error == 0);
 
 	memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
-	error = npf_table_remove(tblset, TREE_TID, alen, addr, 32);
+	error = npf_table_remove(t, alen, addr, 32);
 	fail |= !(error == 0);
 
 
 	memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
-	error = npf_table_insert(tblset, TREE_TID, alen, addr, 126);
+	error = npf_table_insert(t, alen, addr, 126);
 	fail |= !(error == 0);
 
 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
-	error = npf_table_lookup(tblset, TREE_TID, alen, addr);
+	error = npf_table_lookup(t, alen, addr);
 	fail |= !(error != 0);
 
 	memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
-	error = npf_table_remove(tblset, TREE_TID, alen, addr, 126);
+	error = npf_table_remove(t, alen, addr, 126);
 	fail |= !(error == 0);
 
 
@@ -201,10 +212,12 @@ npf_table_test(bool verbose)
 	for (i = 0; i < __arraycount(ip_list); i++) {
 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
 
-		error = npf_table_remove(tblset, HASH_TID, alen, addr, nm);
+		t = npf_tableset_getbyname(tblset, HASH_TID);
+		error = npf_table_remove(t, alen, addr, nm);
 		fail |= !(error == 0);
 
-		error = npf_table_remove(tblset, TREE_TID, alen, addr, nm);
+		t = npf_tableset_getbyname(tblset, TREE_TID);
+		error = npf_table_remove(t, alen, addr, nm);
 		fail |= !(error == 0);
 	}
 

Reply via email to