- Add NPF_DECISION_BLOCK and NPF_DECISION_PASS. Be more defensive in the trunk
authorrmind <rmind@NetBSD.org>
Mon, 20 Feb 2012 00:18:19 +0000
branchtrunk
changeset 209336 3b255ee721de
parent 209335 729fa81d7010
child 209337 12278c8bac1c
- Add NPF_DECISION_BLOCK and NPF_DECISION_PASS. Be more defensive in the packet handler. Change the default policy to block when the config is loaded and set it to pass when flush operation is performed. - Use kmem_zalloc(9) instead of kmem_alloc(9) in few places. - npf_rproc_{create,release}: use kmem_intr_{alloc,free} as the destruction of rule procedure might happen in the interrupt handler (under a very rare condition, if config reload races with the handler). - npf_session_establish: check whether layer 3 and 4 are cached. - npfctl_build_group: do not make groups as passing rules. - Remove some unecessary header inclusion.
sys/net/npf/npf.c
sys/net/npf/npf_alg.c
sys/net/npf/npf_alg_icmp.c
sys/net/npf/npf_ctl.c
sys/net/npf/npf_handler.c
sys/net/npf/npf_impl.h
sys/net/npf/npf_inet.c
sys/net/npf/npf_instr.c
sys/net/npf/npf_log.c
sys/net/npf/npf_nat.c
sys/net/npf/npf_processor.c
sys/net/npf/npf_rproc.c
sys/net/npf/npf_ruleset.c
sys/net/npf/npf_sendpkt.c
sys/net/npf/npf_session.c
sys/net/npf/npf_tableset.c
usr.sbin/npf/npfctl/npf_build.c
--- a/sys/net/npf/npf.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf.c,v 1.7 2012/01/15 00:49:48 rmind Exp $	*/
+/*	$NetBSD: npf.c,v 1.8 2012/02/20 00:18:19 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.7 2012/01/15 00:49:48 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.8 2012/02/20 00:18:19 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -70,6 +70,7 @@
 	npf_ruleset_t *		n_rules;
 	npf_tableset_t *	n_tables;
 	npf_ruleset_t *		n_nat_rules;
+	bool			n_default_pass;
 } npf_core_t;
 
 static void	npf_core_destroy(npf_core_t *);
@@ -106,7 +107,7 @@
 	rset = npf_ruleset_create();
 	tset = npf_tableset_create();
 	nset = npf_ruleset_create();
-	npf_reload(rset, tset, nset);
+	npf_reload(rset, tset, nset, true);
 	KASSERT(npf_core != NULL);
 
 #ifdef _MODULE
@@ -265,12 +266,14 @@
  * Then destroy old (unloaded) structures.
  */
 void
-npf_reload(npf_ruleset_t *rset, npf_tableset_t *tset, npf_ruleset_t *nset)
+npf_reload(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_alloc(sizeof(npf_core_t), KM_SLEEP);
+	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;
@@ -330,6 +333,13 @@
 	return rw_lock_held(&npf_lock);
 }
 
+bool
+npf_default_pass(void)
+{
+	KASSERT(rw_lock_held(&npf_lock));
+	return npf_core->n_default_pass;
+}
+
 /*
  * NPF statistics interface.
  */
