[libvirt] [PATCH 3/6] conf: Introduce virnwfilterobj

John Ferlan jferlan at redhat.com
Mon Mar 6 16:36:09 UTC 2017


Move all the NWFilterObj API's into their own module virnwfilterobj
from the nwfilter_conf

Purely code motion at this point, plus adjustments to cleanly build.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 po/POTFILES.in                         |   1 +
 src/Makefile.am                        |   6 +-
 src/conf/nwfilter_conf.c               | 348 +-----------------------------
 src/conf/nwfilter_conf.h               |  58 +----
 src/conf/virnwfilterobj.c              | 382 +++++++++++++++++++++++++++++++++
 src/conf/virnwfilterobj.h              |  85 ++++++++
 src/libvirt_private.syms               |  22 +-
 src/nwfilter/nwfilter_driver.c         |   1 -
 src/nwfilter/nwfilter_gentech_driver.h |   2 +-
 src/nwfilter/nwfilter_tech_driver.h    |   2 +-
 10 files changed, 489 insertions(+), 418 deletions(-)
 create mode 100644 src/conf/virnwfilterobj.c
 create mode 100644 src/conf/virnwfilterobj.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 50289a5..ceda3ed 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -44,6 +44,7 @@ src/conf/virchrdev.c
 src/conf/virdomainobjlist.c
 src/conf/virinterfaceobj.c
 src/conf/virnodedeviceobj.c
+src/conf/virnwfilterobj.c
 src/conf/virsecretobj.c
 src/cpu/cpu.c
 src/cpu/cpu_arm.c
diff --git a/src/Makefile.am b/src/Makefile.am
index c85927f..f2c35b1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -369,11 +369,13 @@ NWFILTER_PARAM_CONF_SOURCES =					\
 		conf/nwfilter_params.c conf/nwfilter_params.h	\
 		conf/nwfilter_ipaddrmap.c			\
 		conf/nwfilter_ipaddrmap.h			\
-		conf/nwfilter_conf.h
+		conf/nwfilter_conf.h                            \
+		conf/virnwfilterobj.h
 
 NWFILTER_CONF_SOURCES =						\
 		$(NWFILTER_PARAM_CONF_SOURCES)			\
-		conf/nwfilter_conf.c conf/nwfilter_conf.h
+		conf/nwfilter_conf.c conf/nwfilter_conf.h	\
+		conf/virnwfilterobj.c conf/virnwfilterobj.h
 
 # Storage driver generic impl APIs
 STORAGE_CONF_SOURCES =                                         \
diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
index f529081..c4e8ec1 100644
--- a/src/conf/nwfilter_conf.c
+++ b/src/conf/nwfilter_conf.c
@@ -30,7 +30,6 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <dirent.h>
 #if HAVE_NET_ETHERNET_H
 # include <net/ethernet.h>
 #endif
@@ -344,32 +343,6 @@ virNWFilterDefFree(virNWFilterDefPtr def)
 }
 
 
