diff --git a/src/conf/Makefile.inc.am b/src/conf/Makefile.inc.am
index f5fb323233..3d55ba688d 100644
--- a/src/conf/Makefile.inc.am
+++ b/src/conf/Makefile.inc.am
@@ -87,6 +87,8 @@ NWFILTER_CONF_SOURCES = \
conf/virnwfilterobj.h \
conf/virnwfilterbindingdef.c \
conf/virnwfilterbindingdef.h \
+ conf/virnwfilterbindingobj.c \
+ conf/virnwfilterbindingobj.h \
$(NULL)
STORAGE_CONF_SOURCES = \
diff --git a/src/conf/virnwfilterbindingobj.c b/src/conf/virnwfilterbindingobj.c
new file mode 100644
index 0000000000..a145fb4538
--- /dev/null
+++ b/src/conf/virnwfilterbindingobj.c
@@ -0,0 +1,299 @@
+/*
+ * virnwfilterbindingobj.c: network filter binding object processing
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * 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
+ * .
+ */
+
+#include
+
+#include "viralloc.h"
+#include "virerror.h"
+#include "virstring.h"
+#include "nwfilter_params.h"
+#include "virnwfilterbindingobj.h"
+#include "viruuid.h"
+#include "virfile.h"
+
+
+#define VIR_FROM_THIS VIR_FROM_NWFILTER
+
+struct _virNWFilterBindingObj {
+ virObjectLockable parent;
+
+ bool removing;
+ virNWFilterBindingDefPtr def;
+};
+
+
+static virClassPtr virNWFilterBindingObjClass;
+static void virNWFilterBindingObjDispose(void *obj);
+
+static int
+virNWFilterBindingObjOnceInit(void)
+{
+ if (!VIR_CLASS_NEW(virNWFilterBindingObj, virClassForObjectLockable()))
+ return -1;
+
+ return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virNWFilterBindingObj)
+
+virNWFilterBindingObjPtr
+virNWFilterBindingObjNew(void)
+{
+ if (virNWFilterBindingObjInitialize() < 0)
+ return NULL;
+
+ return virObjectNew(virNWFilterBindingObjClass);
+}
+
+
+static void
+virNWFilterBindingObjDispose(void *obj)
+{
+ virNWFilterBindingObjPtr bobj = obj;
+
+ virNWFilterBindingDefFree(bobj->def);
+}
+
+
+virNWFilterBindingDefPtr
+virNWFilterBindingObjGetDef(virNWFilterBindingObjPtr obj)
+{
+ return obj->def;
+}
+
+
+void
+virNWFilterBindingObjSetDef(virNWFilterBindingObjPtr obj,
+ virNWFilterBindingDefPtr def)
+{
+ virNWFilterBindingDefFree(obj->def);
+ obj->def = def;
+}
+
+
+bool
+virNWFilterBindingObjGetRemoving(virNWFilterBindingObjPtr obj)
+{
+ return obj->removing;
+}
+
+
+void
+virNWFilterBindingObjSetRemoving(virNWFilterBindingObjPtr obj,
+ bool removing)
+{
+ obj->removing = removing;
+}
+
+
+/**
+ * virNWFilterBindingObjEndAPI:
+ * @obj: binding object
+ *
+ * Finish working with a binding object in an API. This function
+ * clears whatever was left of a domain that was gathered using
+ * virNWFilterBindingObjListFindByPortDev(). Currently that means
+ * only unlocking and decrementing the reference counter of that
+ * object. And in order to make sure the caller does not access
+ * the object, the pointer is cleared.
+ */
+void
+virNWFilterBindingObjEndAPI(virNWFilterBindingObjPtr *obj)
+{
+ if (!*obj)
+ return;
+
+ virObjectUnlock(*obj);
+ virObjectUnref(*obj);
+ *obj = NULL;
+}
+
+
+char *
+virNWFilterBindingObjConfigFile(const char *dir,
+ const char *name)
+{
+ char *ret;
+
+ ignore_value(virAsprintf(&ret, "%s/%s.xml", dir, name));
+ return ret;
+}
+
+
+int
+virNWFilterBindingObjSave(const virNWFilterBindingObj *obj,
+ const char *statusDir)
+{
+ char *filename;
+ char *xml = NULL;
+ int ret = -1;
+
+ if (!(filename = virNWFilterBindingObjConfigFile(statusDir,
+ obj->def->portdevname)))
+ return -1;
+
+ if (!(xml = virNWFilterBindingObjFormat(obj)))
+ goto cleanup;
+
+ if (virFileMakePath(statusDir) < 0) {
+ virReportSystemError(errno,
+ _("cannot create config directory '%s'"),
+ statusDir);
+ goto cleanup;
+ }
+
+ ret = virXMLSaveFile(filename,
+ obj->def->portdevname, "nwfilter-binding-create",
+ xml);
+
+ cleanup:
+ VIR_FREE(xml);
+ VIR_FREE(filename);
+ return ret;
+}
+
+
+int
+virNWFilterBindingObjDelete(const virNWFilterBindingObj *obj,
+ const char *statusDir)
+{
+ char *filename;
+ int ret = -1;
+
+ if (!(filename = virNWFilterBindingObjConfigFile(statusDir,
+ obj->def->portdevname)))
+ return -1;
+
+ if (unlink(filename) < 0 &&
+ errno != ENOENT) {
+ virReportSystemError(errno,
+ _("Unable to remove status '%s' for nwfilter binding %s'"),
+ filename, obj->def->portdevname);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(filename);
+ return ret;
+}
+
+
+static virNWFilterBindingObjPtr
+virNWFilterBindingObjParseXML(xmlDocPtr doc,
+ xmlXPathContextPtr ctxt)
+{
+ virNWFilterBindingObjPtr ret;
+ xmlNodePtr node;
+
+ if (!(ret = virNWFilterBindingObjNew()))
+ return NULL;
+
+ if (!(node = virXPathNode("./filterbindingstatus", ctxt))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("filter binding status missing content"));
+ goto cleanup;
+ }
+
+ if (!(ret->def = virNWFilterBindingDefParseNode(doc, node)))
+ goto cleanup;
+
+ return ret;
+
+ cleanup:
+ virObjectUnref(ret);
+ return NULL;
+}
+
+
+static virNWFilterBindingObjPtr
+virNWFilterBindingObjParseNode(xmlDocPtr doc,
+ xmlNodePtr root)
+{
+ xmlXPathContextPtr ctxt = NULL;
+ virNWFilterBindingObjPtr obj = NULL;
+
+ if (STRNEQ((const char *)root->name, "filterbinding")) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("unknown root element for filter binding"));
+ goto cleanup;
+ }
+
+ ctxt = xmlXPathNewContext(doc);
+ if (ctxt == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ ctxt->node = root;
+ obj = virNWFilterBindingObjParseXML(doc, ctxt);
+
+ cleanup:
+ xmlXPathFreeContext(ctxt);
+ return obj;
+}
+
+
+static virNWFilterBindingObjPtr
+virNWFilterBindingObjParse(const char *xmlStr,
+ const char *filename)
+{
+ virNWFilterBindingObjPtr obj = NULL;
+ xmlDocPtr xml;
+
+ if ((xml = virXMLParse(filename, xmlStr, _("(nwfilterbinding_status)")))) {
+ obj = virNWFilterBindingObjParseNode(xml, xmlDocGetRootElement(xml));
+ xmlFreeDoc(xml);
+ }
+
+ return obj;
+}
+
+
+virNWFilterBindingObjPtr
+virNWFilterBindingObjParseFile(const char *filename)
+{
+ return virNWFilterBindingObjParse(NULL, filename);
+}
+
+
+char *
+virNWFilterBindingObjFormat(const virNWFilterBindingObj *obj)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ virBufferAddLit(&buf, "\n");
+
+ virBufferAdjustIndent(&buf, 2);
+
+ if (virNWFilterBindingDefFormatBuf(&buf, obj->def) < 0) {
+ virBufferFreeAndReset(&buf);
+ return NULL;
+ }
+
+ virBufferAdjustIndent(&buf, -2);
+ virBufferAddLit(&buf, "\n");
+
+ if (virBufferCheckError(&buf) < 0)
+ return NULL;
+
+ return virBufferContentAndReset(&buf);
+}
diff --git a/src/conf/virnwfilterbindingobj.h b/src/conf/virnwfilterbindingobj.h
new file mode 100644
index 0000000000..21ae85b064
--- /dev/null
+++ b/src/conf/virnwfilterbindingobj.h
@@ -0,0 +1,69 @@
+/*
+ * virnwfilterbindingobj.h: network filter binding object processing
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * 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
+ * .
+ *
+ */
+#ifndef VIR_NWFILTER_BINDING_OBJ_H
+# define VIR_NWFILTER_BINDING_OBJ_H
+
+# include "internal.h"
+# include "virnwfilterbindingdef.h"
+# include "virobject.h"
+
+typedef struct _virNWFilterBindingObj virNWFilterBindingObj;
+typedef virNWFilterBindingObj *virNWFilterBindingObjPtr;
+
+virNWFilterBindingObjPtr
+virNWFilterBindingObjNew(void);
+
+virNWFilterBindingDefPtr
+virNWFilterBindingObjGetDef(virNWFilterBindingObjPtr obj);
+
+void
+virNWFilterBindingObjSetDef(virNWFilterBindingObjPtr obj,
+ virNWFilterBindingDefPtr def);
+
+bool
+virNWFilterBindingObjGetRemoving(virNWFilterBindingObjPtr obj);
+
+void
+virNWFilterBindingObjSetRemoving(virNWFilterBindingObjPtr obj,
+ bool removing);
+
+void
+virNWFilterBindingObjEndAPI(virNWFilterBindingObjPtr *obj);
+
+char *
+virNWFilterBindingObjConfigFile(const char *dir,
+ const char *name);
+
+int
+virNWFilterBindingObjSave(const virNWFilterBindingObj *obj,
+ const char *statusDir);
+
+int
+virNWFilterBindingObjDelete(const virNWFilterBindingObj *obj,
+ const char *statusDir);
+
+virNWFilterBindingObjPtr
+virNWFilterBindingObjParseFile(const char *filename);
+
+char *
+virNWFilterBindingObjFormat(const virNWFilterBindingObj *obj);
+
+#endif /* VIR_NWFILTER_BINDING_OBJ_H */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b5b8266709..ad0c385f49 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1057,6 +1057,20 @@ virNWFilterBindingDefParseNode;
virNWFilterBindingDefParseString;
+# conf/virnwfilterbindingobj.h
+virNWFilterBindingObjConfigFile;
+virNWFilterBindingObjDelete;
+virNWFilterBindingObjEndAPI;
+virNWFilterBindingObjFormat;
+virNWFilterBindingObjGetDef;
+virNWFilterBindingObjGetRemoving;
+virNWFilterBindingObjNew;
+virNWFilterBindingObjParseFile;
+virNWFilterBindingObjSave;
+virNWFilterBindingObjSetDef;
+virNWFilterBindingObjSetRemoving;
+
+
# conf/virnwfilterobj.h
virNWFilterObjGetDef;
virNWFilterObjGetNewDef;