ng_ipfw and vnet
Avernar
avernar at gmail.com
Sat Oct 1 06:43:57 UTC 2016
I needed to have the netgraph ipfw node appear in a vnet jail but it
is only created once on module load and only for the base system. I
put together this modification to get it to also appear in vnet jails.
Since I'm very new to this code base I'd like to know if I made any
mistakes. So any help and advice would be appreciated.
Index: ng_ipfw.c
===================================================================
--- ng_ipfw.c (revision 306382)
+++ ng_ipfw.c (working copy)
@@ -74,7 +74,8 @@
int);
/* We have only one node */
-static node_p fw_node;
+static VNET_DEFINE(node_p, fw_node);
+#define V_fw_node VNET(fw_node)
/* Netgraph node type descriptor */
static struct ng_type ng_ipfw_typestruct = {
@@ -112,18 +113,6 @@
break;
}
- /* Setup node without any private data */
- if ((error = ng_make_node_common(&ng_ipfw_typestruct, &fw_node))
- != 0) {
- log(LOG_ERR, "%s: can't create ng_ipfw node", __func__);
- break;
- }
-
- /* Try to name node */
- if (ng_name_node(fw_node, "ipfw") != 0)
- log(LOG_WARNING, "%s: failed to name node \"ipfw\"",
- __func__);
-
/* Register hook */
ng_ipfw_input_p = ng_ipfw_input;
break;
@@ -131,8 +120,8 @@
case MOD_UNLOAD:
/*
* This won't happen if a node exists.
- * ng_ipfw_input_p is already cleared.
*/
+ ng_ipfw_input_p = NULL;
break;
default:
@@ -293,8 +282,8 @@
/*
* Node must be loaded and corresponding hook must be present.
*/
- if (fw_node == NULL ||
- (hook = ng_ipfw_findhook1(fw_node, fwa->rule.info)) == NULL)
+ if (V_fw_node == NULL ||
+ (hook = ng_ipfw_findhook1(V_fw_node, fwa->rule.info)) == NULL)
return (ESRCH); /* no hook associated with this rule */
/*
@@ -339,13 +328,8 @@
ng_ipfw_shutdown(node_p node)
{
- /*
- * After our single node has been removed,
- * the only thing that can be done is
- * 'kldunload ng_ipfw.ko'
- */
- ng_ipfw_input_p = NULL;
NG_NODE_UNREF(node);
+ V_fw_node = NULL;
return (0);
}
@@ -359,3 +343,33 @@
return (0);
}
+
+static void
+vnet_ng_ipfw_init(const void *unused)
+{
+
+ if (ng_ipfw_input_p != ng_ipfw_input)
+ return;
+
+ /* Setup node without any private data */
+ if (ng_make_node_common(&ng_ipfw_typestruct, &V_fw_node) != 0) {
+ log(LOG_ERR, "%s: can't create ng_ipfw node", __func__);
+ return;
+ }
+
+ /* Try to name node */
+ if (ng_name_node(V_fw_node, "ipfw") != 0)
+ log(LOG_WARNING, "%s: failed to name node \"ipfw\"", __func__);
+}
+VNET_SYSINIT(vnet_ng_ipfw_init, SI_SUB_PSEUDO, SI_ORDER_ANY,
+ vnet_ng_ipfw_init, NULL);
+
+static void
+vnet_ng_ipfw_uninit(const void *unused)
+{
+
+ if ((V_fw_node != NULL) && NG_NODE_IS_VALID(V_fw_node))
+ ng_rmnode_self(V_fw_node);
+}
+VNET_SYSUNINIT(vnet_ng_ipfw_uninit, SI_SUB_INIT_IF, SI_ORDER_ANY,
+ vnet_ng_ipfw_uninit, NULL);
More information about the freebsd-net
mailing list