When the daemons are split there will need to be a way for the virt
drivers and/or network driver to create and delete bindings between
network ports and network filters. This defines a set of public APIs
that are suitable for managing this facility.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
include/libvirt/libvirt-nwfilter.h | 39 ++++
include/libvirt/virterror.h | 2 +
src/datatypes.c | 67 +++++++
src/datatypes.h | 31 +++
src/driver-nwfilter.h | 30 +++
src/libvirt-nwfilter.c | 305 +++++++++++++++++++++++++++++
src/libvirt_private.syms | 1 +
src/libvirt_public.syms | 13 ++
src/util/virerror.c | 12 ++
9 files changed, 500 insertions(+)
diff --git a/include/libvirt/libvirt-nwfilter.h b/include/libvirt/libvirt-nwfilter.h
index 9f01c175a9..20e6d1ff9a 100644
--- a/include/libvirt/libvirt-nwfilter.h
+++ b/include/libvirt/libvirt-nwfilter.h
@@ -43,6 +43,23 @@ typedef struct _virNWFilter virNWFilter;
*/
typedef virNWFilter *virNWFilterPtr;
+/**
+ * virNWFilterBinding:
+ *
+ * a virNWFilterBinding is a private structure representing a network
+ * filter binding to a port
+ */
+typedef struct _virNWFilterBinding virNWFilterBinding;
+
+/**
+ * virNWFilterBindingPtr:
+ *
+ * a virNWFilterBindingPtr is pointer to a virNWFilterBinding private
+ * structure, this is the type used to reference a network filter
+ * port binding in the API.
+ */
+typedef virNWFilterBinding *virNWFilterBindingPtr;
+
/*
* List NWFilters
@@ -92,4 +109,26 @@ int virNWFilterGetUUIDString (virNWFilterPtr nwfilter,
char * virNWFilterGetXMLDesc (virNWFilterPtr nwfilter,
unsigned int flags);
+
+virNWFilterBindingPtr virNWFilterBindingLookupByPortDev(virConnectPtr conn,
+ const char *portdev);
+
+const char * virNWFilterBindingGetPortDev(virNWFilterBindingPtr binding);
+const char * virNWFilterBindingGetFilterName(virNWFilterBindingPtr binding);
+
+int virConnectListAllNWFilterBindings(virConnectPtr conn,
+ virNWFilterBindingPtr **bindings,
+ unsigned int flags);
+
+virNWFilterBindingPtr virNWFilterBindingCreateXML(virConnectPtr conn,
+ const char *xml,
+ unsigned int flags);
+
+char * virNWFilterBindingGetXMLDesc(virNWFilterBindingPtr binding,
+ unsigned int flags);
+
+int virNWFilterBindingDelete(virNWFilterBindingPtr binding);
+int virNWFilterBindingRef(virNWFilterBindingPtr binding);
+int virNWFilterBindingFree(virNWFilterBindingPtr binding);
+
#endif /* __VIR_LIBVIRT_NWFILTER_H__ */
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index 3e7c7a02c7..02bc141f1c 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -321,6 +321,8 @@ typedef enum {
to guest-sync command (DEPRECATED)*/
VIR_ERR_LIBSSH = 98, /* error in libssh transport driver */
VIR_ERR_DEVICE_MISSING = 99, /* fail to find the desired device */
+ VIR_ERR_INVALID_NWFILTER_BINDING = 100, /* invalid nwfilter binding */
+ VIR_ERR_NO_NWFILTER_BINDING = 101, /* no nwfilter binding */
} virErrorNumber;
/**
diff --git a/src/datatypes.c b/src/datatypes.c
index 09b8eea5a2..878a1c5b5f 100644
--- a/src/datatypes.c
+++ b/src/datatypes.c
@@ -41,6 +41,7 @@ virClassPtr virInterfaceClass;
virClassPtr virNetworkClass;
virClassPtr virNodeDeviceClass;
virClassPtr virNWFilterClass;
+virClassPtr virNWFilterBindingClass;
virClassPtr virSecretClass;
virClassPtr virStreamClass;
virClassPtr virStorageVolClass;
@@ -54,6 +55,7 @@ static void virInterfaceDispose(void *obj);
static void virNetworkDispose(void *obj);
static void virNodeDeviceDispose(void *obj);
static void virNWFilterDispose(void *obj);
+static void virNWFilterBindingDispose(void *obj);
static void virSecretDispose(void *obj);
static void virStreamDispose(void *obj);
static void virStorageVolDispose(void *obj);
@@ -89,6 +91,7 @@ virDataTypesOnceInit(void)
DECLARE_CLASS(virNetwork);
DECLARE_CLASS(virNodeDevice);
DECLARE_CLASS(virNWFilter);
+ DECLARE_CLASS(virNWFilterBinding);
DECLARE_CLASS(virSecret);
DECLARE_CLASS(virStream);
DECLARE_CLASS(virStorageVol);
@@ -830,6 +833,70 @@ virNWFilterDispose(void *obj)
}
+/**
+ * virGetNWFilterBinding:
+ * @conn: the hypervisor connection
+ * @portdev: pointer to the network filter port device name
+ * @filtername: name of the network filter
+ *
+ * Allocates a new network filter binding object. When the object is no longer
+ * needed, virObjectUnref() must be called in order to not leak data.
+ *
+ * Returns a pointer to the network filter binding object, or NULL on error.
+ */
+virNWFilterBindingPtr
+virGetNWFilterBinding(virConnectPtr conn, const char *portdev,
+ const char *filtername)
+{
+ virNWFilterBindingPtr ret = NULL;
+
+ if (virDataTypesInitialize() < 0)
+ return NULL;
+
+ virCheckConnectGoto(conn, error);
+ virCheckNonNullArgGoto(portdev, error);
+
+ if (!(ret = virObjectNew(virNWFilterBindingClass)))
+ goto error;
+
+ if (VIR_STRDUP(ret->portdev, portdev) < 0)
+ goto error;
+
+ if (VIR_STRDUP(ret->filtername, filtername) < 0)
+ goto error;
+
+ ret->conn = virObjectRef(conn);
+
+ return ret;
+
+ error:
+ virObjectUnref(ret);
+ return NULL;
+}
+
+
+/**
+ * virNWFilterBindingDispose:
+ * @obj: the network filter binding to release
+ *
+ * Unconditionally release all memory associated with a nwfilter binding.
+ * The nwfilter binding object must not be used once this method returns.
+ *
+ * It will also unreference the associated connection object,
+ * which may also be released if its ref count hits zero.
+ */
+static void
+virNWFilterBindingDispose(void *obj)
+{
+ virNWFilterBindingPtr binding = obj;
+
+ VIR_DEBUG("release binding %p %s", binding, binding->portdev);
+
+ VIR_FREE(binding->portdev);
+ virObjectUnref(binding->conn);
+}
+
+
/**
* virGetDomainSnapshot:
* @domain: the domain to snapshot
diff --git a/src/datatypes.h b/src/datatypes.h
index 192c86be80..e1b38706dc 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -36,6 +36,7 @@ extern virClassPtr virInterfaceClass;
extern virClassPtr virNetworkClass;
extern virClassPtr virNodeDeviceClass;
extern virClassPtr virNWFilterClass;
+extern virClassPtr virNWFilterBindingClass;
extern virClassPtr virSecretClass;
extern virClassPtr virStreamClass;
extern virClassPtr virStorageVolClass;
@@ -277,6 +278,20 @@ extern virClassPtr virAdmClientClass;
} \
} while (0)
+# define virCheckNWFilterBindingReturn(obj, retval) \
+ do { \
+ virNWFilterBindingPtr _nw = (obj); \
+ if (!virObjectIsClass(_nw, virNWFilterBindingClass) || \
+ !virObjectIsClass(_nw->conn, virConnectClass)) { \
+ virReportErrorHelper(VIR_FROM_NWFILTER, \
+ VIR_ERR_INVALID_NWFILTER_BINDING, \
+ __FILE__, __FUNCTION__, __LINE__, \
+ __FUNCTION__); \
+ virDispatchError(NULL); \
+ return retval; \
+ } \
+ } while (0)
+
# define virCheckDomainSnapshotReturn(obj, retval) \
do { \
virDomainSnapshotPtr _snap = (obj); \
@@ -676,6 +691,19 @@ struct _virNWFilter {
};
+/**
+* _virNWFilterBinding:
+*
+* Internal structure associated to a network filter port binding
+*/
+struct _virNWFilterBinding {
+ virObject parent;
+ virConnectPtr conn; /* pointer back to the connection */
+ char *portdev; /* the network filter port device name */
+ char *filtername; /* the network filter name */
+};
+
+
/*
* Helper APIs for allocating new object instances
*/
@@ -712,6 +740,9 @@ virStreamPtr virGetStream(virConnectPtr conn);
virNWFilterPtr virGetNWFilter(virConnectPtr conn,
const char *name,
const unsigned char *uuid);
+virNWFilterBindingPtr virGetNWFilterBinding(virConnectPtr conn,
+ const char *portdev,
+ const char *filtername);
virDomainSnapshotPtr virGetDomainSnapshot(virDomainPtr domain,
const char *name);
diff --git a/src/driver-nwfilter.h b/src/driver-nwfilter.h
index cb49542f92..2c3e480a32 100644
--- a/src/driver-nwfilter.h
+++ b/src/driver-nwfilter.h
@@ -57,6 +57,31 @@ typedef char *
(*virDrvNWFilterGetXMLDesc)(virNWFilterPtr nwfilter,
unsigned int flags);
+typedef virNWFilterBindingPtr
+(*virDrvNWFilterBindingLookupByPortDev)(virConnectPtr conn,
+ const char *portdev);
+
+typedef int
+(*virDrvConnectListAllNWFilterBindings)(virConnectPtr conn,
+ virNWFilterBindingPtr **bindings,
+ unsigned int flags);
+
+typedef virNWFilterBindingPtr
+(*virDrvNWFilterBindingCreateXML)(virConnectPtr conn,
+ const char *xml,
+ unsigned int flags);
+
+typedef char *
+(*virDrvNWFilterBindingGetXMLDesc)(virNWFilterBindingPtr binding,
+ unsigned int flags);
+
+typedef int
+(*virDrvNWFilterBindingDelete)(virNWFilterBindingPtr binding);
+typedef int
+(*virDrvNWFilterBindingRef)(virNWFilterBindingPtr binding);
+typedef int
+(*virDrvNWFilterBindingFree)(virNWFilterBindingPtr binding);
+
typedef struct _virNWFilterDriver virNWFilterDriver;
typedef virNWFilterDriver *virNWFilterDriverPtr;
@@ -77,6 +102,11 @@ struct _virNWFilterDriver {
virDrvNWFilterDefineXML nwfilterDefineXML;
virDrvNWFilterUndefine nwfilterUndefine;
virDrvNWFilterGetXMLDesc nwfilterGetXMLDesc;
+ virDrvConnectListAllNWFilterBindings connectListAllNWFilterBindings;
+ virDrvNWFilterBindingLookupByPortDev nwfilterBindingLookupByPortDev;
+ virDrvNWFilterBindingCreateXML nwfilterBindingCreateXML;
+ virDrvNWFilterBindingDelete nwfilterBindingDelete;
+ virDrvNWFilterBindingGetXMLDesc nwfilterBindingGetXMLDesc;
};
diff --git a/src/libvirt-nwfilter.c b/src/libvirt-nwfilter.c
index 948c30deef..e572d46c18 100644
--- a/src/libvirt-nwfilter.c
+++ b/src/libvirt-nwfilter.c
@@ -513,3 +513,308 @@ virNWFilterRef(virNWFilterPtr nwfilter)
virObjectRef(nwfilter);
return 0;
}
+
+
+/**
+ * virConnectListAllNWFilterBindings:
+ * @conn: Pointer to the hypervisor connection.
+ * @bindings: Pointer to a variable to store the array containing the network
+ * filter objects or NULL if the list is not required (just returns
+ * number of network filters).
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Collect the list of network filters, and allocate an array to store those
+ * objects.
+ *
+ * Returns the number of network filters found or -1 and sets @filters to NULL
+ * in case of error. On success, the array stored into @filters is guaranteed to
+ * have an extra allocated element set to NULL but not included in the return count,
+ * to make iteration easier. The caller is responsible for calling
+ * virNWFilterFree() on each array element, then calling free() on @filters.
+ */
+int
+virConnectListAllNWFilterBindings(virConnectPtr conn,
+ virNWFilterBindingPtr **bindings,
+ unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, bindings=%p, flags=0x%x", conn, bindings, flags);
+
+ virResetLastError();
+
+ if (bindings)
+ *bindings = NULL;
+
+ virCheckConnectReturn(conn, -1);
+
+ if (conn->nwfilterDriver &&
+ conn->nwfilterDriver->connectListAllNWFilterBindings) {
+ int ret;
+ ret = conn->nwfilterDriver->connectListAllNWFilterBindings(conn, bindings, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virNWFilterBindingLookupByPortDev:
+ * @conn: pointer to the hypervisor connection
+ * @portdev: name for the network port device
+ *
+ * Try to lookup a network filter binding on the given hypervisor based
+ * on network port device name.
+ *
+ * virNWFilterBindingFree should be used to free the resources after the
+ * binding object is no longer needed.
+ *
+ * Returns a new binding object or NULL in case of failure. If the
+ * network filter cannot be found, then VIR_ERR_NO_NWFILTER_BINDING
+ * error is raised.
+ */
+virNWFilterBindingPtr
+virNWFilterBindingLookupByPortDev(virConnectPtr conn, const char *portdev)
+{
+ VIR_DEBUG("conn=%p, name=%s", conn, NULLSTR(portdev));
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckNonNullArgGoto(portdev, error);
+
+ if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterBindingLookupByPortDev) {
+ virNWFilterBindingPtr ret;
+ ret = conn->nwfilterDriver->nwfilterBindingLookupByPortDev(conn, portdev);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virNWFilterBindingFree:
+ * @binding: a binding object
+ *
+ * Free the binding object. The running instance is kept alive.
+ * The data structure is freed and should not be used thereafter.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virNWFilterBindingFree(virNWFilterBindingPtr binding)
+{
+ VIR_DEBUG("binding=%p", binding);
+
+ virResetLastError();
+
+ virCheckNWFilterBindingReturn(binding, -1);
+
+ virObjectUnref(binding);
+ return 0;
+}
+
+
+/**
+ * virNWFilterBindingGetPortDev:
+ * @binding: a binding object
+ *
+ * Get the port dev name for the network filter binding
+ *
+ * Returns a pointer to the name or NULL, the string need not be deallocated
+ * its lifetime will be the same as the binding object.
+ */
+const char *
+virNWFilterBindingGetPortDev(virNWFilterBindingPtr binding)
+{
+ VIR_DEBUG("binding=%p", binding);
+
+ virResetLastError();
+
+ virCheckNWFilterBindingReturn(binding, NULL);
+
+ return binding->portdev;
+}
+
+
+/**
+ * virNWFilterBindingGetFilterName:
+ * @binding: a binding object
+ *
+ * Get the filter name for the network filter binding
+ *
+ * Returns a pointer to the name or NULL, the string need not be deallocated
+ * its lifetime will be the same as the binding object.
+ */
+const char *
+virNWFilterBindingGetFilterName(virNWFilterBindingPtr binding)
+{
+ VIR_DEBUG("binding=%p", binding);
+
+ virResetLastError();
+
+ virCheckNWFilterBindingReturn(binding, NULL);
+
+ return binding->filtername;
+}
+
+
+/**
+ * virNWFilterBindingCreateXML:
+ * @conn: pointer to the hypervisor connection
+ * @xml: an XML description of the binding
+ * @flags: currently unused, pass 0
+ *
+ * Define a new network filter, based on an XML description
+ * similar to the one returned by virNWFilterGetXMLDesc()
+ *
+ * virNWFilterFree should be used to free the resources after the
+ * binding object is no longer needed.
+ *
+ * Returns a new binding object or NULL in case of failure
+ */
+virNWFilterBindingPtr
+virNWFilterBindingCreateXML(virConnectPtr conn, const char *xml, unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, xml=%s", conn, NULLSTR(xml));
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckNonNullArgGoto(xml, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterBindingCreateXML) {
+ virNWFilterBindingPtr ret;
+ ret = conn->nwfilterDriver->nwfilterBindingCreateXML(conn, xml, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virNWFilterBindingDelete:
+ * @binding: a binding object
+ *
+ * Delete the binding object. This does not free the
+ * associated virNWFilterBindingPtr object.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virNWFilterBindingDelete(virNWFilterBindingPtr binding)
+{
+ virConnectPtr conn;
+ VIR_DEBUG("binding=%p", binding);
+
+ virResetLastError();
+
+ virCheckNWFilterBindingReturn(binding, -1);
+ conn = binding->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterBindingDelete) {
+ int ret;
+ ret = conn->nwfilterDriver->nwfilterBindingDelete(binding);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(binding->conn);
+ return -1;
+}
+
+
+/**
+ * virNWFilterBindingGetXMLDesc:
+ * @binding: a binding object
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Provide an XML description of the network filter. The description may be
+ * reused later to redefine the network filter with virNWFilterCreateXML().
+ *
+ * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
+ * the caller must free() the returned value.
+ */
+char *
+virNWFilterBindingGetXMLDesc(virNWFilterBindingPtr binding, unsigned int flags)
+{
+ virConnectPtr conn;
+ VIR_DEBUG("binding=%p, flags=0x%x", binding, flags);
+
+ virResetLastError();
+
+ virCheckNWFilterBindingReturn(binding, NULL);
+ conn = binding->conn;
+
+ if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterBindingGetXMLDesc) {
+ char *ret;
+ ret = conn->nwfilterDriver->nwfilterBindingGetXMLDesc(binding, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(binding->conn);
+ return NULL;
+}
+
+
+/**
+ * virNWFilterBindingRef:
+ * @binding: the binding to hold a reference on
+ *
+ * Increment the reference count on the binding. For each
+ * additional call to this method, there shall be a corresponding
+ * call to virNWFilterFree to release the reference count, once
+ * the caller no longer needs the reference to this object.
+ *
+ * This method is typically useful for applications where multiple
+ * threads are using a connection, and it is required that the
+ * connection remain open until all threads have finished using
+ * it. ie, each new thread using an binding would increment
+ * the reference count.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virNWFilterBindingRef(virNWFilterBindingPtr binding)
+{
+ VIR_DEBUG("binding=%p refs=%d", binding,
+ binding ? binding->parent.u.s.refs : 0);
+
+ virResetLastError();
+
+ virCheckNWFilterBindingReturn(binding, -1);
+
+ virObjectRef(binding);
+ return 0;
+}
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 03145c70d5..0ce685b6f2 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1193,6 +1193,7 @@ virGetInterface;
virGetNetwork;
virGetNodeDevice;
virGetNWFilter;
+virGetNWFilterBinding;
virGetSecret;
virGetStoragePool;
virGetStorageVol;
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 95df3a0dbc..cc73fd8528 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -785,4 +785,17 @@ LIBVIRT_4.1.0 {
virStoragePoolLookupByTargetPath;
} LIBVIRT_3.9.0;
+LIBVIRT_4.4.0 {
+ global:
+ virNWFilterBindingLookupByPortDev;
+ virConnectListAllNWFilterBindings;
+ virNWFilterBindingCreateXML;
+ virNWFilterBindingGetXMLDesc;
+ virNWFilterBindingDelete;
+ virNWFilterBindingRef;
+ virNWFilterBindingFree;
+ virNWFilterBindingGetPortDev;
+ virNWFilterBindingGetFilterName;
+} LIBVIRT_4.1.0;
+
# .... define new API here using predicted next version number ....
diff --git a/src/util/virerror.c b/src/util/virerror.c
index c000b00436..074e217849 100644
--- a/src/util/virerror.c
+++ b/src/util/virerror.c
@@ -1459,6 +1459,18 @@ virErrorMsg(virErrorNumber error, const char *info)
else
errmsg = _("device not found: %s");
break;
+ case VIR_ERR_INVALID_NWFILTER_BINDING:
+ if (info == NULL)
+ errmsg = _("Invalid network filter binding");
+ else
+ errmsg = _("Invalid network filter binding: %s");
+ break;
+ case VIR_ERR_NO_NWFILTER_BINDING:
+ if (info == NULL)
+ errmsg = _("Network filter binding not found");
+ else
+ errmsg = _("Network filter binding not found: %s");
+ break;
}
return errmsg;
}
--
2.17.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 05/15/2018 01:43 PM, Daniel P. Berrangé wrote: > When the daemons are split there will need to be a way for the virt > drivers and/or network driver to create and delete bindings between > network ports and network filters. This defines a set of public APIs > that are suitable for managing this facility. > > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> > --- > include/libvirt/libvirt-nwfilter.h | 39 ++++ > include/libvirt/virterror.h | 2 + > src/datatypes.c | 67 +++++++ > src/datatypes.h | 31 +++ > src/driver-nwfilter.h | 30 +++ > src/libvirt-nwfilter.c | 305 +++++++++++++++++++++++++++++ > src/libvirt_private.syms | 1 + > src/libvirt_public.syms | 13 ++ > src/util/virerror.c | 12 ++ > 9 files changed, 500 insertions(+) > I keep wondering, is there anything else that needs to be in virNWFilterBindingPtr... Or some other parameter or way we need to get the data we need. Which further makes me wonder should we wait for 4.5.0 just in case something comes up since we're now more than halfway through the month? There's mostly some nits and small adjustments below, but in general with those taken care of... Reviewed-by: John Ferlan <jferlan@redhat.com> John [...] > > +/** > + * virGetNWFilterBinding: > + * @conn: the hypervisor connection > + * @portdev: pointer to the network filter port device name > + * @filtername: name of the network filter > + * > + * Allocates a new network filter binding object. When the object is no longer > + * needed, virObjectUnref() must be called in order to not leak data. > + * > + * Returns a pointer to the network filter binding object, or NULL on error. > + */ > +virNWFilterBindingPtr > +virGetNWFilterBinding(virConnectPtr conn, const char *portdev, > + const char *filtername) One argument per line (this repeats a few times, I'll mention it once - your call) > +{ > + virNWFilterBindingPtr ret = NULL; > + > + if (virDataTypesInitialize() < 0) > + return NULL; > + > + virCheckConnectGoto(conn, error); > + virCheckNonNullArgGoto(portdev, error); Check filtername too... > + > + if (!(ret = virObjectNew(virNWFilterBindingClass))) > + goto error; > + > + if (VIR_STRDUP(ret->portdev, portdev) < 0) > + goto error; > + > + if (VIR_STRDUP(ret->filtername, filtername) < 0) > + goto error; > + > + ret->conn = virObjectRef(conn); > + > + return ret; > + > + error: > + virObjectUnref(ret); > + return NULL; > +} > + > + > +/** > + * virNWFilterBindingDispose: > + * @obj: the network filter binding to release > + * > + * Unconditionally release all memory associated with a nwfilter binding. > + * The nwfilter binding object must not be used once this method returns. > + * > + * It will also unreference the associated connection object, > + * which may also be released if its ref count hits zero. > + */ > +static void > +virNWFilterBindingDispose(void *obj) > +{ > + virNWFilterBindingPtr binding = obj; > + > + VIR_DEBUG("release binding %p %s", binding, binding->portdev); Your call to print the filtername too > + > + VIR_FREE(binding->portdev); VIR_FREE(binding->filtername); > + virObjectUnref(binding->conn); > +} > + > + > /** > * virGetDomainSnapshot: > * @domain: the domain to snapshot [...] > diff --git a/src/libvirt-nwfilter.c b/src/libvirt-nwfilter.c > index 948c30deef..e572d46c18 100644 > --- a/src/libvirt-nwfilter.c > +++ b/src/libvirt-nwfilter.c > @@ -513,3 +513,308 @@ virNWFilterRef(virNWFilterPtr nwfilter) > virObjectRef(nwfilter); > return 0; > } > + > + > +/** > + * virConnectListAllNWFilterBindings: > + * @conn: Pointer to the hypervisor connection. > + * @bindings: Pointer to a variable to store the array containing the network > + * filter objects or NULL if the list is not required (just returns > + * number of network filters). > + * @flags: extra flags; not used yet, so callers should always pass 0 > + * > + * Collect the list of network filters, and allocate an array to store those > + * objects. > + * > + * Returns the number of network filters found or -1 and sets @filters to NULL s/to NULL/to NULL/ > + * in case of error. On success, the array stored into @filters is guaranteed to > + * have an extra allocated element set to NULL but not included in the return count, > + * to make iteration easier. The caller is responsible for calling > + * virNWFilterFree() on each array element, then calling free() on @filters. > + */ > +int > +virConnectListAllNWFilterBindings(virConnectPtr conn, > + virNWFilterBindingPtr **bindings, > + unsigned int flags) [...] > + > +/** > + * virNWFilterBindingGetPortDev: > + * @binding: a binding object > + * > + * Get the port dev name for the network filter binding > + * > + * Returns a pointer to the name or NULL, the string need not be deallocated> + * its lifetime will be the same as the binding object. need not be free()'d in its lifetime as it is owned by the binding object. [or something else - the existing sentence needs some sprucing up] > + */ > +const char * > +virNWFilterBindingGetPortDev(virNWFilterBindingPtr binding) > +{ > + VIR_DEBUG("binding=%p", binding); > + > + virResetLastError(); > + > + virCheckNWFilterBindingReturn(binding, NULL); > + > + return binding->portdev; > +} > + > + > +/** > + * virNWFilterBindingGetFilterName: > + * @binding: a binding object > + * > + * Get the filter name for the network filter binding > + * > + * Returns a pointer to the name or NULL, the string need not be deallocated > + * its lifetime will be the same as the binding object. similar comment... > + */ > +const char * > +virNWFilterBindingGetFilterName(virNWFilterBindingPtr binding) > +{ > + VIR_DEBUG("binding=%p", binding); > + > + virResetLastError(); > + > + virCheckNWFilterBindingReturn(binding, NULL); > + > + return binding->filtername; > +} > + > + > +/** > + * virNWFilterBindingCreateXML: > + * @conn: pointer to the hypervisor connection > + * @xml: an XML description of the binding > + * @flags: currently unused, pass 0 > + * > + * Define a new network filter, based on an XML description > + * similar to the one returned by virNWFilterGetXMLDesc() > + * > + * virNWFilterFree should be used to free the resources after the virNWFilterBindingFree > + * binding object is no longer needed. > + * > + * Returns a new binding object or NULL in case of failure > + */ > +virNWFilterBindingPtr > +virNWFilterBindingCreateXML(virConnectPtr conn, const char *xml, unsigned int flags) > +{ > + VIR_DEBUG("conn=%p, xml=%s", conn, NULLSTR(xml)); > + > + virResetLastError(); [...] > + > +/** > + * virNWFilterBindingRef: > + * @binding: the binding to hold a reference on > + * > + * Increment the reference count on the binding. For each > + * additional call to this method, there shall be a corresponding > + * call to virNWFilterFree to release the reference count, once virNWFilterBindingFree > + * the caller no longer needs the reference to this object. > + * > + * This method is typically useful for applications where multiple > + * threads are using a connection, and it is required that the > + * connection remain open until all threads have finished using > + * it. ie, each new thread using an binding would increment > + * the reference count. > + * > + * Returns 0 in case of success, -1 in case of failure. > + */ [...] -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2025 Red Hat, Inc.