Change the nwfilter driver loading mechanism to read from nwfilter.conf.
By default, it will use the existing ebiptables driver, which can be
replaced in the future to remove the {eb,ip}tables dependency.

Added nftables to *filter_tech_drivers as an available driver option
for users to choose from.

Signed-off-by: Dion Bosschieter <[email protected]>
---
 src/nwfilter/nwfilter_driver.c         | 49 +++++++++++++++++++--
 src/nwfilter/nwfilter_gentech_driver.c | 60 +++++++++++---------------
 src/nwfilter/nwfilter_gentech_driver.h |  4 +-
 3 files changed, 73 insertions(+), 40 deletions(-)

diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index 522cfda022..18d322574d 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -26,9 +26,7 @@
 
 #include "virgdbus.h"
 #include "virlog.h"
-
 #include "internal.h"
-
 #include "virerror.h"
 #include "datatypes.h"
 #include "nwfilter_driver.h"
@@ -36,7 +34,6 @@
 #include "configmake.h"
 #include "virpidfile.h"
 #include "viraccessapicheck.h"
-
 #include "nwfilter_ipaddrmap.h"
 #include "nwfilter_dhcpsnoop.h"
 #include "nwfilter_learnipaddr.h"
@@ -203,6 +200,41 @@ nwfilterStateCleanup(void)
 }
 
 
+/**
+ * virNWFilterLoadGentechDriverFromConfig:
+ *
+ * Loading driver name from nwfilter.conf config file
+ */
+static char *
+virNWFilterLoadGentechDriverFromConfig(const char *configfile)
+{
+    g_autoptr(virConf) conf = NULL;
+    g_autofree char *drivername = NULL;
+
+    if (access(configfile, R_OK) == 0) {
+
+        conf = virConfReadFile(configfile, 0);
+        if (!conf)
+            return NULL;
+
+        if (virConfGetValueString(conf, "driver", &drivername) < 0)
+            return NULL;
+
+        if (drivername) {
+            VIR_DEBUG("nwfilter driver setting requested from config file %s: 
'%s'",
+                      configfile, drivername);
+        }
+    }
+
+    if (!drivername) {
+        drivername = g_strdup(NWFILTER_DEFAULT_DRIVER);
+    }
+
+
+    return g_steal_pointer(&drivername);
+}
+
+
 /**
  * nwfilterStateInitialize:
  *
@@ -217,6 +249,8 @@ nwfilterStateInitialize(bool privileged,
 {
     VIR_LOCK_GUARD lock = virLockGuardLock(&driverMutex);
     GDBusConnection *sysbus = NULL;
+    g_autofree char *configfile = NULL;
+    char *gentechdrivername = NULL;
 
     if (root != NULL) {
         virReportError(VIR_ERR_INVALID_ARG, "%s",
@@ -266,7 +300,14 @@ nwfilterStateInitialize(bool privileged,
     if (virNWFilterDHCPSnoopInit() < 0)
         goto error;
 
-    if (virNWFilterTechDriversInit(privileged) < 0)
+    configfile = g_strdup(SYSCONFDIR "/libvirt/nwfilter.conf");
+
+    /* get chosen driver from config file */
+    gentechdrivername = virNWFilterLoadGentechDriverFromConfig(configfile);
+    if (gentechdrivername == NULL)
+        goto error;
+
+    if (virNWFilterTechDriversInit(privileged, gentechdrivername) < 0)
         goto error;
 
     if (virNWFilterConfLayerInit(virNWFilterTriggerRebuildImpl, driver) < 0)
diff --git a/src/nwfilter/nwfilter_gentech_driver.c 
b/src/nwfilter/nwfilter_gentech_driver.c
index 1465734a54..adb96acca6 100644
--- a/src/nwfilter/nwfilter_gentech_driver.c
+++ b/src/nwfilter/nwfilter_gentech_driver.c
@@ -32,6 +32,7 @@
 #include "nwfilter_dhcpsnoop.h"
 #include "nwfilter_ipaddrmap.h"
 #include "nwfilter_learnipaddr.h"
+#include "nwfilter_nftables_driver.h"
 #include "virnetdev.h"
 
 #define VIR_FROM_THIS VIR_FROM_NWFILTER
@@ -48,18 +49,20 @@ static int _virNWFilterTeardownFilter(const char *ifname);
 
 static virNWFilterTechDriver *filter_tech_drivers[] = {
     &ebiptables_driver,
-    NULL
+    &nftables_driver,
 };
 