-void
-virNWFilterObjFree(virNWFilterObjPtr obj)
-{
-    if (!obj)
-        return;
-
-    virNWFilterDefFree(obj->def);
-    virNWFilterDefFree(obj->newDef);
-
-    virMutexDestroy(&obj->lock);
-
-    VIR_FREE(obj);
-}
-
-
-void
-virNWFilterObjListFree(virNWFilterObjListPtr nwfilters)
-{
-    size_t i;
-    for (i = 0; i < nwfilters->count; i++)
-        virNWFilterObjFree(nwfilters->objs[i]);
-    VIR_FREE(nwfilters->objs);
-    nwfilters->count = 0;
-}
-
-
 static int
 virNWFilterRuleDefAddVar(virNWFilterRuleDefPtr nwf,
                          nwItemDesc *item,
@@ -418,27 +391,6 @@ virNWFilterRuleDefAddString(virNWFilterRuleDefPtr nwf,
 }
 
 
-void
-virNWFilterObjRemove(virNWFilterObjListPtr nwfilters,
-                     virNWFilterObjPtr nwfilter)
-{
-    size_t i;
-
-    virNWFilterObjUnlock(nwfilter);
-
-    for (i = 0; i < nwfilters->count; i++) {
-        virNWFilterObjLock(nwfilters->objs[i]);
-        if (nwfilters->objs[i] == nwfilter) {
-            virNWFilterObjUnlock(nwfilters->objs[i]);
-            virNWFilterObjFree(nwfilters->objs[i]);
-
-            VIR_DELETE_ELEMENT(nwfilters->objs, i, nwfilters->count);
-            break;
-        }
-        virNWFilterObjUnlock(nwfilters->objs[i]);
-    }
-}
-
 union data {
     void *v;
     char *c;
@@ -2779,39 +2731,6 @@ virNWFilterDefParseFile(const char *filename)
 }
 
 
-virNWFilterObjPtr
-virNWFilterObjFindByUUID(virNWFilterObjListPtr nwfilters,
-                         const unsigned char *uuid)
-{
-    size_t i;
-
-    for (i = 0; i < nwfilters->count; i++) {
-        virNWFilterObjLock(nwfilters->objs[i]);
-        if (!memcmp(nwfilters->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN))
-            return nwfilters->objs[i];
-        virNWFilterObjUnlock(nwfilters->objs[i]);
-    }
-
-    return NULL;
-}
-
-
-virNWFilterObjPtr
-virNWFilterObjFindByName(virNWFilterObjListPtr nwfilters, const char *name)
-{
-    size_t i;
-
-    for (i = 0; i < nwfilters->count; i++) {
-        virNWFilterObjLock(nwfilters->objs[i]);
-        if (STREQ_NULLABLE(nwfilters->objs[i]->def->name, name))
-            return nwfilters->objs[i];
-        virNWFilterObjUnlock(nwfilters->objs[i]);
-    }
-
-    return NULL;
-}
-
-
 int virNWFilterSaveXML(const char *configDir,
                        virNWFilterDefPtr def,
                        const char *xml)
@@ -2860,62 +2779,6 @@ int virNWFilterSaveConfig(const char *configDir,
 }
 
 
-static int
-_virNWFilterDefLoopDetect(virNWFilterObjListPtr nwfilters,
-                          virNWFilterDefPtr def,
-                          const char *filtername)
-{
-    int rc = 0;
-    size_t i;
-    virNWFilterEntryPtr entry;
-    virNWFilterObjPtr obj;
-
-    if (!def)
-        return 0;
-
-    for (i = 0; i < def->nentries; i++) {
-        entry = def->filterEntries[i];
-        if (entry->include) {
-
-            if (STREQ(filtername, entry->include->filterref)) {
-                rc = -1;
-                break;
-            }
-
-            obj = virNWFilterObjFindByName(nwfilters,
-                                           entry->include->filterref);
-            if (obj) {
-                rc = _virNWFilterDefLoopDetect(nwfilters,
-                                               obj->def, filtername);
-
-                virNWFilterObjUnlock(obj);
-                if (rc < 0)
-                    break;
-            }
-        }
-    }
-
-    return rc;
-}
-
-
-/*
- * virNWFilterDefLoopDetect:
- * @nwfilters : the nwfilters to search
- * @def : the filter definition that may add a loop and is to be tested
- *
- * Detect a loop introduced through the filters being able to
- * reference each other.
- *
- * Returns 0 in case no loop was detected, -1 otherwise.
- */
-static int
-virNWFilterDefLoopDetect(virNWFilterObjListPtr nwfilters,
-                         virNWFilterDefPtr def)
-{
-    return _virNWFilterDefLoopDetect(nwfilters, def, def->name);
-}
-
 int nCallbackDriver;
 #define MAX_CALLBACK_DRIVER 10
 static virNWFilterCallbackDriverPtr callbackDrvArray[MAX_CALLBACK_DRIVER];
@@ -2987,7 +2850,7 @@ virNWFilterInstFiltersOnAllVMs(void)
     return 0;
 }
 