--- a/sys/net/npf/npf_alg.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_alg.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_alg.c,v 1.2 2010/11/11 06:30:39 rmind Exp $	*/
+/*	$NetBSD: npf_alg.c,v 1.3 2012/02/20 00:18:19 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -36,10 +36,9 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.2 2010/11/11 06:30:39 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.3 2012/02/20 00:18:19 rmind Exp $");
 
 #include <sys/param.h>
-#include <sys/kernel.h>
 #include <sys/kmem.h>
 #include <sys/pool.h>
 #include <net/pfil.h>
@@ -83,7 +82,7 @@
 {
 	npf_alg_t *alg;
 
-	alg = kmem_alloc(sizeof(npf_alg_t), KM_SLEEP);
+	alg = kmem_zalloc(sizeof(npf_alg_t), KM_SLEEP);
 	alg->na_bptr = alg;
 	alg->na_match_func = match;
 	alg->na_out_func = out;
--- a/sys/net/npf/npf_alg_icmp.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_alg_icmp.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_alg_icmp.c,v 1.8 2011/11/29 20:05:30 rmind Exp $	*/
+/*	$NetBSD: npf_alg_icmp.c,v 1.9 2012/02/20 00:18:19 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -34,10 +34,9 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.8 2011/11/29 20:05:30 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.9 2012/02/20 00:18:19 rmind Exp $");
 
 #include <sys/param.h>
-#include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/pool.h>
 
--- a/sys/net/npf/npf_ctl.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_ctl.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: npf_ctl.c,v 1.12 2012/02/05 00:37:13 rmind Exp $	*/
+/*	$NetBSD: npf_ctl.c,v 1.13 2012/02/20 00:18:19 rmind Exp $	*/
 
 /*-
- * Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
+ * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This material is based upon work partially supported by The
@@ -37,11 +37,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.12 2012/02/05 00:37:13 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.13 2012/02/20 00:18:19 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
-#include <sys/kernel.h>
 
 #include <prop/proplib.h>
 
@@ -479,7 +478,7 @@
 	 * Finally - reload ruleset, tableset and NAT policies.
 	 * Operation will be performed as a single transaction.
 	 */
-	npf_reload(rlset, tblset, nset);
+	npf_reload(rlset, tblset, nset, flush);
 
 	/* Turn on/off session tracking accordingly. */
 	npf_session_tracking(!flush);
@@ -506,7 +505,9 @@
 
 	/* Error report. */
 	prop_dictionary_set_int32(errdict, "errno", error);
+#ifdef _KERNEL
 	prop_dictionary_copyout_ioctl(pref, cmd, errdict);
+#endif
 	prop_object_release(errdict);
 	return 0;
 }
@@ -561,7 +562,9 @@
 
 	/* Error report. */
 	prop_dictionary_set_int32(errdict, "errno", error);
+#ifdef _KERNEL
 	prop_dictionary_copyout_ioctl(pref, cmd, errdict);
+#endif
 	prop_object_release(errdict);
 	return error;
 }
--- a/sys/net/npf/npf_handler.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_handler.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: npf_handler.c,v 1.13 2012/02/06 23:30:14 rmind Exp $	*/
+/*	$NetBSD: npf_handler.c,v 1.14 2012/02/20 00:18:19 rmind Exp $	*/
 
 /*-
- * Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
+ * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This material is based upon work partially supported by The
@@ -34,10 +34,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.13 2012/02/06 23:30:14 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.14 2012/02/20 00:18:19 rmind Exp $");
 
+#include <sys/types.h>
 #include <sys/param.h>
-#include <sys/systm.h>
 
 #include <sys/mbuf.h>
 #include <sys/mutex.h>
@@ -61,8 +61,6 @@
 static struct pfil_head *	npf_ph_inet = NULL;
 static struct pfil_head *	npf_ph_inet6 = NULL;
 
-static bool			default_pass = true;
-
 int	npf_packet_handler(void *, struct mbuf **, ifnet_t *, int);
 
 /*
@@ -89,26 +87,28 @@
 	npf_ruleset_t *rlset;
 	npf_rule_t *rl;
 	npf_rproc_t *rp;
-	int retfl, error, ret;
+	int error, retfl;
+	int decision;
 
 	/*
 	 * Initialise packet information cache.
 	 * Note: it is enough to clear the info bits.
 	 */
 	npc.npc_info = 0;
+	decision = NPF_DECISION_BLOCK;
 	error = 0;
 	retfl = 0;
 	rp = NULL;
