Introduce nwfilter_tech_driver.c which holds shared non driver specific
methods.
The following logic can be reused by new nwfilter drivers, which are not
ebiptables specific:
- data type print logic, used for constructing ascii cli arguments out
  of nwfilter data;
- chain jump proto type l3_proto_idx logic;
- virNWFilterRule sorting.

Signed-off-by: Dion Bosschieter <[email protected]>
---
 src/nwfilter/meson.build                  |   1 +
 src/nwfilter/nwfilter_ebiptables_driver.c | 262 +---------------------
 src/nwfilter/nwfilter_tech_driver.c       | 250 +++++++++++++++++++++
 src/nwfilter/nwfilter_tech_driver.h       |  50 ++++-
 4 files changed, 299 insertions(+), 264 deletions(-)
 create mode 100644 src/nwfilter/nwfilter_tech_driver.c

diff --git a/src/nwfilter/meson.build b/src/nwfilter/meson.build
index de3d202267..9e8a4797c5 100644
--- a/src/nwfilter/meson.build
+++ b/src/nwfilter/meson.build
@@ -1,6 +1,7 @@
 nwfilter_driver_sources = [
   'nwfilter_driver.c',
   'nwfilter_gentech_driver.c',
+  'nwfilter_tech_driver.c',
   'nwfilter_dhcpsnoop.c',
   'nwfilter_ebiptables_driver.c',
   'nwfilter_learnipaddr.c',
diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c 
b/src/nwfilter/nwfilter_ebiptables_driver.c
index 4578152670..97a90d586e 100644
--- a/src/nwfilter/nwfilter_ebiptables_driver.c
+++ b/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -25,7 +25,6 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <sys/utsname.h>
 
 #include "internal.h"
 
@@ -35,6 +34,7 @@
 #include "virerror.h"
 #include "nwfilter_conf.h"
 #include "nwfilter_ebiptables_driver.h"
+#include "nwfilter_tech_driver.h"
 #include "virfile.h"
 #include "configmake.h"
 #include "virstring.h"
@@ -83,24 +83,6 @@ static void ebiptablesDriverShutdown(void);
 static int ebtablesCleanAll(const char *ifname);
 static int ebiptablesAllTeardown(const char *ifname);
 
-struct ushort_map {
-    unsigned short attr;
-    const char *val;
-};
-
-
-enum l3_proto_idx {
-    L3_PROTO_IPV4_IDX = 0,
-    L3_PROTO_IPV6_IDX,
-    L3_PROTO_ARP_IDX,
-    L3_PROTO_RARP_IDX,
-    L2_PROTO_MAC_IDX,
-    L2_PROTO_VLAN_IDX,
-    L2_PROTO_STP_IDX,
-    L3_PROTO_LAST_IDX
-};
-
-#define USHORTMAP_ENTRY_IDX(IDX, ATT, VAL) [IDX] = { .attr = ATT, .val = VAL }
 
 /* A lookup table for translating ethernet protocol IDs to human readable
  * strings. None of the human readable strings must be found as a prefix
@@ -118,7 +100,6 @@ static const struct ushort_map l3_protocols[] = {
     USHORTMAP_ENTRY_IDX(L3_PROTO_LAST_IDX, 0,                NULL),
 };
 
-
 static char chainprefixes_host[3] = {
     CHAINPREFIX_HOST_IN,
     CHAINPREFIX_HOST_OUT,
@@ -137,12 +118,6 @@ typedef struct {
     const char *targetChain;
 } iptablesBaseChainFW;
 
-typedef struct {
-    const char *ifname;
-    int nrules;
-    virNWFilterRuleInst **rules;
-} chainCreateCallbackData;
-
 static iptablesBaseChainFW fw_base_chains[] = {
     {"FORWARD", "1", VIRT_IN_CHAIN},
     {"FORWARD", "2", VIRT_OUT_CHAIN},
@@ -150,206 +125,6 @@ static iptablesBaseChainFW fw_base_chains[] = {
     {"INPUT", "1", HOST_IN_CHAIN},
 };
 
-static int
-printVar(virNWFilterVarCombIter *vars,
-         char *buf, int bufsize,
-         nwItemDesc *item,
-         bool *done)
-{
-    *done = false;
-
-    if ((item->flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
-        const char *val;
-
-        val = virNWFilterVarCombIterGetVarValue(vars, item->varAccess);
-        if (!val) {
-            /* error has been reported */
-            return -1;
-        }
-
-        if (virStrcpy(buf, val, bufsize) < 0) {
-            const char *varName;
-
-            varName = virNWFilterVarAccessGetVarName(item->varAccess);
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Buffer too small to print variable '%1$s' into"),
-                           varName);
-            return -1;
-        }
-
-        *done = true;
-    }
-    return 0;
-}
-
-
-static int
-_printDataType(virNWFilterVarCombIter *vars,
-               char *buf, int bufsize,
-               nwItemDesc *item,
-               bool asHex, bool directionIn)
-{
-    bool done;
-    g_autofree char *data = NULL;
-    uint8_t ctr;
-    g_auto(virBuffer) vb = VIR_BUFFER_INITIALIZER;
-    g_autofree char *flags = NULL;
-
-    if (printVar(vars, buf, bufsize, item, &done) < 0)
-        return -1;
-
-    if (done)
-        return 0;
-
-    switch (item->datatype) {
-    case DATATYPE_IPADDR:
-        data = virSocketAddrFormat(&item->u.ipaddr);
-        if (!data)
-            return -1;
-        if (g_snprintf(buf, bufsize, "%s", data) >= bufsize) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("buffer too small for IP address"));
-            return -1;
-        }
-    break;
-
-    case DATATYPE_IPV6ADDR:
-        data = virSocketAddrFormat(&item->u.ipaddr);
-        if (!data)
-            return -1;
-
-        if (g_snprintf(buf, bufsize, "%s", data) >= bufsize) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("buffer too small for IPv6 address"));
-            return -1;
-        }
-    break;
-
-    case DATATYPE_MACADDR:
-    case DATATYPE_MACMASK:
-        if (bufsize < VIR_MAC_STRING_BUFLEN) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("Buffer too small for MAC address"));
-            return -1;
-        }
-
-        virMacAddrFormat(&item->u.macaddr, buf);
-    break;
-
-    case DATATYPE_IPV6MASK:
-    case DATATYPE_IPMASK:
-        if (g_snprintf(buf, bufsize, "%d",
-                       item->u.u8) >= bufsize) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("Buffer too small for uint8 type"));
-            return -1;
-        }
-    break;
-
-    case DATATYPE_UINT32:
-    case DATATYPE_UINT32_HEX:
-        if (g_snprintf(buf, bufsize, asHex ? "0x%x" : "%u",
-                       item->u.u32) >= bufsize) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("Buffer too small for uint32 type"));
-            return -1;
-        }
-    break;
-
-    case DATATYPE_UINT16:
-    case DATATYPE_UINT16_HEX:
-        if (g_snprintf(buf, bufsize, asHex ? "0x%x" : "%d",
-                       item->u.u16) >= bufsize) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("Buffer too small for uint16 type"));
-            return -1;
-        }
-    break;
-
-    case DATATYPE_UINT8:
-    case DATATYPE_UINT8_HEX:
-        if (g_snprintf(buf, bufsize, asHex ? "0x%x" : "%d",
-                       item->u.u8) >= bufsize) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("Buffer too small for uint8 type"));
-            return -1;
-        }
-    break;
-
-    case DATATYPE_IPSETNAME:
-        if (virStrcpy(buf, item->u.ipset.setname, bufsize) < 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("Buffer to small for ipset name"));
-            return -1;
-        }
-    break;
-
-    case DATATYPE_IPSETFLAGS:
-        for (ctr = 0; ctr < item->u.ipset.numFlags; ctr++) {
-            if (ctr != 0)
-                virBufferAddLit(&vb, ",");
-            if ((item->u.ipset.flags & (1 << ctr))) {
-                if (directionIn)
-                    virBufferAddLit(&vb, "dst");
-                else
-                    virBufferAddLit(&vb, "src");
-            } else {
-                if (directionIn)
-                    virBufferAddLit(&vb, "src");
-                else
-                    virBufferAddLit(&vb, "dst");
-            }
-        }
-
-        flags = virBufferContentAndReset(&vb);
-
-        if (virStrcpy(buf, flags, bufsize) < 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("Buffer too small for IPSETFLAGS type"));
-            return -1;
-        }
-    break;
-
-    case DATATYPE_STRING:
-    case DATATYPE_STRINGCOPY:
-    case DATATYPE_BOOLEAN:
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Cannot print data type %1$x"), item->datatype);
-        return -1;
-    case DATATYPE_LAST:
-    default:
-        virReportEnumRangeError(virNWFilterAttrDataType, item->datatype);
-        return -1;
-    }
-
-    return 0;
-}
-
-
-static int
-printDataType(virNWFilterVarCombIter *vars,
-              char *buf, int bufsize,
-              nwItemDesc *item)
-{
-    return _printDataType(vars, buf, bufsize, item, 0, 0);
-}
-
-static int
-printDataTypeDirection(virNWFilterVarCombIter *vars,
-                       char *buf, int bufsize,
-                       nwItemDesc *item, bool directionIn)
-{
-    return _printDataType(vars, buf, bufsize, item, 0, directionIn);
-}
-
-static int
-printDataTypeAsHex(virNWFilterVarCombIter *vars,
-                   char *buf, int bufsize,
-                   nwItemDesc *item)
-{
-    return _printDataType(vars, buf, bufsize, item, 1, 0);
-}
-
 
 static int
 ebtablesHandleEthHdr(virFirewall *fw,
@@ -3041,41 +2816,6 @@ ebtablesCleanAll(const char *ifname)
 }
 
 