-static int
+int
 virNWFilterTriggerVMFilterRebuild(void)
 {
     size_t i;
@@ -3028,204 +2891,6 @@ virNWFilterTriggerVMFilterRebuild(void)
 
 
 int
-virNWFilterTestUnassignDef(virNWFilterObjPtr nwfilter)
-{
-    int rc = 0;
-
-    nwfilter->wantRemoved = 1;
-    /* trigger the update on VMs referencing the filter */
-    if (virNWFilterTriggerVMFilterRebuild())
-        rc = -1;
-
-    nwfilter->wantRemoved = 0;
-
-    return rc;
-}
-
-static bool
-virNWFilterDefEqual(const virNWFilterDef *def1, virNWFilterDefPtr def2,
-                    bool cmpUUIDs)
-{
-    bool ret = false;
-    unsigned char rem_uuid[VIR_UUID_BUFLEN];
-    char *xml1, *xml2 = NULL;
-
-    if (!cmpUUIDs) {
-        /* make sure the UUIDs are equal */
-        memcpy(rem_uuid, def2->uuid, sizeof(rem_uuid));
-        memcpy(def2->uuid, def1->uuid, sizeof(def2->uuid));
-    }
-
-    if (!(xml1 = virNWFilterDefFormat(def1)) ||
-        !(xml2 = virNWFilterDefFormat(def2)))
-        goto cleanup;
-
-    ret = STREQ(xml1, xml2);
-
- cleanup:
-    if (!cmpUUIDs)
-        memcpy(def2->uuid, rem_uuid, sizeof(rem_uuid));
-
-    VIR_FREE(xml1);
-    VIR_FREE(xml2);
-
-    return ret;
-}
-
-virNWFilterObjPtr
-virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters,
-                        virNWFilterDefPtr def)
-{
-    virNWFilterObjPtr nwfilter;
-
-    nwfilter = virNWFilterObjFindByUUID(nwfilters, def->uuid);
-
-    if (nwfilter) {
-        if (STRNEQ(def->name, nwfilter->def->name)) {
-            virReportError(VIR_ERR_OPERATION_FAILED,
-                           _("filter with same UUID but different name "
-                             "('%s') already exists"),
-                           nwfilter->def->name);
-            virNWFilterObjUnlock(nwfilter);
-            return NULL;
-        }
-        virNWFilterObjUnlock(nwfilter);
-    } else {
-        nwfilter = virNWFilterObjFindByName(nwfilters, def->name);
-        if (nwfilter) {
-            char uuidstr[VIR_UUID_STRING_BUFLEN];
-            virUUIDFormat(nwfilter->def->uuid, uuidstr);
-            virReportError(VIR_ERR_OPERATION_FAILED,
-                           _("filter '%s' already exists with uuid %s"),
-                           def->name, uuidstr);
-            virNWFilterObjUnlock(nwfilter);
-            return NULL;
-        }
-    }
-
-    if (virNWFilterDefLoopDetect(nwfilters, def) < 0) {
-        virReportError(VIR_ERR_OPERATION_FAILED,
-                       "%s", _("filter would introduce a loop"));
-        return NULL;
-    }
-
-
-    if ((nwfilter = virNWFilterObjFindByName(nwfilters, def->name))) {
-
-        if (virNWFilterDefEqual(def, nwfilter->def, false)) {
-            virNWFilterDefFree(nwfilter->def);
-            nwfilter->def = def;
-            return nwfilter;
-        }
-
-        nwfilter->newDef = def;
-        /* trigger the update on VMs referencing the filter */
-        if (virNWFilterTriggerVMFilterRebuild()) {
-            nwfilter->newDef = NULL;
-            virNWFilterObjUnlock(nwfilter);
-            return NULL;
-        }
-
-        virNWFilterDefFree(nwfilter->def);
-        nwfilter->def = def;
-        nwfilter->newDef = NULL;
-        return nwfilter;
-    }
-
-    if (VIR_ALLOC(nwfilter) < 0)
-        return NULL;
-
-    if (virMutexInitRecursive(&nwfilter->lock) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("cannot initialize mutex"));
-        VIR_FREE(nwfilter);
-        return NULL;
-    }
-    virNWFilterObjLock(nwfilter);
-    nwfilter->active = 0;
-
-    if (VIR_APPEND_ELEMENT_COPY(nwfilters->objs,
-                                nwfilters->count, nwfilter) < 0) {
-        virNWFilterObjUnlock(nwfilter);
-        virNWFilterObjFree(nwfilter);
-        return NULL;
-    }
-    nwfilter->def = def;
-
-    return nwfilter;
-}
-
-
-static virNWFilterObjPtr
-virNWFilterLoadConfig(virNWFilterObjListPtr nwfilters,
-                      const char *configDir,
-                      const char *name)
-{
-    virNWFilterDefPtr def = NULL;
-    virNWFilterObjPtr nwfilter;
-    char *configFile = NULL;
-
-    if (!(configFile = virFileBuildPath(configDir, name, ".xml")))
-        goto error;
-
-    if (!(def = virNWFilterDefParseFile(configFile)))
-        goto error;
-
-    if (STRNEQ(name, def->name)) {
-        virReportError(VIR_ERR_XML_ERROR,
-                       _("network filter config filename '%s' "
-                         "does not match name '%s'"),
-                       configFile, def->name);
-        goto error;
-    }
-
-    /* We generated a UUID, make it permanent by saving the config to disk */
-    if (!def->uuid_specified &&
-        virNWFilterSaveConfig(configDir, def) < 0)
-        goto error;
-
-    if (!(nwfilter = virNWFilterObjAssignDef(nwfilters, def)))
-        goto error;
-
-    VIR_FREE(configFile);
-    return nwfilter;
-
- error:
-    VIR_FREE(configFile);
-    virNWFilterDefFree(def);
-    return NULL;
-}
-
-
-int
-virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters,
-                          const char *configDir)
-{
-    DIR *dir;
-    struct dirent *entry;
-    int ret = -1;
-    int rc;
-
-    if ((rc = virDirOpenIfExists(&dir, configDir)) <= 0)
-        return rc;
-
-    while ((ret = virDirRead(dir, &entry, configDir)) > 0) {
-        virNWFilterObjPtr nwfilter;
-
-        if (!virFileStripSuffix(entry->d_name, ".xml"))
-            continue;
-
-        nwfilter = virNWFilterLoadConfig(nwfilters, configDir, entry->d_name);
-        if (nwfilter)
-            virNWFilterObjUnlock(nwfilter);
-    }
-
-    VIR_DIR_CLOSE(dir);
-    return ret;
-}
-
-
-int
 virNWFilterSaveDef(const char *configDir,
                    virNWFilterDefPtr def)
 {
@@ -3568,17 +3233,6 @@ void virNWFilterConfLayerShutdown(void)
 }
 
 
