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 <dionbosschieter@gmail.com>
---
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
© 2016 - 2025 Red Hat, Inc.