-static int
-virNWFilterRuleInstSort(const void *a, const void *b)
-{
-    const virNWFilterRuleInst *insta = a;
-    const virNWFilterRuleInst *instb = b;
-    const char *root = virNWFilterChainSuffixTypeToString(
-                                     VIR_NWFILTER_CHAINSUFFIX_ROOT);
-    bool root_a = STREQ(insta->chainSuffix, root);
-    bool root_b = STREQ(instb->chainSuffix, root);
-
-    /* ensure root chain commands appear before all others since
-       we will need them to create the child chains */
-    if (root_a) {
-        if (!root_b)
-            return -1; /* a before b */
-    } else if (root_b) {
-        return 1; /* b before a */
-    }
-
-    /* priorities are limited to range [-1000, 1000] */
-    return insta->priority - instb->priority;
-}
-
-
-static int
-virNWFilterRuleInstSortPtr(const void *a,
-                           const void *b,
-                           void *opaque G_GNUC_UNUSED)
-{
-    virNWFilterRuleInst * const *insta = a;
-    virNWFilterRuleInst * const *instb = b;
-    return virNWFilterRuleInstSort(*insta, *instb);
-}
-
-
 static int
 ebiptablesFilterOrderSort(const void *va,
                           const void *vb,
diff --git a/src/nwfilter/nwfilter_tech_driver.c 
b/src/nwfilter/nwfilter_tech_driver.c
new file mode 100644
index 0000000000..7b3edff8e6
--- /dev/null
+++ b/src/nwfilter/nwfilter_tech_driver.c
@@ -0,0 +1,250 @@
+/*
+ * nwfilter_tech_driver.c: common/shared functions used in nwfilter gentech 
drivers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "nwfilter_tech_driver.h"
+#include "nwfilter_conf.h"
+
+#define VIR_FROM_THIS VIR_FROM_NWFILTER
+
+int virNWFilterRuleInstSort(const void *a, const void *b)
+{
+    const virNWFilterRuleInst *insta = a;
+    const virNWFilterRuleInst *instb = b;
+    const char *root = virNWFilterChainSuffixTypeToString(
+                                     VIR_NWFILTER_CHAINSUFFIX_ROOT);
+    bool root_a = STREQ(insta->chainSuffix, root);
+    bool root_b = STREQ(instb->chainSuffix, root);
+
+    /* ensure root chain commands appear before all others since
+       we will need them to create the child chains */
+    if (root_a) {
+        if (!root_b)
+            return -1; /* a before b */
+    } else if (root_b) {
+        return 1; /* b before a */
+    }
+
+    /* priorities are limited to range [-1000, 1000] */
+    return insta->priority - instb->priority;
+}
+
+
+int virNWFilterRuleInstSortPtr(const void *a,
+                               const void *b,
+                               void *opaque G_GNUC_UNUSED)
+{
+    virNWFilterRuleInst * const *insta = a;
+    virNWFilterRuleInst * const *instb = b;
+    return virNWFilterRuleInstSort(*insta, *instb);
+}
+
+int printVar(virNWFilterVarCombIter *vars,
+             char *buf, int bufsize,
+             nwItemDesc *item,
+             bool *done)
+{
+    *done = false;
+
+    if ((item->flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
+        const char *val;
+
+        val = virNWFilterVarCombIterGetVarValue(vars, item->varAccess);
+        if (!val) {
+            /* error has been reported */
+            return -1;
+        }
+
+        if (virStrcpy(buf, val, bufsize) < 0) {
+            const char *varName;
+
+            varName = virNWFilterVarAccessGetVarName(item->varAccess);
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Buffer too small to print variable '%1$s' into"),
+                           varName);
+            return -1;
+        }
+
+        *done = true;
+    }
+    return 0;
+}
+
+static int
+_printDataType(virNWFilterVarCombIter *vars,
+               char *buf, int bufsize,
+               nwItemDesc *item,
+               bool asHex, bool directionIn)
+{
+    bool done;
+    g_autofree char *data = NULL;
+    uint8_t ctr;
+    g_auto(virBuffer) vb = VIR_BUFFER_INITIALIZER;
+    g_autofree char *flags = NULL;
+
+    if (printVar(vars, buf, bufsize, item, &done) < 0)
+        return -1;
+
+    if (done)
+        return 0;
+
+    switch (item->datatype) {
+    case DATATYPE_IPADDR:
+        data = virSocketAddrFormat(&item->u.ipaddr);
+        if (!data)
+            return -1;
+        if (g_snprintf(buf, bufsize, "%s", data) >= bufsize) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("buffer too small for IP address"));
+            return -1;
+        }
+    break;
+
+    case DATATYPE_IPV6ADDR:
+        data = virSocketAddrFormat(&item->u.ipaddr);
+        if (!data)
+            return -1;
+
+        if (g_snprintf(buf, bufsize, "%s", data) >= bufsize) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("buffer too small for IPv6 address"));
+            return -1;
+        }
+    break;
+
+    case DATATYPE_MACADDR:
+    case DATATYPE_MACMASK:
+        if (bufsize < VIR_MAC_STRING_BUFLEN) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Buffer too small for MAC address"));
+            return -1;
+        }
+
+        virMacAddrFormat(&item->u.macaddr, buf);
+    break;
+
+    case DATATYPE_IPV6MASK:
+    case DATATYPE_IPMASK:
+        if (g_snprintf(buf, bufsize, "%d",
+                       item->u.u8) >= bufsize) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Buffer too small for uint8 type"));
+            return -1;
+        }
+    break;
+
+    case DATATYPE_UINT32:
+    case DATATYPE_UINT32_HEX:
+        if (g_snprintf(buf, bufsize, asHex ? "0x%x" : "%u",
+                       item->u.u32) >= bufsize) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Buffer too small for uint32 type"));
+            return -1;
+        }
+    break;
+
+    case DATATYPE_UINT16:
+    case DATATYPE_UINT16_HEX:
+        if (g_snprintf(buf, bufsize, asHex ? "0x%x" : "%d",
+                       item->u.u16) >= bufsize) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Buffer too small for uint16 type"));
+            return -1;
+        }
+    break;
+
+    case DATATYPE_UINT8:
+    case DATATYPE_UINT8_HEX:
+        if (g_snprintf(buf, bufsize, asHex ? "0x%x" : "%d",
+                       item->u.u8) >= bufsize) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Buffer too small for uint8 type"));
+            return -1;
+        }
+    break;
+
+    case DATATYPE_IPSETNAME:
+        if (virStrcpy(buf, item->u.ipset.setname, bufsize) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Buffer to small for ipset name"));
+            return -1;
+        }
+    break;
+
+    case DATATYPE_IPSETFLAGS:
+        for (ctr = 0; ctr < item->u.ipset.numFlags; ctr++) {
+            if (ctr != 0)
+                virBufferAddLit(&vb, ",");
+            if ((item->u.ipset.flags & (1 << ctr))) {
+                if (directionIn)
+                    virBufferAddLit(&vb, "dst");
+                else
+                    virBufferAddLit(&vb, "src");
+            } else {
+                if (directionIn)
+                    virBufferAddLit(&vb, "src");
+                else
+                    virBufferAddLit(&vb, "dst");
+            }
+        }
+
+        flags = virBufferContentAndReset(&vb);
+
+        if (virStrcpy(buf, flags, bufsize) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Buffer too small for IPSETFLAGS type"));
+            return -1;
+        }
+    break;
+
+    case DATATYPE_STRING:
+    case DATATYPE_STRINGCOPY:
+    case DATATYPE_BOOLEAN:
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Cannot print data type %1$x"), item->datatype);
+        return -1;
+    case DATATYPE_LAST:
+    default:
+        virReportEnumRangeError(virNWFilterAttrDataType, item->datatype);
+        return -1;
+    }
+
+    return 0;
+}
+
+int printDataType(virNWFilterVarCombIter *vars,
+                  char *buf, int bufsize,
+                  nwItemDesc *item)
+{
+    return _printDataType(vars, buf, bufsize, item, 0, 0);
+}
+
+int printDataTypeDirection(virNWFilterVarCombIter *vars,
+                           char *buf, int bufsize,
+                           nwItemDesc *item, bool directionIn)
+{
+    return _printDataType(vars, buf, bufsize, item, 0, directionIn);
+}
+
+int printDataTypeAsHex(virNWFilterVarCombIter *vars,
+                       char *buf, int bufsize,
+                       nwItemDesc *item)
+{
+    return _printDataType(vars, buf, bufsize, item, 1, 0);
+}
diff --git a/src/nwfilter/nwfilter_tech_driver.h 
b/src/nwfilter/nwfilter_tech_driver.h
index a4af0bf6d5..7a85c46339 100644
--- a/src/nwfilter/nwfilter_tech_driver.h
+++ b/src/nwfilter/nwfilter_tech_driver.h
@@ -24,9 +24,7 @@
 #pragma once
 
 #include "virnwfilterobj.h"