-void virNWFilterObjLock(virNWFilterObjPtr obj)
-{
-    virMutexLock(&obj->lock);
-}
-
-void virNWFilterObjUnlock(virNWFilterObjPtr obj)
-{
-    virMutexUnlock(&obj->lock);
-}
-
-
 bool virNWFilterRuleIsProtocolIPv4(virNWFilterRuleDefPtr rule)
 {
     if (rule->prtclType >= VIR_NWFILTER_RULE_PROTOCOL_TCP &&
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index d87da0c..96c330d 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -546,41 +546,6 @@ struct _virNWFilterDef {
 };
 
 
-typedef struct _virNWFilterObj virNWFilterObj;
-typedef virNWFilterObj *virNWFilterObjPtr;
-
-struct _virNWFilterObj {
-    virMutex lock;
-
-    int active;
-    int wantRemoved;
-
-    virNWFilterDefPtr def;
-    virNWFilterDefPtr newDef;
-};
-
-
-typedef struct _virNWFilterObjList virNWFilterObjList;
-typedef virNWFilterObjList *virNWFilterObjListPtr;
-struct _virNWFilterObjList {
-    size_t count;
-    virNWFilterObjPtr *objs;
-};
-
-
-typedef struct _virNWFilterDriverState virNWFilterDriverState;
-typedef virNWFilterDriverState *virNWFilterDriverStatePtr;
-struct _virNWFilterDriverState {
-    virMutex lock;
-    bool privileged;
-
-    virNWFilterObjList nwfilters;
-
-    char *configDir;
-    bool watchingFirewallD;
-};
-
-
 typedef enum {
     STEP_APPLY_NEW,
     STEP_TEAR_NEW,
@@ -598,18 +563,8 @@ struct domUpdateCBStruct {
 void virNWFilterRuleDefFree(virNWFilterRuleDefPtr def);
 
 void virNWFilterDefFree(virNWFilterDefPtr def);
-void virNWFilterObjListFree(virNWFilterObjListPtr nwfilters);
-void virNWFilterObjRemove(virNWFilterObjListPtr nwfilters,
-                          virNWFilterObjPtr nwfilter);
-
-void virNWFilterObjFree(virNWFilterObjPtr obj);
-
-virNWFilterObjPtr virNWFilterObjFindByUUID(virNWFilterObjListPtr nwfilters,
-                                           const unsigned char *uuid);
-
-virNWFilterObjPtr virNWFilterObjFindByName(virNWFilterObjListPtr nwfilters,
-                                           const char *name);
 
+int virNWFilterTriggerVMFilterRebuild(void);
 
 int virNWFilterSaveDef(const char *configDir,
                        virNWFilterDefPtr def);
@@ -617,11 +572,6 @@ int virNWFilterSaveDef(const char *configDir,
 int virNWFilterDeleteDef(const char *configDir,
                          virNWFilterDefPtr def);
 
-virNWFilterObjPtr virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters,
-                                          virNWFilterDefPtr def);
-
-int virNWFilterTestUnassignDef(virNWFilterObjPtr nwfilter);
-
 virNWFilterDefPtr virNWFilterDefParseNode(xmlDocPtr xml,
                                           xmlNodePtr root);
 
@@ -634,18 +584,12 @@ int virNWFilterSaveXML(const char *configDir,
 int virNWFilterSaveConfig(const char *configDir,
                           virNWFilterDefPtr def);
 
-int virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters,
-                              const char *configDir);
-
 char *virNWFilterConfigFile(const char *dir,
                             const char *name);
 
 virNWFilterDefPtr virNWFilterDefParseString(const char *xml);
 virNWFilterDefPtr virNWFilterDefParseFile(const char *filename);
 
-void virNWFilterObjLock(virNWFilterObjPtr obj);
-void virNWFilterObjUnlock(virNWFilterObjPtr obj);
-
 void virNWFilterWriteLockFilterUpdates(void);
 void virNWFilterReadLockFilterUpdates(void);
 void virNWFilterUnlockFilterUpdates(void);
diff --git a/src/conf/virnwfilterobj.c b/src/conf/virnwfilterobj.c
new file mode 100644
index 0000000..869365c
--- /dev/null
+++ b/src/conf/virnwfilterobj.c
@@ -0,0 +1,382 @@
+/*
+ * virnwfilterobj.c: network filter object processing
+ *                   (derived from nwfilter_conf.c)
+ *
+ * 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 <dirent.h>
+
+#include "datatypes.h"
+
+#include "viralloc.h"
+#include "virerror.h"
+#include "virfile.h"
+#include "virlog.h"
+#include "virnwfilterobj.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_NWFILTER
+
+VIR_LOG_INIT("conf.virnwfilterobj");
+
+
+void
+virNWFilterObjFree(virNWFilterObjPtr obj)
+{
+    if (!obj)
+        return;
+
+    virNWFilterDefFree(obj->def);
+    virNWFilterDefFree(obj->newDef);
+
+    virMutexDestroy(&obj->lock);
+
+    VIR_FREE(obj);
+}
+
+
+void
+virNWFilterObjListFree(virNWFilterObjListPtr nwfilters)
+{
+    size_t i;
+    for (i = 0; i < nwfilters->count; i++)
+        virNWFilterObjFree(nwfilters->objs[i]);
+    VIR_FREE(nwfilters->objs);
+    nwfilters->count = 0;
+}
+
+
+void
+virNWFilterObjRemove(virNWFilterObjListPtr nwfilters,
+                     virNWFilterObjPtr nwfilter)
+{
+    size_t i;
+
+    virNWFilterObjUnlock(nwfilter);
+
+    for (i = 0; i < nwfilters->count; i++) {
+        virNWFilterObjLock(nwfilters->objs[i]);
+        if (nwfilters->objs[i] == nwfilter) {
+            virNWFilterObjUnlock(nwfilters->objs[i]);
+            virNWFilterObjFree(nwfilters->objs[i]);
+
+            VIR_DELETE_ELEMENT(nwfilters->objs, i, nwfilters->count);
+            break;
+        }
+        virNWFilterObjUnlock(nwfilters->objs[i]);
+    }
+}
+
+
+virNWFilterObjPtr
+virNWFilterObjFindByUUID(virNWFilterObjListPtr nwfilters,
+                         const unsigned char *uuid)
+{
+    size_t i;
+
+    for (i = 0; i < nwfilters->count; i++) {
+        virNWFilterObjLock(nwfilters->objs[i]);
+        if (!memcmp(nwfilters->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN))
+            return nwfilters->objs[i];
+        virNWFilterObjUnlock(nwfilters->objs[i]);
+    }
+
+    return NULL;
+}
+
+
+virNWFilterObjPtr
+virNWFilterObjFindByName(virNWFilterObjListPtr nwfilters, const char *name)
+{
+    size_t i;
+
+    for (i = 0; i < nwfilters->count; i++) {
+        virNWFilterObjLock(nwfilters->objs[i]);
+        if (STREQ_NULLABLE(nwfilters->objs[i]->def->name, name))
+            return nwfilters->objs[i];
+        virNWFilterObjUnlock(nwfilters->objs[i]);
+    }
+
+    return NULL;
+}
+
+
+static int
+_virNWFilterDefLoopDetect(virNWFilterObjListPtr nwfilters,
+                          virNWFilterDefPtr def,
+                          const char *filtername)
+{
+    int rc = 0;
+    size_t i;
+    virNWFilterEntryPtr entry;
+    virNWFilterObjPtr obj;
+
+    if (!def)
+        return 0;
+
+    for (i = 0; i < def->nentries; i++) {
+        entry = def->filterEntries[i];
+        if (entry->include) {
+
+            if (STREQ(filtername, entry->include->filterref)) {
+                rc = -1;
+                break;
+            }
+
+            obj = virNWFilterObjFindByName(nwfilters,
+                                           entry->include->filterref);
+            if (obj) {
+                rc = _virNWFilterDefLoopDetect(nwfilters,
+                                               obj->def, filtername);
+
+                virNWFilterObjUnlock(obj);
+                if (rc < 0)
+                    break;
+            }
+        }
+    }
+
+    return rc;
+}
+
+
+/*
+ * virNWFilterDefLoopDetect:
+ * @nwfilters : the nwfilters to search
+ * @def : the filter definition that may add a loop and is to be tested
+ *
+ * Detect a loop introduced through the filters being able to
+ * reference each other.
+ *
+ * Returns 0 in case no loop was detected, -1 otherwise.
+ */
+static int
+virNWFilterDefLoopDetect(virNWFilterObjListPtr nwfilters,
+                         virNWFilterDefPtr def)
+{
+    return _virNWFilterDefLoopDetect(nwfilters, def, def->name);
+}
+
+
+int
+virNWFilterTestUnassignDef(virNWFilterObjPtr nwfilter)
+{
+    int rc = 0;
+
+    nwfilter->wantRemoved = 1;
+    /* trigger the update on VMs referencing the filter */
+    if (virNWFilterTriggerVMFilterRebuild())
+        rc = -1;
+
+    nwfilter->wantRemoved = 0;
+
+    return rc;
+}
+
+static bool
+virNWFilterDefEqual(const virNWFilterDef *def1, virNWFilterDefPtr def2,
+                    bool cmpUUIDs)
+{
+    bool ret = false;
+    unsigned char rem_uuid[VIR_UUID_BUFLEN];
+    char *xml1, *xml2 = NULL;
+
+    if (!cmpUUIDs) {
+        /* make sure the UUIDs are equal */
+        memcpy(rem_uuid, def2->uuid, sizeof(rem_uuid));
+        memcpy(def2->uuid, def1->uuid, sizeof(def2->uuid));
+    }
+
+    if (!(xml1 = virNWFilterDefFormat(def1)) ||
+        !(xml2 = virNWFilterDefFormat(def2)))
+        goto cleanup;
+
+    ret = STREQ(xml1, xml2);
+
+ cleanup:
+    if (!cmpUUIDs)
+        memcpy(def2->uuid, rem_uuid, sizeof(rem_uuid));
+
+    VIR_FREE(xml1);
+    VIR_FREE(xml2);
+
+    return ret;
+}
+
+virNWFilterObjPtr
+virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters,
+                        virNWFilterDefPtr def)
+{
+    virNWFilterObjPtr nwfilter;
+
+    nwfilter = virNWFilterObjFindByUUID(nwfilters, def->uuid);
+
+    if (nwfilter) {
+        if (STRNEQ(def->name, nwfilter->def->name)) {
+            virReportError(VIR_ERR_OPERATION_FAILED,
+                           _("filter with same UUID but different name "
+                             "('%s') already exists"),
+                           nwfilter->def->name);
+            virNWFilterObjUnlock(nwfilter);
+            return NULL;
+        }
+        virNWFilterObjUnlock(nwfilter);
+    } else {
+        nwfilter = virNWFilterObjFindByName(nwfilters, def->name);
+        if (nwfilter) {
+            char uuidstr[VIR_UUID_STRING_BUFLEN];
+            virUUIDFormat(nwfilter->def->uuid, uuidstr);
+            virReportError(VIR_ERR_OPERATION_FAILED,
+                           _("filter '%s' already exists with uuid %s"),
+                           def->name, uuidstr);
+            virNWFilterObjUnlock(nwfilter);
+            return NULL;
+        }
+    }
+
+    if (virNWFilterDefLoopDetect(nwfilters, def) < 0) {
+        virReportError(VIR_ERR_OPERATION_FAILED,
+                       "%s", _("filter would introduce a loop"));
+        return NULL;
+    }
+
+
+    if ((nwfilter = virNWFilterObjFindByName(nwfilters, def->name))) {
+
+        if (virNWFilterDefEqual(def, nwfilter->def, false)) {
+            virNWFilterDefFree(nwfilter->def);
+            nwfilter->def = def;
+            return nwfilter;
+        }
+
+        nwfilter->newDef = def;
+        /* trigger the update on VMs referencing the filter */
+        if (virNWFilterTriggerVMFilterRebuild()) {
+            nwfilter->newDef = NULL;
+            virNWFilterObjUnlock(nwfilter);
+            return NULL;
+        }
+
+        virNWFilterDefFree(nwfilter->def);
+        nwfilter->def = def;
+        nwfilter->newDef = NULL;
+        return nwfilter;
+    }
+
+    if (VIR_ALLOC(nwfilter) < 0)
+        return NULL;
+
+    if (virMutexInitRecursive(&nwfilter->lock) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("cannot initialize mutex"));
+        VIR_FREE(nwfilter);
+        return NULL;
+    }
+    virNWFilterObjLock(nwfilter);
+    nwfilter->active = 0;
+
+    if (VIR_APPEND_ELEMENT_COPY(nwfilters->objs,
+                                nwfilters->count, nwfilter) < 0) {
+        virNWFilterObjUnlock(nwfilter);
+        virNWFilterObjFree(nwfilter);
+        return NULL;
+    }
+    nwfilter->def = def;
+
+    return nwfilter;
+}
+
+
+static virNWFilterObjPtr
+virNWFilterLoadConfig(virNWFilterObjListPtr nwfilters,
+                      const char *configDir,
+                      const char *name)
+{
+    virNWFilterDefPtr def = NULL;
+    virNWFilterObjPtr nwfilter;
+    char *configFile = NULL;
+
+    if (!(configFile = virFileBuildPath(configDir, name, ".xml")))
+        goto error;
+
+    if (!(def = virNWFilterDefParseFile(configFile)))
+        goto error;
+
+    if (STRNEQ(name, def->name)) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("network filter config filename '%s' "
+                         "does not match name '%s'"),
+                       configFile, def->name);
+        goto error;
+    }
+
+    /* We generated a UUID, make it permanent by saving the config to disk */
+    if (!def->uuid_specified &&
+        virNWFilterSaveConfig(configDir, def) < 0)
+        goto error;
+
+    if (!(nwfilter = virNWFilterObjAssignDef(nwfilters, def)))
+        goto error;
+
+    VIR_FREE(configFile);
+    return nwfilter;
+
+ error:
+    VIR_FREE(configFile);
+    virNWFilterDefFree(def);
+    return NULL;
+}
+
+
+int
+virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters,
+                          const char *configDir)
+{
+    DIR *dir;
+    struct dirent *entry;
+    int ret = -1;
+    int rc;
+
+    if ((rc = virDirOpenIfExists(&dir, configDir)) <= 0)
+        return rc;
+
+    while ((ret = virDirRead(dir, &entry, configDir)) > 0) {
+        virNWFilterObjPtr nwfilter;
+
+        if (!virFileStripSuffix(entry->d_name, ".xml"))
+            continue;
+
+        nwfilter = virNWFilterLoadConfig(nwfilters, configDir, entry->d_name);
+        if (nwfilter)
+            virNWFilterObjUnlock(nwfilter);
+    }
+
+    VIR_DIR_CLOSE(dir);
+    return ret;
+}
+
+
+void virNWFilterObjLock(virNWFilterObjPtr obj)
+{
+    virMutexLock(&obj->lock);
+}
+
+
+void virNWFilterObjUnlock(virNWFilterObjPtr obj)
+{
+    virMutexUnlock(&obj->lock);
+}
diff --git a/src/conf/virnwfilterobj.h b/src/conf/virnwfilterobj.h
new file mode 100644
index 0000000..00b8d0a
--- /dev/null
+++ b/src/conf/virnwfilterobj.h
@@ -0,0 +1,85 @@
+/*
+ * virnwfilterobj.h: network filter object processing
+ *                  (derived from nwfilter_conf.h)
+ *
+ * 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/>.
+ */
+#ifndef VIRNWFILTEROBJ_H
+# define VIRNWFILTEROBJ_H
+
+# include "internal.h"
+
+# include "nwfilter_conf.h"
+
+typedef struct _virNWFilterObj virNWFilterObj;
+typedef virNWFilterObj *virNWFilterObjPtr;
+
+struct _virNWFilterObj {
+    virMutex lock;
+
+    int active;
+    int wantRemoved;
+
+    virNWFilterDefPtr def;
+    virNWFilterDefPtr newDef;
+};
+
+
+typedef struct _virNWFilterObjList virNWFilterObjList;
+typedef virNWFilterObjList *virNWFilterObjListPtr;
+struct _virNWFilterObjList {
+    size_t count;
+    virNWFilterObjPtr *objs;
+};
+
+
+typedef struct _virNWFilterDriverState virNWFilterDriverState;
+typedef virNWFilterDriverState *virNWFilterDriverStatePtr;
+struct _virNWFilterDriverState {
+    virMutex lock;
+    bool privileged;
+
+    virNWFilterObjList nwfilters;
+
+    char *configDir;
+    bool watchingFirewallD;
+};
+
+void virNWFilterObjListFree(virNWFilterObjListPtr nwfilters);
+
+void virNWFilterObjRemove(virNWFilterObjListPtr nwfilters,
+                          virNWFilterObjPtr nwfilter);
+
+void virNWFilterObjFree(virNWFilterObjPtr obj);
+
+virNWFilterObjPtr virNWFilterObjFindByUUID(virNWFilterObjListPtr nwfilters,
+                                           const unsigned char *uuid);
+
+virNWFilterObjPtr virNWFilterObjFindByName(virNWFilterObjListPtr nwfilters,
+                                           const char *name);
+
+virNWFilterObjPtr virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters,
+                                          virNWFilterDefPtr def);
+
+int virNWFilterTestUnassignDef(virNWFilterObjPtr nwfilter);
+
+int virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters,
+                              const char *configDir);
+
+void virNWFilterObjLock(virNWFilterObjPtr obj);
+
+void virNWFilterObjUnlock(virNWFilterObjPtr obj);
+
+#endif /* VIRNWFILTEROBJ_H */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 80fe9d8..3c4b943 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -746,14 +746,6 @@ virNWFilterDefParseString;
 virNWFilterDeleteDef;
 virNWFilterInstFiltersOnAllVMs;
 virNWFilterJumpTargetTypeToString;
