Module Name:    src
Committed By:   martin
Date:           Mon Dec  1 13:05:26 UTC 2014

Modified Files:
        src/sys/net/npf [netbsd-7]: npf_conf.c npf_conn.c npf_conn.h npf_impl.h
            npf_nat.c npf_ruleset.c

Log Message:
Pull up following revision(s) (requested by rmind in ticket #280):
        sys/net/npf/npf_ruleset.c: revision 1.40
        sys/net/npf/npf_nat.c: revision 1.36
        sys/net/npf/npf_nat.c: revision 1.37
        sys/net/npf/npf_conn.h: revision 1.7
        sys/net/npf/npf_conf.c: revision 1.9
        sys/net/npf/npf_ruleset.c: revision 1.39
        sys/net/npf/npf_conn.c: revision 1.13
        sys/net/npf/npf_impl.h: revision 1.60
NPF:
- npf_nat_import: take the port only if using the portmap.
- Sprinkle some comments and asserts.
- npf_config_load: if loading the connections, do not perform any actice
  NAT policy take over or or portmap sharing - just replace them all.
- npf_config_fini: flush with the empty connection database.
- npf_nat_import: fix the stat counter.


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.8.2.1 src/sys/net/npf/npf_conf.c
cvs rdiff -u -r1.10.2.1 -r1.10.2.2 src/sys/net/npf/npf_conn.c
cvs rdiff -u -r1.6 -r1.6.2.1 src/sys/net/npf/npf_conn.h
cvs rdiff -u -r1.58.2.1 -r1.58.2.2 src/sys/net/npf/npf_impl.h
cvs rdiff -u -r1.32.2.2 -r1.32.2.3 src/sys/net/npf/npf_nat.c
cvs rdiff -u -r1.37.2.1 -r1.37.2.2 src/sys/net/npf/npf_ruleset.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_conf.c
diff -u src/sys/net/npf/npf_conf.c:1.8 src/sys/net/npf/npf_conf.c:1.8.2.1
--- src/sys/net/npf/npf_conf.c:1.8	Mon Aug 11 01:54:12 2014
+++ src/sys/net/npf/npf_conf.c	Mon Dec  1 13:05:26 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_conf.c,v 1.8 2014/08/11 01:54:12 rmind Exp $	*/
+/*	$NetBSD: npf_conf.c,v 1.8.2.1 2014/12/01 13:05:26 martin 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.8 2014/08/11 01:54:12 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.8.2.1 2014/12/01 13:05:26 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -105,11 +105,13 @@ npf_config_destroy(npf_config_t *nc)
 void
 npf_config_fini(void)
 {
+	npf_conndb_t *cd = npf_conndb_create();
+
 	/* Flush the connections. */
 	mutex_enter(&npf_config_lock);
 	npf_conn_tracking(false);
 	pserialize_perform(npf_config_psz);
-	npf_conn_load(NULL, false);
+	npf_conn_load(cd, false);
 	npf_ifmap_flush();
 	mutex_exit(&npf_config_lock);
 
@@ -127,6 +129,7 @@ npf_config_load(npf_ruleset_t *rset, npf
     npf_ruleset_t *nset, npf_rprocset_t *rpset,
     npf_conndb_t *conns, bool flush)
 {
+	const bool load = conns != NULL;
 	npf_config_t *nc, *onc;
 
 	nc = kmem_zalloc(sizeof(npf_config_t), KM_SLEEP);
@@ -143,9 +146,9 @@ npf_config_load(npf_ruleset_t *rset, npf
 	 */
 	mutex_enter(&npf_config_lock);
 	if ((onc = npf_config) != NULL) {
-		npf_ruleset_reload(rset, onc->n_rules);
+		npf_ruleset_reload(rset, onc->n_rules, load);
 		npf_tableset_reload(tset, onc->n_tables);
-		npf_ruleset_reload(nset, onc->n_nat_rules);
+		npf_ruleset_reload(nset, onc->n_nat_rules, load);
 	}
 
 	/*

Index: src/sys/net/npf/npf_conn.c
diff -u src/sys/net/npf/npf_conn.c:1.10.2.1 src/sys/net/npf/npf_conn.c:1.10.2.2
--- src/sys/net/npf/npf_conn.c:1.10.2.1	Fri Aug 29 11:14:14 2014
+++ src/sys/net/npf/npf_conn.c	Mon Dec  1 13:05:26 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_conn.c,v 1.10.2.1 2014/08/29 11:14:14 martin Exp $	*/
+/*	$NetBSD: npf_conn.c,v 1.10.2.2 2014/12/01 13:05:26 martin 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.10.2.1 2014/08/29 11:14:14 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.10.2.2 2014/12/01 13:05:26 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -680,11 +680,11 @@ npf_conn_release(npf_conn_t *con)
 }
 
 /*
- * npf_conn_retnat: return associated NAT data entry and indicate
+ * npf_conn_getnat: return associated NAT data entry and indicate
  * whether it is a "forwards" or "backwards" stream.
  */
 npf_nat_t *
-npf_conn_retnat(npf_conn_t *con, const int di, bool *forw)
+npf_conn_getnat(npf_conn_t *con, const int di, bool *forw)
 {
 	KASSERT(con->c_refcnt > 0);
 	*forw = (con->c_flags & PFIL_ALL) == di;

Index: src/sys/net/npf/npf_conn.h
diff -u src/sys/net/npf/npf_conn.h:1.6 src/sys/net/npf/npf_conn.h:1.6.2.1
--- src/sys/net/npf/npf_conn.h:1.6	Sun Aug 10 19:09:43 2014
+++ src/sys/net/npf/npf_conn.h	Mon Dec  1 13:05:26 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_conn.h,v 1.6 2014/08/10 19:09:43 rmind Exp $	*/
+/*	$NetBSD: npf_conn.h,v 1.6.2.1 2014/12/01 13:05:26 martin Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -113,7 +113,7 @@ bool		npf_conn_pass(const npf_conn_t *, 
 void		npf_conn_setpass(npf_conn_t *, npf_rproc_t *);
 int		npf_conn_setnat(const npf_cache_t *, npf_conn_t *,
 		    npf_nat_t *, u_int);
-npf_nat_t *	npf_conn_retnat(npf_conn_t *, const int, bool *);
+npf_nat_t *	npf_conn_getnat(npf_conn_t *, const int, bool *);
 void		npf_conn_gc(npf_conndb_t *, bool, bool);
 int		npf_conn_import(npf_conndb_t *, prop_dictionary_t,
 		    npf_ruleset_t *);

Index: src/sys/net/npf/npf_impl.h
diff -u src/sys/net/npf/npf_impl.h:1.58.2.1 src/sys/net/npf/npf_impl.h:1.58.2.2
--- src/sys/net/npf/npf_impl.h:1.58.2.1	Fri Aug 29 11:14:14 2014
+++ src/sys/net/npf/npf_impl.h	Mon Dec  1 13:05:26 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_impl.h,v 1.58.2.1 2014/08/29 11:14:14 martin Exp $	*/
+/*	$NetBSD: npf_impl.h,v 1.58.2.2 2014/12/01 13:05:26 martin Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -254,7 +254,7 @@ int		npf_table_flush(npf_table_t *);
 npf_ruleset_t *	npf_ruleset_create(size_t);
 void		npf_ruleset_destroy(npf_ruleset_t *);
 void		npf_ruleset_insert(npf_ruleset_t *, npf_rule_t *);
-void		npf_ruleset_reload(npf_ruleset_t *, npf_ruleset_t *);
+void		npf_ruleset_reload(npf_ruleset_t *, npf_ruleset_t *, bool);
 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 *);

Index: src/sys/net/npf/npf_nat.c
diff -u src/sys/net/npf/npf_nat.c:1.32.2.2 src/sys/net/npf/npf_nat.c:1.32.2.3
--- src/sys/net/npf/npf_nat.c:1.32.2.2	Mon Dec  1 09:02:26 2014
+++ src/sys/net/npf/npf_nat.c	Mon Dec  1 13:05:26 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_nat.c,v 1.32.2.2 2014/12/01 09:02:26 martin Exp $	*/
+/*	$NetBSD: npf_nat.c,v 1.32.2.3 2014/12/01 13:05:26 martin 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.32.2.2 2014/12/01 09:02:26 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.32.2.3 2014/12/01 13:05:26 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -252,6 +252,7 @@ npf_nat_newpolicy(prop_dictionary_t natd
 		np->n_portmap = pm;
 	} else {
 		KASSERT(np->n_portmap != NULL);
+		KASSERT(np->n_portmap->p_refcnt > 0);
 	}
 	return np;
 err:
@@ -363,6 +364,8 @@ npf_nat_sharepm(npf_natpolicy_t *np, npf
 	npf_portmap_t *pm, *mpm;
 
 	KASSERT(np && mnp && np != mnp);
+	KASSERT(LIST_EMPTY(&mnp->n_nat_list));
+	KASSERT(mnp->n_refcnt == 0);
 
 	/* Using port map and having equal translation address? */
 	if ((np->n_flags & mnp->n_flags & NPF_NAT_PORTMAP) == 0) {
@@ -417,6 +420,9 @@ npf_nat_getport(npf_natpolicy_t *np)
 	u_int n = PORTMAP_SIZE, idx, bit;
 	uint32_t map, nmap;
 
+	KASSERT((np->n_flags & NPF_NAT_PORTMAP) != 0);
+	KASSERT(pm->p_refcnt > 0);
+
 	idx = cprng_fast32() % PORTMAP_SIZE;
 	for (;;) {
 		KASSERT(idx < PORTMAP_SIZE);
@@ -450,6 +456,9 @@ npf_nat_takeport(npf_natpolicy_t *np, in
 	uint32_t map, nmap;
 	u_int idx, bit;
 
+	KASSERT((np->n_flags & NPF_NAT_PORTMAP) != 0);
+	KASSERT(pm->p_refcnt > 0);
+
 	port = ntohs(port) - PORTMAP_FIRST;
 	idx = port >> PORTMAP_SHIFT;
 	bit = port & PORTMAP_MASK;
@@ -474,6 +483,9 @@ npf_nat_putport(npf_natpolicy_t *np, in_
 	uint32_t map, nmap;
 	u_int idx, bit;
 
+	KASSERT((np->n_flags & NPF_NAT_PORTMAP) != 0);
+	KASSERT(pm->p_refcnt > 0);
+
 	port = ntohs(port) - PORTMAP_FIRST;
 	idx = port >> PORTMAP_SHIFT;
 	bit = port & PORTMAP_MASK;
@@ -686,7 +698,7 @@ npf_do_nat(npf_cache_t *npc, npf_conn_t 
 	 * Determines whether the stream is "forwards" or "backwards".
 	 * Note: no need to lock, since reference on connection is held.
 	 */
-	if (con && (nt = npf_conn_retnat(con, di, &forw)) != NULL) {
+	if (con && (nt = npf_conn_getnat(con, di, &forw)) != NULL) {
 		np = nt->nt_natpolicy;
 		goto translate;
 	}
@@ -874,10 +886,12 @@ npf_nat_import(prop_dictionary_t natdict
 	prop_dictionary_get_uint16(natdict, "tport", &nt->nt_tport);
 
 	/* Take a specific port from port-map. */
-	if (!npf_nat_takeport(np, nt->nt_tport)) {
+	if ((np->n_flags & NPF_NAT_PORTMAP) != 0 && nt->nt_tport &
+	    !npf_nat_takeport(np, nt->nt_tport)) {
 		pool_cache_put(nat_cache, nt);
 		return NULL;
 	}
+	npf_stats_inc(NPF_STAT_NAT_CREATE);
 
 	/*
 	 * Associate, take a reference and insert.  Unlocked since

Index: src/sys/net/npf/npf_ruleset.c
diff -u src/sys/net/npf/npf_ruleset.c:1.37.2.1 src/sys/net/npf/npf_ruleset.c:1.37.2.2
--- src/sys/net/npf/npf_ruleset.c:1.37.2.1	Mon Dec  1 09:02:26 2014
+++ src/sys/net/npf/npf_ruleset.c	Mon Dec  1 13:05:26 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_ruleset.c,v 1.37.2.1 2014/12/01 09:02:26 martin Exp $	*/
+/*	$NetBSD: npf_ruleset.c,v 1.37.2.2 2014/12/01 13:05:26 martin 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.37.2.1 2014/12/01 09:02:26 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.37.2.2 2014/12/01 13:05:26 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -216,6 +216,9 @@ npf_ruleset_lookup(npf_ruleset_t *rlset,
 	return rl;
 }
 
+/*
+ * npf_ruleset_add: insert dynamic rule into the (active) ruleset.
+ */
 int
 npf_ruleset_add(npf_ruleset_t *rlset, const char *rname, npf_rule_t *rl)
 {
@@ -273,6 +276,9 @@ npf_ruleset_add(npf_ruleset_t *rlset, co
 	return 0;
 }
 
+/*
+ * npf_ruleset_remove: remove the dynamic rule given the rule ID.
+ */
 int
 npf_ruleset_remove(npf_ruleset_t *rlset, const char *rname, uint64_t id)
 {
@@ -294,6 +300,9 @@ npf_ruleset_remove(npf_ruleset_t *rlset,
 	return ENOENT;
 }
 
+/*
+ * npf_ruleset_remkey: remove the dynamic rule given the rule key.
+ */
 int
 npf_ruleset_remkey(npf_ruleset_t *rlset, const char *rname,
     const void *key, size_t len)
@@ -320,6 +329,9 @@ npf_ruleset_remkey(npf_ruleset_t *rlset,
 	return ENOENT;
 }
 
+/*
+ * npf_ruleset_list: serialise and return the dynamic rules.
+ */
 prop_dictionary_t
 npf_ruleset_list(npf_ruleset_t *rlset, const char *rname)
 {
@@ -363,6 +375,10 @@ npf_ruleset_list(npf_ruleset_t *rlset, c
 	return rgdict;
 }
 
+/*
+ * npf_ruleset_flush: flush the dynamic rules in the ruleset by inserting
+ * them into the G/C list.
+ */
 int
 npf_ruleset_flush(npf_ruleset_t *rlset, const char *rname)
 {
@@ -379,6 +395,23 @@ npf_ruleset_flush(npf_ruleset_t *rlset, 
 	return 0;
 }
 
+/*
+ * npf_ruleset_gc: destroy the rules in G/C list.
+ */
+void
+npf_ruleset_gc(npf_ruleset_t *rlset)
+{
+	npf_rule_t *rl;
+
+	while ((rl = LIST_FIRST(&rlset->rs_gc)) != NULL) {
+		LIST_REMOVE(rl, r_aentry);
+		npf_rule_free(rl);
+	}
+}
+
+/*
+ * npf_ruleset_export: serialise and return the static rules.
+ */
 int
 npf_ruleset_export(const npf_ruleset_t *rlset, prop_array_t rules)
 {
@@ -409,25 +442,14 @@ npf_ruleset_export(const npf_ruleset_t *
 	return error;
 }
 
-void
-npf_ruleset_gc(npf_ruleset_t *rlset)
-{
-	npf_rule_t *rl;
-
-	while ((rl = LIST_FIRST(&rlset->rs_gc)) != NULL) {
-		LIST_REMOVE(rl, r_aentry);
-		npf_rule_free(rl);
-	}
-}
-
 /*
  * npf_ruleset_reload: prepare the new ruleset by scanning the active
- * ruleset and 1) sharing the dynamic rules 2) sharing NAT policies.
+ * ruleset and: 1) sharing the dynamic rules 2) sharing NAT policies.
  *
  * => The active (old) ruleset should be exclusively locked.
  */
 void
-npf_ruleset_reload(npf_ruleset_t *newset, npf_ruleset_t *oldset)
+npf_ruleset_reload(npf_ruleset_t *newset, npf_ruleset_t *oldset, bool load)
 {
 	npf_rule_t *rg, *rl;
 	uint64_t nid = 0;
@@ -464,6 +486,14 @@ npf_ruleset_reload(npf_ruleset_t *newset
 	}
 
 	/*
+	 * If performing the load of connections then NAT policies may
+	 * already have translated connections associated with them and
+	 * we should not share or inherit anything.
+	 */
+	if (load)
+		return;
+
+	/*
 	 * Scan all rules in the new ruleset and share NAT policies.
 	 * Also, assign a unique ID for each policy here.
 	 */
@@ -515,13 +545,22 @@ npf_ruleset_reload(npf_ruleset_t *newset
 	newset->rs_idcnt = oldset->rs_idcnt;
 }
 
+/*
+ * npf_ruleset_sharepm: attempt to share the active NAT portmap.
+ */
 npf_rule_t *
 npf_ruleset_sharepm(npf_ruleset_t *rlset, npf_natpolicy_t *mnp)
 {
 	npf_natpolicy_t *np;
 	npf_rule_t *rl;
 
-	/* Find a matching NAT policy in the old ruleset; skip the self. */
+	/*
+	 * Scan the NAT policies in the ruleset and match with the
+	 * given policy based on the translation IP address.  If they
+	 * match - adjust the given NAT policy to use the active NAT
+	 * portmap.  In such case the reference on the old portmap is
+	 * dropped and acquired on the active one.
+	 */
 	LIST_FOREACH(rl, &rlset->rs_all, r_aentry) {
 		np = rl->r_natp;
 		if (np == NULL || np == mnp)

Reply via email to