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