-virNWFilterLoadAllConfigs;
-virNWFilterObjAssignDef;
-virNWFilterObjFindByName;
-virNWFilterObjFindByUUID;
-virNWFilterObjListFree;
-virNWFilterObjLock;
-virNWFilterObjRemove;
-virNWFilterObjUnlock;
 virNWFilterPrintStateMatchFlags;
 virNWFilterPrintTCPFlags;
 virNWFilterReadLockFilterUpdates;
@@ -765,7 +757,7 @@ virNWFilterRuleIsProtocolIPv4;
 virNWFilterRuleIsProtocolIPv6;
 virNWFilterRuleProtocolTypeToString;
 virNWFilterSaveDef;
-virNWFilterTestUnassignDef;
+virNWFilterTriggerVMFilterRebuild;
 virNWFilterUnlockFilterUpdates;
 virNWFilterUnRegisterCallbackDriver;
 virNWFilterWriteLockFilterUpdates;
@@ -964,6 +956,18 @@ virNodeDeviceObjRemove;
 virNodeDeviceObjUnlock;
 
 
+# conf/virnwfilterobj.h
+virNWFilterLoadAllConfigs;
+virNWFilterObjAssignDef;
+virNWFilterObjFindByName;
+virNWFilterObjFindByUUID;
+virNWFilterObjListFree;
+virNWFilterObjLock;
+virNWFilterObjRemove;
+virNWFilterObjUnlock;
+virNWFilterTestUnassignDef;
+
+
 # conf/virsecretobj.h
 virSecretLoadAllConfigs;
 virSecretObjDeleteConfig;
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index 5e4f076..6ce2bfd 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -37,7 +37,6 @@
 #include "viralloc.h"
 #include "domain_conf.h"
 #include "domain_nwfilter.h"
