NPF: add nbuf_t * into npf_cache_t and remove unnecessary carrying by argument. trunk
authorrmind <rmind@NetBSD.org>
Sun, 20 Jul 2014 00:37:41 +0000
branchtrunk
changeset 228590 8200d1f89dab
parent 228589 925bd0928f69
child 228591 27c528dc4a65
NPF: add nbuf_t * into npf_cache_t and remove unnecessary carrying by argument.
sys/net/npf/npf.h
sys/net/npf/npf_alg.c
sys/net/npf/npf_alg_icmp.c
sys/net/npf/npf_bpf.c
sys/net/npf/npf_conn.c
sys/net/npf/npf_conn.h
sys/net/npf/npf_ext_log.c
sys/net/npf/npf_ext_normalize.c
sys/net/npf/npf_ext_rndblock.c
sys/net/npf/npf_handler.c
sys/net/npf/npf_impl.h
sys/net/npf/npf_inet.c
sys/net/npf/npf_nat.c
sys/net/npf/npf_rproc.c
sys/net/npf/npf_ruleset.c
sys/net/npf/npf_sendpkt.c
sys/net/npf/npf_state.c
sys/net/npf/npf_state_tcp.c
usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c
usr.sbin/npf/npftest/libnpftest/npf_nat_test.c
usr.sbin/npf/npftest/libnpftest/npf_rule_test.c
usr.sbin/npf/npftest/libnpftest/npf_state_test.c
--- a/sys/net/npf/npf.h	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf.h	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf.h,v 1.43 2014/07/19 18:24:16 rmind Exp $	*/
+/*	$NetBSD: npf.h,v 1.44 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -78,9 +78,6 @@
 #define	NPF_EXT_MODULE(name, req)	\
     MODULE(MODULE_CLASS_MISC, name, (sizeof(req) - 1) ? ("npf," req) : "npf")
 
-/*
- * Packet information cache.
- */
 #include <net/if.h>
 #include <netinet/ip.h>
 #include <netinet/ip6.h>
@@ -89,6 +86,43 @@
 #include <netinet/ip_icmp.h>
 #include <netinet/icmp6.h>
 
+/*
+ * Network buffer interface.
+ */
+
+#define	NBUF_DATAREF_RESET	0x01
+
+typedef struct {
+	struct mbuf *	nb_mbuf0;
+	struct mbuf *	nb_mbuf;
+	void *		nb_nptr;
+	const ifnet_t *	nb_ifp;
+	unsigned	nb_ifid;
+	int		nb_flags;
+} nbuf_t;
+
+void		nbuf_init(nbuf_t *, struct mbuf *, const ifnet_t *);
+void		nbuf_reset(nbuf_t *);
+struct mbuf *	nbuf_head_mbuf(nbuf_t *);
+
+bool		nbuf_flag_p(const nbuf_t *, int);
+void		nbuf_unset_flag(nbuf_t *, int);
+
+void *		nbuf_dataptr(nbuf_t *);
+size_t		nbuf_offset(const nbuf_t *);
+void *		nbuf_advance(nbuf_t *, size_t, size_t);
+
+void *		nbuf_ensure_contig(nbuf_t *, size_t);
+void *		nbuf_ensure_writable(nbuf_t *, size_t);
+
+bool		nbuf_cksum_barrier(nbuf_t *, int);
+int		nbuf_add_tag(nbuf_t *, uint32_t, uint32_t);
+int		nbuf_find_tag(nbuf_t *, uint32_t, void **);
+
+/*
+ * Packet information cache.
+ */
+
 #define	NPC_IP4		0x01	/* Indicates IPv4 header. */
 #define	NPC_IP6		0x02	/* Indicates IPv6 header. */
 #define	NPC_IPFRAG	0x04	/* IPv4/IPv6 fragment. */
@@ -104,8 +138,9 @@
 #define	NPC_IP46	(NPC_IP4|NPC_IP6)
 
 typedef struct {
-	/* Information flags. */
+	/* Information flags and the nbuf. */
 	uint32_t		npc_info;
+	nbuf_t *		npc_nbuf;
 
 	/*
 	 * Pointers to the IP source and destination addresses,
@@ -144,39 +179,6 @@
 #define	NPF_DST		1
 
 /*
- * Network buffer interface.
- */
-
-#define	NBUF_DATAREF_RESET	0x01
-
-typedef struct {
-	struct mbuf *	nb_mbuf0;
-	struct mbuf *	nb_mbuf;
-	void *		nb_nptr;
-	const ifnet_t *	nb_ifp;
-	unsigned	nb_ifid;
-	int		nb_flags;
-} nbuf_t;
-
-void		nbuf_init(nbuf_t *, struct mbuf *, const ifnet_t *);
-void		nbuf_reset(nbuf_t *);
-struct mbuf *	nbuf_head_mbuf(nbuf_t *);
-
-bool		nbuf_flag_p(const nbuf_t *, int);
-void		nbuf_unset_flag(nbuf_t *, int);
-
-void *		nbuf_dataptr(nbuf_t *);
-size_t		nbuf_offset(const nbuf_t *);
-void *		nbuf_advance(nbuf_t *, size_t, size_t);
-
-void *		nbuf_ensure_contig(nbuf_t *, size_t);
-void *		nbuf_ensure_writable(nbuf_t *, size_t);
-
-bool		nbuf_cksum_barrier(nbuf_t *, int);
-int		nbuf_add_tag(nbuf_t *, uint32_t, uint32_t);
-int		nbuf_find_tag(nbuf_t *, uint32_t, void **);
-
-/*
  * NPF extensions and rule procedure interface.
  */
 
@@ -190,7 +192,7 @@
 	void *		ctx;
 	int		(*ctor)(npf_rproc_t *, prop_dictionary_t);
 	void		(*dtor)(npf_rproc_t *, void *);
-	bool		(*proc)(npf_cache_t *, nbuf_t *, void *, int *);
+	bool		(*proc)(npf_cache_t *, void *, int *);
 } npf_ext_ops_t;
 
 void *		npf_ext_register(const char *, const npf_ext_ops_t *);
--- a/sys/net/npf/npf_alg.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_alg.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_alg.c,v 1.13 2014/07/19 18:24:16 rmind Exp $	*/
+/*	$NetBSD: npf_alg.c,v 1.14 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.13 2014/07/19 18:24:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.14 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -189,7 +189,7 @@
  * npf_alg_match: call ALG matching inspectors, determine if any ALG matches.
  */
 bool
