]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
nwfilter: keep track of active filter bindings
authorDaniel P. Berrangé <berrange@redhat.com>
Thu, 26 Apr 2018 17:34:33 +0000 (18:34 +0100)
committerDaniel P. Berrangé <berrange@redhat.com>
Tue, 26 Jun 2018 17:17:13 +0000 (18:17 +0100)
Currently the nwfilter driver does not keep any record of what filter
bindings it has active. This means that when it needs to recreate
filters, it has to rely on triggering callbacks provided by the virt
drivers. This introduces a hash table recording the virNWFilterBinding
objects so the driver has a record of all active filters.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/conf/virnwfilterobj.h
src/nwfilter/nwfilter_driver.c

index 433b0402d0a9424423d1af2c6af9da3fc231ef57..4a54dd50dac4f6dd63ea571c6cada2e5ea5c0bb4 100644 (file)
@@ -22,6 +22,7 @@
 # include "internal.h"
 
 # include "nwfilter_conf.h"
+# include "virnwfilterbindingobjlist.h"
 
 typedef struct _virNWFilterObj virNWFilterObj;
 typedef virNWFilterObj *virNWFilterObjPtr;
@@ -37,7 +38,10 @@ struct _virNWFilterDriverState {
 
     virNWFilterObjListPtr nwfilters;
 
+    virNWFilterBindingObjListPtr bindings;
+
     char *configDir;
+    char *bindingDir;
 };
 
 virNWFilterDefPtr
index 7202691646a80e79e0fddad6036c78fc30d48e89..1449b67c72ec53e1075a19bded811068c2fdc9b6 100644 (file)
@@ -38,7 +38,6 @@
 #include "domain_conf.h"
 #include "domain_nwfilter.h"
 #include "nwfilter_driver.h"
-#include "virnwfilterbindingdef.h"
 #include "nwfilter_gentech_driver.h"
 #include "configmake.h"
 #include "virfile.h"
@@ -174,7 +173,6 @@ nwfilterStateInitialize(bool privileged,
                         virStateInhibitCallback callback ATTRIBUTE_UNUSED,
                         void *opaque ATTRIBUTE_UNUSED)
 {
-    char *base = NULL;
     DBusConnection *sysbus = NULL;
 
     if (virDBusHasSystemBus() &&
@@ -191,6 +189,9 @@ nwfilterStateInitialize(bool privileged,
     if (!(driver->nwfilters = virNWFilterObjListNew()))
         goto error;
 
+    if (!(driver->bindings = virNWFilterBindingObjListNew()))
+        goto error;
+
     if (!privileged)
         return 0;
 
@@ -230,30 +231,35 @@ nwfilterStateInitialize(bool privileged,
         goto error;
     }
 
-    if (VIR_STRDUP(base, SYSCONFDIR "/libvirt") < 0)
+    if (VIR_STRDUP(driver->configDir, SYSCONFDIR "/libvirt/nwfilter") < 0)
         goto error;
 
-    if (virAsprintf(&driver->configDir,
-                    "%s/nwfilter", base) == -1)
+    if (virFileMakePathWithMode(driver->configDir, S_IRWXU) < 0) {
+        virReportSystemError(errno, _("cannot create config directory '%s'"),
+                             driver->configDir);
         goto error;
+    }
 
-    VIR_FREE(base);
+    if (VIR_STRDUP(driver->bindingDir, LOCALSTATEDIR "/run/libvirt/nwfilter-binding") < 0)
+        goto error;
 
-    if (virFileMakePathWithMode(driver->configDir, S_IRWXU) < 0) {
+    if (virFileMakePathWithMode(driver->bindingDir, S_IRWXU) < 0) {
         virReportSystemError(errno, _("cannot create config directory '%s'"),
-                             driver->configDir);
+                             driver->bindingDir);
         goto error;
     }
 
     if (virNWFilterObjListLoadAllConfigs(driver->nwfilters, driver->configDir) < 0)
         goto error;
 
+    if (virNWFilterBindingObjListLoadAllConfigs(driver->bindings, driver->bindingDir) < 0)
+        goto error;
+
     nwfilterDriverUnlock();
 
     return 0;
 
  error:
-    VIR_FREE(base);
     nwfilterDriverUnlock();
     nwfilterStateCleanup();
 
@@ -333,9 +339,12 @@ nwfilterStateCleanup(void)
         nwfilterDriverRemoveDBusMatches();
 
         VIR_FREE(driver->configDir);
+        VIR_FREE(driver->bindingDir);
         nwfilterDriverUnlock();
     }
 
+    virObjectUnref(driver->bindings);
+
     /* free inactive nwfilters */
     virNWFilterObjListFree(driver->nwfilters);
 
@@ -647,13 +656,35 @@ nwfilterInstantiateFilter(const char *vmname,
                           const unsigned char *vmuuid,
                           virDomainNetDefPtr net)
 {
-    virNWFilterBindingDefPtr binding;
+    virNWFilterBindingObjPtr obj;
+    virNWFilterBindingDefPtr def;
     int ret;
 
-    if (!(binding = virNWFilterBindingDefForNet(vmname, vmuuid, net)))
+    obj = virNWFilterBindingObjListFindByPortDev(driver->bindings, net->ifname);
+    if (obj) {
+        virNWFilterBindingObjEndAPI(&obj);
+        return 0;
+    }
+
+    if (!(def = virNWFilterBindingDefForNet(vmname, vmuuid, net)))
+        return -1;
+
+    obj = virNWFilterBindingObjListAdd(driver->bindings,
+                                       def);
+    if (!obj) {
+        virNWFilterBindingDefFree(def);
         return -1;
-    ret = virNWFilterInstantiateFilter(driver, binding);
-    virNWFilterBindingDefFree(binding);
+    }
+
+    ret = virNWFilterInstantiateFilter(driver, def);
+
+    if (ret >= 0)
+        virNWFilterBindingObjSave(obj, driver->bindingDir);
+    else
+        virNWFilterBindingObjListRemove(driver->bindings, obj);
+
+    virNWFilterBindingObjEndAPI(&obj);
+
     return ret;
 }
 
@@ -661,18 +692,21 @@ nwfilterInstantiateFilter(const char *vmname,
 static void
 nwfilterTeardownFilter(virDomainNetDefPtr net)
 {
-    virNWFilterBindingDef binding = {
-        .portdevname = net->ifname,
-        .linkdevname = (net->type == VIR_DOMAIN_NET_TYPE_DIRECT ?
-                        net->data.direct.linkdev : NULL),
-        .mac = net->mac,
-        .filter = net->filter,
-        .filterparams = net->filterparams,
-        .ownername = NULL,
-        .owneruuid = {0},
-    };
-    if ((net->ifname) && (net->filter))
-        virNWFilterTeardownFilter(&binding);
+    virNWFilterBindingObjPtr obj;
+    virNWFilterBindingDefPtr def;
+    if (!net->ifname)
+        return;
+
+    obj = virNWFilterBindingObjListFindByPortDev(driver->bindings, net->ifname);
+    if (!obj)
+        return;
+
+    def = virNWFilterBindingObjGetDef(obj);
+    virNWFilterTeardownFilter(def);
+    virNWFilterBindingObjDelete(obj, driver->bindingDir);
+
+    virNWFilterBindingObjListRemove(driver->bindings, obj);
+    virNWFilterBindingObjEndAPI(&obj);
 }