[prev in list] [next in list] [prev in thread] [next in thread]
List: freebsd-stable
Subject: Re: Sequence of packet processing with ipfw, pf, ipfilter ?
From: Max Laier <max () love2party ! net>
Date: 2007-02-27 12:44:27
Message-ID: 200702271344.33881.max () love2party ! net
[Download RAW message or body]
[Attachment #2 (multipart/mixed)]
On Tuesday 27 February 2007 09:31, Kurt Jaeger wrote:
> can someone point me to some documentation about the sequence
> of packet processing in fbsd6 if more than one of the filter
> systems is active ?
Unfortunately, there is no defined sequence. Currently it depends on the
sequence the individual components are enabled, or - more specificly -
the sequence of pfil_add_hook() calls. Note that ipfw does this on
module load, while pf waits until you issue "pfctl -e". I had
experimental patches to control the sequence back in 2005 (see attached).
Note that this will not work!!! It's more for reference. Back then
nobody was interesting in testing.
> There once was a nice ascii graphic which described the flow
> of packets through the rules -- I can't find it any more ?
--
/"\ Best regards, | mlaier@freebsd.org
\ / Max Laier | ICQ #67774661
X http://pf4freebsd.love2party.net/ | mlaier@EFnet
/ \ ASCII Ribbon Campaign | Against HTML Mail and News
["pfil_lockless_20051204.diff" (text/x-diff)]
Index: contrib/pf/net/pf_ioctl.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/contrib/pf/net/pf_ioctl.c,v
retrieving revision 1.21
diff -u -r1.21 pf_ioctl.c
--- contrib/pf/net/pf_ioctl.c 8 Sep 2005 15:06:52 -0000 1.21
+++ contrib/pf/net/pf_ioctl.c 4 Dec 2005 13:47:24 -0000
@@ -3461,19 +3461,23 @@
pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
if (pfh_inet == NULL)
return (ESRCH); /* XXX */
- pfil_add_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet);
- pfil_add_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet);
+ pfil_add_named_hook(pf_check_in, NULL, "pf", PFIL_IN|PFIL_WAITOK,
+ pfh_inet);
+ pfil_add_named_hook(pf_check_out, NULL, "pf", PFIL_OUT|PFIL_WAITOK,
+ pfh_inet);
#ifdef INET6
pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
if (pfh_inet6 == NULL) {
- pfil_remove_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK,
+ pfil_remove_hook(pf_check_in, NULL, PFIL_IN|PFIL_WAITOK,
pfh_inet);
- pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
+ pfil_remove_hook(pf_check_out, NULL, PFIL_OUT|PFIL_WAITOK,
pfh_inet);
return (ESRCH); /* XXX */
}
- pfil_add_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
- pfil_add_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
+ pfil_add_named_hook(pf_check6_in, NULL, "pf", PFIL_IN|PFIL_WAITOK,
+ pfh_inet6);
+ pfil_add_named_hook(pf_check6_out, NULL, "pf", PFIL_OUT|PFIL_WAITOK,
+ pfh_inet6);
#endif
pf_pfil_hooked = 1;
Index: net/bridge.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/net/Attic/bridge.c,v
retrieving revision 1.93.2.1
diff -u -r1.93.2.1 bridge.c
--- net/bridge.c 25 Aug 2005 05:01:19 -0000 1.93.2.1
+++ net/bridge.c 3 Dec 2005 16:47:15 -0000
@@ -995,7 +995,7 @@
* and pkts already gone through a pipe.
*/
if (src != NULL && (
- (inet_pfil_hook.ph_busy_count >= 0 && bdg_ipf != 0) ||
+ (!PFIL_IS_EMPTY(inet_pfil_hook) && bdg_ipf != 0) ||
(IPFW_LOADED && bdg_ipfw != 0))) {
int i;
@@ -1044,7 +1044,7 @@
* Enables ipf(8) in bridging.
*/
if (!IPFW_LOADED) { /* XXX: Prevent ipfw from being run twice. */
- if (inet_pfil_hook.ph_busy_count >= 0 &&
+ if (!PFIL_IS_EMPTY(inet_pfil_hook) &&
m0->m_pkthdr.len >= sizeof(struct ip) &&
ntohs(save_eh.ether_type) == ETHERTYPE_IP) {
/*
Index: net/if_bridge.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/net/if_bridge.c,v
retrieving revision 1.35
diff -u -r1.35 if_bridge.c
--- net/if_bridge.c 29 Nov 2005 20:29:44 -0000 1.35
+++ net/if_bridge.c 4 Dec 2005 13:47:57 -0000
@@ -1315,9 +1315,9 @@
return;
}
- if (inet_pfil_hook.ph_busy_count >= 0
+ if (!PFIL_IS_EMPTY(inet_pfil_hook)
#ifdef INET6
- || inet6_pfil_hook.ph_busy_count >= 0
+ || !PFIL_IS_EMPTY(inet6_pfil_hook)
#endif
) {
if (bridge_pfil(&m, sc->sc_ifp, ifp, PFIL_OUT) != 0)
@@ -1577,9 +1577,9 @@
}
/* run the packet filter */
- if (inet_pfil_hook.ph_busy_count >= 0
+ if (!PFIL_IS_EMPTY(inet_pfil_hook)
#ifdef INET6
- || inet6_pfil_hook.ph_busy_count >= 0
+ || !PFIL_IS_EMPTY(inet6_pfil_hook)
#endif
) {
BRIDGE_UNLOCK(sc);
@@ -1630,9 +1630,9 @@
BRIDGE_UNLOCK(sc);
- if (inet_pfil_hook.ph_busy_count >= 0
+ if (!PFIL_IS_EMPTY(inet_pfil_hook)
#ifdef INET6
- || inet6_pfil_hook.ph_busy_count >= 0
+ || !PFIL_IS_EMPTY(inet6_pfil_hook)
#endif
) {
if (bridge_pfil(&m, sc->sc_ifp, dst_if, PFIL_OUT) != 0)
@@ -1819,9 +1819,9 @@
}
/* Filter on the bridge interface before broadcasting */
- if (runfilt && (inet_pfil_hook.ph_busy_count >= 0
+ if (runfilt && (!PFIL_IS_EMPTY(inet_pfil_hook)
#ifdef INET6
- || inet6_pfil_hook.ph_busy_count >= 0
+ || PFIL_IS_EMPTY(inet6_pfil_hook)
#endif
)) {
if (bridge_pfil(&m, sc->sc_ifp, NULL, PFIL_OUT) != 0)
@@ -1866,9 +1866,9 @@
* pointer so we do not redundantly filter on the bridge for
* each interface we broadcast on.
*/
- if (runfilt && (inet_pfil_hook.ph_busy_count >= 0
+ if (runfilt && (!PFIL_IS_EMPTY(inet_pfil_hook)
#ifdef INET6
- || inet6_pfil_hook.ph_busy_count >= 0
+ || !PFIL_IS_EMPTY(inet6_pfil_hook)
#endif
)) {
if (bridge_pfil(&mc, NULL, dst_if, PFIL_OUT) != 0)
Index: net/pfil.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/net/pfil.c,v
retrieving revision 1.13
diff -u -r1.13 pfil.c
--- net/pfil.c 23 May 2005 17:07:16 -0000 1.13
+++ net/pfil.c 4 Dec 2005 13:27:58 -0000
@@ -2,6 +2,7 @@
/* $NetBSD: pfil.c,v 1.20 2001/11/12 23:49:46 lukem Exp $ */
/*-
+ * Copyright (c) 2005 Max Laier
* Copyright (c) 1996 Matthew R. Green
* All rights reserved.
*
@@ -33,8 +34,10 @@
#include <sys/kernel.h>
#include <sys/errno.h>
#include <sys/malloc.h>
+#include <sys/sbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
+#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/condvar.h>
#include <sys/lock.h>
@@ -46,67 +49,20 @@
#include <net/pfil.h>
static struct mtx pfil_global_lock;
+static struct callout pfil_gc_tmo;
-MTX_SYSINIT(pfil_heads_lock, &pfil_global_lock, "pfil_head_list lock", MTX_DEF);
-
-static int pfil_list_add(pfil_list_t *, struct packet_filter_hook *, int);
-
-static int pfil_list_remove(pfil_list_t *,
- int (*)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), void *);
+MTX_SYSINIT(pfil_heads_lock, &pfil_global_lock, "pfil lock", MTX_DEF);
LIST_HEAD(, pfil_head) pfil_head_list =
- LIST_HEAD_INITIALIZER(&pfil_head_list);
-
-static __inline void
-PFIL_RLOCK(struct pfil_head *ph)
-{
- mtx_lock(&ph->ph_mtx);
- ph->ph_busy_count++;
- mtx_unlock(&ph->ph_mtx);
-}
+ LIST_HEAD_INITIALIZER(pfil_head_list);
-static __inline void
-PFIL_RUNLOCK(struct pfil_head *ph)
-{
- mtx_lock(&ph->ph_mtx);
- ph->ph_busy_count--;
- if (ph->ph_busy_count == 0 && ph->ph_want_write)
- cv_signal(&ph->ph_cv);
- mtx_unlock(&ph->ph_mtx);
-}
+STAILQ_HEAD(, packet_filter_list) pfil_gc_list =
+ STAILQ_HEAD_INITIALIZER(pfil_gc_list);
-static __inline void
-PFIL_WLOCK(struct pfil_head *ph)
-{
- mtx_lock(&ph->ph_mtx);
- ph->ph_want_write = 1;
- while (ph->ph_busy_count > 0)
- cv_wait(&ph->ph_cv, &ph->ph_mtx);
-}
-
-static __inline int
-PFIL_TRY_WLOCK(struct pfil_head *ph)
-{
- mtx_lock(&ph->ph_mtx);
- ph->ph_want_write = 1;
- if (ph->ph_busy_count > 0) {
- ph->ph_want_write = 0;
- mtx_unlock(&ph->ph_mtx);
- return EBUSY;
- }
- return 0;
-}
-
-static __inline void
-PFIL_WUNLOCK(struct pfil_head *ph)
-{
- ph->ph_want_write = 0;
- cv_signal(&ph->ph_cv);
- mtx_unlock(&ph->ph_mtx);
-}
+#define PFIL_LOCK() mtx_lock(&pfil_global_lock)
+#define PFIL_UNLOCK() mtx_unlock(&pfil_global_lock)
-#define PFIL_LIST_LOCK() mtx_lock(&pfil_global_lock)
-#define PFIL_LIST_UNLOCK() mtx_unlock(&pfil_global_lock)
+static void pfil_gc(void *);
/*
* pfil_run_hooks() runs the specified packet filter hooks.
@@ -115,33 +71,39 @@
pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
int dir, struct inpcb *inp)
{
+ struct packet_filter_list *pfl;
struct packet_filter_hook *pfh;
struct mbuf *m = *mp;
- int rv = 0;
+ int i, rv = 0;
- if (ph->ph_busy_count == -1)
- return (0);
- /*
- * Prevent packet filtering from starving the modification of
- * the packet filters. We would prefer a reader/writer locking
- * mechanism with guaranteed ordering, though.
- */
- if (ph->ph_want_write) {
- m_freem(*mp);
- *mp = NULL;
- return (ENOBUFS);
- }
-
- PFIL_RLOCK(ph);
- for (pfh = pfil_hook_get(dir, ph); pfh != NULL;
- pfh = TAILQ_NEXT(pfh, pfil_link)) {
- if (pfh->pfil_func != NULL) {
- rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir, inp);
- if (rv != 0 || m == NULL)
- break;
- }
+ if (dir & PFIL_IN) {
+ pfl = (struct packet_filter_list *)atomic_load_acq_ptr(
+ (void *)&ph->ph_in);
+ if (pfl != NULL)
+ for (i = 0; i < pfl->pfl_size; i++) {
+ pfh = &pfl->pfl_hooks[i];
+ if (pfh->pfil_func != NULL) {
+ rv = (*pfh->pfil_func)(pfh->pfil_arg,
+ &m, ifp, dir, inp);
+ if (rv != 0 || m == NULL)
+ break;
+ }
+ }
+ }
+ if ((dir & PFIL_OUT) && rv == 0) {
+ pfl = (struct packet_filter_list *)atomic_load_acq_ptr(
+ (void *)&ph->ph_out);
+ if (pfl != NULL)
+ for (i = 0; i < pfl->pfl_size; i++) {
+ pfh = &pfl->pfl_hooks[i];
+ if (pfh->pfil_func != NULL) {
+ rv = (*pfh->pfil_func)(pfh->pfil_arg,
+ &m, ifp, dir, inp);
+ if (rv != 0 || m == NULL)
+ break;
+ }
+ }
}
- PFIL_RUNLOCK(ph);
*mp = m;
return (rv);
@@ -156,38 +118,141 @@
{
struct pfil_head *lph;
- PFIL_LIST_LOCK();
+ PFIL_LOCK();
+ if (LIST_EMPTY(&pfil_head_list))
+ callout_init_mtx(&pfil_gc_tmo, &pfil_global_lock, 0);
LIST_FOREACH(lph, &pfil_head_list, ph_list)
if (ph->ph_type == lph->ph_type &&
ph->ph_un.phu_val == lph->ph_un.phu_val) {
- PFIL_LIST_UNLOCK();
+ PFIL_UNLOCK();
return EEXIST;
}
- PFIL_LIST_UNLOCK();
- if (mtx_initialized(&ph->ph_mtx)) { /* should not happen */
- KASSERT((0), ("%s: allready initialized!", __func__));
- return EBUSY;
- } else {
- ph->ph_busy_count = -1;
- ph->ph_want_write = 1;
- mtx_init(&ph->ph_mtx, "pfil_head_mtx", NULL, MTX_DEF);
- cv_init(&ph->ph_cv, "pfil_head_cv");
- mtx_lock(&ph->ph_mtx); /* XXX: race? */
- }
-
- TAILQ_INIT(&ph->ph_in);
- TAILQ_INIT(&ph->ph_out);
+ ph->ph_in = NULL;
+ ph->ph_out = NULL;
+ sysctl_ctx_init(&ph->ph_clist);
- PFIL_LIST_LOCK();
LIST_INSERT_HEAD(&pfil_head_list, ph, ph_list);
- PFIL_LIST_UNLOCK();
-
- PFIL_WUNLOCK(ph);
+ PFIL_UNLOCK();
return (0);
}
+static int
+pfil_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+ struct packet_filter_list *pfl, *npfl;
+ struct sbuf *sb;
+ char *new_order, *elm, *parse;
+ int i, j, err, hintlen;
+
+ hintlen = 0;
+ npfl = NULL;
+
+ pfl = (struct packet_filter_list *)atomic_load_acq_ptr(
+ (void *)arg1);
+ if (pfl == NULL || pfl->pfl_size == 0)
+ err = SYSCTL_OUT(req, "empty", 6);
+ else {
+ sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
+ for (i = 0; i < pfl->pfl_size; i++) {
+ if (i > 0)
+ sbuf_printf(sb, ", ");
+ if (pfl->pfl_hooks[i].pfil_name)
+ sbuf_printf(sb, "%s",
+ pfl->pfl_hooks[i].pfil_name);
+ else
+ sbuf_printf(sb, "N/A");
+ }
+ /* hint for sensible write buffer sizes */
+ hintlen = sbuf_len(sb) + (pfl->pfl_size * 2);
+ err = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
+ sbuf_delete(sb);
+ }
+
+ if (err || pfl == NULL || !req->newptr)
+ return (err);
+
+ if ((req->newlen - req->newidx) > hintlen)
+ return (E2BIG);
+ new_order = malloc(req->newlen - req->newidx + 1, M_TEMP,
+ M_WAITOK|M_ZERO);
+ err = SYSCTL_IN(req, new_order, (req->newlen - req->newidx));
+ if (err)
+ goto error;
+
+ /* Get memory for new ordered hooks */
+ npfl = (struct packet_filter_list *)malloc(sizeof(*npfl), M_IFADDR,
+ M_WAITOK);
+ npfl->pfl_size = pfl->pfl_size;
+ npfl->pfl_generation = pfl->pfl_generation + 1;
+ npfl->pfl_hooks = malloc(sizeof(struct packet_filter_hook) *
+ npfl->pfl_size, M_IFADDR, M_WAITOK);
+
+ /* Parse request and collect hooks accordingly */
+ j = 0;
+ parse = new_order;
+ while ((elm = strsep(&parse, " \t,")) != NULL) {
+ if (*elm == '\0')
+ continue;
+ for (i = 0; i < pfl->pfl_size; i++)
+ if (strcmp(pfl->pfl_hooks[i].pfil_name, elm) == 0) {
+ npfl->pfl_hooks[j++] = pfl->pfl_hooks[i];
+ break;
+ }
+ if (j >= npfl->pfl_size)
+ break;
+ }
+ if (parse != NULL) {
+ err = EINVAL;
+ goto error;
+ }
+ npfl->pfl_size = j;
+ free(new_order, M_TEMP);
+
+ /* Lock - only one writer at a time */
+ PFIL_LOCK();
+ if (pfl->pfl_generation !=
+ (*((struct packet_filter_list **)arg1))->pfl_generation) {
+ PFIL_UNLOCK();
+ err = EAGAIN;
+ goto error;
+ }
+ atomic_store_rel_ptr((volatile void *)arg1, (uintptr_t)npfl);
+ PFIL_UNLOCK();
+
+ /* free old memory */
+ tsleep(arg1, 0, "pfilrm", hz);
+ free(pfl->pfl_hooks, M_IFADDR);
+ free(pfl, M_IFADDR);
+
+ return (0);
+error:
+ if (npfl != NULL) {
+ free(npfl->pfl_hooks, M_IFADDR);
+ free(npfl, M_IFADDR);
+ }
+ free(new_order, M_TEMP);
+ return (err);
+}
+
+void
+pfil_head_export_sysctl(struct pfil_head *ph, struct sysctl_oid_list *parent)
+{
+ struct sysctl_oid *root;
+
+ root = SYSCTL_ADD_NODE(&ph->ph_clist, parent, OID_AUTO, "pfil",
+ CTLFLAG_RW, 0, "pfil(9) management");
+ SYSCTL_ADD_PROC(&ph->ph_clist, SYSCTL_CHILDREN(root), OID_AUTO,
+ "inbound", CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_SECURE3,
+ (void *)&ph->ph_in, 0, pfil_sysctl_handler, "A",
+ "Inbound filter hooks");
+ SYSCTL_ADD_PROC(&ph->ph_clist, SYSCTL_CHILDREN(root), OID_AUTO,
+ "outbound", CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_SECURE3,
+ (void *)&ph->ph_out, 0, pfil_sysctl_handler, "A",
+ "Outbound filter hooks");
+}
+
/*
* pfil_head_unregister() removes a pfil_head from the packet filter
* hook mechanism.
@@ -195,24 +260,20 @@
int
pfil_head_unregister(struct pfil_head *ph)
{
- struct packet_filter_hook *pfh, *pfnext;
-
- PFIL_LIST_LOCK();
- /*
- * LIST_REMOVE is safe for unlocked pfil_heads in ph_list.
- * No need to WLOCK all of them.
- */
+ sysctl_ctx_free(&ph->ph_clist);
+
+ PFIL_LOCK();
LIST_REMOVE(ph, ph_list);
- PFIL_LIST_UNLOCK();
+ PFIL_UNLOCK();
- PFIL_WLOCK(ph); /* XXX: may sleep (cv_wait)! */
-
- TAILQ_FOREACH_SAFE(pfh, &ph->ph_in, pfil_link, pfnext)
- free(pfh, M_IFADDR);
- TAILQ_FOREACH_SAFE(pfh, &ph->ph_out, pfil_link, pfnext)
- free(pfh, M_IFADDR);
- cv_destroy(&ph->ph_cv);
- mtx_destroy(&ph->ph_mtx);
+ if (ph->ph_in != NULL) {
+ free(ph->ph_in->pfl_hooks, M_IFADDR);
+ free(ph->ph_in, M_IFADDR);
+ }
+ if (ph->ph_out != NULL) {
+ free(ph->ph_out->pfl_hooks, M_IFADDR);
+ free(ph->ph_out, M_IFADDR);
+ }
return (0);
}
@@ -225,15 +286,31 @@
{
struct pfil_head *ph;
- PFIL_LIST_LOCK();
+ PFIL_LOCK();
LIST_FOREACH(ph, &pfil_head_list, ph_list)
if (ph->ph_type == type && ph->ph_un.phu_val == val)
break;
- PFIL_LIST_UNLOCK();
+ PFIL_UNLOCK();
return (ph);
}
+static void
+pfil_gc(void *arg) {
+ struct packet_filter_list *pfl;
+
+ pfl = STAILQ_FIRST(&pfil_gc_list);
+ STAILQ_REMOVE_HEAD(&pfil_gc_list, pfl_next);
+
+ free(pfl->pfl_hooks, M_IFADDR);
+ free(pfl, M_IFADDR);
+
+ if (!STAILQ_EMPTY(&pfil_gc_list))
+ callout_reset(&pfil_gc_tmo, hz, pfil_gc, NULL);
+ else
+ callout_deactivate(&pfil_gc_tmo);
+}
+
/*
* pfil_add_hook() adds a function to the packet filter hook. the
* flags are:
@@ -243,71 +320,157 @@
* PFIL_WAITOK OK to call malloc with M_WAITOK.
*/
int
-pfil_add_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *),
- void *arg, int flags, struct pfil_head *ph)
+pfil_add_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int,
+ struct inpcb *), void *arg, int flags, struct pfil_head *ph)
{
- struct packet_filter_hook *pfh1 = NULL;
- struct packet_filter_hook *pfh2 = NULL;
- int err;
+ return (pfil_add_named_hook(func, arg, NULL, flags, ph));
+}
+
+int
+pfil_add_named_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int,
+ struct inpcb *), void *arg, char *name, int flags, struct pfil_head *ph)
+{
+ struct packet_filter_list *pfl_i, *pfl_o, *opfl_i, *opfl_o;
+ int i, err;
+
+ pfl_i = pfl_o = NULL;
+
+ /* Get old filter lists */
+ opfl_i = (struct packet_filter_list *)atomic_load_acq_ptr((void *)
+ &ph->ph_in);
+ opfl_o = (struct packet_filter_list *)atomic_load_acq_ptr((void *)
+ &ph->ph_out);
+
+ /* Check for duplicates */
+ err = EEXIST;
+ if ((flags & PFIL_IN) && (opfl_i != NULL))
+ for (i = 0; i < opfl_i->pfl_size; i++)
+ if ((opfl_i->pfl_hooks[i].pfil_func == func) &&
+ (opfl_i->pfl_hooks[i].pfil_arg == arg))
+ goto error;
+ if ((flags & PFIL_OUT) && (opfl_o != NULL))
+ for (i = 0; i < opfl_o->pfl_size; i++)
+ if ((opfl_o->pfl_hooks[i].pfil_func == func) &&
+ (opfl_o->pfl_hooks[i].pfil_arg == arg))
+ goto error;
/* Get memory */
+ err = ENOMEM;
if (flags & PFIL_IN) {
- pfh1 = (struct packet_filter_hook *)malloc(sizeof(*pfh1),
+ pfl_i = (struct packet_filter_list *)malloc(sizeof(*pfl_i),
M_IFADDR, (flags & PFIL_WAITOK) ? M_WAITOK : M_NOWAIT);
- if (pfh1 == NULL) {
- err = ENOMEM;
+ if (pfl_i == NULL)
goto error;
+ if (opfl_i != NULL) {
+ pfl_i->pfl_size = opfl_i->pfl_size + 1;
+ pfl_i->pfl_generation = opfl_i->pfl_generation + 1;
+ } else {
+ pfl_i->pfl_size = 1;
+ pfl_i->pfl_generation = 1;
}
+ pfl_i->pfl_hooks = malloc(sizeof(struct packet_filter_hook) *
+ pfl_i->pfl_size, M_IFADDR,
+ (flags & PFIL_WAITOK) ? M_WAITOK : M_NOWAIT);
+ if (pfl_i->pfl_hooks == NULL)
+ goto error;
}
if (flags & PFIL_OUT) {
- pfh2 = (struct packet_filter_hook *)malloc(sizeof(*pfh1),
+ pfl_o = (struct packet_filter_list *)malloc(sizeof(*pfl_o),
M_IFADDR, (flags & PFIL_WAITOK) ? M_WAITOK : M_NOWAIT);
- if (pfh2 == NULL) {
- err = ENOMEM;
+ if (pfl_o == NULL)
goto error;
+ if (opfl_o != NULL) {
+ pfl_o->pfl_size = opfl_o->pfl_size + 1;
+ pfl_o->pfl_generation = opfl_o->pfl_generation + 1;
+ } else {
+ pfl_o->pfl_size = 1;
+ pfl_o->pfl_generation = 1;
}
- }
-
- /* Lock */
- if (flags & PFIL_WAITOK)
- PFIL_WLOCK(ph);
- else {
- err = PFIL_TRY_WLOCK(ph);
- if (err)
+ pfl_o->pfl_hooks = malloc(sizeof(struct packet_filter_hook) *
+ pfl_o->pfl_size, M_IFADDR,
+ (flags & PFIL_WAITOK) ? M_WAITOK : M_NOWAIT);
+ if (pfl_o->pfl_hooks == NULL)
goto error;
}
- /* Add */
+ /* Copy old and add new hooks */
if (flags & PFIL_IN) {
- pfh1->pfil_func = func;
- pfh1->pfil_arg = arg;
- err = pfil_list_add(&ph->ph_in, pfh1, flags & ~PFIL_OUT);
- if (err)
- goto done;
+ pfl_i->pfl_hooks[0].pfil_func = func;
+ pfl_i->pfl_hooks[0].pfil_arg = arg;
+ pfl_i->pfl_hooks[0].pfil_name = name;
+ if (opfl_i != NULL)
+ bcopy(&opfl_i->pfl_hooks[0], &pfl_i->pfl_hooks[1],
+ opfl_i->pfl_size *
+ sizeof(struct packet_filter_hook));
}
if (flags & PFIL_OUT) {
- pfh2->pfil_func = func;
- pfh2->pfil_arg = arg;
- err = pfil_list_add(&ph->ph_out, pfh2, flags & ~PFIL_IN);
- if (err) {
- if (flags & PFIL_IN)
- pfil_list_remove(&ph->ph_in, func, arg);
- goto done;
- }
+ pfl_o->pfl_hooks[pfl_o->pfl_size - 1].pfil_func = func;
+ pfl_o->pfl_hooks[pfl_o->pfl_size - 1].pfil_arg = arg;
+ pfl_o->pfl_hooks[pfl_o->pfl_size - 1].pfil_name = name;
+ if (opfl_o != NULL)
+ bcopy(&opfl_o->pfl_hooks[0], &pfl_o->pfl_hooks[0],
+ opfl_o->pfl_size *
+ sizeof(struct packet_filter_hook));
}
- ph->ph_busy_count = 0;
- PFIL_WUNLOCK(ph);
+ /* Lock - only one writer at a time */
+ PFIL_LOCK();
+ err = EAGAIN;
+ if ((flags & PFIL_IN) && (opfl_i != NULL) &&
+ (opfl_i->pfl_generation != ph->ph_in->pfl_generation)) {
+ PFIL_UNLOCK();
+ goto error;
+ }
+ if ((flags & PFIL_OUT) && (opfl_o != NULL) &&
+ (opfl_o->pfl_generation != ph->ph_out->pfl_generation)) {
+ PFIL_UNLOCK();
+ goto error;
+ }
+ if (flags & PFIL_IN)
+ atomic_store_rel_ptr((volatile void *)&ph->ph_in,
+ (uintptr_t)pfl_i);
+ if (flags & PFIL_OUT)
+ atomic_store_rel_ptr((volatile void *)&ph->ph_out,
+ (uintptr_t)pfl_o);
+
+ /* Put old hooks on the GC list and schedule a timeout */
+ if (!(flags & PFIL_WAITOK)) {
+ if (flags & PFIL_IN && opfl_i != NULL)
+ STAILQ_INSERT_TAIL(&pfil_gc_list, opfl_i, pfl_next);
+ if (flags & PFIL_IN && opfl_i != NULL)
+ STAILQ_INSERT_TAIL(&pfil_gc_list, opfl_o, pfl_next);
+ if (!callout_active(&pfil_gc_tmo))
+ callout_reset(&pfil_gc_tmo, hz, pfil_gc, NULL);
+ }
+ PFIL_UNLOCK();
- return 0;
-done:
- PFIL_WUNLOCK(ph);
+ /* free old memory */
+ if (flags & PFIL_WAITOK) {
+ tsleep(ph, 0, "pfilrm", hz);
+ if (flags & PFIL_IN && opfl_i != NULL) {
+ free(opfl_i->pfl_hooks, M_IFADDR);
+ free(opfl_i, M_IFADDR);
+ }
+ if (flags & PFIL_OUT && opfl_o != NULL) {
+ free(opfl_o->pfl_hooks, M_IFADDR);
+ free(opfl_o, M_IFADDR);
+ }
+ }
+
+ return (0);
error:
- if (pfh1 != NULL)
- free(pfh1, M_IFADDR);
- if (pfh2 != NULL)
- free(pfh2, M_IFADDR);
- return err;
+ if (pfl_i != NULL) {
+ if (pfl_i->pfl_hooks)
+ free(pfl_i->pfl_hooks, M_IFADDR);
+ free(pfl_i, M_IFADDR);
+ }
+ if (pfl_o != NULL) {
+ if (pfl_o->pfl_hooks)
+ free(pfl_o->pfl_hooks, M_IFADDR);
+ free(pfl_o, M_IFADDR);
+ }
+
+ return (err);
}
/*
@@ -315,71 +478,142 @@
* hook list.
*/
int
-pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *),
- void *arg, int flags, struct pfil_head *ph)
+pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int,
+ struct inpcb *), void *arg, int flags, struct pfil_head *ph)
{
- int err = 0;
+ struct packet_filter_list *pfl_i, *pfl_o, *opfl_i, *opfl_o;
+ int i, j, lflags, err;
- if (flags & PFIL_WAITOK)
- PFIL_WLOCK(ph);
- else {
- err = PFIL_TRY_WLOCK(ph);
- if (err)
- return err;
- }
+ pfl_i = pfl_o = NULL;
- if (flags & PFIL_IN)
- err = pfil_list_remove(&ph->ph_in, func, arg);
- if ((err == 0) && (flags & PFIL_OUT))
- err = pfil_list_remove(&ph->ph_out, func, arg);
+ /* Get old filter lists */
+ opfl_i = (struct packet_filter_list *)atomic_load_acq_ptr((void *)
+ &ph->ph_in);
+ opfl_o = (struct packet_filter_list *)atomic_load_acq_ptr((void *)
+ &ph->ph_out);
+
+ /* Check for existance, only delete when necessary */
+ lflags = 0;
+ if ((flags & PFIL_IN) && (opfl_i != NULL))
+ for (i = 0; i < opfl_i->pfl_size; i++)
+ if ((opfl_i->pfl_hooks[i].pfil_func == func) &&
+ (opfl_i->pfl_hooks[i].pfil_arg == arg)) {
+ lflags |= PFIL_IN;
+ break;
+ }
+ if ((flags & PFIL_OUT) && (opfl_o != NULL))
+ for (i = 0; i < opfl_o->pfl_size; i++)
+ if ((opfl_o->pfl_hooks[i].pfil_func == func) &&
+ (opfl_o->pfl_hooks[i].pfil_arg == arg)) {
+ lflags |= PFIL_OUT;
+ break;
+ }
- if (TAILQ_EMPTY(&ph->ph_in) && TAILQ_EMPTY(&ph->ph_out))
- ph->ph_busy_count = -1;
+ if (!lflags & PFIL_ALL)
+ return (ENOENT);
- PFIL_WUNLOCK(ph);
-
- return err;
-}
+ /* Get memory */
+ err = ENOMEM;
+ if ((lflags & PFIL_IN) && (opfl_i->pfl_size > 1)) {
+ pfl_i = (struct packet_filter_list *)malloc(sizeof(*pfl_i),
+ M_IFADDR, (flags & PFIL_WAITOK) ? M_WAITOK : M_NOWAIT);
+ if (pfl_i == NULL)
+ goto error;
+ pfl_i->pfl_size = opfl_i->pfl_size - 1;
+ pfl_i->pfl_generation = opfl_i->pfl_generation + 1;
+ pfl_i->pfl_hooks = malloc(sizeof(struct packet_filter_hook) *
+ pfl_i->pfl_size, M_IFADDR,
+ (flags & PFIL_WAITOK) ? M_WAITOK : M_NOWAIT);
+ if (pfl_i->pfl_hooks == NULL)
+ goto error;
+ }
+ if ((lflags & PFIL_OUT) && (opfl_o->pfl_size > 1)) {
+ pfl_o = (struct packet_filter_list *)malloc(sizeof(*pfl_o),
+ M_IFADDR, (flags & PFIL_WAITOK) ? M_WAITOK : M_NOWAIT);
+ if (pfl_o == NULL)
+ goto error;
+ pfl_o->pfl_size = opfl_o->pfl_size - 1;
+ pfl_o->pfl_generation = opfl_o->pfl_generation + 1;
+ pfl_o->pfl_hooks = malloc(sizeof(struct packet_filter_hook) *
+ pfl_o->pfl_size, M_IFADDR,
+ (flags & PFIL_WAITOK) ? M_WAITOK : M_NOWAIT);
+ if (pfl_o->pfl_hooks == NULL)
+ goto error;
+ }
-static int
-pfil_list_add(pfil_list_t *list, struct packet_filter_hook *pfh1, int flags)
-{
- struct packet_filter_hook *pfh;
+ /* Copy old hooks but the one we are deleting */
+ if (lflags & PFIL_IN)
+ for (j = i = 0; i < opfl_i->pfl_size; i++) {
+ if ((opfl_i->pfl_hooks[i].pfil_func == func) &&
+ (opfl_i->pfl_hooks[i].pfil_arg == arg))
+ continue;
+ pfl_i->pfl_hooks[j++] = opfl_i->pfl_hooks[i];
+ }
+ if (lflags & PFIL_OUT)
+ for (j = i = 0; i < opfl_o->pfl_size; i++) {
+ if ((opfl_o->pfl_hooks[i].pfil_func == func) &&
+ (opfl_o->pfl_hooks[i].pfil_arg == arg))
+ continue;
+ pfl_o->pfl_hooks[j++] = opfl_o->pfl_hooks[i];
+ }
- /*
- * First make sure the hook is not already there.
- */
- TAILQ_FOREACH(pfh, list, pfil_link)
- if (pfh->pfil_func == pfh1->pfil_func &&
- pfh->pfil_arg == pfh1->pfil_arg)
- return EEXIST;
- /*
- * insert the input list in reverse order of the output list
- * so that the same path is followed in or out of the kernel.
- */
+ /* Lock - only one writer at a time */
+ PFIL_LOCK();
+ err = EAGAIN;
+ if ((flags & PFIL_IN) && (opfl_i != NULL) &&
+ (opfl_i->pfl_generation != ph->ph_in->pfl_generation)) {
+ PFIL_UNLOCK();
+ goto error;
+ }
+ if ((flags & PFIL_OUT) && (opfl_o != NULL) &&
+ (opfl_o->pfl_generation != ph->ph_out->pfl_generation)) {
+ PFIL_UNLOCK();
+ goto error;
+ }
if (flags & PFIL_IN)
- TAILQ_INSERT_HEAD(list, pfh1, pfil_link);
- else
- TAILQ_INSERT_TAIL(list, pfh1, pfil_link);
+ atomic_store_rel_ptr((volatile void *)&ph->ph_in,
+ (uintptr_t)pfl_i);
+ if (flags & PFIL_OUT)
+ atomic_store_rel_ptr((volatile void *)&ph->ph_out,
+ (uintptr_t)pfl_o);
+
+ /* Put old hooks on the GC list and schedule a timeout */
+ if (!(flags & PFIL_WAITOK)) {
+ if (flags & PFIL_IN && opfl_i != NULL)
+ STAILQ_INSERT_TAIL(&pfil_gc_list, opfl_i, pfl_next);
+ if (flags & PFIL_IN && opfl_i != NULL)
+ STAILQ_INSERT_TAIL(&pfil_gc_list, opfl_o, pfl_next);
+ if (!callout_active(&pfil_gc_tmo))
+ callout_reset(&pfil_gc_tmo, hz, pfil_gc, NULL);
+ }
+ PFIL_UNLOCK();
- return 0;
-}
+ /* free old memory */
+ if (flags & PFIL_WAITOK) {
+ tsleep(ph, 0, "pfilrm", hz);
+ if (flags & PFIL_IN && opfl_i != NULL) {
+ free(opfl_i->pfl_hooks, M_IFADDR);
+ free(opfl_i, M_IFADDR);
+ }
+ if (flags & PFIL_OUT && opfl_o != NULL) {
+ free(opfl_o->pfl_hooks, M_IFADDR);
+ free(opfl_o, M_IFADDR);
+ }
+ }
-/*
- * pfil_list_remove is an internal function that takes a function off the
- * specified list.
- */
-static int
-pfil_list_remove(pfil_list_t *list,
- int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), void *arg)
-{
- struct packet_filter_hook *pfh;
+ return (0);
+error:
+ if (pfl_i != NULL) {
+ if (pfl_i->pfl_hooks)
+ free(pfl_i->pfl_hooks, M_IFADDR);
+ free(pfl_i, M_IFADDR);
+ }
+ if (pfl_o != NULL) {
+ if (pfl_o->pfl_hooks)
+ free(pfl_o->pfl_hooks, M_IFADDR);
+ free(pfl_o, M_IFADDR);
+ }
+
+ return (err);
- TAILQ_FOREACH(pfh, list, pfil_link)
- if (pfh->pfil_func == func && pfh->pfil_arg == arg) {
- TAILQ_REMOVE(list, pfh, pfil_link);
- free(pfh, M_IFADDR);
- return 0;
- }
- return ENOENT;
}
Index: net/pfil.h
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/net/pfil.h,v
retrieving revision 1.13
diff -u -r1.13 pfil.h
--- net/pfil.h 7 Jan 2005 01:45:35 -0000 1.13
+++ net/pfil.h 4 Dec 2005 13:24:24 -0000
@@ -2,6 +2,7 @@
/* $NetBSD: pfil.h,v 1.22 2003/06/23 12:57:08 martin Exp $ */
/*-
+ * Copyright (c) 2005 Max Laier
* Copyright (c) 1996 Matthew R. Green
* All rights reserved.
*
@@ -34,9 +35,7 @@
#include <sys/systm.h>
#include <sys/queue.h>
-#include <sys/_lock.h>
-#include <sys/_mutex.h>
-#include <sys/condvar.h> /* XXX */
+#include <sys/sysctl.h>
struct mbuf;
struct ifnet;
@@ -47,34 +46,34 @@
* possibly intercept the packet.
*/
struct packet_filter_hook {
- TAILQ_ENTRY(packet_filter_hook) pfil_link;
int (*pfil_func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *);
void *pfil_arg;
- int pfil_flags;
+ char *pfil_name;
};
+struct packet_filter_list {
+ STAILQ_ENTRY(packet_filter_list) pfl_next;
+ struct packet_filter_hook *pfl_hooks;
+ int pfl_size;
+ int pfl_generation;
+};
+
+STAILQ_HEAD(pfil_gclist, packet_filter_list);
+
#define PFIL_IN 0x00000001
#define PFIL_OUT 0x00000002
-#define PFIL_WAITOK 0x00000004
#define PFIL_ALL (PFIL_IN|PFIL_OUT)
-
-typedef TAILQ_HEAD(pfil_list, packet_filter_hook) pfil_list_t;
+#define PFIL_WAITOK 0x00000004
#define PFIL_TYPE_AF 1 /* key is AF_* type */
#define PFIL_TYPE_IFNET 2 /* key is ifnet pointer */
struct pfil_head {
- pfil_list_t ph_in;
- pfil_list_t ph_out;
+ struct packet_filter_list *ph_in;
+ struct packet_filter_list *ph_out;
+#define PFIL_IS_EMPTY(ph) (((ph).ph_in == NULL) && ((ph).ph_out == NULL))
+ struct sysctl_ctx_list ph_clist;
int ph_type;
- /*
- * Locking: use a busycounter per pfil_head.
- * Use ph_busy_count = -1 to indicate pfil_head is empty.
- */
- int ph_busy_count; /* count of threads with read lock */
- int ph_want_write; /* want write lock flag */
- struct cv ph_cv; /* for waking up writers */
- struct mtx ph_mtx; /* mutex on locking state */
union {
u_long phu_val;
void *phu_ptr;
@@ -88,26 +87,19 @@
int, struct inpcb *inp);
int pfil_add_hook(int (*func)(void *, struct mbuf **,
- struct ifnet *, int, struct inpcb *), void *, int, struct pfil_head *);
+ struct ifnet *, int, struct inpcb *), void *, int,
+ struct pfil_head *);
+int pfil_add_named_hook(int (*func)(void *, struct mbuf **,
+ struct ifnet *, int, struct inpcb *), void *, char *, int,
+ struct pfil_head *);
int pfil_remove_hook(int (*func)(void *, struct mbuf **,
- struct ifnet *, int, struct inpcb *), void *, int, struct pfil_head *);
+ struct ifnet *, int, struct inpcb *), void *, int,
+ struct pfil_head *);
int pfil_head_register(struct pfil_head *);
+void pfil_head_export_sysctl(struct pfil_head *, struct sysctl_oid_list *);
int pfil_head_unregister(struct pfil_head *);
struct pfil_head *pfil_head_get(int, u_long);
-static __inline struct packet_filter_hook *
-pfil_hook_get(int dir, struct pfil_head *ph)
-{
- KASSERT(ph->ph_busy_count > 0,
- ("pfil_hook_get: called on unbusy pfil_head"));
- if (dir == PFIL_IN)
- return (TAILQ_FIRST(&ph->ph_in));
- else if (dir == PFIL_OUT)
- return (TAILQ_FIRST(&ph->ph_out));
- else
- return (NULL);
-}
-
#endif /* _NET_PFIL_H_ */
Index: netinet/ip_fastfwd.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/netinet/ip_fastfwd.c,v
retrieving revision 1.33
diff -u -r1.33 ip_fastfwd.c
--- netinet/ip_fastfwd.c 18 Nov 2005 20:12:39 -0000 1.33
+++ netinet/ip_fastfwd.c 4 Dec 2005 13:47:59 -0000
@@ -345,7 +345,7 @@
/*
* Run through list of ipfilter hooks for input packets
*/
- if (inet_pfil_hook.ph_busy_count == -1)
+ if (PFIL_IS_EMPTY(inet_pfil_hook))
goto passin;
if (pfil_run_hooks(&inet_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, NULL) ||
@@ -430,7 +430,7 @@
/*
* Run through list of hooks for output packets.
*/
- if (inet_pfil_hook.ph_busy_count == -1)
+ if (PFIL_IS_EMPTY(inet_pfil_hook))
goto passout;
if (pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT, NULL) || m == NULL) {
Index: netinet/ip_fw_pfil.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/netinet/ip_fw_pfil.c,v
retrieving revision 1.20
diff -u -r1.20 ip_fw_pfil.c
--- netinet/ip_fw_pfil.c 29 Nov 2005 17:56:11 -0000 1.20
+++ netinet/ip_fw_pfil.c 4 Dec 2005 13:47:59 -0000
@@ -433,11 +433,15 @@
return ENOENT;
#endif
- pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet);
- pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet);
+ pfil_add_named_hook(ipfw_check_in, NULL, "ipfw", PFIL_IN | PFIL_WAITOK,
+ pfh_inet);
+ pfil_add_named_hook(ipfw_check_out, NULL, "ipfw",
+ PFIL_OUT | PFIL_WAITOK, pfh_inet);
#ifdef INET6
- pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
- pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
+ pfil_add_named_hook(ipfw_check_in, NULL, "ipfw", PFIL_IN | PFIL_WAITOK,
+ pfh_inet6);
+ pfil_add_named_hook(ipfw_check_out, NULL, "ipfw",
+ PFIL_OUT | PFIL_WAITOK, pfh_inet6);
#endif
return 0;
Index: netinet/ip_input.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.309
diff -u -r1.309 ip_input.c
--- netinet/ip_input.c 4 Dec 2005 02:12:43 -0000 1.309
+++ netinet/ip_input.c 4 Dec 2005 13:47:59 -0000
@@ -242,6 +242,9 @@
if ((i = pfil_head_register(&inet_pfil_hook)) != 0)
printf("%s: WARNING: unable to register pfil hook, "
"error %d\n", __func__, i);
+ else
+ pfil_head_export_sysctl(&inet_pfil_hook,
+ SYSCTL_STATIC_CHILDREN(_net_inet_ip));
/* Initialize IP reassembly queue. */
IPQ_LOCK_INIT();
@@ -415,7 +418,7 @@
*/
/* Jump over all PFIL processing if hooks are not active. */
- if (inet_pfil_hook.ph_busy_count == -1)
+ if (PFIL_IS_EMPTY(inet_pfil_hook))
goto passin;
odst = ip->ip_dst;
Index: netinet/ip_output.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.250
diff -u -r1.250 ip_output.c
--- netinet/ip_output.c 18 Nov 2005 20:12:39 -0000 1.250
+++ netinet/ip_output.c 4 Dec 2005 13:47:59 -0000
@@ -654,7 +654,7 @@
#endif /* FAST_IPSEC */
/* Jump over all PFIL processing if hooks are not active. */
- if (inet_pfil_hook.ph_busy_count == -1)
+ if (PFIL_IS_EMPTY(inet_pfil_hook))
goto passout;
/* Run through list of hooks for output packets. */
Index: netinet6/ip6_forward.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/netinet6/ip6_forward.c,v
retrieving revision 1.30
diff -u -r1.30 ip6_forward.c
--- netinet6/ip6_forward.c 10 Aug 2005 09:13:35 -0000 1.30
+++ netinet6/ip6_forward.c 4 Dec 2005 13:48:00 -0000
@@ -611,7 +611,7 @@
in6_clearscope(&ip6->ip6_dst);
/* Jump over all PFIL processing if hooks are not active. */
- if (inet6_pfil_hook.ph_busy_count == -1)
+ if (PFIL_IS_EMPTY(inet6_pfil_hook))
goto pass;
/* Run through list of hooks for output packets. */
Index: netinet6/ip6_input.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.84
diff -u -r1.84 ip6_input.c
--- netinet6/ip6_input.c 19 Oct 2005 16:20:18 -0000 1.84
+++ netinet6/ip6_input.c 4 Dec 2005 13:48:00 -0000
@@ -136,6 +136,7 @@
int ip6_ours_check_algorithm;
+SYSCTL_DECL(_net_inet6_ip6);
struct pfil_head inet6_pfil_hook;
/* firewall hooks */
@@ -192,6 +193,9 @@
if ((i = pfil_head_register(&inet6_pfil_hook)) != 0)
printf("%s: WARNING: unable to register pfil hook, "
"error %d\n", __func__, i);
+ else
+ pfil_head_export_sysctl(&inet6_pfil_hook,
+ SYSCTL_STATIC_CHILDREN(_net_inet6_ip6));
ip6intrq.ifq_maxlen = ip6qmaxlen;
mtx_init(&ip6intrq.ifq_mtx, "ip6_inq", NULL, MTX_DEF);
@@ -434,7 +438,7 @@
odst = ip6->ip6_dst;
/* Jump over all PFIL processing if hooks are not active. */
- if (inet6_pfil_hook.ph_busy_count == -1)
+ if (PFIL_IS_EMPTY(inet6_pfil_hook))
goto passin;
if (pfil_run_hooks(&inet6_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, NULL))
Index: netinet6/ip6_output.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.100
diff -u -r1.100 ip6_output.c
--- netinet6/ip6_output.c 21 Oct 2005 16:23:00 -0000 1.100
+++ netinet6/ip6_output.c 4 Dec 2005 13:48:00 -0000
@@ -889,7 +889,7 @@
}
/* Jump over all PFIL processing if hooks are not active. */
- if (inet6_pfil_hook.ph_busy_count == -1)
+ if (PFIL_IS_EMPTY(inet6_pfil_hook))
goto passout;
odst = ip6->ip6_dst;
[Attachment #6 (application/pgp-signature)]
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic