Module Name: src
Committed By: rmind
Date: Mon Feb 6 23:30:15 UTC 2012
Modified Files:
src/sys/modules/npf: Makefile
src/sys/net/npf: files.npf npf.h npf_handler.c npf_impl.h npf_ruleset.c
Added Files:
src/sys/net/npf: npf_rproc.c
Log Message:
- Split NPF rule procedure code into a separate module (no functional changes).
- Simplify some code, add more comments, some asserts.
- G/C unused rule hook code.
To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sys/modules/npf/Makefile
cvs rdiff -u -r1.5 -r1.6 src/sys/net/npf/files.npf
cvs rdiff -u -r1.13 -r1.14 src/sys/net/npf/npf.h
cvs rdiff -u -r1.12 -r1.13 src/sys/net/npf/npf_handler.c
cvs rdiff -u -r1.9 -r1.10 src/sys/net/npf/npf_impl.h \
src/sys/net/npf/npf_ruleset.c
cvs rdiff -u -r0 -r1.1 src/sys/net/npf/npf_rproc.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/modules/npf/Makefile
diff -u src/sys/modules/npf/Makefile:1.8 src/sys/modules/npf/Makefile:1.9
--- src/sys/modules/npf/Makefile:1.8 Tue Nov 29 20:05:30 2011
+++ src/sys/modules/npf/Makefile Mon Feb 6 23:30:14 2012
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.8 2011/11/29 20:05:30 rmind Exp $
+# $NetBSD: Makefile,v 1.9 2012/02/06 23:30:14 rmind Exp $
.include "../Makefile.inc"
@@ -8,8 +8,8 @@ KMOD= npf
SRCS= npf.c npf_alg.c npf_ctl.c npf_handler.c
SRCS+= npf_inet.c npf_instr.c npf_log.c npf_mbuf.c npf_nat.c
-SRCS+= npf_processor.c npf_ruleset.c npf_sendpkt.c npf_session.c
-SRCS+= npf_state.c npf_state_tcp.c npf_tableset.c
+SRCS+= npf_processor.c npf_ruleset.c npf_rproc.c npf_sendpkt.c
+SRCS+= npf_session.c npf_state.c npf_state_tcp.c npf_tableset.c
CPPFLAGS+= -DINET6
Index: src/sys/net/npf/files.npf
diff -u src/sys/net/npf/files.npf:1.5 src/sys/net/npf/files.npf:1.6
--- src/sys/net/npf/files.npf:1.5 Tue Nov 29 20:05:30 2011
+++ src/sys/net/npf/files.npf Mon Feb 6 23:30:14 2012
@@ -1,4 +1,4 @@
-# $NetBSD: files.npf,v 1.5 2011/11/29 20:05:30 rmind Exp $
+# $NetBSD: files.npf,v 1.6 2012/02/06 23:30:14 rmind Exp $
#
# Public Domain.
#
@@ -17,6 +17,7 @@ file net/npf/npf_instr.c npf
file net/npf/npf_mbuf.c npf
file net/npf/npf_processor.c npf
file net/npf/npf_ruleset.c npf
+file net/npf/npf_rproc.c npf
file net/npf/npf_tableset.c npf
file net/npf/npf_inet.c npf
file net/npf/npf_session.c npf
Index: src/sys/net/npf/npf.h
diff -u src/sys/net/npf/npf.h:1.13 src/sys/net/npf/npf.h:1.14
--- src/sys/net/npf/npf.h:1.13 Sun Feb 5 00:37:13 2012
+++ src/sys/net/npf/npf.h Mon Feb 6 23:30:14 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf.h,v 1.13 2012/02/05 00:37:13 rmind Exp $ */
+/* $NetBSD: npf.h,v 1.14 2012/02/06 23:30:14 rmind Exp $ */
/*-
* Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
@@ -68,10 +68,7 @@ typedef uint8_t npf_netmask_t;
typedef void nbuf_t;
struct npf_rproc;
-struct npf_hook;
-
typedef struct npf_rproc npf_rproc_t;
-typedef struct npf_hook npf_hook_t;
/*
* Packet information cache.
@@ -215,12 +212,6 @@ int nbuf_store_datum(nbuf_t *, void *,
int nbuf_add_tag(nbuf_t *, uint32_t, uint32_t);
int nbuf_find_tag(nbuf_t *, uint32_t, void **);
-#if 0
-npf_hook_t * npf_hook_register(npf_rule_t *,
- void (*)(npf_cache_t *, nbuf_t *, void *), void *);
-void npf_hook_unregister(npf_rule_t *, npf_hook_t *);
-#endif
-
#endif /* _KERNEL */
/* Rule attributes. */
Index: src/sys/net/npf/npf_handler.c
diff -u src/sys/net/npf/npf_handler.c:1.12 src/sys/net/npf/npf_handler.c:1.13
--- src/sys/net/npf/npf_handler.c:1.12 Sun Jan 15 00:49:48 2012
+++ src/sys/net/npf/npf_handler.c Mon Feb 6 23:30:14 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_handler.c,v 1.12 2012/01/15 00:49:48 rmind Exp $ */
+/* $NetBSD: npf_handler.c,v 1.13 2012/02/06 23:30:14 rmind Exp $ */
/*-
* Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.12 2012/01/15 00:49:48 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.13 2012/02/06 23:30:14 rmind Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -166,9 +166,12 @@ npf_packet_handler(void *arg, struct mbu
goto block;
}
- /* Get rule procedure for assocation and/or execution. */
+ /*
+ * Get the rule procedure (acquires a reference) for assocation
+ * with a session (if any) and execution.
+ */
KASSERT(rp == NULL);
- rp = npf_rproc_return(rl);
+ rp = npf_rule_getrproc(rl);
/* Apply the rule, release the lock. */
error = npf_rule_apply(&npc, nbuf, rl, &retfl);
@@ -185,6 +188,10 @@ npf_packet_handler(void *arg, struct mbu
error = ENOMEM;
goto out;
}
+ /*
+ * 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:
@@ -195,44 +202,47 @@ pass:
error = npf_do_nat(&npc, se, nbuf, ifp, di);
block:
/*
- * Perform rule procedure, if any.
+ * Execute rule procedure, if any.
*/
if (rp) {
npf_rproc_run(&npc, nbuf, rp, error);
}
out:
- /* Release the reference on session, or rule procedure. */
+ /*
+ * Release the reference on a session. Release the reference on a
+ * rule procedure only if there was no association.
+ */
if (se) {
npf_session_release(se);
} else if (rp) {
- npf_rproc_release(rp); /* XXXkmem */
+ npf_rproc_release(rp);
}
- /*
- * If error is set - drop the packet.
- * Normally, ENETUNREACH is used for "block".
- */
- if (error) {
- /*
- * Depending on flags and protocol, return TCP reset (RST)
- * or ICMP destination unreachable
- */
- if (retfl) {
- npf_return_block(&npc, nbuf, retfl);
- }
- if (error != ENETUNREACH) {
- NPF_PRINTF(("NPF: error in handler '%d'\n", error));
- npf_stats_inc(NPF_STAT_ERROR);
- }
- m_freem(*mp);
- *mp = NULL;
- } else {
+ /* Pass the packet, if no error. */
+ if (!error) {
/*
* XXX: Disable for now, it will be set accordingly later,
* for optimisations (to reduce inspection).
*/
(*mp)->m_flags &= ~M_CANFASTFWD;
+ return 0;
}
+
+ /*
+ * Block the packet. ENETUNREACH is used to indicate blocking.
+ * Depending on the flags and protocol, return TCP reset (RST) or
+ * ICMP destination unreachable.
+ */
+ if (retfl) {
+ npf_return_block(&npc, nbuf, retfl);
+ }
+ if (error != ENETUNREACH) {
+ NPF_PRINTF(("NPF: error in handler '%d'\n", error));
+ npf_stats_inc(NPF_STAT_ERROR);
+ }
+ m_freem(*mp);
+ *mp = NULL;
+
return error;
}
Index: src/sys/net/npf/npf_impl.h
diff -u src/sys/net/npf/npf_impl.h:1.9 src/sys/net/npf/npf_impl.h:1.10
--- src/sys/net/npf/npf_impl.h:1.9 Tue Nov 29 20:05:30 2011
+++ src/sys/net/npf/npf_impl.h Mon Feb 6 23:30:14 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_impl.h,v 1.9 2011/11/29 20:05:30 rmind Exp $ */
+/* $NetBSD: npf_impl.h,v 1.10 2012/02/06 23:30:14 rmind Exp $ */
/*-
* Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
@@ -226,9 +226,10 @@ void npf_rule_free(npf_rule_t *);
npf_ruleset_t * npf_rule_subset(npf_rule_t *);
npf_natpolicy_t *npf_rule_getnat(const npf_rule_t *);
void npf_rule_setnat(npf_rule_t *, npf_natpolicy_t *);
+npf_rproc_t * npf_rule_getrproc(npf_rule_t *);
npf_rproc_t * npf_rproc_create(prop_dictionary_t);
-npf_rproc_t * npf_rproc_return(npf_rule_t *);
+void npf_rproc_acquire(npf_rproc_t *);
void npf_rproc_release(npf_rproc_t *);
void npf_rproc_run(npf_cache_t *, nbuf_t *, npf_rproc_t *, int);
Index: src/sys/net/npf/npf_ruleset.c
diff -u src/sys/net/npf/npf_ruleset.c:1.9 src/sys/net/npf/npf_ruleset.c:1.10
--- src/sys/net/npf/npf_ruleset.c:1.9 Sun Jan 15 00:49:49 2012
+++ src/sys/net/npf/npf_ruleset.c Mon Feb 6 23:30:14 2012
@@ -1,7 +1,7 @@
-/* $NetBSD: npf_ruleset.c,v 1.9 2012/01/15 00:49:49 rmind Exp $ */
+/* $NetBSD: npf_ruleset.c,v 1.10 2012/02/06 23:30:14 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
@@ -34,14 +34,12 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.9 2012/01/15 00:49:49 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.10 2012/02/06 23:30:14 rmind Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
-#include <sys/atomic.h>
#include <sys/kmem.h>
-#include <sys/pool.h>
#include <sys/queue.h>
#include <sys/types.h>
@@ -57,31 +55,8 @@ struct npf_ruleset {
npf_rule_t * rs_default;
};
-/* Rule hook entry. */
-struct npf_hook {
- void (*hk_fn)(npf_cache_t *, nbuf_t *, void *);
- void * hk_arg;
- LIST_ENTRY(npf_hook) hk_entry;
-};
-
#define NPF_RNAME_LEN 16
-/* Rule procedure structure. */
-struct npf_rproc {
- /* Name. */
- char rp_name[NPF_RNAME_LEN];
- /* Reference count. */
- u_int rp_refcnt;
- uint32_t rp_flags;
- /* Normalization options. */
- bool rp_rnd_ipid;
- bool rp_no_df;
- u_int rp_minttl;
- u_int rp_maxmss;
- /* Logging interface. */
- u_int rp_log_ifid;
-};
-
/* Rule structure. */
struct npf_rule {
/* Rule name (optional) and list entry. */
@@ -101,9 +76,6 @@ struct npf_rule {
u_int r_ifid;
/* Rule procedure data. */
npf_rproc_t * r_rproc;
- /* List of hooks to process on match. */
- kmutex_t r_hooks_lock;
- LIST_HEAD(, npf_hook) r_hooks;
};
npf_ruleset_t *
@@ -222,79 +194,6 @@ npf_ruleset_natreload(npf_ruleset_t *nrl
}
}
-npf_rproc_t *
-npf_rproc_create(prop_dictionary_t rpdict)
-{
- npf_rproc_t *rp;
- const char *rname;
-
- rp = kmem_zalloc(sizeof(npf_rproc_t), KM_SLEEP);
- rp->rp_refcnt = 1;
-
- /* Name and flags. */
- prop_dictionary_get_cstring_nocopy(rpdict, "name", &rname);
- strlcpy(rp->rp_name, rname, NPF_RNAME_LEN);
- prop_dictionary_get_uint32(rpdict, "flags", &rp->rp_flags);
-
- /* Logging interface ID (integer). */
- prop_dictionary_get_uint32(rpdict, "log-interface", &rp->rp_log_ifid);
-
- /* IP ID randomization and IP_DF flag cleansing. */
- prop_dictionary_get_bool(rpdict, "randomize-id", &rp->rp_rnd_ipid);
- prop_dictionary_get_bool(rpdict, "no-df", &rp->rp_no_df);
-
- /* Minimum IP TTL and maximum TCP MSS. */
- prop_dictionary_get_uint32(rpdict, "min-ttl", &rp->rp_minttl);
- prop_dictionary_get_uint32(rpdict, "max-mss", &rp->rp_maxmss);
-
- return rp;
-}
-
-npf_rproc_t *
-npf_rproc_return(npf_rule_t *rl)
-{
- npf_rproc_t *rp = rl->r_rproc;
-
- KASSERT(npf_core_locked());
- if (rp) {
- atomic_inc_uint(&rp->rp_refcnt);
- }
- return rp;
-}
-
-void
-npf_rproc_release(npf_rproc_t *rp)
-{
-
- /* Destroy on last reference. */
- if (atomic_dec_uint_nv(&rp->rp_refcnt) != 0) {
- return;
- }
- kmem_free(rp, sizeof(npf_rproc_t));
-}
-
-void
-npf_rproc_run(npf_cache_t *npc, nbuf_t *nbuf, npf_rproc_t *rp, int error)
-{
- const uint32_t flags = rp->rp_flags;
-
- KASSERT(rp->rp_refcnt > 0);
-
- /* Normalize the packet, if required. */
- if ((flags & NPF_RPROC_NORMALIZE) != 0 && !error) {
- (void)npf_normalize(npc, nbuf,
- rp->rp_rnd_ipid, rp->rp_no_df,
- rp->rp_minttl, rp->rp_maxmss);
- npf_stats_inc(NPF_STAT_RPROC_NORM);
- }
-
- /* Log packet, if required. */
- if ((flags & NPF_RPROC_LOG) != 0) {
- npf_log_packet(npc, nbuf, rp->rp_log_ifid);
- npf_stats_inc(NPF_STAT_RPROC_LOG);
- }
-}
-
/*
* npf_rule_alloc: allocate a rule and copy n-code from user-space.
*
@@ -311,8 +210,6 @@ npf_rule_alloc(prop_dictionary_t rldict,
/* Allocate a rule structure. */
rl = kmem_alloc(sizeof(npf_rule_t), KM_SLEEP);
TAILQ_INIT(&rl->r_subset.rs_queue);
- mutex_init(&rl->r_hooks_lock, MUTEX_DEFAULT, IPL_SOFTNET);
- LIST_INIT(&rl->r_hooks);
rl->r_natp = NULL;
/* N-code. */
@@ -334,7 +231,7 @@ npf_rule_alloc(prop_dictionary_t rldict,
/* Rule procedure. */
if (rp) {
- atomic_inc_uint(&rp->rp_refcnt);
+ npf_rproc_acquire(rp);
}
rl->r_rproc = rp;
@@ -362,12 +259,12 @@ npf_rule_free(npf_rule_t *rl)
/* Free n-code. */
npf_ncode_free(rl->r_ncode, rl->r_nc_size);
}
- mutex_destroy(&rl->r_hooks_lock);
kmem_free(rl, sizeof(npf_rule_t));
}
/*
* npf_rule_subset: return sub-ruleset, if any.
+ * npf_rule_getrproc: acquire a reference and return rule procedure, if any.
* npf_rule_getnat: get NAT policy assigned to the rule.
*/
@@ -377,6 +274,18 @@ npf_rule_subset(npf_rule_t *rl)
return &rl->r_subset;
}
+npf_rproc_t *
+npf_rule_getrproc(npf_rule_t *rl)
+{
+ npf_rproc_t *rp = rl->r_rproc;
+
+ KASSERT(npf_core_locked());
+ if (rp) {
+ npf_rproc_acquire(rp);
+ }
+ return rp;
+}
+
npf_natpolicy_t *
npf_rule_getnat(const npf_rule_t *rl)
{
@@ -395,43 +304,6 @@ npf_rule_setnat(npf_rule_t *rl, npf_natp
rl->r_natp = np;
}
-#if 0
-/*
- * npf_hook_register: register action hook in the rule.
- */
-npf_hook_t *
-npf_hook_register(npf_rule_t *rl,
- void (*fn)(npf_cache_t *, nbuf_t *, void *), void *arg)
-{
- npf_hook_t *hk;
-
- hk = kmem_alloc(sizeof(npf_hook_t), KM_SLEEP);
- if (hk != NULL) {
- hk->hk_fn = fn;
- hk->hk_arg = arg;
- mutex_enter(&rl->r_hooks_lock);
- LIST_INSERT_HEAD(&rl->r_hooks, hk, hk_entry);
- mutex_exit(&rl->r_hooks_lock);
- }
- return hk;
-}
-
-/*
- * npf_hook_unregister: unregister a specified hook.
- *
- * => Hook should have been registered in the rule.
- */
-void
-npf_hook_unregister(npf_rule_t *rl, npf_hook_t *hk)
-{
-
- mutex_enter(&rl->r_hooks_lock);
- LIST_REMOVE(hk, hk_entry);
- mutex_exit(&rl->r_hooks_lock);
- kmem_free(hk, sizeof(npf_hook_t));
-}
-#endif
-
npf_rule_t *
npf_ruleset_replace(const char *name, npf_ruleset_t *rlset)
{
@@ -511,7 +383,7 @@ again:
}
/*
- * npf_rule_apply: apply the rule i.e. run hooks and return appropriate value.
+ * npf_rule_apply: apply the rule and return appropriate value.
*
* => Returns ENETUNREACH if "block" and 0 if "pass".
* => Releases the ruleset lock.
@@ -519,26 +391,16 @@ again:
int
npf_rule_apply(npf_cache_t *npc, nbuf_t *nbuf, npf_rule_t *rl, int *retfl)
{
- npf_hook_t *hk;
int error;
KASSERT(npf_core_locked());
/* If not passing - drop the packet. */
- if ((rl->r_attr & NPF_RULE_PASS) == 0) {
- error = ENETUNREACH;
- goto done;
- }
- error = 0;
-
- /* Passing. Run the hooks. */
- LIST_FOREACH(hk, &rl->r_hooks, hk_entry) {
- KASSERT(hk->hk_fn != NULL);
- (*hk->hk_fn)(npc, nbuf, hk->hk_arg);
- }
-done:
+ error = (rl->r_attr & NPF_RULE_PASS) ? 0 : ENETUNREACH;
+
*retfl = rl->r_attr;
npf_core_exit();
+
return error;
}
Added files:
Index: src/sys/net/npf/npf_rproc.c
diff -u /dev/null src/sys/net/npf/npf_rproc.c:1.1
--- /dev/null Mon Feb 6 23:30:15 2012
+++ src/sys/net/npf/npf_rproc.c Mon Feb 6 23:30:14 2012
@@ -0,0 +1,133 @@
+/* $NetBSD: npf_rproc.c,v 1.1 2012/02/06 23:30:14 rmind Exp $ */
+
+/*-
+ * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This material is based upon work partially supported by The
+ * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * NPF rule procedure interface.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+
+#include <sys/atomic.h>
+#include <sys/kmem.h>
+#include <sys/types.h>
+
+#include "npf_impl.h"
+
+#define NPF_RNAME_LEN 16
+
+/* Rule procedure structure. */
+struct npf_rproc {
+ /* Name. */
+ char rp_name[NPF_RNAME_LEN];
+ /* Reference count. */
+ u_int rp_refcnt;
+ uint32_t rp_flags;
+ /* Normalisation options. */
+ bool rp_rnd_ipid;
+ bool rp_no_df;
+ u_int rp_minttl;
+ u_int rp_maxmss;
+ /* Logging interface. */
+ u_int rp_log_ifid;
+};
+
+npf_rproc_t *
+npf_rproc_create(prop_dictionary_t rpdict)
+{
+ npf_rproc_t *rp;
+ const char *rname;
+
+ rp = kmem_zalloc(sizeof(npf_rproc_t), KM_SLEEP);
+ rp->rp_refcnt = 1;
+
+ /* Name and flags. */
+ prop_dictionary_get_cstring_nocopy(rpdict, "name", &rname);
+ strlcpy(rp->rp_name, rname, NPF_RNAME_LEN);
+ prop_dictionary_get_uint32(rpdict, "flags", &rp->rp_flags);
+
+ /* Logging interface ID (integer). */
+ prop_dictionary_get_uint32(rpdict, "log-interface", &rp->rp_log_ifid);
+
+ /* IP ID randomisation and IP_DF flag cleansing. */
+ prop_dictionary_get_bool(rpdict, "randomize-id", &rp->rp_rnd_ipid);
+ prop_dictionary_get_bool(rpdict, "no-df", &rp->rp_no_df);
+
+ /* Minimum IP TTL and maximum TCP MSS. */
+ prop_dictionary_get_uint32(rpdict, "min-ttl", &rp->rp_minttl);
+ prop_dictionary_get_uint32(rpdict, "max-mss", &rp->rp_maxmss);
+
+ return rp;
+}
+
+void
+npf_rproc_acquire(npf_rproc_t *rp)
+{
+
+ atomic_inc_uint(&rp->rp_refcnt);
+}
+
+void
+npf_rproc_release(npf_rproc_t *rp)
+{
+
+ /* Destroy on last reference. */
+ KASSERT(rp->rp_refcnt > 0);
+ if (atomic_dec_uint_nv(&rp->rp_refcnt) != 0) {
+ return;
+ }
+ kmem_free(rp, sizeof(npf_rproc_t));
+}
+
+void
+npf_rproc_run(npf_cache_t *npc, nbuf_t *nbuf, npf_rproc_t *rp, int error)
+{
+ const uint32_t flags = rp->rp_flags;
+
+ KASSERT(rp->rp_refcnt > 0);
+
+ /* Normalise the packet, if required. */
+ if ((flags & NPF_RPROC_NORMALIZE) != 0 && !error) {
+ (void)npf_normalize(npc, nbuf,
+ rp->rp_rnd_ipid, rp->rp_no_df,
+ rp->rp_minttl, rp->rp_maxmss);
+ npf_stats_inc(NPF_STAT_RPROC_NORM);
+ }
+
+ /* Log packet, if required. */
+ if ((flags & NPF_RPROC_LOG) != 0) {
+ npf_log_packet(npc, nbuf, rp->rp_log_ifid);
+ npf_stats_inc(NPF_STAT_RPROC_LOG);
+ }
+}