-#include "nwfilter_conf.h"
 #include "nwfilter_driver.h"
 #include "nwfilter_gentech_driver.h"
 #include "configmake.h"
diff --git a/src/nwfilter/nwfilter_gentech_driver.h b/src/nwfilter/nwfilter_gentech_driver.h
index 8349ab4..7192487 100644
--- a/src/nwfilter/nwfilter_gentech_driver.h
+++ b/src/nwfilter/nwfilter_gentech_driver.h
@@ -24,7 +24,7 @@
 #ifndef __NWFILTER_GENTECH_DRIVER_H
 # define __NWFILTER_GENTECH_DRIVER_H
 
-# include "nwfilter_conf.h"
+# include "virnwfilterobj.h"
 # include "nwfilter_tech_driver.h"
 
 virNWFilterTechDriverPtr virNWFilterTechDriverForName(const char *name);
diff --git a/src/nwfilter/nwfilter_tech_driver.h b/src/nwfilter/nwfilter_tech_driver.h
index 7b6f56f..bc30496 100644
--- a/src/nwfilter/nwfilter_tech_driver.h
+++ b/src/nwfilter/nwfilter_tech_driver.h
@@ -26,7 +26,7 @@
 #ifndef __NWFILTER_TECH_DRIVER_H__
 # define __NWFILTER_TECH_DRIVER_H__
 
-# include "nwfilter_conf.h"
+# include "virnwfilterobj.h"
 
 typedef struct _virNWFilterTechDriver virNWFilterTechDriver;
 typedef virNWFilterTechDriver *virNWFilterTechDriverPtr;
-- 
2.9.3




More information about the libvir-list mailing list