summaryrefslogtreecommitdiffstats
path: root/sys/net/pfil.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>2009-10-11 05:59:43 +0000
committerjulian <julian@FreeBSD.org>2009-10-11 05:59:43 +0000
commit79c1f884ef6881dc506df5a23203f4cc0a447a35 (patch)
treed481a2e714a210799fdaf274f5482c3e67e5c845 /sys/net/pfil.c
parentc98bb6fb8fe1b6c9437608e3d30fd1cbf47e2e6a (diff)
downloadFreeBSD-src-79c1f884ef6881dc506df5a23203f4cc0a447a35.zip
FreeBSD-src-79c1f884ef6881dc506df5a23203f4cc0a447a35.tar.gz
Virtualize the pfil hooks so that different jails may chose different
packet filters. ALso allows ipfw to be enabled on on ejail and disabled on another. In 8.0 it's a global setting. Sitting aroung in tree waiting to commit for: 2 months MFC after: 2 months
Diffstat (limited to 'sys/net/pfil.c')
-rw-r--r--sys/net/pfil.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/sys/net/pfil.c b/sys/net/pfil.c
index 3018eb9..76ed664 100644
--- a/sys/net/pfil.c
+++ b/sys/net/pfil.c
@@ -56,8 +56,9 @@ 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 *);
-LIST_HEAD(, pfil_head) pfil_head_list =
- LIST_HEAD_INITIALIZER(&pfil_head_list);
+LIST_HEAD(pfilheadhead, pfil_head);
+VNET_DEFINE(struct pfilheadhead, pfil_head_list);
+#define V_pfil_head_list VNET(pfil_head_list)
/*
* pfil_run_hooks() runs the specified packet filter hooks.
@@ -97,7 +98,7 @@ pfil_head_register(struct pfil_head *ph)
struct pfil_head *lph;
PFIL_LIST_LOCK();
- LIST_FOREACH(lph, &pfil_head_list, ph_list) {
+ LIST_FOREACH(lph, &V_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();
@@ -108,7 +109,7 @@ pfil_head_register(struct pfil_head *ph)
ph->ph_nhooks = 0;
TAILQ_INIT(&ph->ph_in);
TAILQ_INIT(&ph->ph_out);
- LIST_INSERT_HEAD(&pfil_head_list, ph, ph_list);
+ LIST_INSERT_HEAD(&V_pfil_head_list, ph, ph_list);
PFIL_LIST_UNLOCK();
return (0);
}
@@ -143,7 +144,7 @@ pfil_head_get(int type, u_long val)
struct pfil_head *ph;
PFIL_LIST_LOCK();
- LIST_FOREACH(ph, &pfil_head_list, ph_list)
+ LIST_FOREACH(ph, &V_pfil_head_list, ph_list)
if (ph->ph_type == type && ph->ph_un.phu_val == val)
break;
PFIL_LIST_UNLOCK();
@@ -284,3 +285,45 @@ pfil_list_remove(pfil_list_t *list,
}
return ENOENT;
}
+
+/****************
+ * Stuff that must be initialized for every instance
+ * (including the first of course).
+ */
+static int
+vnet_pfil_init(const void *unused)
+{
+ LIST_INIT(&V_pfil_head_list);
+ return (0);
+}
+
+/***********************
+ * Called for the removal of each instance.
+ */
+static int
+vnet_pfil_uninit(const void *unused)
+{
+ /* XXX should panic if list is not empty */
+ return 0;
+}
+
+/* Define startup order. */
+#define PFIL_SYSINIT_ORDER SI_SUB_PROTO_BEGIN
+#define PFIL_MODEVENT_ORDER (SI_ORDER_FIRST) /* On boot slot in here. */
+#define PFIL_VNET_ORDER (PFIL_MODEVENT_ORDER + 2) /* Later still. */
+
+/*
+ * Starting up.
+ * VNET_SYSINIT is called for each existing vnet and each new vnet.
+ */
+VNET_SYSINIT(vnet_pfil_init, PFIL_SYSINIT_ORDER, PFIL_VNET_ORDER,
+ vnet_pfil_init, NULL);
+
+/*
+ * Closing up shop. These are done in REVERSE ORDER,
+ * Not called on reboot.
+ * VNET_SYSUNINIT is called for each exiting vnet as it exits.
+ */
+VNET_SYSUNINIT(vnet_pfil_uninit, PFIL_SYSINIT_ORDER, PFIL_VNET_ORDER,
+ vnet_pfil_uninit, NULL);
+
OpenPOWER on IntegriCloud