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 <dionbosschieter@gmail.com> --- 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