-
-typedef struct _virNWFilterTechDriver virNWFilterTechDriver;
-
+#include "virstring.h"
 
 typedef struct _virNWFilterRuleInst virNWFilterRuleInst;
 struct _virNWFilterRuleInst {
@@ -38,6 +36,31 @@ struct _virNWFilterRuleInst {
 };
 
 
+typedef struct _chainCreateCallbackData chainCreateCallbackData;
+struct _chainCreateCallbackData {
+    const char *ifname;
+    int nrules;
+    virNWFilterRuleInst **rules;
+};
+
+struct ushort_map {
+    unsigned short attr;
+    const char *val;
+};
+
+#define USHORTMAP_ENTRY_IDX(IDX, ATT, VAL) [IDX] = { .attr = ATT, .val = VAL }
+
+enum l3_proto_idx {
+    L3_PROTO_IPV4_IDX = 0,
+    L3_PROTO_IPV6_IDX,
+    L3_PROTO_ARP_IDX,
+    L3_PROTO_RARP_IDX,
+    L2_PROTO_MAC_IDX,
+    L2_PROTO_VLAN_IDX,
+    L2_PROTO_STP_IDX,
+    L3_PROTO_LAST_IDX
+};
+
 typedef int (*virNWFilterTechDrvInit)(bool privileged);
 typedef void (*virNWFilterTechDrvShutdown)(void);
 
@@ -69,6 +92,7 @@ enum techDrvFlags {
     TECHDRV_FLAG_INITIALIZED = (1 << 0),
 };
 
+typedef struct _virNWFilterTechDriver virNWFilterTechDriver;
 struct _virNWFilterTechDriver {
     const char *name;
     enum techDrvFlags flags;
@@ -87,3 +111,23 @@ struct _virNWFilterTechDriver {
     virNWFilterDropAllRules applyDropAllRules;
     virNWFilterRemoveBasicRules removeBasicRules;
 };
+
+int virNWFilterRuleInstSort(const void *a, const void *b);
+int virNWFilterRuleInstSortPtr(const void *a,
+                           const void *b,
+                           void *opaque);
+int printVar(virNWFilterVarCombIter *vars,
+             char *buf, int bufsize,
+             nwItemDesc *item,
+             bool *done);
+
+int printDataType(virNWFilterVarCombIter *vars,
+                  char *buf, int bufsize,
+                  nwItemDesc *item);
+
+int printDataTypeDirection(virNWFilterVarCombIter *vars,
+                           char *buf, int bufsize,
+                           nwItemDesc *item, bool directionIn);
+int printDataTypeAsHex(virNWFilterVarCombIter *vars,
+                       char *buf, int bufsize,
+                       nwItemDesc *item);
-- 
2.43.0

Reply via email to