Module Name: src Committed By: rmind Date: Sun Mar 11 18:27:59 UTC 2012
Modified Files: src/sys/net/npf: npf.c npf.h npf_ctl.c npf_handler.c npf_impl.h npf_nat.c npf_session.c Log Message: - Save active config in proplib dictionary; add GETCONF ioctl to retrieve. - Few fixes. Improve some comments. To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 src/sys/net/npf/npf.c cvs rdiff -u -r1.14 -r1.15 src/sys/net/npf/npf.h \ src/sys/net/npf/npf_handler.c cvs rdiff -u -r1.13 -r1.14 src/sys/net/npf/npf_ctl.c cvs rdiff -u -r1.11 -r1.12 src/sys/net/npf/npf_impl.h \ src/sys/net/npf/npf_nat.c src/sys/net/npf/npf_session.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/npf/npf.c diff -u src/sys/net/npf/npf.c:1.8 src/sys/net/npf/npf.c:1.9 --- src/sys/net/npf/npf.c:1.8 Mon Feb 20 00:18:19 2012 +++ src/sys/net/npf/npf.c Sun Mar 11 18:27:59 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf.c,v 1.8 2012/02/20 00:18:19 rmind Exp $ */ +/* $NetBSD: npf.c,v 1.9 2012/03/11 18:27:59 rmind Exp $ */ /*- * Copyright (c) 2009-2010 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.8 2012/02/20 00:18:19 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.9 2012/03/11 18:27:59 rmind Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -70,6 +70,7 @@ typedef struct { npf_ruleset_t * n_rules; npf_tableset_t * n_tables; npf_ruleset_t * n_nat_rules; + prop_dictionary_t n_dict; bool n_default_pass; } npf_core_t; @@ -93,6 +94,7 @@ npf_init(void) #endif npf_ruleset_t *rset, *nset; npf_tableset_t *tset; + prop_dictionary_t dict; int error = 0; rw_init(&npf_lock); @@ -104,10 +106,11 @@ npf_init(void) npflogattach(1); /* Load empty configuration. */ + dict = prop_dictionary_create(); rset = npf_ruleset_create(); tset = npf_tableset_create(); nset = npf_ruleset_create(); - npf_reload(rset, tset, nset, true); + npf_reload(dict, rset, tset, nset, true); KASSERT(npf_core != NULL); #ifdef _MODULE @@ -125,20 +128,20 @@ static int npf_fini(void) { - /* - * At first, detach device, remove pfil hooks and unload existing - * configuration, destroy structures. - */ + /* At first, detach device and remove pfil hooks. */ #ifdef _MODULE devsw_detach(NULL, &npf_cdevsw); #endif - npf_unregister_pfil(); - npf_core_destroy(npf_core); npflogdetach(); + npf_pfil_unregister(); - /* Note: order is particular. */ - npf_nat_sysfini(); + /* Flush all sessions, destroy configuration (ruleset, etc). */ + npf_session_tracking(false); + npf_core_destroy(npf_core); + + /* Finally, safe to destroy the subsystems. */ npf_alg_sysfini(); + npf_nat_sysfini(); npf_session_sysfini(); npf_tableset_sysfini(); percpu_free(npf_stats_percpu, NPF_STATS_SIZE); @@ -211,6 +214,9 @@ npf_dev_ioctl(dev_t dev, u_long cmd, voi case IOC_NPF_RELOAD: error = npfctl_reload(cmd, data); break; + case IOC_NPF_GETCONF: + error = npfctl_getconf(cmd, data); + break; case IOC_NPF_TABLE: error = npfctl_table(data); break; @@ -255,6 +261,7 @@ static void npf_core_destroy(npf_core_t *nc) { + prop_object_release(nc->n_dict); npf_ruleset_destroy(nc->n_rules); npf_ruleset_destroy(nc->n_nat_rules); npf_tableset_destroy(nc->n_tables); @@ -266,17 +273,18 @@ npf_core_destroy(npf_core_t *nc) * Then destroy old (unloaded) structures. */ void -npf_reload(npf_ruleset_t *rset, npf_tableset_t *tset, npf_ruleset_t *nset, - bool flush) +npf_reload(prop_dictionary_t dict, npf_ruleset_t *rset, + npf_tableset_t *tset, npf_ruleset_t *nset, bool flush) { npf_core_t *nc, *onc; /* Setup a new core structure. */ nc = kmem_zalloc(sizeof(npf_core_t), KM_SLEEP); - nc->n_default_pass = flush; nc->n_rules = rset; nc->n_tables = tset; nc->n_nat_rules = nset; + nc->n_dict = dict; + nc->n_default_pass = flush; /* Lock and load the core structure. */ rw_enter(&npf_lock, RW_WRITER); @@ -333,6 +341,13 @@ npf_core_locked(void) return rw_lock_held(&npf_lock); } +prop_dictionary_t +npf_core_dict(void) +{ + KASSERT(rw_lock_held(&npf_lock)); + return npf_core->n_dict; +} + bool npf_default_pass(void) { Index: src/sys/net/npf/npf.h diff -u src/sys/net/npf/npf.h:1.14 src/sys/net/npf/npf.h:1.15 --- src/sys/net/npf/npf.h:1.14 Mon Feb 6 23:30:14 2012 +++ src/sys/net/npf/npf.h Sun Mar 11 18:27:59 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf.h,v 1.14 2012/02/06 23:30:14 rmind Exp $ */ +/* $NetBSD: npf.h,v 1.15 2012/03/11 18:27:59 rmind Exp $ */ /*- * Copyright (c) 2009-2011 The NetBSD Foundation, Inc. @@ -306,5 +306,6 @@ typedef enum { #define IOC_NPF_SESSIONS_SAVE _IOR('N', 105, struct plistref) #define IOC_NPF_SESSIONS_LOAD _IOW('N', 106, struct plistref) #define IOC_NPF_UPDATE_RULE _IOWR('N', 107, struct plistref) +#define IOC_NPF_GETCONF _IOR('N', 108, struct plistref) #endif /* _NPF_NET_H_ */ Index: src/sys/net/npf/npf_handler.c diff -u src/sys/net/npf/npf_handler.c:1.14 src/sys/net/npf/npf_handler.c:1.15 --- src/sys/net/npf/npf_handler.c:1.14 Mon Feb 20 00:18:19 2012 +++ src/sys/net/npf/npf_handler.c Sun Mar 11 18:27:59 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_handler.c,v 1.14 2012/02/20 00:18:19 rmind Exp $ */ +/* $NetBSD: npf_handler.c,v 1.15 2012/03/11 18:27:59 rmind Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.14 2012/02/20 00:18:19 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.15 2012/03/11 18:27:59 rmind Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -251,10 +251,10 @@ out: } /* - * npf_register_pfil: register pfil(9) hooks. + * npf_pfil_register: register pfil(9) hooks. */ int -npf_register_pfil(void) +npf_pfil_register(void) { int error; @@ -298,10 +298,10 @@ fail: } /* - * npf_unregister: unregister pfil(9) hooks. + * npf_pfil_unregister: unregister pfil(9) hooks. */ void -npf_unregister_pfil(void) +npf_pfil_unregister(void) { mutex_enter(softnet_lock); @@ -321,3 +321,9 @@ npf_unregister_pfil(void) KERNEL_UNLOCK_ONE(NULL); mutex_exit(softnet_lock); } + +bool +npf_pfil_registered_p(void) +{ + return npf_ph_if != NULL; +} Index: src/sys/net/npf/npf_ctl.c diff -u src/sys/net/npf/npf_ctl.c:1.13 src/sys/net/npf/npf_ctl.c:1.14 --- src/sys/net/npf/npf_ctl.c:1.13 Mon Feb 20 00:18:19 2012 +++ src/sys/net/npf/npf_ctl.c Sun Mar 11 18:27:59 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_ctl.c,v 1.13 2012/02/20 00:18:19 rmind Exp $ */ +/* $NetBSD: npf_ctl.c,v 1.14 2012/03/11 18:27:59 rmind Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.13 2012/02/20 00:18:19 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.14 2012/03/11 18:27:59 rmind Exp $"); #include <sys/param.h> #include <sys/conf.h> @@ -66,10 +66,10 @@ npfctl_switch(void *data) if (onoff) { /* Enable: add pfil hooks. */ - error = npf_register_pfil(); + error = npf_pfil_register(); } else { /* Disable: remove pfil hooks. */ - npf_unregister_pfil(); + npf_pfil_unregister(); error = 0; } return error; @@ -425,7 +425,7 @@ int npfctl_reload(u_long cmd, void *data) { struct plistref *pref = data; - prop_dictionary_t dict, errdict; + prop_dictionary_t npf_dict, errdict; prop_array_t natlist, tables, rprocs, rules; npf_tableset_t *tblset = NULL; npf_ruleset_t *rlset = NULL; @@ -435,12 +435,12 @@ npfctl_reload(u_long cmd, void *data) /* Retrieve the dictionary. */ #ifdef _KERNEL - error = prop_dictionary_copyin_ioctl(pref, cmd, &dict); + error = prop_dictionary_copyin_ioctl(pref, cmd, &npf_dict); if (error) return error; #else - dict = prop_dictionary_internalize_from_file(data); - if (dict == NULL) + npf_dict = prop_dictionary_internalize_from_file(data); + if (npf_dict == NULL) return EINVAL; #endif /* Dictionary for error reporting. */ @@ -448,7 +448,7 @@ npfctl_reload(u_long cmd, void *data) /* NAT policies. */ nset = npf_ruleset_create(); - natlist = prop_dictionary_get(dict, "translation"); + natlist = prop_dictionary_get(npf_dict, "translation"); error = npf_mk_natlist(nset, natlist, errdict); if (error) { goto fail; @@ -456,7 +456,7 @@ npfctl_reload(u_long cmd, void *data) /* Tables. */ tblset = npf_tableset_create(); - tables = prop_dictionary_get(dict, "tables"); + tables = prop_dictionary_get(npf_dict, "tables"); error = npf_mk_tables(tblset, tables, errdict); if (error) { goto fail; @@ -464,21 +464,21 @@ npfctl_reload(u_long cmd, void *data) /* Rules and rule procedures. */ rlset = npf_ruleset_create(); - rprocs = prop_dictionary_get(dict, "rprocs"); - rules = prop_dictionary_get(dict, "rules"); + rprocs = prop_dictionary_get(npf_dict, "rprocs"); + rules = prop_dictionary_get(npf_dict, "rules"); error = npf_mk_rules(rlset, rules, rprocs, errdict); if (error) { goto fail; } flush = false; - prop_dictionary_get_bool(dict, "flush", &flush); + prop_dictionary_get_bool(npf_dict, "flush", &flush); /* * Finally - reload ruleset, tableset and NAT policies. * Operation will be performed as a single transaction. */ - npf_reload(rlset, tblset, nset, flush); + npf_reload(npf_dict, rlset, tblset, nset, flush); /* Turn on/off session tracking accordingly. */ npf_session_tracking(!flush); @@ -501,7 +501,9 @@ fail: if (tblset) { npf_tableset_destroy(tblset); } - prop_object_release(dict); + if (error) { + prop_object_release(npf_dict); + } /* Error report. */ prop_dictionary_set_int32(errdict, "errno", error); @@ -512,6 +514,22 @@ fail: return 0; } +int +npfctl_getconf(u_long cmd, void *data) +{ + struct plistref *pref = data; + prop_dictionary_t npf_dict; + int error; + + npf_core_enter(); + npf_dict = npf_core_dict(); + prop_dictionary_set_bool(npf_dict, "active", npf_pfil_registered_p()); + error = prop_dictionary_copyout_ioctl(pref, cmd, npf_dict); + npf_core_exit(); + + return error; +} + /* * npfctl_update_rule: reload a specific rule identified by the name. */ Index: src/sys/net/npf/npf_impl.h diff -u src/sys/net/npf/npf_impl.h:1.11 src/sys/net/npf/npf_impl.h:1.12 --- src/sys/net/npf/npf_impl.h:1.11 Mon Feb 20 00:18:19 2012 +++ src/sys/net/npf/npf_impl.h Sun Mar 11 18:27:59 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_impl.h,v 1.11 2012/02/20 00:18:19 rmind Exp $ */ +/* $NetBSD: npf_impl.h,v 1.12 2012/03/11 18:27:59 rmind Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -131,13 +131,16 @@ npf_tableset_t *npf_core_tableset(void); void npf_core_exit(void); bool npf_core_locked(void); bool npf_default_pass(void); -void npf_reload(npf_ruleset_t *, npf_tableset_t *, - npf_ruleset_t *, bool); +prop_dictionary_t npf_core_dict(void); + +void npf_reload(prop_dictionary_t, npf_ruleset_t *, + npf_tableset_t *, npf_ruleset_t *, bool); void npflogattach(int); void npflogdetach(void); int npfctl_switch(void *); int npfctl_reload(u_long, void *); +int npfctl_getconf(u_long, void *); int npfctl_sessions_save(u_long, void *); int npfctl_sessions_load(u_long, void *); int npfctl_update_rule(u_long, void *); @@ -147,8 +150,9 @@ void npf_stats_inc(npf_stats_t); void npf_stats_dec(npf_stats_t); /* Packet filter hooks. */ -int npf_register_pfil(void); -void npf_unregister_pfil(void); +int npf_pfil_register(void); +void npf_pfil_unregister(void); +bool npf_pfil_registered_p(void); void npf_log_packet(npf_cache_t *, nbuf_t *, int); /* Protocol helpers. */ Index: src/sys/net/npf/npf_nat.c diff -u src/sys/net/npf/npf_nat.c:1.11 src/sys/net/npf/npf_nat.c:1.12 --- src/sys/net/npf/npf_nat.c:1.11 Mon Feb 20 00:18:20 2012 +++ src/sys/net/npf/npf_nat.c Sun Mar 11 18:27:59 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_nat.c,v 1.11 2012/02/20 00:18:20 rmind Exp $ */ +/* $NetBSD: npf_nat.c,v 1.12 2012/03/11 18:27:59 rmind Exp $ */ /*- * Copyright (c) 2010-2011 The NetBSD Foundation, Inc. @@ -76,7 +76,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.11 2012/02/20 00:18:20 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.12 2012/03/11 18:27:59 rmind Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -112,7 +112,9 @@ typedef struct { #define PORTMAP_MEM_SIZE \ (sizeof(npf_portmap_t) + (PORTMAP_SIZE * sizeof(uint32_t))) -/* NAT policy structure. */ +/* + * NAT policy structure. + */ struct npf_natpolicy { LIST_HEAD(, npf_nat) n_nat_list; kmutex_t n_lock; @@ -128,7 +130,9 @@ struct npf_natpolicy { #define NPF_NP_CMP_START offsetof(npf_natpolicy_t, n_type) #define NPF_NP_CMP_SIZE (sizeof(npf_natpolicy_t) - NPF_NP_CMP_START) -/* NAT translation entry for a session. */ +/* + * NAT translation entry for a session. + */ struct npf_nat { /* Association (list entry and a link pointer) with NAT policy. */ LIST_ENTRY(npf_nat) nt_entry; @@ -302,7 +306,7 @@ npf_nat_sharepm(npf_natpolicy_t *np, npf /* If NAT policy has an old port map - drop the reference. */ mpm = mnp->n_portmap; if (mpm) { - /* Note: in such case, we must not be a last reference. */ + /* Note: at this point we cannot hold a last reference. */ KASSERT(mpm->p_refcnt > 1); mpm->p_refcnt--; } @@ -440,10 +444,6 @@ npf_nat_create(npf_cache_t *npc, npf_nat nt->nt_session = NULL; nt->nt_alg = NULL; - mutex_enter(&np->n_lock); - LIST_INSERT_HEAD(&np->n_nat_list, nt, nt_entry); - mutex_exit(&np->n_lock); - /* Save the original address which may be rewritten. */ if (np->n_type == NPF_NATOUT) { /* Source (local) for Outbound NAT. */ @@ -461,8 +461,9 @@ npf_nat_create(npf_cache_t *npc, npf_nat (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) { nt->nt_oport = 0; nt->nt_tport = 0; - return nt; + goto out; } + /* Save the relevant TCP/UDP port. */ if (proto == IPPROTO_TCP) { struct tcphdr *th = &npc->npc_l4.tcp; @@ -480,6 +481,10 @@ npf_nat_create(npf_cache_t *npc, npf_nat } else { nt->nt_tport = np->n_tport; } +out: + mutex_enter(&np->n_lock); + LIST_INSERT_HEAD(&np->n_nat_list, nt, nt_entry); + mutex_exit(&np->n_lock); return nt; } @@ -526,6 +531,7 @@ npf_nat_translate(npf_cache_t *npc, nbuf if (!npf_rwrcksum(npc, nbuf, n_ptr, di, addr, port)) { return EINVAL; } + /* * Address translation: rewrite source/destination address, depending * on direction (PFIL_OUT - for source, PFIL_IN - for destination). @@ -537,6 +543,7 @@ npf_nat_translate(npf_cache_t *npc, nbuf /* Done. */ return 0; } + switch (npf_cache_ipproto(npc)) { case IPPROTO_TCP: case IPPROTO_UDP: Index: src/sys/net/npf/npf_session.c diff -u src/sys/net/npf/npf_session.c:1.11 src/sys/net/npf/npf_session.c:1.12 --- src/sys/net/npf/npf_session.c:1.11 Mon Feb 20 00:18:20 2012 +++ src/sys/net/npf/npf_session.c Sun Mar 11 18:27:59 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_session.c,v 1.11 2012/02/20 00:18:20 rmind Exp $ */ +/* $NetBSD: npf_session.c,v 1.12 2012/03/11 18:27:59 rmind Exp $ */ /*- * Copyright (c) 2010-2012 The NetBSD Foundation, Inc. @@ -49,7 +49,7 @@ * indicate that the packet of the backwards stream should be passed * without inspection of the ruleset. Another purpose is to associate * NAT with a connection (which implies connection tracking). Such - * sessions are created according to the NAT policies and they have a 1:1 + * sessions are created according to the NAT policies and they have a * relationship with NAT translation structure via npf_session_t::s_nat. * A single session can serve both purposes, which is a common case. * @@ -61,9 +61,9 @@ * depending on session properties (e.g. last activity time, protocol) * removes session entries and expires the actual sessions. * - * Each session has a reference count, which is taken on lookup and - * needs to be released by the caller. Reference guarantees that - * session will not be destroyed, although it might be expired. + * Each session has a reference count. Reference is acquired on lookup + * and should be released by the caller. Reference guarantees that the + * session will not be destroyed, although it may be expired. * * External session identifiers * @@ -74,7 +74,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.11 2012/02/20 00:18:20 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.12 2012/03/11 18:27:59 rmind Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -196,7 +196,7 @@ npf_session_sysfini(void) { /* Disable tracking, flush all sessions. */ - sess_tracking_stop(); + npf_session_tracking(false); KASSERT(sess_tracking == 0); KASSERT(sess_gc_lwp == NULL);