Module Name:    src
Committed By:   rmind
Date:           Sun Aug 10 19:09:43 UTC 2014

Modified Files:
        src/lib/libnpf: npf.c
        src/sys/net/npf: npf.h npf_conn.c npf_conn.h npf_ctl.c npf_if.c
            npf_impl.h npf_mbuf.c npf_nat.c npf_ruleset.c
        src/usr.sbin/npf: npf.7
        src/usr.sbin/npf/npftest/libnpftest: npf_rule_test.c

Log Message:
- Add npf_ruleset_export(), npf_rule_export() and npf_nat_policyexport().
- Split off npf_conn_export().  Add npf_ifmap_getname() and use it to save
  the interface name; pick it up on npf_conn_import().
- Misc fixes.  Bump NPF_VERSION.


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/lib/libnpf/npf.c
cvs rdiff -u -r1.46 -r1.47 src/sys/net/npf/npf.h
cvs rdiff -u -r1.9 -r1.10 src/sys/net/npf/npf_conn.c
cvs rdiff -u -r1.5 -r1.6 src/sys/net/npf/npf_conn.h
cvs rdiff -u -r1.36 -r1.37 src/sys/net/npf/npf_ctl.c
cvs rdiff -u -r1.3 -r1.4 src/sys/net/npf/npf_if.c
cvs rdiff -u -r1.56 -r1.57 src/sys/net/npf/npf_impl.h
cvs rdiff -u -r1.12 -r1.13 src/sys/net/npf/npf_mbuf.c
cvs rdiff -u -r1.31 -r1.32 src/sys/net/npf/npf_nat.c
cvs rdiff -u -r1.35 -r1.36 src/sys/net/npf/npf_ruleset.c
cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/npf/npf.7
cvs rdiff -u -r1.11 -r1.12 \
    src/usr.sbin/npf/npftest/libnpftest/npf_rule_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.c
diff -u src/lib/libnpf/npf.c:1.31 src/lib/libnpf/npf.c:1.32
--- src/lib/libnpf/npf.c:1.31	Wed Jul 23 05:00:38 2014
+++ src/lib/libnpf/npf.c	Sun Aug 10 19:09:43 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf.c,v 1.31 2014/07/23 05:00:38 htodd Exp $	*/
+/*	$NetBSD: npf.c,v 1.32 2014/08/10 19:09:43 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010-2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.31 2014/07/23 05:00:38 htodd Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.32 2014/08/10 19:09:43 rmind Exp $");
 
 #include <sys/types.h>
 #include <netinet/in_systm.h>
@@ -152,7 +152,7 @@ npf_config_submit(nl_config_t *ncf, int 
 	prop_dictionary_set(npf_dict, "algs", ncf->ncf_alg_list);
 	prop_dictionary_set(npf_dict, "rprocs", ncf->ncf_rproc_list);
 	prop_dictionary_set(npf_dict, "tables", ncf->ncf_table_list);
-	prop_dictionary_set(npf_dict, "translation", ncf->ncf_nat_list);
+	prop_dictionary_set(npf_dict, "nat", ncf->ncf_nat_list);
 	prop_dictionary_set_bool(npf_dict, "flush", ncf->ncf_flush);
 	if (ncf->ncf_debug) {
 		prop_dictionary_set(npf_dict, "debug", ncf->ncf_debug);
@@ -193,7 +193,7 @@ _npf_config_consdict(prop_dictionary_t n
 	ncf->ncf_rules_list = prop_dictionary_get(npf_dict, "rules");
 	ncf->ncf_rproc_list = prop_dictionary_get(npf_dict, "rprocs");
 	ncf->ncf_table_list = prop_dictionary_get(npf_dict, "tables");
-	ncf->ncf_nat_list = prop_dictionary_get(npf_dict, "translation");
+	ncf->ncf_nat_list = prop_dictionary_get(npf_dict, "nat");
 	return ncf;
 }
 
@@ -502,10 +502,10 @@ npf_rule_create(const char *name, uint32
 	if (name) {
 		prop_dictionary_set_cstring(rldict, "name", name);
 	}
-	prop_dictionary_set_uint32(rldict, "attributes", attr);
+	prop_dictionary_set_uint32(rldict, "attr", attr);
 
 	if (ifname) {
-		prop_dictionary_set_cstring(rldict, "interface", ifname);
+		prop_dictionary_set_cstring(rldict, "ifname", ifname);
 	}
 	rl->nrl_dict = rldict;
 	return rl;
@@ -566,7 +566,7 @@ npf_rule_setprio(nl_rule_t *rl, pri_t pr
 {
 	prop_dictionary_t rldict = rl->nrl_dict;
 
-	prop_dictionary_set_int32(rldict, "priority", pri);
+	prop_dictionary_set_int32(rldict, "prio", pri);
 	return 0;
 }
 
@@ -675,7 +675,7 @@ npf_rule_getattr(nl_rule_t *rl)
 	prop_dictionary_t rldict = rl->nrl_dict;
 	uint32_t attr = 0;
 
-	prop_dictionary_get_uint32(rldict, "attributes", &attr);
+	prop_dictionary_get_uint32(rldict, "attr", &attr);
 	return attr;
 }
 
@@ -685,7 +685,7 @@ npf_rule_getinterface(nl_rule_t *rl)
 	prop_dictionary_t rldict = rl->nrl_dict;
 	const char *ifname = NULL;
 
-	prop_dictionary_get_cstring_nocopy(rldict, "interface", &ifname);
+	prop_dictionary_get_cstring_nocopy(rldict, "ifname", &ifname);
 	return ifname;
 }
 
@@ -845,7 +845,7 @@ npf_rproc_getname(nl_rproc_t *rp)
 }
 
 /*
- * TRANSLATION INTERFACE.
+ * NAT INTERFACE.
  */
 
 nl_nat_t *