-int virNWFilterTechDriversInit(bool privileged)
+int virNWFilterTechDriversInit(bool privileged, const char *drivername)
 {
     size_t i = 0;
-    VIR_DEBUG("Initializing NWFilter technology drivers");
-    while (filter_tech_drivers[i]) {
-        if (!(filter_tech_drivers[i]->flags & TECHDRV_FLAG_INITIALIZED))
+    VIR_DEBUG("Initializing NWFilter technology drivers, chosen %s", 
drivername);
+
+    for (i = 0; i < G_N_ELEMENTS(filter_tech_drivers); i++) {
+        if (!(filter_tech_drivers[i]->flags & TECHDRV_FLAG_INITIALIZED)
+            && STREQ(filter_tech_drivers[i]->name, drivername))
             filter_tech_drivers[i]->init(privileged);
-        i++;
     }
+
     return 0;
 }
 
@@ -67,25 +70,20 @@ int virNWFilterTechDriversInit(bool privileged)
 void virNWFilterTechDriversShutdown(void)
 {
     size_t i = 0;
-    while (filter_tech_drivers[i]) {
+    for (i = 0; i < G_N_ELEMENTS(filter_tech_drivers); i++) {
         if ((filter_tech_drivers[i]->flags & TECHDRV_FLAG_INITIALIZED))
             filter_tech_drivers[i]->shutdown();
-        i++;
     }
 }
 
 
 static virNWFilterTechDriver *
-virNWFilterTechDriverForName(const char *name)
+virNWFilterInitializedTechDriver(void)
 {
     size_t i = 0;
-    while (filter_tech_drivers[i]) {
-        if (STREQ(filter_tech_drivers[i]->name, name)) {
-            if ((filter_tech_drivers[i]->flags & TECHDRV_FLAG_INITIALIZED) == 
0)
-                break;
+    for (i = 0; i < G_N_ELEMENTS(filter_tech_drivers); i++) {
+        if ((filter_tech_drivers[i]->flags & TECHDRV_FLAG_INITIALIZED))
             return filter_tech_drivers[i];
-        }
-        i++;
     }
     return NULL;
 }
@@ -617,7 +615,6 @@ virNWFilterInstantiateFilterUpdate(virNWFilterDriverState 
*driver,
                                    bool *foundNewFilter)
 {
     int rc = -1;
-    const char *drvname = EBIPTABLES_DRIVER_ID;
     virNWFilterTechDriver *techdriver;
     virNWFilterObj *obj;
     virNWFilterDef *filter;
@@ -625,12 +622,11 @@ virNWFilterInstantiateFilterUpdate(virNWFilterDriverState 
*driver,
     char vmmacaddr[VIR_MAC_STRING_BUFLEN] = {0};
     virNWFilterVarValue *ipaddr;
 
-    techdriver = virNWFilterTechDriverForName(drvname);
+    techdriver = virNWFilterInitializedTechDriver();
 
     if (!techdriver) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Could not get access to ACL tech driver '%1$s'"),
-                       drvname);
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not get access to ACL tech driver"));
         return -1;
     }
 
@@ -768,15 +764,13 @@ virNWFilterUpdateInstantiateFilter(virNWFilterDriverState 
*driver,
 static int
 virNWFilterRollbackUpdateFilter(virNWFilterBindingDef *binding)
 {
-    const char *drvname = EBIPTABLES_DRIVER_ID;
     int ifindex;
     virNWFilterTechDriver *techdriver;
 
-    techdriver = virNWFilterTechDriverForName(drvname);
+    techdriver = virNWFilterInitializedTechDriver();
     if (!techdriver) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Could not get access to ACL tech driver '%1$s'"),
-                       drvname);
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not get access to ACL tech driver"));
         return -1;
     }
 
@@ -793,15 +787,13 @@ virNWFilterRollbackUpdateFilter(virNWFilterBindingDef 
*binding)
 static int
 virNWFilterTearOldFilter(virNWFilterBindingDef *binding)
 {
-    const char *drvname = EBIPTABLES_DRIVER_ID;
     int ifindex;
     virNWFilterTechDriver *techdriver;
 
-    techdriver = virNWFilterTechDriverForName(drvname);
+    techdriver = virNWFilterInitializedTechDriver();
     if (!techdriver) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Could not get access to ACL tech driver '%1$s'"),
-                       drvname);
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not get access to ACL tech driver"));
         return -1;
     }
 
@@ -818,14 +810,12 @@ virNWFilterTearOldFilter(virNWFilterBindingDef *binding)
 static int
 _virNWFilterTeardownFilter(const char *ifname)
 {
-    const char *drvname = EBIPTABLES_DRIVER_ID;
     virNWFilterTechDriver *techdriver;
-    techdriver = virNWFilterTechDriverForName(drvname);
+    techdriver = virNWFilterInitializedTechDriver();
 
     if (!techdriver) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Could not get access to ACL tech driver '%1$s'"),
-                       drvname);
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not get access to ACL tech driver"));
         return -1;
     }
 
diff --git a/src/nwfilter/nwfilter_gentech_driver.h 
b/src/nwfilter/nwfilter_gentech_driver.h
index 946d5d3d56..8f6f4d164a 100644
--- a/src/nwfilter/nwfilter_gentech_driver.h
+++ b/src/nwfilter/nwfilter_gentech_driver.h
@@ -25,7 +25,9 @@
 #include "virnwfilterobj.h"
 #include "virnwfilterbindingdef.h"
 
-int virNWFilterTechDriversInit(bool privileged);
+#define NWFILTER_DEFAULT_DRIVER "ebiptables"
+
+int virNWFilterTechDriversInit(bool privileged, const char *drivername);
 void virNWFilterTechDriversShutdown(void);
 
 enum instCase {
-- 
2.43.0

Reply via email to