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