[libvirt] [PATCH 13/14] nwfilter: keep track of active filter bindings

Daniel P. Berrangé posted 14 patches 6 years, 7 months ago
There is a newer version of this series
[libvirt] [PATCH 13/14] nwfilter: keep track of active filter bindings
Posted by Daniel P. Berrangé 6 years, 7 months ago
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.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 src/conf/virnwfilterobj.h      |  3 +++
 src/nwfilter/nwfilter_driver.c | 57 +++++++++++++++++++++++++++++++++---------
 2 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/src/conf/virnwfilterobj.h b/src/conf/virnwfilterobj.h
index 433b0402d0..5e69313476 100644
--- a/src/conf/virnwfilterobj.h
+++ b/src/conf/virnwfilterobj.h
@@ -37,6 +37,9 @@ struct _virNWFilterDriverState {
 
     virNWFilterObjListPtr nwfilters;
 
+    /* ifname -> virNWFilterBindingPtr */
+    virHashTablePtr bindings;
+
     char *configDir;
 };
 
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index a375e9bda8..ccbcfbbf67 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -163,6 +163,13 @@ nwfilterDriverInstallDBusMatches(DBusConnection *sysbus ATTRIBUTE_UNUSED)
 
 #endif /* HAVE_FIREWALLD */
 
+static void virNWFilterBindingDataFree(void *payload, const void *name ATTRIBUTE_UNUSED)
+{
+    virNWFilterBindingPtr binding = payload;
+
+    virNWFilterBindingFree(binding);
+}
+
 /**
  * nwfilterStateInitialize:
  *
@@ -190,6 +197,10 @@ nwfilterStateInitialize(bool privileged,
     if (!(driver->nwfilters = virNWFilterObjListNew()))
         goto error;
 
+    if (!(driver->bindings = virHashCreate(0,
+                                           virNWFilterBindingDataFree)))
+        goto error;
+
     if (!privileged)
         return 0;
 
@@ -335,6 +346,8 @@ nwfilterStateCleanup(void)
         nwfilterDriverUnlock();
     }
 
+    virHashFree(driver->bindings);
+
     /* free inactive nwfilters */
     virNWFilterObjListFree(driver->nwfilters);
 
@@ -649,10 +662,28 @@ nwfilterInstantiateFilter(const char *vmname,
     virNWFilterBindingPtr binding;
     int ret;
 
-    if (!(binding = virNWFilterBindingForNet(vmname, vmuuid, net)))
+    nwfilterDriverLock();
+    binding = virHashLookup(driver->bindings, net->ifname);
+    if (binding) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Filter already present for NIC %s"), net->ifname);
+        nwfilterDriverUnlock();
+        return -1;
+    }
+    if (!(binding = virNWFilterBindingForNet(vmname, vmuuid, net))) {
+        nwfilterDriverUnlock();
         return -1;
+    }
+    virHashAddEntry(driver->bindings, net->ifname, binding);
+    nwfilterDriverUnlock();
+
     ret = virNWFilterInstantiateFilter(driver, binding);
-    virNWFilterBindingFree(binding);
+
+    if (ret < 0) {
+        nwfilterDriverLock();
+        virHashRemoveEntry(driver->bindings, net->ifname);
+        nwfilterDriverUnlock();
+    }
     return ret;
 }
 
@@ -660,16 +691,18 @@ nwfilterInstantiateFilter(const char *vmname,
 static void
 nwfilterTeardownFilter(virDomainNetDefPtr net)
 {
-    virNWFilterBinding 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,
-    };
-    if ((net->ifname) && (net->filter))
-        virNWFilterTeardownFilter(&binding);
+    virNWFilterBindingPtr binding;
+    if (!net->ifname)
+        return;
+
+    nwfilterDriverLock();
+    binding = virHashSteal(driver->bindings, net->ifname);
+    nwfilterDriverUnlock();
+    if (!binding)
+        return;
+
+    virNWFilterTeardownFilter(binding);
+    virNWFilterBindingFree(binding);
 }
 
 
-- 
2.14.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list