-	ret = 0;
 
 	/* Cache everything.  Determine whether it is an IP fragment. */
 	if (npf_cache_all(&npc, nbuf) & NPC_IPFRAG) {
+		int ret = -1;
+
 		/* Pass to IPv4 or IPv6 reassembly mechanism. */
 		if (npf_iscached(&npc, NPC_IP4)) {
 			struct ip *ip = nbuf_dataptr(*mp);
 			ret = ip_reass_packet(mp, ip);
-		} else {
-			KASSERT(npf_iscached(&npc, NPC_IP6));
+		} else if (npf_iscached(&npc, NPC_IP6)) {
 #ifdef INET6
 			/*
 			 * Note: frag6_input() offset is the start of the
@@ -116,11 +116,8 @@
 			 */
 			const u_int hlen = npf_cache_hlen(&npc);
 			ret = ip6_reass_packet(mp, hlen);
-#else
-			ret = -1;
 #endif
 		}
-
 		if (ret) {
 			error = EINVAL;
 			se = NULL;
@@ -137,7 +134,9 @@
 		 */
 		nbuf = (nbuf_t *)*mp;
 		npc.npc_info = 0;
-		(void)npf_cache_all(&npc, nbuf);
+
+		ret = npf_cache_all(&npc, nbuf);
+		KASSERT((ret & NPC_IPFRAG) == 0);
 	}
 
 	/* Inspect the list of sessions. */
@@ -146,8 +145,10 @@
 	/* If "passing" session found - skip the ruleset inspection. */
 	if (se && npf_session_pass(se, &rp)) {
 		npf_stats_inc(NPF_STAT_PASS_SESSION);
+		KASSERT(error == 0);
 		goto pass;
-	} else if (error) {
+	}
+	if (error) {
 		goto block;
 	}
 
@@ -156,13 +157,14 @@
 	rlset = npf_core_ruleset();
 	rl = npf_ruleset_inspect(&npc, nbuf, rlset, ifp, di, NPF_LAYER_3);
 	if (rl == NULL) {
+		bool default_pass = npf_default_pass();
 		npf_core_exit();
+
 		if (default_pass) {
 			npf_stats_inc(NPF_STAT_PASS_DEFAULT);
 			goto pass;
 		}
 		npf_stats_inc(NPF_STAT_BLOCK_DEFAULT);
-		error = ENETUNREACH;
 		goto block;
 	}
 
@@ -181,20 +183,21 @@
 	}
 	npf_stats_inc(NPF_STAT_PASS_RULESET);
 