@@ -869,7 +869,7 @@ npf_nat_create(int type, u_int flags, co
 	attr = NPF_RULE_PASS | NPF_RULE_FINAL |
 	    (type == NPF_NATOUT ? NPF_RULE_OUT : NPF_RULE_IN);
 
-	/* Create a rule for NAT policy.  Next, will add translation data. */
+	/* Create a rule for NAT policy.  Next, will add NAT data. */
 	rl = npf_rule_create(NULL, attr, ifname);
 	if (rl == NULL) {
 		return NULL;
@@ -886,12 +886,12 @@ npf_nat_create(int type, u_int flags, co
 		npf_rule_destroy(rl);
 		return NULL;
 	}
-	prop_dictionary_set(rldict, "translation-ip", addrdat);
-	prop_dictionary_set_uint32(rldict, "translation-mask", mask);
+	prop_dictionary_set(rldict, "nat-ip", addrdat);
+	prop_dictionary_set_uint32(rldict, "nat-mask", mask);
 	prop_object_release(addrdat);
 
 	/* Translation port (for redirect case). */
-	prop_dictionary_set_uint16(rldict, "translation-port", port);
+	prop_dictionary_set_uint16(rldict, "nat-port", port);
 
 	return (nl_nat_t *)rl;
 }
@@ -901,7 +901,7 @@ npf_nat_insert(nl_config_t *ncf, nl_nat_
 {
 	prop_dictionary_t rldict = nt->nrl_dict;
 
-	prop_dictionary_set_int32(rldict, "priority", NPF_PRI_LAST);
+	prop_dictionary_set_int32(rldict, "prio", NPF_PRI_LAST);
 	prop_array_add(ncf->ncf_nat_list, rldict);
 	return 0;
 }
@@ -917,7 +917,7 @@ int
 npf_nat_setalgo(nl_nat_t *nt, u_int algo)
 {
 	prop_dictionary_t rldict = nt->nrl_dict;
-	prop_dictionary_set_uint32(rldict, "translation-algo", algo);
+	prop_dictionary_set_uint32(rldict, "nat-algo", algo);
 	return 0;
 }
 
@@ -930,7 +930,7 @@ npf_nat_setnpt66(nl_nat_t *nt, uint16_t 
 	if ((error = npf_nat_setalgo(nt, NPF_ALGO_NPT66)) != 0) {
 		return error;
 	}
-	prop_dictionary_set_uint16(rldict, "npt66-adjustment", adj);
+	prop_dictionary_set_uint16(rldict, "npt66-adj", adj);
 	return 0;
 }
 
@@ -958,13 +958,13 @@ void
 npf_nat_getmap(nl_nat_t *nt, npf_addr_t *addr, size_t *alen, in_port_t *port)
 {
 	prop_dictionary_t rldict = nt->nrl_dict;
-	prop_object_t obj = prop_dictionary_get(rldict, "translation-ip");
+	prop_object_t obj = prop_dictionary_get(rldict, "nat-ip");
 
 	*alen = prop_data_size(obj);
 	memcpy(addr, prop_data_data_nocopy(obj), *alen);
 
 	*port = 0;
-	prop_dictionary_get_uint16(rldict, "translation-port", port);
+	prop_dictionary_get_uint16(rldict, "nat-port", port);
 }
 
 /*

Index: src/sys/net/npf/npf.h
diff -u src/sys/net/npf/npf.h:1.46 src/sys/net/npf/npf.h:1.47
--- src/sys/net/npf/npf.h:1.46	Wed Jul 23 01:48:05 2014
+++ src/sys/net/npf/npf.h	Sun Aug 10 19:09:43 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf.h,v 1.46 2014/07/23 01:48:05 rmind Exp $	*/
+/*	$NetBSD: npf.h,v 1.47 2014/08/10 19:09:43 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -45,7 +45,7 @@
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
 
-#define	NPF_VERSION		16
+#define	NPF_VERSION		17
 
 /*
  * Public declarations and definitions.

Index: src/sys/net/npf/npf_conn.c
diff -u src/sys/net/npf/npf_conn.c:1.9 src/sys/net/npf/npf_conn.c:1.10
--- src/sys/net/npf/npf_conn.c:1.9	Sat Jul 26 16:42:03 2014
+++ src/sys/net/npf/npf_conn.c	Sun Aug 10 19:09:43 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_conn.c,v 1.9 2014/07/26 16:42:03 rmind Exp $	*/
+/*	$NetBSD: npf_conn.c,v 1.10 2014/08/10 19:09:43 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2014 Mindaugas Rasiukevicius <rmind at netbsd org>
@@ -99,7 +99,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.9 2014/07/26 16:42:03 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.10 2014/08/10 19:09:43 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -809,11 +809,11 @@ npf_conn_worker(void)
 }
 
 /*
- * npf_conn_export: construct a list of connections prepared for saving.
+ * npf_conndb_export: construct a list of connections prepared for saving.
  * Note: this is expected to be an expensive operation.
  */
 int
-npf_conn_export(prop_array_t conlist)
+npf_conndb_export(prop_array_t conlist)
 {
 	npf_conn_t *con, *prev;
 
@@ -830,33 +830,12 @@ npf_conn_export(prop_array_t conlist)
 	con = npf_conndb_getlist(conn_db);
 	while (con) {
 		npf_conn_t *next = con->c_next;
-		prop_data_t d;
+		prop_dictionary_t cdict;
 
-		if ((con->c_flags & (CONN_ACTIVE|CONN_EXPIRE)) != CONN_ACTIVE)
-			goto skip;
-
-		prop_dictionary_t cdict = prop_dictionary_create();
-		prop_dictionary_set_uint32(cdict, "flags", con->c_flags);
-		prop_dictionary_set_uint32(cdict, "proto", con->c_proto);
-		/* FIXME: interface-id */
-
-		d = prop_data_create_data(&con->c_state, sizeof(npf_state_t));
-		prop_dictionary_set_and_rel(cdict, "state", d);
-
-		const uint32_t *fkey = con->c_forw_entry.ck_key;
-		d = prop_data_create_data(fkey, NPF_CONN_MAXKEYLEN);
-		prop_dictionary_set_and_rel(cdict, "forw-key", d);
-
-		const uint32_t *bkey = con->c_back_entry.ck_key;
-		d = prop_data_create_data(bkey, NPF_CONN_MAXKEYLEN);
-		prop_dictionary_set_and_rel(cdict, "back-key", d);
-
-		if (con->c_nat) {
-			npf_nat_export(cdict, con->c_nat);
+		if ((cdict = npf_conn_export(con)) != NULL) {
+			prop_array_add(conlist, cdict);
+			prop_object_release(cdict);
 		}
-		prop_array_add(conlist, cdict);
-		prop_object_release(cdict);
-skip:
 		prev = con;
 		con = next;
 	}
@@ -866,6 +845,43 @@ skip:
 }
 
 /*
+ * npf_conn_export: serialise a single connection.
+ */
+prop_dictionary_t
+npf_conn_export(const npf_conn_t *con)
+{
+	prop_dictionary_t cdict;
+	prop_data_t d;
+
+	if ((con->c_flags & (CONN_ACTIVE|CONN_EXPIRE)) != CONN_ACTIVE) {
+		return NULL;
+	}
+	cdict = prop_dictionary_create();
+	prop_dictionary_set_uint32(cdict, "flags", con->c_flags);
+	prop_dictionary_set_uint32(cdict, "proto", con->c_proto);
+	if (con->c_ifid) {
+		const char *ifname = npf_ifmap_getname(con->c_ifid);
+		prop_dictionary_set_cstring(cdict, "ifname", ifname);
+	}
+
+	d = prop_data_create_data(&con->c_state, sizeof(npf_state_t));
+	prop_dictionary_set_and_rel(cdict, "state", d);
+
+	const uint32_t *fkey = con->c_forw_entry.ck_key;
+	d = prop_data_create_data(fkey, NPF_CONN_MAXKEYLEN);
+	prop_dictionary_set_and_rel(cdict, "forw-key", d);
+
+	const uint32_t *bkey = con->c_back_entry.ck_key;
+	d = prop_data_create_data(bkey, NPF_CONN_MAXKEYLEN);
+	prop_dictionary_set_and_rel(cdict, "back-key", d);
+
+	if (con->c_nat) {
+		npf_nat_export(cdict, con->c_nat);
+	}
+	return cdict;
+}
+
+/*
  * npf_conn_import: fully reconstruct a single connection from a
  * directory and insert into the given database.
  */
@@ -876,6 +892,7 @@ npf_conn_import(npf_conndb_t *cd, prop_d
 	npf_conn_t *con;
 	npf_connkey_t *fw, *bk;
 	prop_object_t obj;
+	const char *ifname;
 	const void *d;
 
 	/* Allocate a connection and initialise it (clear first). */
@@ -888,6 +905,11 @@ npf_conn_import(npf_conndb_t *cd, prop_d
 	con->c_flags &= PFIL_ALL | CONN_ACTIVE | CONN_PASS;
 	getnanouptime(&con->c_atime);
 
+	if (prop_dictionary_get_cstring_nocopy(cdict, "ifname", &ifname) &&
+	    (con->c_ifid = npf_ifmap_register(ifname)) == 0) {
+		goto err;
+	}
+
 	obj = prop_dictionary_get(cdict, "state");
 	if ((d = prop_data_data_nocopy(obj)) == NULL ||
 	    prop_data_size(obj) != sizeof(npf_state_t)) {

Index: src/sys/net/npf/npf_conn.h
diff -u src/sys/net/npf/npf_conn.h:1.5 src/sys/net/npf/npf_conn.h:1.6
--- src/sys/net/npf/npf_conn.h:1.5	Fri Jul 25 23:21:46 2014
+++ src/sys/net/npf/npf_conn.h	Sun Aug 10 19:09:43 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_conn.h,v 1.5 2014/07/25 23:21:46 rmind Exp $	*/
+/*	$NetBSD: npf_conn.h,v 1.6 2014/08/10 19:09:43 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -115,9 +115,9 @@ int		npf_conn_setnat(const npf_cache_t *
 		    npf_nat_t *, u_int);
 npf_nat_t *	npf_conn_retnat(npf_conn_t *, const int, bool *);
 void		npf_conn_gc(npf_conndb_t *, bool, bool);
-int		npf_conn_export(prop_array_t);
 int		npf_conn_import(npf_conndb_t *, prop_dictionary_t,
 		    npf_ruleset_t *);
+prop_dictionary_t npf_conn_export(const npf_conn_t *);
 void		npf_conn_print(const npf_conn_t *);
 
 /*
@@ -137,5 +137,6 @@ void		npf_conndb_dequeue(npf_conndb_t *,
 		    npf_conn_t *);
 npf_conn_t *	npf_conndb_getlist(npf_conndb_t *);
 void		npf_conndb_settail(npf_conndb_t *, npf_conn_t *);
+int		npf_conndb_export(prop_array_t);
 
 #endif	/* _NPF_CONN_H_ */

Index: src/sys/net/npf/npf_ctl.c
diff -u src/sys/net/npf/npf_ctl.c:1.36 src/sys/net/npf/npf_ctl.c:1.37
--- src/sys/net/npf/npf_ctl.c:1.36	Fri Jul 25 23:07:21 2014
+++ src/sys/net/npf/npf_ctl.c	Sun Aug 10 19:09:43 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_ctl.c,v 1.36 2014/07/25 23:07:21 rmind Exp $	*/
+/*	$NetBSD: npf_ctl.c,v 1.37 2014/08/10 19:09:43 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.36 2014/07/25 23:07:21 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.37 2014/08/10 19:09:43 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -356,7 +356,7 @@ npf_mk_singlerule(prop_dictionary_t rldi
 	return 0;
 err:
 	npf_rule_free(rl);
-	prop_dictionary_get_int32(rldict, "priority", &p); /* XXX */
+	prop_dictionary_get_int32(rldict, "prio", &p); /* XXX */
 	prop_dictionary_set_int32(errdict, "id", p);
 	return error;
 }
@@ -545,7 +545,7 @@ npfctl_load(u_long cmd, void *data)
 	}
 
 	/* NAT policies. */
-	natlist = prop_dictionary_get(npf_dict, "translation");
+	natlist = prop_dictionary_get(npf_dict, "nat");
 	if ((nitems = prop_array_count(natlist)) > NPF_MAX_RULES) {
 		goto fail;
 	}
@@ -555,6 +555,7 @@ npfctl_load(u_long cmd, void *data)
 	if (error) {
 		goto fail;
 	}
+	prop_dictionary_remove(npf_dict, "nat");
 
 	/* Tables. */
 	tables = prop_dictionary_get(npf_dict, "tables");
@@ -652,27 +653,37 @@ int
 npfctl_save(u_long cmd, void *data)
 {
 	struct plistref *pref = data;
+	prop_array_t conlist, natlist;
 	prop_dictionary_t npf_dict;
-	prop_array_t conlist;
 	int error;
 
-	npf_config_enter();
 	conlist = prop_array_create();
+	natlist = prop_array_create();
 
-	/* Serialise the connections. */
-	error = npf_conn_export(conlist);
+	/*
+	 * Serialise the connections and NAT policies.
+	 */
+	npf_config_enter();
+	error = npf_conndb_export(conlist);
+	if (error) {
+		goto out;
+	}
+	error = npf_ruleset_export(npf_config_natset(), natlist);
 	if (error) {
-		prop_object_release(conlist);
 		goto out;
 	}
-
 	npf_dict = npf_config_dict();
-	prop_dictionary_set_bool(npf_dict, "active", npf_pfil_registered_p());
+	prop_dictionary_set_and_rel(npf_dict, "nat", natlist);
 	prop_dictionary_set_and_rel(npf_dict, "conn-list", conlist);
-
+	prop_dictionary_set_bool(npf_dict, "active", npf_pfil_registered_p());
 	error = prop_dictionary_copyout_ioctl(pref, cmd, npf_dict);
 out:
 	npf_config_exit();
+
+	if (error) {
+		prop_object_release(conlist);
+		prop_object_release(natlist);
+	}
 	return error;
 }
 

Index: src/sys/net/npf/npf_if.c
diff -u src/sys/net/npf/npf_if.c:1.3 src/sys/net/npf/npf_if.c:1.4
--- src/sys/net/npf/npf_if.c:1.3	Sat Jul 19 18:24:16 2014
+++ src/sys/net/npf/npf_if.c	Sun Aug 10 19:09:43 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_if.c,v 1.3 2014/07/19 18:24:16 rmind Exp $	*/
+/*	$NetBSD: npf_if.c,v 1.4 2014/08/10 19:09:43 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_if.c,v 1.3 2014/07/19 18:24:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_if.c,v 1.4 2014/08/10 19:09:43 rmind Exp $");
 
 #ifdef _KERNEL_OPT
 #include "pf.h"
@@ -152,7 +152,7 @@ npf_ifmap_flush(void)
 }
 
 u_int
-npf_ifmap_id(const ifnet_t *ifp)
+npf_ifmap_getid(const ifnet_t *ifp)
 {
 	const u_int i = (uintptr_t)ifp->if_pf_kif;
 
@@ -160,6 +160,19 @@ npf_ifmap_id(const ifnet_t *ifp)
 	return i;
 }
 
+const char *
+npf_ifmap_getname(const u_int id)
+{
+	const char *ifname;
+
+	KASSERT(npf_config_locked_p());
+	KASSERT(id > 0 && id <= npf_ifmap_cnt);
+
+	ifname = npf_ifmap[id - 1].n_ifname;
+	KASSERT(ifname[0] != '\0');
+	return ifname;
+}
+
 void
 npf_ifmap_attach(ifnet_t *ifp)
 {

Index: src/sys/net/npf/npf_impl.h
diff -u src/sys/net/npf/npf_impl.h:1.56 src/sys/net/npf/npf_impl.h:1.57
--- src/sys/net/npf/npf_impl.h:1.56	Wed Jul 23 01:25:34 2014
+++ src/sys/net/npf/npf_impl.h	Sun Aug 10 19:09:43 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_impl.h,v 1.56 2014/07/23 01:25:34 rmind Exp $	*/
+/*	$NetBSD: npf_impl.h,v 1.57 2014/08/10 19:09:43 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -106,7 +106,7 @@ typedef void (*npf_workfunc_t)(void);
 #define	NPF_MAX_IFMAP		64
 
 /*
- * SESSION STATE STRUCTURES
+ * CONNECTION STATE STRUCTURES
  */
 
 #define	NPF_FLOW_FORW		0
@@ -180,7 +180,8 @@ u_int		npf_ifmap_register(const char *);
 void		npf_ifmap_flush(void);
 void		npf_ifmap_attach(ifnet_t *);
 void		npf_ifmap_detach(ifnet_t *);
-u_int		npf_ifmap_id(const ifnet_t *);
+u_int		npf_ifmap_getid(const ifnet_t *);
+const char *	npf_ifmap_getname(const u_int);
 
 /* Packet filter hooks. */
 int		npf_pfil_register(bool);
@@ -258,6 +259,7 @@ void		npf_ruleset_reload(npf_ruleset_t *
 npf_rule_t *	npf_ruleset_sharepm(npf_ruleset_t *, npf_natpolicy_t *);
 npf_natpolicy_t *npf_ruleset_findnat(npf_ruleset_t *, uint64_t);
 void		npf_ruleset_freealg(npf_ruleset_t *, npf_alg_t *);
+int		npf_ruleset_export(const npf_ruleset_t *, prop_array_t);
 
 int		npf_ruleset_add(npf_ruleset_t *, const char *, npf_rule_t *);
 int		npf_ruleset_remove(npf_ruleset_t *, const char *, uint64_t);
@@ -309,6 +311,7 @@ int		npf_state_tcp_timeout(const npf_sta
 void		npf_nat_sysinit(void);
 void		npf_nat_sysfini(void);
 npf_natpolicy_t *npf_nat_newpolicy(prop_dictionary_t, npf_ruleset_t *);
+int		npf_nat_policyexport(const npf_natpolicy_t *, prop_dictionary_t);
 void		npf_nat_freepolicy(npf_natpolicy_t *);
 bool		npf_nat_cmppolicy(npf_natpolicy_t *, npf_natpolicy_t *);
 bool		npf_nat_sharepm(npf_natpolicy_t *, npf_natpolicy_t *);

Index: src/sys/net/npf/npf_mbuf.c
diff -u src/sys/net/npf/npf_mbuf.c:1.12 src/sys/net/npf/npf_mbuf.c:1.13
--- src/sys/net/npf/npf_mbuf.c:1.12	Fri Nov  8 00:38:26 2013
+++ src/sys/net/npf/npf_mbuf.c	Sun Aug 10 19:09:43 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_mbuf.c,v 1.12 2013/11/08 00:38:26 rmind Exp $	*/
+/*	$NetBSD: npf_mbuf.c,v 1.13 2014/08/10 19:09:43 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_mbuf.c,v 1.12 2013/11/08 00:38:26 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_mbuf.c,v 1.13 2014/08/10 19:09:43 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/mbuf.h>
@@ -51,7 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: npf_mbuf.c,v
 void
 nbuf_init(nbuf_t *nbuf, struct mbuf *m, const ifnet_t *ifp)
 {
-	u_int ifid = npf_ifmap_id(ifp);
+	u_int ifid = npf_ifmap_getid(ifp);
 
 	KASSERT((m->m_flags & M_PKTHDR) != 0);
 

Index: src/sys/net/npf/npf_nat.c
diff -u src/sys/net/npf/npf_nat.c:1.31 src/sys/net/npf/npf_nat.c:1.32
--- src/sys/net/npf/npf_nat.c:1.31	Wed Jul 23 01:25:34 2014
+++ src/sys/net/npf/npf_nat.c	Sun Aug 10 19:09:43 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_nat.c,v 1.31 2014/07/23 01:25:34 rmind Exp $	*/
+/*	$NetBSD: npf_nat.c,v 1.32 2014/08/10 19:09:43 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2014 Mindaugas Rasiukevicius <rmind at netbsd org>
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.31 2014/07/23 01:25:34 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.32 2014/08/10 19:09:43 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -211,19 +211,19 @@ npf_nat_newpolicy(prop_dictionary_t natd
 	LIST_INIT(&np->n_nat_list);
 
 	/* Translation IP, mask and port (if applicable). */
-	obj = prop_dictionary_get(natdict, "translation-ip");
+	obj = prop_dictionary_get(natdict, "nat-ip");
 	np->n_alen = prop_data_size(obj);
 	if (np->n_alen == 0 || np->n_alen > sizeof(npf_addr_t)) {
 		goto err;
 	}
 	memcpy(&np->n_taddr, prop_data_data_nocopy(obj), np->n_alen);
-	prop_dictionary_get_uint8(natdict, "translation-mask", &np->n_tmask);
-	prop_dictionary_get_uint16(natdict, "translation-port", &np->n_tport);
+	prop_dictionary_get_uint8(natdict, "nat-mask", &np->n_tmask);
+	prop_dictionary_get_uint16(natdict, "nat-port", &np->n_tport);
 
-	prop_dictionary_get_uint32(natdict, "translation-algo", &np->n_algo);
+	prop_dictionary_get_uint32(natdict, "nat-algo", &np->n_algo);
 	switch (np->n_algo) {
 	case NPF_ALGO_NPT66:
-		prop_dictionary_get_uint16(natdict, "npt66-adjustment",
+		prop_dictionary_get_uint16(natdict, "npt66-adj",
 		    &np->n_npt66_adj);
 		break;
 	default:
@@ -258,6 +258,30 @@ err:
 	return NULL;
 }
 
+int
+npf_nat_policyexport(const npf_natpolicy_t *np, prop_dictionary_t natdict)
+{
+	prop_data_t d;
+
+	prop_dictionary_set_int32(natdict, "type", np->n_type);
+	prop_dictionary_set_uint32(natdict, "flags", np->n_flags);
+
+	d = prop_data_create_data(&np->n_taddr, np->n_alen);
+	prop_dictionary_set_and_rel(natdict, "nat-ip", d);
+
+	prop_dictionary_set_uint8(natdict, "nat-mask", np->n_tmask);
+	prop_dictionary_set_uint16(natdict, "nat-port", np->n_tport);
+	prop_dictionary_set_uint32(natdict, "nat-algo", np->n_algo);
+
+	switch (np->n_algo) {
+	case NPF_ALGO_NPT66:
+		prop_dictionary_set_uint16(natdict, "npt66-adj", np->n_npt66_adj);
+		break;
+	}
+	prop_dictionary_set_uint64(natdict, "nat-policy", np->n_id);
+	return 0;
+}
+
 /*
  * npf_nat_freepolicy: free NAT policy and, on last reference, free portmap.
  *

Index: src/sys/net/npf/npf_ruleset.c
diff -u src/sys/net/npf/npf_ruleset.c:1.35 src/sys/net/npf/npf_ruleset.c:1.36
--- src/sys/net/npf/npf_ruleset.c:1.35	Wed Jul 23 01:25:34 2014
+++ src/sys/net/npf/npf_ruleset.c	Sun Aug 10 19:09:43 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_ruleset.c,v 1.35 2014/07/23 01:25:34 rmind Exp $	*/
+/*	$NetBSD: npf_ruleset.c,v 1.36 2014/08/10 19:09:43 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.35 2014/07/23 01:25:34 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.36 2014/08/10 19:09:43 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -83,7 +83,7 @@ struct npf_rule {
 	int			r_type;
 	bpfjit_func_t		r_jcode;
 	void *			r_code;
-	size_t			r_clen;
+	u_int			r_clen;
 
 	/* NAT policy (optional), rule procedure and subset. */
 	npf_natpolicy_t *	r_natp;
@@ -105,18 +105,18 @@ struct npf_rule {
 		npf_rule_t *		r_parent;
 	} /* C11 */;
 
-	/* Rule ID and the original dictionary. */
+	/* Rule ID, name and the optional key. */
 	uint64_t		r_id;
-	prop_dictionary_t	r_dict;
-
-	/* Rule name and all-list entry. */
 	char			r_name[NPF_RULE_MAXNAMELEN];
-	LIST_ENTRY(npf_rule)	r_aentry;
-
-	/* Key (optional). */
 	uint8_t			r_key[NPF_RULE_MAXKEYLEN];
+
+	/* All-list entry and the auxiliary info. */
+	LIST_ENTRY(npf_rule)	r_aentry;
+	prop_data_t		r_info;
 };
 
+static int	npf_rule_export(const npf_rule_t *, prop_dictionary_t);
+
 /*
  * Private attributes - must be in the NPF_RULE_PRIVMASK range.
  */
@@ -319,36 +319,43 @@ npf_ruleset_remkey(npf_ruleset_t *rlset,
 prop_dictionary_t
 npf_ruleset_list(npf_ruleset_t *rlset, const char *rname)
 {
-	prop_dictionary_t rldict;
+	prop_dictionary_t rgdict;
 	prop_array_t rules;
 	npf_rule_t *rg, *rl;
 
+	KASSERT(npf_config_locked_p());
+
 	if ((rg = npf_ruleset_lookup(rlset, rname)) == NULL) {
 		return NULL;
 	}
-	if ((rldict = prop_dictionary_create()) == NULL) {
+	if ((rgdict = prop_dictionary_create()) == NULL) {
 		return NULL;
 	}
 	if ((rules = prop_array_create()) == NULL) {
-		prop_object_release(rldict);
+		prop_object_release(rgdict);
 		return NULL;
 	}
 
 	TAILQ_FOREACH(rl, &rg->r_subset, r_entry) {
+		prop_dictionary_t rldict;
+
+		rldict = prop_dictionary_create();
 		KASSERT(rl->r_parent == rg);
-		if (rl->r_dict && !prop_array_add(rules, rl->r_dict)) {
+
+		if (npf_rule_export(rl, rldict) ||
+		    !prop_array_add(rules, rldict)) {
 			prop_object_release(rldict);
 			prop_object_release(rules);
 			return NULL;
 		}
 	}
 
-	if (!prop_dictionary_set(rldict, "rules", rules)) {
-		prop_object_release(rldict);
-		rldict = NULL;
+	if (!prop_dictionary_set(rgdict, "rules", rules)) {
+		prop_object_release(rgdict);
+		rgdict = NULL;
 	}
 	prop_object_release(rules);
-	return rldict;
+	return rgdict;
 }
 
 int
@@ -367,6 +374,35 @@ npf_ruleset_flush(npf_ruleset_t *rlset, 
 	return 0;
 }
 
+int
+npf_ruleset_export(const npf_ruleset_t *rlset, prop_array_t rules)
+{
+	const npf_rule_t *rl;
+	int error = 0;
+
+	KASSERT(npf_config_locked_p());
+
+	LIST_FOREACH(rl, &rlset->rs_all, r_aentry) {
+		const npf_natpolicy_t *natp = rl->r_natp;
+		prop_dictionary_t rldict;
+
+		rldict = prop_dictionary_create();
+		if ((error = npf_rule_export(rl, rldict)) != 0) {
+			prop_object_release(rldict);
+			break;
+		}
+		if (natp && (error = npf_nat_policyexport(natp, rldict)) != 0) {
+			prop_object_release(rldict);
+			break;
+		}
+		if (!prop_array_add(rules, rldict)) {
+			prop_object_release(rldict);
+			return ENOMEM;
+		}
+	}
+	return error;
+}
+
 void
 npf_ruleset_gc(npf_ruleset_t *rlset)
 {
@@ -538,6 +574,7 @@ npf_rule_alloc(prop_dictionary_t rldict)
 {
 	npf_rule_t *rl;
 	const char *rname;
+	prop_data_t d;
 
 	/* Allocate a rule structure. */
 	rl = kmem_zalloc(sizeof(npf_rule_t), KM_SLEEP);
@@ -552,11 +589,11 @@ npf_rule_alloc(prop_dictionary_t rldict)
 	}
 
 	/* Attributes, priority and interface ID (optional). */
-	prop_dictionary_get_uint32(rldict, "attributes", &rl->r_attr);
-	prop_dictionary_get_int32(rldict, "priority", &rl->r_priority);
+	prop_dictionary_get_uint32(rldict, "attr", &rl->r_attr);
+	prop_dictionary_get_int32(rldict, "prio", &rl->r_priority);
 	rl->r_attr &= ~NPF_RULE_PRIVMASK;
 
-	if (prop_dictionary_get_cstring_nocopy(rldict, "interface", &rname)) {
+	if (prop_dictionary_get_cstring_nocopy(rldict, "ifname", &rname)) {
 		if ((rl->r_ifid = npf_ifmap_register(rname)) == 0) {
 			kmem_free(rl, sizeof(npf_rule_t));
 			return NULL;
@@ -581,13 +618,44 @@ npf_rule_alloc(prop_dictionary_t rldict)
 		memcpy(rl->r_key, key, len);
 	}
 
-	if (NPF_DYNAMIC_RULE_P(rl->r_attr)) {
-		rl->r_dict = prop_dictionary_copy(rldict);
+	if ((d = prop_dictionary_get(rldict, "info")) != NULL) {
+		rl->r_info = prop_data_copy(d);
 	}
-
 	return rl;
 }
 
+static int
+npf_rule_export(const npf_rule_t *rl, prop_dictionary_t rldict)
+{
+	prop_data_t d;
+
+	prop_dictionary_set_uint32(rldict, "attr", rl->r_attr);
+	prop_dictionary_set_int32(rldict, "prio", rl->r_priority);
+	prop_dictionary_set_uint32(rldict, "skip-to", rl->r_skip_to);
+
+	prop_dictionary_set_int32(rldict, "code-type", rl->r_type);
+	if (rl->r_code) {
+		d = prop_data_create_data(rl->r_code, rl->r_clen);
+		prop_dictionary_set_and_rel(rldict, "code", d);
+	}
+
+	if (rl->r_ifid) {
+		const char *ifname = npf_ifmap_getname(rl->r_ifid);
+		prop_dictionary_set_cstring(rldict, "ifname", ifname);
+	}
+	prop_dictionary_set_uint64(rldict, "id", rl->r_id);
+
+	if (rl->r_name[0]) {
+		prop_dictionary_set_cstring(rldict, "name", rl->r_name);
+	}
+	if (NPF_DYNAMIC_RULE_P(rl->r_attr)) {
+		d = prop_data_create_data(rl->r_key, NPF_RULE_MAXKEYLEN);
+		prop_dictionary_set_and_rel(rldict, "key", d);
+	}
+	prop_dictionary_set(rldict, "info", rl->r_info);
+	return 0;
+}
+
 /*
  * npf_rule_setcode: assign filter code to the rule.
  *
@@ -599,13 +667,10 @@ npf_rule_setcode(npf_rule_t *rl, const i
 {
 	KASSERT(type == NPF_CODE_BPF);
 
-	if ((rl->r_jcode = npf_bpf_compile(code, size)) == NULL) {
-		rl->r_code = code;
-		rl->r_clen = size;
-	} else {
-		rl->r_code = NULL;
-	}
 	rl->r_type = type;
+	rl->r_code = code;
+	rl->r_clen = size;
+	rl->r_jcode = npf_bpf_compile(code, size);
 }
 
 /*
@@ -643,9 +708,8 @@ npf_rule_free(npf_rule_t *rl)
 		/* Free JIT code. */
 		bpf_jit_freecode(rl->r_jcode);
 	}
-	if (rl->r_dict) {
-		/* Destroy the dictionary. */
-		prop_object_release(rl->r_dict);
+	if (rl->r_info) {
+		prop_object_release(rl->r_info);
 	}
 	kmem_free(rl, sizeof(npf_rule_t));
 }
@@ -711,9 +775,8 @@ npf_rule_inspect(const npf_rule_t *rl, b
 	}
 
 	/* Any code? */
-	if (rl->r_jcode == rl->r_code) {
+	if (!rl->r_code) {
 		KASSERT(rl->r_jcode == NULL);
-		KASSERT(rl->r_code == NULL);
 		return true;
 	}
 	KASSERT(rl->r_type == NPF_CODE_BPF);

Index: src/usr.sbin/npf/npf.7
diff -u src/usr.sbin/npf/npf.7:1.1 src/usr.sbin/npf/npf.7:1.2
--- src/usr.sbin/npf/npf.7:1.1	Sat Aug  2 23:57:40 2014
+++ src/usr.sbin/npf/npf.7	Sun Aug 10 19:09:43 2014
@@ -1,4 +1,4 @@
-.\"	$NetBSD: npf.7,v 1.1 2014/08/02 23:57:40 rmind Exp $
+.\"	$NetBSD: npf.7,v 1.2 2014/08/10 19:09:43 rmind Exp $
 .\"
 .\" Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -84,7 +84,7 @@ documentation and other manual pages.
 .Sh HISTORY
 .Nm
 first appeared in
-.Nx 7.0 .
+.Nx 6.0 .
 .Sh AUTHORS
 .Nm
 was designed and implemented by

Index: src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c
diff -u src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.11 src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.12
--- src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.11	Sun Jul 20 00:37:41 2014
+++ src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c	Sun Aug 10 19:09:43 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_rule_test.c,v 1.11 2014/07/20 00:37:41 rmind Exp $	*/
+/*	$NetBSD: npf_rule_test.c,v 1.12 2014/08/10 19:09:43 rmind Exp $	*/
 
 /*
  * NPF ruleset test.
@@ -114,7 +114,7 @@ npf_blockall_rule(void)
 	prop_dictionary_t rldict;
 
 	rldict = prop_dictionary_create();
-	prop_dictionary_set_uint32(rldict, "attributes",
+	prop_dictionary_set_uint32(rldict, "attr",
 	    NPF_RULE_IN | NPF_RULE_OUT | NPF_RULE_DYNAMIC);
 	return npf_rule_alloc(rldict);
 }

Reply via email to