-npf_alg_match(npf_cache_t *npc, nbuf_t *nbuf, npf_nat_t *nt, int di)
+npf_alg_match(npf_cache_t *npc, npf_nat_t *nt, int di)
 {
 	bool match = false;
 	int s;
@@ -198,7 +198,7 @@
 	for (u_int i = 0; i < alg_count; i++) {
 		const npfa_funcs_t *f = &alg_funcs[i];
 
-		if (f->match && f->match(npc, nbuf, nt, di)) {
+		if (f->match && f->match(npc, nt, di)) {
 			match = true;
 			break;
 		}
@@ -211,7 +211,7 @@
  * npf_alg_exec: execute ALG hooks for translation.
  */
 void
-npf_alg_exec(npf_cache_t *npc, nbuf_t *nbuf, npf_nat_t *nt, bool forw)
+npf_alg_exec(npf_cache_t *npc, npf_nat_t *nt, bool forw)
 {
 	int s;
 
@@ -220,14 +220,14 @@
 		const npfa_funcs_t *f = &alg_funcs[i];
 
 		if (f->translate) {
-			f->translate(npc, nbuf, nt, forw);
+			f->translate(npc, nt, forw);
 		}
 	}
 	pserialize_read_exit(s);
 }
 
 npf_conn_t *
-npf_alg_conn(npf_cache_t *npc, nbuf_t *nbuf, int di)
+npf_alg_conn(npf_cache_t *npc, int di)
 {
 	npf_conn_t *con = NULL;
 	int s;
@@ -238,7 +238,7 @@
 
 		if (!f->inspect)
 			continue;
-		if ((con = f->inspect(npc, nbuf, di)) != NULL)
+		if ((con = f->inspect(npc, di)) != NULL)
 			break;
 	}
 	pserialize_read_exit(s);
--- a/sys/net/npf/npf_alg_icmp.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_alg_icmp.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_alg_icmp.c,v 1.22 2014/07/19 18:24:16 rmind Exp $	*/
+/*	$NetBSD: npf_alg_icmp.c,v 1.23 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.22 2014/07/19 18:24:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.23 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/module.h>
@@ -71,7 +71,7 @@
  * our ALG with the NAT entry.
  */
 static bool
-npfa_icmp_match(npf_cache_t *npc, nbuf_t *nbuf, npf_nat_t *nt, int di)
+npfa_icmp_match(npf_cache_t *npc, npf_nat_t *nt, int di)
 {
 	const int proto = npc->npc_proto;
 	const struct ip *ip = npc->npc_ip.v4;
@@ -121,8 +121,9 @@
  */
 
 static bool
-npfa_icmp4_inspect(const int type, npf_cache_t *npc, nbuf_t *nbuf)
+npfa_icmp4_inspect(const int type, npf_cache_t *npc)
 {
+	nbuf_t *nbuf = npc->npc_nbuf;
 	u_int offby;
 
 	/* Per RFC 792. */
@@ -139,7 +140,7 @@
 		if (!nbuf_advance(nbuf, offsetof(struct icmp, icmp_ip), 0)) {
 			return false;
 		}
-		return (npf_cache_all(npc, nbuf) & NPC_LAYER4) != 0;
+		return (npf_cache_all(npc) & NPC_LAYER4) != 0;
 
 	case ICMP_ECHOREPLY:
 	case ICMP_ECHO:
@@ -161,8 +162,9 @@
 }
 
 static bool
-npfa_icmp6_inspect(const int type, npf_cache_t *npc, nbuf_t *nbuf)
+npfa_icmp6_inspect(const int type, npf_cache_t *npc)
 {
+	nbuf_t *nbuf = npc->npc_nbuf;
 	u_int offby;
 
 	/* Per RFC 4443. */
@@ -178,7 +180,7 @@
 		if (!nbuf_advance(nbuf, sizeof(struct icmp6_hdr), 0)) {
 			return false;
 		}
-		return (npf_cache_all(npc, nbuf) & NPC_LAYER4) != 0;
+		return (npf_cache_all(npc) & NPC_LAYER4) != 0;
 
 	case ICMP6_ECHO_REQUEST:
 	case ICMP6_ECHO_REPLY:
@@ -201,8 +203,9 @@
  * => Returns true if "enpc" is filled.
  */
 static bool
-npfa_icmp_inspect(npf_cache_t *npc, nbuf_t *nbuf, npf_cache_t *enpc)
+npfa_icmp_inspect(npf_cache_t *npc, npf_cache_t *enpc)
 {
+	nbuf_t *nbuf = npc->npc_nbuf;
 	bool ret;
 
 	KASSERT(npf_iscached(npc, NPC_IP46));
@@ -213,6 +216,7 @@
 	if (!nbuf_advance(nbuf, npc->npc_hlen, 0)) {
 		return false;
 	}
+	enpc->npc_nbuf = nbuf;
 	enpc->npc_info = 0;
 
 	/*
@@ -221,10 +225,10 @@
 	 */
 	if (npf_iscached(npc, NPC_IP4)) {
 		const struct icmp *ic = npc->npc_l4.icmp;
-		ret = npfa_icmp4_inspect(ic->icmp_type, enpc, nbuf);
+		ret = npfa_icmp4_inspect(ic->icmp_type, enpc);
 	} else if (npf_iscached(npc, NPC_IP6)) {
 		const struct icmp6_hdr *ic6 = npc->npc_l4.icmp6;
-		ret = npfa_icmp6_inspect(ic6->icmp6_type, enpc, nbuf);
+		ret = npfa_icmp6_inspect(ic6->icmp6_type, enpc);
 	} else {
 		ret = false;
 	}
@@ -243,14 +247,14 @@
 }
 
 static npf_conn_t *
-npfa_icmp_conn(npf_cache_t *npc, nbuf_t *nbuf, int di)
+npfa_icmp_conn(npf_cache_t *npc, int di)
 {
 	npf_cache_t enpc;
 
 	/* Inspect ICMP packet for an embedded packet. */
 	if (!npf_iscached(npc, NPC_ICMP))
 		return NULL;
-	if (!npfa_icmp_inspect(npc, nbuf, &enpc))
+	if (!npfa_icmp_inspect(npc, &enpc))
 		return NULL;
 
 	/*
@@ -279,14 +283,14 @@
 		break;
 	case IPPROTO_ICMP: {
 		const struct icmp *ic = enpc.npc_l4.icmp;
-		ret = npfa_icmp4_inspect(ic->icmp_type, &enpc, nbuf);
+		ret = npfa_icmp4_inspect(ic->icmp_type, &enpc);
 		if (!ret || !npf_iscached(&enpc, NPC_ICMP_ID))
 			return false;
 		break;
 	}
 	case IPPROTO_ICMPV6: {
 		const struct icmp6_hdr *ic6 = enpc.npc_l4.icmp6;
-		ret = npfa_icmp6_inspect(ic6->icmp6_type, &enpc, nbuf);
+		ret = npfa_icmp6_inspect(ic6->icmp6_type, &enpc);
 		if (!ret || !npf_iscached(&enpc, NPC_ICMP_ID))
 			return false;
 		break;
@@ -296,7 +300,7 @@
 	}
 
 	/* Lookup a connection using the embedded packet. */
-	return npf_conn_lookup(&enpc, nbuf, di, &forw);
+	return npf_conn_lookup(&enpc, di, &forw);
 }
 
 /*
@@ -304,14 +308,14 @@
  * which is embedded in ICMP packet.  Note: backwards stream only.
  */
 static bool
-npfa_icmp_nat(npf_cache_t *npc, nbuf_t *nbuf, npf_nat_t *nt, bool forw)
+npfa_icmp_nat(npf_cache_t *npc, npf_nat_t *nt, bool forw)
 {
 	const u_int which = NPF_SRC;
 	npf_cache_t enpc;
 
 	if (forw || !npf_iscached(npc, NPC_ICMP))
 		return false;
-	if (!npfa_icmp_inspect(npc, nbuf, &enpc))
+	if (!npfa_icmp_inspect(npc, &enpc))
 		return false;
 
 	KASSERT(npf_iscached(&enpc, NPC_IP46));
--- a/sys/net/npf/npf_bpf.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_bpf.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_bpf.c,v 1.10 2014/06/30 00:01:23 rmind Exp $	*/
+/*	$NetBSD: npf_bpf.c,v 1.11 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_bpf.c,v 1.10 2014/06/30 00:01:23 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_bpf.c,v 1.11 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -78,9 +78,9 @@
 }
 
 void
-npf_bpf_prepare(npf_cache_t *npc, nbuf_t *nbuf, bpf_args_t *args, uint32_t *M)
+npf_bpf_prepare(npf_cache_t *npc, bpf_args_t *args, uint32_t *M)
 {
-	const struct mbuf *mbuf = nbuf_head_mbuf(nbuf);
+	const struct mbuf *mbuf = nbuf_head_mbuf(npc->npc_nbuf);
 	const size_t pktlen = m_length(mbuf);
 
 	/* Prepare the arguments for the BPF programs. */
--- a/sys/net/npf/npf_conn.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_conn.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_conn.c,v 1.3 2014/07/19 21:22:58 christos Exp $	*/
+/*	$NetBSD: npf_conn.c,v 1.4 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2014 Mindaugas Rasiukevicius <rmind at netbsd org>
@@ -100,7 +100,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.3 2014/07/19 21:22:58 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.4 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -358,9 +358,9 @@
  * => If found, we will hold a reference for the caller.
  */
 npf_conn_t *
-npf_conn_lookup(const npf_cache_t *npc, const nbuf_t *nbuf,
-    const int di, bool *forw)
+npf_conn_lookup(const npf_cache_t *npc, const int di, bool *forw)
 {
+	const nbuf_t *nbuf = npc->npc_nbuf;
 	npf_conn_t *con;
 	npf_connkey_t key;
 	u_int flags, cifid;
@@ -411,8 +411,9 @@
  * => If found, we will hold a reference for the caller.
  */
 npf_conn_t *
-npf_conn_inspect(npf_cache_t *npc, nbuf_t *nbuf, const int di, int *error)
+npf_conn_inspect(npf_cache_t *npc, const int di, int *error)
 {
+	nbuf_t *nbuf = npc->npc_nbuf;
 	npf_conn_t *con;
 	bool forw, ok;
 
@@ -422,7 +423,7 @@
 	}
 
 	/* Query ALG which may lookup connection for us. */
-	if ((con = npf_alg_conn(npc, nbuf, di)) != NULL) {
+	if ((con = npf_alg_conn(npc, di)) != NULL) {
 		/* Note: reference is held. */
 		return con;
 	}
@@ -433,13 +434,13 @@
 	KASSERT(!nbuf_flag_p(nbuf, NBUF_DATAREF_RESET));
 
 	/* Main lookup of the connection. */
-	if ((con = npf_conn_lookup(npc, nbuf, di, &forw)) == NULL) {
+	if ((con = npf_conn_lookup(npc, di, &forw)) == NULL) {
 		return NULL;
 	}
 
 	/* Inspect the protocol data and handle state changes. */
 	mutex_enter(&con->c_lock);
-	ok = npf_state_inspect(npc, nbuf, &con->c_state, forw);
+	ok = npf_state_inspect(npc, &con->c_state, forw);
 	mutex_exit(&con->c_lock);
 
 	if (__predict_false(!ok)) {
@@ -458,8 +459,9 @@
  * => Connection will be activated on the first reference release.
  */
 npf_conn_t *
-npf_conn_establish(npf_cache_t *npc, nbuf_t *nbuf, int di, bool per_if)
+npf_conn_establish(npf_cache_t *npc, int di, bool per_if)
 {
+	const nbuf_t *nbuf = npc->npc_nbuf;
 	npf_conn_t *con;
 
 	KASSERT(!nbuf_flag_p(nbuf, NBUF_DATAREF_RESET));
@@ -484,7 +486,7 @@
 	con->c_nat = NULL;
 
 	/* Initialize protocol state. */
-	if (!npf_state_init(npc, nbuf, &con->c_state)) {
+	if (!npf_state_init(npc, &con->c_state)) {
 		goto err;
 	}
 
--- a/sys/net/npf/npf_conn.h	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_conn.h	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_conn.h,v 1.1 2014/07/19 19:14:21 rmind Exp $	*/
+/*	$NetBSD: npf_conn.h,v 1.2 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -100,10 +100,9 @@
 void		npf_conn_tracking(bool);
 
 bool		npf_conn_conkey(const npf_cache_t *, npf_connkey_t *, bool);
-npf_conn_t *	npf_conn_lookup(const npf_cache_t *, const nbuf_t *,
-		    const int, bool *);
-npf_conn_t *	npf_conn_inspect(npf_cache_t *, nbuf_t *, const int, int *);
-npf_conn_t *	npf_conn_establish(npf_cache_t *, nbuf_t *, int, bool);
+npf_conn_t *	npf_conn_lookup(const npf_cache_t *, const int, bool *);
+npf_conn_t *	npf_conn_inspect(npf_cache_t *, const int, int *);
+npf_conn_t *	npf_conn_establish(npf_cache_t *, int, bool);
 void		npf_conn_release(npf_conn_t *);
 void		npf_conn_expire(npf_conn_t *);
 bool		npf_conn_pass(const npf_conn_t *, npf_rproc_t **);
--- a/sys/net/npf/npf_ext_log.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_ext_log.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_ext_log.c,v 1.7 2014/05/19 18:45:51 jakllsch Exp $	*/
+/*	$NetBSD: npf_ext_log.c,v 1.8 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010-2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ext_log.c,v 1.7 2014/05/19 18:45:51 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ext_log.c,v 1.8 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/module.h>
@@ -79,9 +79,9 @@
 }
 
 static bool
-npf_log(npf_cache_t *npc, nbuf_t *nbuf, void *meta, int *decision)
+npf_log(npf_cache_t *npc, void *meta, int *decision)
 {
-	struct mbuf *m = nbuf_head_mbuf(nbuf);
+	struct mbuf *m = nbuf_head_mbuf(npc->npc_nbuf);
 	const npf_ext_log_t *log = meta;
 	ifnet_t *ifp;
 	int family;
--- a/sys/net/npf/npf_ext_normalize.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_ext_normalize.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_ext_normalize.c,v 1.2 2014/05/19 18:45:51 jakllsch Exp $	*/
+/*	$NetBSD: npf_ext_normalize.c,v 1.3 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ext_normalize.c,v 1.2 2014/05/19 18:45:51 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ext_normalize.c,v 1.3 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/module.h>
@@ -141,7 +141,7 @@
  * npf_normalize: the main routine to normalize IPv4 and/or TCP headers.
  */
 static bool
-npf_normalize(npf_cache_t *npc, nbuf_t *nbuf, void *params, int *decision)
+npf_normalize(npf_cache_t *npc, void *params, int *decision)
 {
 	npf_normalize_t *np = params;
 	struct tcphdr *th = npc->npc_l4.tcp;
@@ -168,7 +168,7 @@
 		return true;
 	}
 	mss = 0;
-	if (!npf_fetch_tcpopts(npc, nbuf, &mss, &wscale)) {
+	if (!npf_fetch_tcpopts(npc, &mss, &wscale)) {
 		return true;
 	}
 	if (ntohs(mss) <= maxmss) {
@@ -178,7 +178,7 @@
 	maxmss = htons(maxmss);
 
 	/* Store new MSS, calculate TCP checksum and update it. */
-	if (npf_fetch_tcpopts(npc, nbuf, &maxmss, &wscale)) {
+	if (npf_fetch_tcpopts(npc, &maxmss, &wscale)) {
 		cksum = npf_fixup16_cksum(th->th_sum, mss, maxmss);
 		th->th_sum = cksum;
 	}
--- a/sys/net/npf/npf_ext_rndblock.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_ext_rndblock.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_ext_rndblock.c,v 1.4 2014/05/19 18:45:51 jakllsch Exp $	*/
+/*	$NetBSD: npf_ext_rndblock.c,v 1.5 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ext_rndblock.c,v 1.4 2014/05/19 18:45:51 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ext_rndblock.c,v 1.5 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/cprng.h>
@@ -97,7 +97,7 @@
  * npf_ext_rndblock: main routine implementing the extension functionality.
  */
 static bool
-npf_ext_rndblock(npf_cache_t *npc, nbuf_t *nbuf, void *meta, int *decision)
+npf_ext_rndblock(npf_cache_t *npc, void *meta, int *decision)
 {
 	npf_ext_rndblock_t *rndblock = meta;
 	unsigned long c;
--- a/sys/net/npf/npf_handler.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_handler.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_handler.c,v 1.31 2014/07/19 18:24:16 rmind Exp $	*/
+/*	$NetBSD: npf_handler.c,v 1.32 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.31 2014/07/19 18:24:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.32 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -87,8 +87,9 @@
 }
 
 static int
-npf_reassembly(npf_cache_t *npc, nbuf_t *nbuf, struct mbuf **mp)
+npf_reassembly(npf_cache_t *npc, struct mbuf **mp)
 {
+	nbuf_t *nbuf = npc->npc_nbuf;
 	int error = EINVAL;
 
 	/* Reset the mbuf as it may have changed. */
@@ -125,7 +126,7 @@
 	nbuf_init(nbuf, *mp, nbuf->nb_ifp);
 	npc->npc_info = 0;
 
-	if (npf_cache_all(npc, nbuf) & NPC_IPFRAG) {
+	if (npf_cache_all(npc) & NPC_IPFRAG) {
 		return EINVAL;
 	}
 	npf_stats_inc(NPF_STAT_REASSEMBLY);
@@ -154,18 +155,20 @@
 	 */
 	KASSERT(ifp != NULL);
 	nbuf_init(&nbuf, *mp, ifp);
+	npc.npc_nbuf = &nbuf;
 	npc.npc_info = 0;
+
 	decision = NPF_DECISION_BLOCK;
 	error = 0;
 	retfl = 0;
 	rp = NULL;
 
 	/* Cache everything.  Determine whether it is an IP fragment. */
-	if (npf_cache_all(&npc, &nbuf) & NPC_IPFRAG) {
+	if (__predict_false(npf_cache_all(&npc) & NPC_IPFRAG)) {
 		/*
 		 * Pass to IPv4 or IPv6 reassembly mechanism.
 		 */
-		error = npf_reassembly(&npc, &nbuf, mp);
+		error = npf_reassembly(&npc, mp);
 		if (error) {
 			con = NULL;
 			goto out;
@@ -177,7 +180,7 @@
 	}
 
 	/* Inspect the list of connections (if found, acquires a reference). */
-	con = npf_conn_inspect(&npc, &nbuf, di, &error);
+	con = npf_conn_inspect(&npc, di, &error);
 
 	/* If "passing" connection found - skip the ruleset inspection. */
 	if (con && npf_conn_pass(con, &rp)) {
@@ -185,7 +188,7 @@
 		KASSERT(error == 0);
 		goto pass;
 	}
-	if (error) {
+	if (__predict_false(error)) {
 		if (error == ENETUNREACH)
 			goto block;
 		goto out;
@@ -195,8 +198,8 @@
 	int slock = npf_config_read_enter();
 	npf_ruleset_t *rlset = npf_config_ruleset();
 
-	rl = npf_ruleset_inspect(&npc, &nbuf, rlset, di, NPF_LAYER_3);
-	if (rl == NULL) {
+	rl = npf_ruleset_inspect(&npc, rlset, di, NPF_LAYER_3);
+	if (__predict_false(rl == NULL)) {
 		const bool pass = npf_default_pass();
 		npf_config_read_exit(slock);
 
@@ -230,7 +233,7 @@
 	 * connection creation fails (e.g. due to unsupported protocol).
 	 */
 	if ((retfl & NPF_RULE_STATEFUL) != 0 && !con) {
-		con = npf_conn_establish(&npc, &nbuf, di,
+		con = npf_conn_establish(&npc, di,
 		    (retfl & NPF_RULE_MULTIENDS) == 0);
 		if (con) {
 			/*
@@ -247,13 +250,13 @@
 	/*
 	 * Perform NAT.
 	 */
-	error = npf_do_nat(&npc, con, &nbuf, di);
+	error = npf_do_nat(&npc, con, di);
 block:
 	/*
 	 * Execute the rule procedure, if any is associated.
 	 * It may reverse the decision from pass to block.
 	 */
-	if (rp && !npf_rproc_run(&npc, &nbuf, rp, &decision)) {
+	if (rp && !npf_rproc_run(&npc, rp, &decision)) {
 		if (con) {
 			npf_conn_release(con);
 		}
@@ -292,7 +295,7 @@
 	 * Depending on the flags and protocol, return TCP reset (RST) or
 	 * ICMP destination unreachable.
 	 */
-	if (retfl && npf_return_block(&npc, &nbuf, retfl)) {
+	if (retfl && npf_return_block(&npc, retfl)) {
 		*mp = NULL;
 	}
 
--- a/sys/net/npf/npf_impl.h	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_impl.h	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_impl.h,v 1.54 2014/07/19 18:24:16 rmind Exp $	*/
+/*	$NetBSD: npf_impl.h,v 1.55 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -129,9 +129,9 @@
  */
 
 typedef struct {
-	bool		(*match)(npf_cache_t *, nbuf_t *, npf_nat_t *, int);
-	bool		(*translate)(npf_cache_t *, nbuf_t *, npf_nat_t *, bool);
-	npf_conn_t *	(*inspect)(npf_cache_t *, nbuf_t *, int);
+	bool		(*match)(npf_cache_t *, npf_nat_t *, int);
+	bool		(*translate)(npf_cache_t *, npf_nat_t *, bool);
+	npf_conn_t *	(*inspect)(npf_cache_t *, int);
 } npfa_funcs_t;
 
 /*
@@ -189,8 +189,8 @@
 int		npf_packet_handler(void *, struct mbuf **, ifnet_t *, int);
 
 /* Protocol helpers. */
-int		npf_cache_all(npf_cache_t *, nbuf_t *);
-void		npf_recache(npf_cache_t *, nbuf_t *);
+int		npf_cache_all(npf_cache_t *);
+void		npf_recache(npf_cache_t *);
 
 bool		npf_rwrip(const npf_cache_t *, u_int, const npf_addr_t *);
 bool		npf_rwrport(const npf_cache_t *, u_int, const in_port_t);
@@ -213,13 +213,13 @@
 
 int		npf_tcpsaw(const npf_cache_t *, tcp_seq *, tcp_seq *,
 		    uint32_t *);
-bool		npf_fetch_tcpopts(npf_cache_t *, nbuf_t *, uint16_t *, int *);
-bool		npf_return_block(npf_cache_t *, nbuf_t *, const int);
+bool		npf_fetch_tcpopts(npf_cache_t *, uint16_t *, int *);
+bool		npf_return_block(npf_cache_t *, const int);
 
 /* BPF interface. */
 void		npf_bpf_sysinit(void);
 void		npf_bpf_sysfini(void);
-void		npf_bpf_prepare(npf_cache_t *, nbuf_t *, bpf_args_t *, uint32_t *);
+void		npf_bpf_prepare(npf_cache_t *, bpf_args_t *, uint32_t *);
 int		npf_bpf_filter(bpf_args_t *, const void *, bpfjit_func_t);
 void *		npf_bpf_compile(void *, size_t);
 bool		npf_bpf_validate(const void *, size_t);
@@ -267,8 +267,8 @@
 int		npf_ruleset_flush(npf_ruleset_t *, const char *);
 void		npf_ruleset_gc(npf_ruleset_t *);
 
-npf_rule_t *	npf_ruleset_inspect(npf_cache_t *, nbuf_t *,
-		    const npf_ruleset_t *, const int, const int);
+npf_rule_t *	npf_ruleset_inspect(npf_cache_t *, const npf_ruleset_t *,
+		    const int, const int);
 int		npf_rule_conclude(const npf_rule_t *, int *);
 
 /* Rule interface. */
@@ -294,16 +294,15 @@
 npf_rproc_t *	npf_rproc_create(prop_dictionary_t);
 void		npf_rproc_acquire(npf_rproc_t *);
 void		npf_rproc_release(npf_rproc_t *);
-bool		npf_rproc_run(npf_cache_t *, nbuf_t *, npf_rproc_t *, int *);
+bool		npf_rproc_run(npf_cache_t *, npf_rproc_t *, int *);
 
 /* State handling. */
-bool		npf_state_init(npf_cache_t *, nbuf_t *, npf_state_t *);
-bool		npf_state_inspect(npf_cache_t *, nbuf_t *, npf_state_t *,
-		    const bool);
+bool		npf_state_init(npf_cache_t *, npf_state_t *);
+bool		npf_state_inspect(npf_cache_t *, npf_state_t *, const bool);
 int		npf_state_etime(const npf_state_t *, const int);
 void		npf_state_destroy(npf_state_t *);
 
-bool		npf_state_tcp(npf_cache_t *, nbuf_t *, npf_state_t *, int);
+bool		npf_state_tcp(npf_cache_t *, npf_state_t *, int);
 int		npf_state_tcp_timeout(const npf_state_t *);
 
 /* NAT. */
@@ -315,7 +314,7 @@
 bool		npf_nat_sharepm(npf_natpolicy_t *, npf_natpolicy_t *);
 void		npf_nat_freealg(npf_natpolicy_t *, npf_alg_t *);
 
-int		npf_do_nat(npf_cache_t *, npf_conn_t *, nbuf_t *, const int);
+int		npf_do_nat(npf_cache_t *, npf_conn_t *, const int);
 void		npf_nat_destroy(npf_nat_t *);
 void		npf_nat_getorig(npf_nat_t *, npf_addr_t **, in_port_t *);
 void		npf_nat_gettrans(npf_nat_t *, npf_addr_t **, in_port_t *);
@@ -330,9 +329,9 @@
 npf_alg_t *	npf_alg_register(const char *, const npfa_funcs_t *);
 int		npf_alg_unregister(npf_alg_t *);
 npf_alg_t *	npf_alg_construct(const char *);
-bool		npf_alg_match(npf_cache_t *, nbuf_t *, npf_nat_t *, int);
-void		npf_alg_exec(npf_cache_t *, nbuf_t *, npf_nat_t *, bool);
-npf_conn_t *	npf_alg_conn(npf_cache_t *, nbuf_t *, int);
+bool		npf_alg_match(npf_cache_t *, npf_nat_t *, int);
+void		npf_alg_exec(npf_cache_t *, npf_nat_t *, bool);
+npf_conn_t *	npf_alg_conn(npf_cache_t *, int);
 
 /* Debugging routines. */
 const char *	npf_addr_dump(const npf_addr_t *, int);
--- a/sys/net/npf/npf_inet.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_inet.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_inet.c,v 1.31 2014/07/19 18:24:16 rmind Exp $	*/
+/*	$NetBSD: npf_inet.c,v 1.32 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.31 2014/07/19 18:24:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.32 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -221,8 +221,9 @@
  * npf_fetch_tcpopts: parse and return TCP options.
  */
 bool
-npf_fetch_tcpopts(npf_cache_t *npc, nbuf_t *nbuf, uint16_t *mss, int *wscale)
+npf_fetch_tcpopts(npf_cache_t *npc, uint16_t *mss, int *wscale)
 {
+	nbuf_t *nbuf = npc->npc_nbuf;
 	const struct tcphdr *th = npc->npc_l4.tcp;
 	int topts_len, step;
 	void *nptr;
@@ -306,7 +307,7 @@
 	ok = true;
 done:
 	if (nbuf_flag_p(nbuf, NBUF_DATAREF_RESET)) {
-		npf_recache(npc, nbuf);
+		npf_recache(npc);
 	}
 	return ok;
 }
@@ -433,8 +434,9 @@
  * => nbuf offset shall be set accordingly.
  */
 int
-npf_cache_all(npf_cache_t *npc, nbuf_t *nbuf)
+npf_cache_all(npf_cache_t *npc)
 {
+	nbuf_t *nbuf = npc->npc_nbuf;
 	int flags, l4flags;
 	u_int hlen;
 
@@ -500,14 +502,16 @@
 }
 
 void
-npf_recache(npf_cache_t *npc, nbuf_t *nbuf)
+npf_recache(npf_cache_t *npc)
 {
+	nbuf_t *nbuf = npc->npc_nbuf;
 	const int mflags __diagused = npc->npc_info & (NPC_IP46 | NPC_LAYER4);
 	int flags __diagused;
 
 	nbuf_reset(nbuf);
 	npc->npc_info = 0;
-	flags = npf_cache_all(npc, nbuf);
+	flags = npf_cache_all(npc);
+
 	KASSERT((flags & mflags) == mflags);
 	KASSERT(nbuf_flag_p(nbuf, NBUF_DATAREF_RESET) == 0);
 }
--- a/sys/net/npf/npf_nat.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_nat.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_nat.c,v 1.29 2014/07/19 18:24:16 rmind Exp $	*/
+/*	$NetBSD: npf_nat.c,v 1.30 2014/07/20 00:37:41 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.29 2014/07/19 18:24:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.30 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -464,14 +464,14 @@
  * => Acquire a reference on the policy, if found.
  */
 static npf_natpolicy_t *
-npf_nat_inspect(npf_cache_t *npc, nbuf_t *nbuf, const int di)
+npf_nat_inspect(npf_cache_t *npc, const int di)
 {
 	int slock = npf_config_read_enter();
 	npf_ruleset_t *rlset = npf_config_natset();
 	npf_natpolicy_t *np;
 	npf_rule_t *rl;
 
-	rl = npf_ruleset_inspect(npc, nbuf, rlset, di, NPF_LAYER_3);
+	rl = npf_ruleset_inspect(npc, rlset, di, NPF_LAYER_3);
 	if (rl == NULL) {
 		npf_config_read_exit(slock);
 		return NULL;
@@ -552,7 +552,7 @@
  * npf_nat_translate: perform translation given the state data.
  */
 static inline int
-npf_nat_translate(npf_cache_t *npc, nbuf_t *nbuf, npf_nat_t *nt, bool forw)
+npf_nat_translate(npf_cache_t *npc, npf_nat_t *nt, bool forw)
 {
 	const npf_natpolicy_t *np = nt->nt_natpolicy;
 	const u_int which = npf_nat_which(np->n_type, forw);
@@ -576,10 +576,10 @@
 	/* Execute ALG translation first. */
 	if ((npc->npc_info & NPC_ALG_EXEC) == 0) {
 		npc->npc_info |= NPC_ALG_EXEC;
-		npf_alg_exec(npc, nbuf, nt, forw);
-		npf_recache(npc, nbuf);
+		npf_alg_exec(npc, nt, forw);
+		npf_recache(npc);
 	}
-	KASSERT(!nbuf_flag_p(nbuf, NBUF_DATAREF_RESET));
+	KASSERT(!nbuf_flag_p(npc->npc_nbuf, NBUF_DATAREF_RESET));
 
 	/* Finally, perform the translation. */
 	return npf_napt_rwr(npc, which, addr, port);
@@ -617,8 +617,9 @@
  *	- Associate a NAT policy with a connection (may establish a new).
  */
 int
-npf_do_nat(npf_cache_t *npc, npf_conn_t *con, nbuf_t *nbuf, const int di)
+npf_do_nat(npf_cache_t *npc, npf_conn_t *con, const int di)
 {
+	nbuf_t *nbuf = npc->npc_nbuf;
 	npf_conn_t *ncon = NULL;
 	npf_natpolicy_t *np;
 	npf_nat_t *nt;
@@ -645,7 +646,7 @@
 	 * Inspect the packet for a NAT policy, if there is no connection.
 	 * Note: acquires a reference if found.
 	 */
-	np = npf_nat_inspect(npc, nbuf, di);
+	np = npf_nat_inspect(npc, di);
 	if (np == NULL) {
 		/* If packet does not match - done. */
 		return 0;
@@ -655,7 +656,7 @@
 	/* Static NAT - just perform the translation. */
 	if (np->n_flags & NPF_NAT_STATIC) {
 		if (nbuf_cksum_barrier(nbuf, di)) {
-			npf_recache(npc, nbuf);
+			npf_recache(npc);
 		}
 		error = npf_nat_algo(npc, np, forw);
 		atomic_dec_uint(&np->n_refcnt);
@@ -669,7 +670,7 @@
 	 * "backwards" stream depends on other, stateless filtering rules.
 	 */
 	if (con == NULL) {
-		ncon = npf_conn_establish(npc, nbuf, di, true);
+		ncon = npf_conn_establish(npc, di, true);
 		if (ncon == NULL) {
 			atomic_dec_uint(&np->n_refcnt);
 			return ENOMEM;
@@ -697,18 +698,18 @@
 	}
 
 	/* Determine whether any ALG matches. */
-	if (npf_alg_match(npc, nbuf, nt, di)) {
+	if (npf_alg_match(npc, nt, di)) {
 		KASSERT(nt->nt_alg != NULL);
 	}
 
 translate:
 	/* May need to process the delayed checksums first (XXX: NetBSD). */
 	if (nbuf_cksum_barrier(nbuf, di)) {
-		npf_recache(npc, nbuf);
+		npf_recache(npc);
 	}
 
 	/* Perform the translation. */
-	error = npf_nat_translate(npc, nbuf, nt, forw);
+	error = npf_nat_translate(npc, nt, forw);
 out:
 	if (__predict_false(ncon)) {
 		if (error) {
--- a/sys/net/npf/npf_rproc.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_rproc.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_rproc.c,v 1.10 2014/05/19 18:45:51 jakllsch Exp $	*/
+/*	$NetBSD: npf_rproc.c,v 1.11 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -331,11 +331,11 @@
  * => Reference on the rule procedure must be held.
  */
 bool
-npf_rproc_run(npf_cache_t *npc, nbuf_t *nbuf, npf_rproc_t *rp, int *decision)
+npf_rproc_run(npf_cache_t *npc, npf_rproc_t *rp, int *decision)
 {
 	const unsigned extcount = rp->rp_ext_count;
 
-	KASSERT(!nbuf_flag_p(nbuf, NBUF_DATAREF_RESET));
+	KASSERT(!nbuf_flag_p(npc->npc_nbuf, NBUF_DATAREF_RESET));
 	KASSERT(rp->rp_refcnt > 0);
 
 	for (unsigned i = 0; i < extcount; i++) {
@@ -343,12 +343,12 @@
 		const npf_ext_ops_t *extops = ext->ext_ops;
 
 		KASSERT(ext->ext_refcnt > 0);
-		if (!extops->proc(npc, nbuf, rp->rp_ext_meta[i], decision)) {
+		if (!extops->proc(npc, rp->rp_ext_meta[i], decision)) {
 			return false;
 		}
 
-		if (nbuf_flag_p(nbuf, NBUF_DATAREF_RESET)) {
-			npf_recache(npc, nbuf);
+		if (nbuf_flag_p(npc->npc_nbuf, NBUF_DATAREF_RESET)) {
+			npf_recache(npc);
 		}
 	}
 
--- a/sys/net/npf/npf_ruleset.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_ruleset.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_ruleset.c,v 1.33 2014/06/25 00:20:06 rmind Exp $	*/
+/*	$NetBSD: npf_ruleset.c,v 1.34 2014/07/20 00:37:41 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.33 2014/06/25 00:20:06 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.34 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -730,13 +730,12 @@
  *
  * Loop through the rules in the set and run the byte-code of each rule
  * against the packet (nbuf chain).  If sub-ruleset is found, inspect it.
- *
- * => Caller is responsible for nbuf chain protection.
  */
 npf_rule_t *
-npf_ruleset_inspect(npf_cache_t *npc, nbuf_t *nbuf,
-    const npf_ruleset_t *rlset, const int di, const int layer)
+npf_ruleset_inspect(npf_cache_t *npc, const npf_ruleset_t *rlset,
+    const int di, const int layer)
 {
+	nbuf_t *nbuf = npc->npc_nbuf;
 	const int di_mask = (di & PFIL_IN) ? NPF_RULE_IN : NPF_RULE_OUT;
 	const u_int nitems = rlset->rs_nitems;
 	const u_int ifid = nbuf->nb_ifid;
@@ -751,7 +750,7 @@
 	 * the BPF programs to be executed.
 	 */
 	uint32_t bc_words[NPF_BPF_NWORDS];
-	npf_bpf_prepare(npc, nbuf, &bc_args, bc_words);
+	npf_bpf_prepare(npc, &bc_args, bc_words);
 
 	while (n < nitems) {
 		npf_rule_t *rl = rlset->rs_rules[n];
--- a/sys/net/npf/npf_sendpkt.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_sendpkt.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_sendpkt.c,v 1.14 2013/02/09 03:35:32 rmind Exp $	*/
+/*	$NetBSD: npf_sendpkt.c,v 1.15 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_sendpkt.c,v 1.14 2013/02/09 03:35:32 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_sendpkt.c,v 1.15 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -175,9 +175,9 @@
  * npf_return_icmp: return an ICMP error.
  */
 static int
-npf_return_icmp(const npf_cache_t *npc, nbuf_t *nbuf)
+npf_return_icmp(const npf_cache_t *npc)
 {
-	struct mbuf *m = nbuf_head_mbuf(nbuf);
+	struct mbuf *m = nbuf_head_mbuf(npc->npc_nbuf);
 
 	if (npf_iscached(npc, NPC_IP4)) {
 		icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_ADMIN_PROHIBIT, 0, 0);
@@ -195,7 +195,7 @@
  * => Returns true if the buffer was consumed (freed) and false otherwise.
  */
 bool
-npf_return_block(npf_cache_t *npc, nbuf_t *nbuf, const int retfl)
+npf_return_block(npf_cache_t *npc, const int retfl)
 {
 	if (!npf_iscached(npc, NPC_IP46) || !npf_iscached(npc, NPC_LAYER4)) {
 		return false;
@@ -208,7 +208,7 @@
 		break;
 	case IPPROTO_UDP:
 		if (retfl & NPF_RULE_RETICMP)
-			if (npf_return_icmp(npc, nbuf) == 0)
+			if (npf_return_icmp(npc) == 0)
 				return true;
 		break;
 	}
--- a/sys/net/npf/npf_state.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_state.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_state.c,v 1.16 2014/07/19 18:24:16 rmind Exp $	*/
+/*	$NetBSD: npf_state.c,v 1.17 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010-2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_state.c,v 1.16 2014/07/19 18:24:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_state.c,v 1.17 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -92,7 +92,7 @@
  * success and false otherwise (e.g. if protocol is not supported).
  */
 bool
-npf_state_init(npf_cache_t *npc, nbuf_t *nbuf, npf_state_t *nst)
+npf_state_init(npf_cache_t *npc, npf_state_t *nst)
 {
 	const int proto = npc->npc_proto;
 	bool ret;
@@ -105,7 +105,7 @@
 	switch (proto) {
 	case IPPROTO_TCP:
 		/* Pass to TCP state tracking engine. */
-		ret = npf_state_tcp(npc, nbuf, nst, NPF_FLOW_FORW);
+		ret = npf_state_tcp(npc, nst, NPF_FLOW_FORW);
 		break;
 	case IPPROTO_UDP:
 	case IPPROTO_ICMP:
@@ -133,8 +133,7 @@
  * the packet belongs to the tracked connection) and false otherwise.
  */
 bool
-npf_state_inspect(npf_cache_t *npc, nbuf_t *nbuf,
-    npf_state_t *nst, const bool forw)
+npf_state_inspect(npf_cache_t *npc, npf_state_t *nst, const bool forw)
 {
 	const int proto = npc->npc_proto;
 	const int di = forw ? NPF_FLOW_FORW : NPF_FLOW_BACK;
@@ -143,7 +142,7 @@
 	switch (proto) {
 	case IPPROTO_TCP:
 		/* Pass to TCP state tracking engine. */
-		ret = npf_state_tcp(npc, nbuf, nst, di);
+		ret = npf_state_tcp(npc, nst, di);
 		break;
 	case IPPROTO_UDP:
 	case IPPROTO_ICMP:
--- a/sys/net/npf/npf_state_tcp.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/sys/net/npf/npf_state_tcp.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_state_tcp.c,v 1.14 2014/07/19 18:24:16 rmind Exp $	*/
+/*	$NetBSD: npf_state_tcp.c,v 1.15 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010-2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.14 2014/07/19 18:24:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.15 2014/07/20 00:37:41 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -291,7 +291,7 @@
  * and thus part of the connection we are tracking.
  */
 static bool
-npf_tcp_inwindow(npf_cache_t *npc, nbuf_t *nbuf, npf_state_t *nst, const int di)
+npf_tcp_inwindow(npf_cache_t *npc, npf_state_t *nst, const int di)
 {
 	const struct tcphdr * const th = npc->npc_l4.tcp;
 	const int tcpfl = th->th_flags;
@@ -356,7 +356,7 @@
 		 * send this option in their SYN packets.
 		 */
 		fstate->nst_wscale = 0;
-		(void)npf_fetch_tcpopts(npc, nbuf, NULL, &fstate->nst_wscale);
+		(void)npf_fetch_tcpopts(npc, NULL, &fstate->nst_wscale);
 
 		tstate->nst_wscale = 0;
 
@@ -376,8 +376,7 @@
 
 		/* Handle TCP Window Scaling (must be ignored if no SYN). */
 		if (tcpfl & TH_SYN) {
-			(void)npf_fetch_tcpopts(npc, nbuf, NULL,
-			    &fstate->nst_wscale);
+			(void)npf_fetch_tcpopts(npc, NULL, &fstate->nst_wscale);
 		}
 	}
 
@@ -457,7 +456,7 @@
  * the connection and track its state.
  */
 bool
-npf_state_tcp(npf_cache_t *npc, nbuf_t *nbuf, npf_state_t *nst, int di)
+npf_state_tcp(npf_cache_t *npc, npf_state_t *nst, int di)
 {
 	const struct tcphdr * const th = npc->npc_l4.tcp;
 	const u_int tcpfl = th->th_flags, state = nst->nst_state;
@@ -477,7 +476,7 @@
 	}
 
 	/* Determine whether TCP packet really belongs to this connection. */
-	if (!npf_tcp_inwindow(npc, nbuf, nst, di)) {
+	if (!npf_tcp_inwindow(npc, nst, di)) {
 		return false;
 	}
 	if (__predict_true(nstate == NPF_TCPS_OK)) {
--- a/usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_bpf_test.c,v 1.6 2014/06/25 00:20:06 rmind Exp $	*/
+/*	$NetBSD: npf_bpf_test.c,v 1.7 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -73,7 +73,8 @@
 	/* Layer 3 (IP + TCP). */
 	m = fill_packet(IPPROTO_TCP);
 	nbuf_init(&nbuf, m, dummy_ifp);
-	npf_cache_all(&npc, &nbuf);
+	npc.npc_nbuf = &nbuf;
+	npf_cache_all(&npc);
 
 	bc_args.pkt = (const uint8_t *)m;
 	bc_args.buflen = m_length(m);
--- a/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_nat_test.c,v 1.8 2014/02/13 03:34:40 rmind Exp $	*/
+/*	$NetBSD: npf_nat_test.c,v 1.9 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*
  * NPF NAT test.
@@ -166,7 +166,8 @@
 	}
 
 	nbuf_init(&nbuf, m, ifp);
-	if (!npf_cache_all(&npc, &nbuf)) {
+	npc.npc_nbuf = &nbuf;
+	if (!npf_cache_all(&npc)) {
 		printf("error: could not fetch the packet data");
 		return false;
 	}
--- a/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_rule_test.c,v 1.10 2013/09/24 02:04:21 rmind Exp $	*/
+/*	$NetBSD: npf_rule_test.c,v 1.11 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*
  * NPF ruleset test.
@@ -80,10 +80,11 @@
 	int retfl, error;
 
 	nbuf_init(&nbuf, m, ifp);
-	npf_cache_all(&npc, &nbuf);
+	npc.npc_nbuf = &nbuf;
+	npf_cache_all(&npc);
 
 	int slock = npf_config_read_enter();
-	rl = npf_ruleset_inspect(&npc, &nbuf, npf_config_ruleset(),
+	rl = npf_ruleset_inspect(&npc, npf_config_ruleset(),
 	    di, NPF_LAYER_3);
 	if (rl) {
 		error = npf_rule_conclude(rl, &retfl);
--- a/usr.sbin/npf/npftest/libnpftest/npf_state_test.c	Sat Jul 19 22:08:54 2014 +0000
+++ b/usr.sbin/npf/npftest/libnpftest/npf_state_test.c	Sun Jul 20 00:37:41 2014 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_state_test.c,v 1.5 2013/11/08 00:38:27 rmind Exp $	*/
+/*	$NetBSD: npf_state_test.c,v 1.6 2014/07/20 00:37:41 rmind Exp $	*/
 
 /*
  * NPF state tracking test.
@@ -146,15 +146,16 @@
 	}
 
 	nbuf_init(&nbuf, construct_packet(p), dummy_ifp);
-	ret = npf_cache_all(&npc, &nbuf);
+	npc.npc_nbuf = &nbuf;
+	ret = npf_cache_all(&npc);
 	KASSERT((ret & NPC_IPFRAG) == 0);
 
 	if (*snew) {
-		ret = npf_state_init(&npc, &nbuf, nst);
+		ret = npf_state_init(&npc, nst);
 		KASSERT(ret == true);
 		*snew = false;
 	}
-	ret = npf_state_inspect(&npc, &nbuf, nst, p->flags == OUT);
+	ret = npf_state_inspect(&npc, nst, p->flags == OUT);
 	m_freem(nbuf.nb_mbuf);
 
 	return ret ? true : (p->flags & ERR) != 0;