-	/* Establish a "pass" session, if required. */
+	/*
+	 * Establish a "pass" session, if required.  Just proceed, if session
+	 * creation fails (e.g. due to unsupported protocol).
+	 *
+	 * Note: the reference on the rule procedure is transfered to the
+	 * session.  It will be released on session destruction.
+	 */
 	if ((retfl & NPF_RULE_KEEPSTATE) != 0 && !se) {
 		se = npf_session_establish(&npc, nbuf, di);
-		if (se == NULL) {
-			error = ENOMEM;
-			goto out;
+		if (se) {
+			npf_session_setpass(se, rp);
 		}
-		/*
-		 * Note: the reference to the rule procedure is transfered to
-		 * the session.  It will be released on session destruction.
-		 */
-		npf_session_setpass(se, rp);
 	}
 pass:
+	decision = NPF_DECISION_PASS;
 	KASSERT(error == 0);
 	/*
 	 * Perform NAT.
@@ -218,8 +221,8 @@
 		npf_rproc_release(rp);
 	}
 
-	/* Pass the packet, if no error. */
-	if (!error) {
+	/* Pass the packet if decided and there is no error. */
+	if (decision == NPF_DECISION_PASS && !error) {
 		/*
 		 * XXX: Disable for now, it will be set accordingly later,
 		 * for optimisations (to reduce inspection).
@@ -236,9 +239,10 @@
 	if (retfl) {
 		npf_return_block(&npc, nbuf, retfl);
 	}
-	if (error != ENETUNREACH) {
-		NPF_PRINTF(("NPF: error in handler '%d'\n", error));
+	if (error) {
 		npf_stats_inc(NPF_STAT_ERROR);
+	} else {
+		error = ENETUNREACH;
 	}
 	m_freem(*mp);
 	*mp = NULL;
@@ -267,7 +271,7 @@
 	npf_ph_if = pfil_head_get(PFIL_TYPE_IFNET, 0);
 	npf_ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
 	npf_ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
-	if (npf_ph_if == NULL || npf_ph_inet == NULL) {
+	if (npf_ph_if == NULL || npf_ph_inet == NULL || npf_ph_inet6 == NULL) {
 		npf_ph_if = NULL;
 		error = ENOENT;
 		goto fail;
--- a/sys/net/npf/npf_impl.h	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_impl.h	Mon Feb 20 00:18:19 2012 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: npf_impl.h,v 1.10 2012/02/06 23:30:14 rmind Exp $	*/
+/*	$NetBSD: npf_impl.h,v 1.11 2012/02/20 00:18:19 rmind Exp $	*/
 
 /*-
- * Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
+ * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This material is based upon work partially supported by The
@@ -91,6 +91,9 @@
  * DEFINITIONS.
  */
 
+#define	NPF_DECISION_BLOCK	0
+#define	NPF_DECISION_PASS	1
+
 typedef bool (*npf_algfunc_t)(npf_cache_t *, nbuf_t *, void *);
 
 #define	NPF_NCODE_LIMIT		1024
@@ -127,7 +130,9 @@
 npf_tableset_t *npf_core_tableset(void);
 void		npf_core_exit(void);
 bool		npf_core_locked(void);
-void		npf_reload(npf_ruleset_t *, npf_tableset_t *, npf_ruleset_t *);
+bool		npf_default_pass(void);
+void		npf_reload(npf_ruleset_t *, npf_tableset_t *,
+		    npf_ruleset_t *, bool);
 
 void		npflogattach(int);
 void		npflogdetach(void);
--- a/sys/net/npf/npf_inet.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_inet.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_inet.c,v 1.10 2011/11/29 20:05:30 rmind Exp $	*/
+/*	$NetBSD: npf_inet.c,v 1.11 2012/02/20 00:18:19 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
@@ -34,10 +34,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.10 2011/11/29 20:05:30 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.11 2012/02/20 00:18:19 rmind Exp $");
 
 #include <sys/param.h>
-#include <sys/kernel.h>
+#include <sys/types.h>
 
 #include <net/pfil.h>
 #include <net/if.h>
--- a/sys/net/npf/npf_instr.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_instr.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_instr.c,v 1.9 2012/01/15 00:49:48 rmind Exp $	*/
+/*	$NetBSD: npf_instr.c,v 1.10 2012/02/20 00:18:20 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
@@ -34,10 +34,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_instr.c,v 1.9 2012/01/15 00:49:48 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_instr.c,v 1.10 2012/02/20 00:18:20 rmind Exp $");
 
 #include <sys/param.h>
-#include <sys/kernel.h>
+#include <sys/types.h>
 
 #include <net/if.h>
 #include <net/ethertypes.h>
--- a/sys/net/npf/npf_log.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_log.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_log.c,v 1.2 2011/01/18 20:33:46 rmind Exp $	*/
+/*	$NetBSD: npf_log.c,v 1.3 2012/02/20 00:18:20 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
@@ -34,10 +34,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_log.c,v 1.2 2011/01/18 20:33:46 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_log.c,v 1.3 2012/02/20 00:18:20 rmind Exp $");
 
 #include <sys/param.h>
-#include <sys/kernel.h>
+#include <sys/types.h>
 
 #include <sys/conf.h>
 #include <sys/kmem.h>
--- a/sys/net/npf/npf_nat.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_nat.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_nat.c,v 1.10 2012/02/05 00:37:13 rmind Exp $	*/
+/*	$NetBSD: npf_nat.c,v 1.11 2012/02/20 00:18:20 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
@@ -76,10 +76,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.10 2012/02/05 00:37:13 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.11 2012/02/20 00:18:20 rmind Exp $");
 
 #include <sys/param.h>
-#include <sys/kernel.h>
+#include <sys/types.h>
 
 #include <sys/atomic.h>
 #include <sys/bitops.h>
--- a/sys/net/npf/npf_processor.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_processor.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_processor.c,v 1.9 2012/02/05 00:37:13 rmind Exp $	*/
+/*	$NetBSD: npf_processor.c,v 1.10 2012/02/20 00:18:20 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
@@ -47,17 +47,12 @@
  * N-code memory address and thus instructions should be word aligned.
  * All processing is done in 32 bit words, since both instructions (their
  * codes) and arguments use 32 bits words.
- *
- * TODO:
- * - There is some space for better a abstraction.  Duplicated opcode
- *   maintenance in npf_ncode_process() and nc_insn_check() might be avoided.
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_processor.c,v 1.9 2012/02/05 00:37:13 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_processor.c,v 1.10 2012/02/20 00:18:20 rmind Exp $");
 
 #include <sys/param.h>
-#include <sys/kernel.h>
 #include <sys/types.h>
 #include <sys/kmem.h>
 
--- a/sys/net/npf/npf_rproc.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_rproc.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_rproc.c,v 1.1 2012/02/06 23:30:14 rmind Exp $	*/
+/*	$NetBSD: npf_rproc.c,v 1.2 2012/02/20 00:18:20 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -37,11 +37,10 @@
 __KERNEL_RCSID(0, "$NetBSD");
 
 #include <sys/param.h>
-#include <sys/kernel.h>
+#include <sys/types.h>
 
 #include <sys/atomic.h>
 #include <sys/kmem.h>
-#include <sys/types.h>
 
 #include "npf_impl.h"
 
@@ -69,7 +68,7 @@
 	npf_rproc_t *rp;
 	const char *rname;
 
-	rp = kmem_zalloc(sizeof(npf_rproc_t), KM_SLEEP);
+	rp = kmem_intr_zalloc(sizeof(npf_rproc_t), KM_SLEEP);
 	rp->rp_refcnt = 1;
 
 	/* Name and flags. */
@@ -107,7 +106,7 @@
 	if (atomic_dec_uint_nv(&rp->rp_refcnt) != 0) {
 		return;
 	}
-	kmem_free(rp, sizeof(npf_rproc_t));
+	kmem_intr_free(rp, sizeof(npf_rproc_t));
 }
 
 void
--- a/sys/net/npf/npf_ruleset.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_ruleset.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_ruleset.c,v 1.10 2012/02/06 23:30:14 rmind Exp $	*/
+/*	$NetBSD: npf_ruleset.c,v 1.11 2012/02/20 00:18:20 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -34,10 +34,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.10 2012/02/06 23:30:14 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.11 2012/02/20 00:18:20 rmind Exp $");
 
 #include <sys/param.h>
-#include <sys/kernel.h>
+#include <sys/types.h>
 
 #include <sys/kmem.h>
 #include <sys/queue.h>
@@ -208,7 +208,7 @@
 	int errat __unused;
 
 	/* Allocate a rule structure. */
-	rl = kmem_alloc(sizeof(npf_rule_t), KM_SLEEP);
+	rl = kmem_zalloc(sizeof(npf_rule_t), KM_SLEEP);
 	TAILQ_INIT(&rl->r_subset.rs_queue);
 	rl->r_natp = NULL;
 
@@ -217,14 +217,14 @@
 	rl->r_ncode = nc;
 	rl->r_nc_size = nc_size;
 
-	/* Name (string, optional) */
+	/* Name (optional) */
 	if (prop_dictionary_get_cstring_nocopy(rldict, "name", &rname)) {
 		strlcpy(rl->r_name, rname, NPF_RNAME_LEN);
 	} else {
 		rl->r_name[0] = '\0';
 	}
 
-	/* Attributes, priority and interface ID. */
+	/* 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, "interface", &rl->r_ifid);
--- a/sys/net/npf/npf_sendpkt.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_sendpkt.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_sendpkt.c,v 1.8 2011/11/29 20:05:30 rmind Exp $	*/
+/*	$NetBSD: npf_sendpkt.c,v 1.9 2012/02/20 00:18:20 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
@@ -34,10 +34,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_sendpkt.c,v 1.8 2011/11/29 20:05:30 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_sendpkt.c,v 1.9 2012/02/20 00:18:20 rmind Exp $");
 
 #include <sys/param.h>
-#include <sys/kernel.h>
+#include <sys/types.h>
 
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
--- a/sys/net/npf/npf_session.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_session.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: npf_session.c,v 1.10 2011/11/29 20:05:30 rmind Exp $	*/
+/*	$NetBSD: npf_session.c,v 1.11 2012/02/20 00:18:20 rmind Exp $	*/
 
 /*-
- * Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
+ * Copyright (c) 2010-2012 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This material is based upon work partially supported by The
@@ -74,10 +74,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.10 2011/11/29 20:05:30 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.11 2012/02/20 00:18:20 rmind Exp $");
 
 #include <sys/param.h>
-#include <sys/kernel.h>
+#include <sys/types.h>
 
 #include <netinet/in.h>
 #include <netinet/tcp.h>
@@ -93,7 +93,6 @@
 #include <sys/rwlock.h>
 #include <sys/queue.h>
 #include <sys/systm.h>
-#include <sys/types.h>
 
 #include "npf_impl.h"
 
@@ -277,7 +276,7 @@
 	npf_sehash_t *stbl, *sh;
 	u_int i;
 
-	stbl = kmem_alloc(SESS_HASH_BUCKETS * sizeof(*sh), KM_SLEEP);
+	stbl = kmem_zalloc(SESS_HASH_BUCKETS * sizeof(*sh), KM_SLEEP);
 	if (stbl == NULL) {
 		return NULL;
 	}
@@ -406,7 +405,10 @@
 	npf_sentry_t *sen;
 	npf_session_t *se;
 
-	/* Layer 3 and 4 should be already cached for session tracking. */
+	/*
+	 * If layer 3 and 4 are not cached - protocol is not supported
+	 * or packet is invalid.
+	 */
 	if (!sess_tracking || !npf_iscached(npc, NPC_IP46) ||
 	    !npf_iscached(npc, NPC_LAYER4)) {
 		return NULL;
@@ -491,7 +493,7 @@
 /*
  * npf_establish_session: create a new session, insert into the global list.
  *
- * => Sessions is created with the held reference (for caller).
+ * => Session is created with the reference held for the caller.
  */
 npf_session_t *
 npf_session_establish(const npf_cache_t *npc, nbuf_t *nbuf, const int di)
@@ -504,11 +506,14 @@
 	int proto, sz;
 	bool ok;
 
-	if (!sess_tracking) {
+	/*
+	 * If layer 3 and 4 are not cached - protocol is not supported
+	 * or packet is invalid.
+	 */
+	if (!sess_tracking || !npf_iscached(npc, NPC_IP46) ||
+	    !npf_iscached(npc, NPC_LAYER4)) {
 		return NULL;
 	}
-	KASSERT(npf_iscached(npc, NPC_IP46));
-	KASSERT(npf_iscached(npc, NPC_LAYER4));
 
 	/* Allocate and initialise new state. */
 	se = pool_cache_get(sess_cache, PR_NOWAIT);
--- a/sys/net/npf/npf_tableset.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/sys/net/npf/npf_tableset.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_tableset.c,v 1.9 2012/01/15 00:49:49 rmind Exp $	*/
+/*	$NetBSD: npf_tableset.c,v 1.10 2012/02/20 00:18:20 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -39,10 +39,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.9 2012/01/15 00:49:49 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.10 2012/02/20 00:18:20 rmind Exp $");
 
 #include <sys/param.h>
-#include <sys/kernel.h>
+#include <sys/types.h>
 
 #include <sys/atomic.h>
 #include <sys/hash.h>
--- a/usr.sbin/npf/npfctl/npf_build.c	Sun Feb 19 23:19:37 2012 +0000
+++ b/usr.sbin/npf/npfctl/npf_build.c	Mon Feb 20 00:18:19 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_build.c,v 1.4 2012/02/06 00:37:52 rmind Exp $	*/
+/*	$NetBSD: npf_build.c,v 1.5 2012/02/20 00:18:19 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_build.c,v 1.4 2012/02/06 00:37:52 rmind Exp $");
+__RCSID("$NetBSD: npf_build.c,v 1.5 2012/02/20 00:18:19 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/ioctl.h>
@@ -400,9 +400,8 @@
 	} else if ((attr & attr_di) == 0) {
 		attr |= attr_di;
 	}
-	attr |= (NPF_RULE_PASS | NPF_RULE_FINAL);
 
-	rl = npf_rule_create(name, attr, if_idx);
+	rl = npf_rule_create(name, attr | NPF_RULE_FINAL, if_idx);
 	npf_rule_insert(npf_conf, NULL, rl, NPF_PRI_NEXT);
 	current_group = rl;
 }