mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 11:01:19 +00:00
Move virNWFilter related APIs out of libvirt.c
Introduce a src/libvirt-nwfilter.c file to hold all the methods related to the virNWFilter type.
This commit is contained in:
parent
6e01ef230b
commit
35ed98755f
@ -27,6 +27,7 @@ included_files = {
|
|||||||
"libvirt-domain-snapshot.c": "Domain snapshot interfaces for the libvirt library",
|
"libvirt-domain-snapshot.c": "Domain snapshot interfaces for the libvirt library",
|
||||||
"libvirt-interface.c": "Interface interfaces for the libvirt library",
|
"libvirt-interface.c": "Interface interfaces for the libvirt library",
|
||||||
"libvirt-network.c": "Network interfaces for the libvirt library",
|
"libvirt-network.c": "Network interfaces for the libvirt library",
|
||||||
|
"libvirt-nwfilter.c": "NWFilter interfaces for the libvirt library",
|
||||||
"virerror.c": "implements error handling and reporting code for libvirt",
|
"virerror.c": "implements error handling and reporting code for libvirt",
|
||||||
"virevent.c": "event loop for monitoring file handles",
|
"virevent.c": "event loop for monitoring file handles",
|
||||||
"virtypedparam.c": "virTypedParameters APIs",
|
"virtypedparam.c": "virTypedParameters APIs",
|
||||||
|
@ -60,6 +60,7 @@ src/libvirt.c
|
|||||||
src/libvirt-domain-snapshot.c
|
src/libvirt-domain-snapshot.c
|
||||||
src/libvirt-lxc.c
|
src/libvirt-lxc.c
|
||||||
src/libvirt-network.c
|
src/libvirt-network.c
|
||||||
|
src/libvirt-nwfilter.c
|
||||||
src/libvirt-qemu.c
|
src/libvirt-qemu.c
|
||||||
src/locking/lock_daemon.c
|
src/locking/lock_daemon.c
|
||||||
src/locking/lock_daemon_config.c
|
src/locking/lock_daemon_config.c
|
||||||
|
@ -192,6 +192,7 @@ DRIVER_SOURCES = \
|
|||||||
libvirt-domain-snapshot.c \
|
libvirt-domain-snapshot.c \
|
||||||
libvirt-interface.c \
|
libvirt-interface.c \
|
||||||
libvirt-network.c \
|
libvirt-network.c \
|
||||||
|
libvirt-nwfilter.c \
|
||||||
locking/lock_manager.c locking/lock_manager.h \
|
locking/lock_manager.c locking/lock_manager.h \
|
||||||
locking/lock_driver.h \
|
locking/lock_driver.h \
|
||||||
locking/lock_driver_nop.h locking/lock_driver_nop.c \
|
locking/lock_driver_nop.h locking/lock_driver_nop.c \
|
||||||
@ -2192,6 +2193,7 @@ libvirt_setuid_rpc_client_la_SOURCES = \
|
|||||||
libvirt-domain-snapshot.c \
|
libvirt-domain-snapshot.c \
|
||||||
libvirt-interface.c \
|
libvirt-interface.c \
|
||||||
libvirt-network.c \
|
libvirt-network.c \
|
||||||
|
libvirt-nwfilter.c \
|
||||||
libvirt-lxc.c \
|
libvirt-lxc.c \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
515
src/libvirt-nwfilter.c
Normal file
515
src/libvirt-nwfilter.c
Normal file
@ -0,0 +1,515 @@
|
|||||||
|
/*
|
||||||
|
* libvirt-nwfilter.c: entry points for virNwfilterPtr APIs
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2014 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
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "datatypes.h"
|
||||||
|
#include "virlog.h"
|
||||||
|
|
||||||
|
VIR_LOG_INIT("libvirt.nwfilter");
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_NWFILTER
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virConnectNumOfNWFilters:
|
||||||
|
* @conn: pointer to the hypervisor connection
|
||||||
|
*
|
||||||
|
* Provides the number of nwfilters.
|
||||||
|
*
|
||||||
|
* Returns the number of nwfilters found or -1 in case of error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virConnectNumOfNWFilters(virConnectPtr conn)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("conn=%p", conn);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckConnectReturn(conn, -1);
|
||||||
|
|
||||||
|
if (conn->nwfilterDriver && conn->nwfilterDriver->connectNumOfNWFilters) {
|
||||||
|
int ret;
|
||||||
|
ret = conn->nwfilterDriver->connectNumOfNWFilters(conn);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virReportUnsupportedError();
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(conn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virConnectListAllNWFilters:
|
||||||
|
* @conn: Pointer to the hypervisor connection.
|
||||||
|
* @filters: 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
|
||||||
|
virConnectListAllNWFilters(virConnectPtr conn,
|
||||||
|
virNWFilterPtr **filters,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("conn=%p, filters=%p, flags=%x", conn, filters, flags);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
if (filters)
|
||||||
|
*filters = NULL;
|
||||||
|
|
||||||
|
virCheckConnectReturn(conn, -1);
|
||||||
|
|
||||||
|
if (conn->nwfilterDriver &&
|
||||||
|
conn->nwfilterDriver->connectListAllNWFilters) {
|
||||||
|
int ret;
|
||||||
|
ret = conn->nwfilterDriver->connectListAllNWFilters(conn, filters, flags);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virReportUnsupportedError();
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(conn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virConnectListNWFilters:
|
||||||
|
* @conn: pointer to the hypervisor connection
|
||||||
|
* @names: array to collect the list of names of network filters
|
||||||
|
* @maxnames: size of @names
|
||||||
|
*
|
||||||
|
* Collect the list of network filters, and store their names in @names
|
||||||
|
*
|
||||||
|
* Returns the number of network filters found or -1 in case of error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virConnectListNWFilters(virConnectPtr conn, char **const names, int maxnames)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckConnectReturn(conn, -1);
|
||||||
|
virCheckNonNullArgGoto(names, error);
|
||||||
|
virCheckNonNegativeArgGoto(maxnames, error);
|
||||||
|
|
||||||
|
if (conn->nwfilterDriver && conn->nwfilterDriver->connectListNWFilters) {
|
||||||
|
int ret;
|
||||||
|
ret = conn->nwfilterDriver->connectListNWFilters(conn, names, maxnames);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virReportUnsupportedError();
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(conn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNWFilterLookupByName:
|
||||||
|
* @conn: pointer to the hypervisor connection
|
||||||
|
* @name: name for the network filter
|
||||||
|
*
|
||||||
|
* Try to lookup a network filter on the given hypervisor based on its name.
|
||||||
|
*
|
||||||
|
* virNWFilterFree should be used to free the resources after the
|
||||||
|
* nwfilter object is no longer needed.
|
||||||
|
*
|
||||||
|
* Returns a new nwfilter object or NULL in case of failure. If the
|
||||||
|
* network filter cannot be found, then VIR_ERR_NO_NWFILTER error is raised.
|
||||||
|
*/
|
||||||
|
virNWFilterPtr
|
||||||
|
virNWFilterLookupByName(virConnectPtr conn, const char *name)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("conn=%p, name=%s", conn, name);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckConnectReturn(conn, NULL);
|
||||||
|
virCheckNonNullArgGoto(name, error);
|
||||||
|
|
||||||
|
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterLookupByName) {
|
||||||
|
virNWFilterPtr ret;
|
||||||
|
ret = conn->nwfilterDriver->nwfilterLookupByName(conn, name);
|
||||||
|
if (!ret)
|
||||||
|
goto error;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virReportUnsupportedError();
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNWFilterLookupByUUID:
|
||||||
|
* @conn: pointer to the hypervisor connection
|
||||||
|
* @uuid: the raw UUID for the network filter
|
||||||
|
*
|
||||||
|
* Try to lookup a network filter on the given hypervisor based on its UUID.
|
||||||
|
*
|
||||||
|
* virNWFilterFree should be used to free the resources after the
|
||||||
|
* nwfilter object is no longer needed.
|
||||||
|
*
|
||||||
|
* Returns a new nwfilter object or NULL in case of failure. If the
|
||||||
|
* nwfdilter cannot be found, then VIR_ERR_NO_NWFILTER error is raised.
|
||||||
|
*/
|
||||||
|
virNWFilterPtr
|
||||||
|
virNWFilterLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
|
||||||
|
{
|
||||||
|
VIR_UUID_DEBUG(conn, uuid);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckConnectReturn(conn, NULL);
|
||||||
|
virCheckNonNullArgGoto(uuid, error);
|
||||||
|
|
||||||
|
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterLookupByUUID) {
|
||||||
|
virNWFilterPtr ret;
|
||||||
|
ret = conn->nwfilterDriver->nwfilterLookupByUUID(conn, uuid);
|
||||||
|
if (!ret)
|
||||||
|
goto error;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virReportUnsupportedError();
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNWFilterLookupByUUIDString:
|
||||||
|
* @conn: pointer to the hypervisor connection
|
||||||
|
* @uuidstr: the string UUID for the nwfilter
|
||||||
|
*
|
||||||
|
* Try to lookup an nwfilter on the given hypervisor based on its UUID.
|
||||||
|
*
|
||||||
|
* virNWFilterFree should be used to free the resources after the
|
||||||
|
* nwfilter object is no longer needed.
|
||||||
|
*
|
||||||
|
* Returns a new nwfilter object or NULL in case of failure. If the
|
||||||
|
* nwfilter cannot be found, then VIR_ERR_NO_NWFILTER error is raised.
|
||||||
|
*/
|
||||||
|
virNWFilterPtr
|
||||||
|
virNWFilterLookupByUUIDString(virConnectPtr conn, const char *uuidstr)
|
||||||
|
{
|
||||||
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||||
|
VIR_DEBUG("conn=%p, uuidstr=%s", conn, NULLSTR(uuidstr));
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckConnectReturn(conn, NULL);
|
||||||
|
virCheckNonNullArgGoto(uuidstr, error);
|
||||||
|
|
||||||
|
if (virUUIDParse(uuidstr, uuid) < 0) {
|
||||||
|
virReportInvalidArg(uuidstr,
|
||||||
|
_("uuidstr in %s must be a valid UUID"),
|
||||||
|
__FUNCTION__);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return virNWFilterLookupByUUID(conn, &uuid[0]);
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNWFilterFree:
|
||||||
|
* @nwfilter: a nwfilter object
|
||||||
|
*
|
||||||
|
* Free the nwfilter 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
|
||||||
|
virNWFilterFree(virNWFilterPtr nwfilter)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("nwfilter=%p", nwfilter);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckNWFilterReturn(nwfilter, -1);
|
||||||
|
|
||||||
|
virObjectUnref(nwfilter);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNWFilterGetName:
|
||||||
|
* @nwfilter: a nwfilter object
|
||||||
|
*
|
||||||
|
* Get the public name for the network filter
|
||||||
|
*
|
||||||
|
* Returns a pointer to the name or NULL, the string need not be deallocated
|
||||||
|
* its lifetime will be the same as the nwfilter object.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
virNWFilterGetName(virNWFilterPtr nwfilter)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("nwfilter=%p", nwfilter);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckNWFilterReturn(nwfilter, NULL);
|
||||||
|
|
||||||
|
return nwfilter->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNWFilterGetUUID:
|
||||||
|
* @nwfilter: a nwfilter object
|
||||||
|
* @uuid: pointer to a VIR_UUID_BUFLEN bytes array
|
||||||
|
*
|
||||||
|
* Get the UUID for a network filter
|
||||||
|
*
|
||||||
|
* Returns -1 in case of error, 0 in case of success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virNWFilterGetUUID(virNWFilterPtr nwfilter, unsigned char *uuid)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("nwfilter=%p, uuid=%p", nwfilter, uuid);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckNWFilterReturn(nwfilter, -1);
|
||||||
|
virCheckNonNullArgGoto(uuid, error);
|
||||||
|
|
||||||
|
memcpy(uuid, &nwfilter->uuid[0], VIR_UUID_BUFLEN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(nwfilter->conn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNWFilterGetUUIDString:
|
||||||
|
* @nwfilter: a nwfilter object
|
||||||
|
* @buf: pointer to a VIR_UUID_STRING_BUFLEN bytes array
|
||||||
|
*
|
||||||
|
* Get the UUID for a network filter as string. For more information about
|
||||||
|
* UUID see RFC4122.
|
||||||
|
*
|
||||||
|
* Returns -1 in case of error, 0 in case of success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virNWFilterGetUUIDString(virNWFilterPtr nwfilter, char *buf)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("nwfilter=%p, buf=%p", nwfilter, buf);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckNWFilterReturn(nwfilter, -1);
|
||||||
|
virCheckNonNullArgGoto(buf, error);
|
||||||
|
|
||||||
|
virUUIDFormat(nwfilter->uuid, buf);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(nwfilter->conn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNWFilterDefineXML:
|
||||||
|
* @conn: pointer to the hypervisor connection
|
||||||
|
* @xmlDesc: an XML description of the nwfilter
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* nwfilter object is no longer needed.
|
||||||
|
*
|
||||||
|
* Returns a new nwfilter object or NULL in case of failure
|
||||||
|
*/
|
||||||
|
virNWFilterPtr
|
||||||
|
virNWFilterDefineXML(virConnectPtr conn, const char *xmlDesc)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("conn=%p, xmlDesc=%s", conn, xmlDesc);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckConnectReturn(conn, NULL);
|
||||||
|
virCheckNonNullArgGoto(xmlDesc, error);
|
||||||
|
virCheckReadOnlyGoto(conn->flags, error);
|
||||||
|
|
||||||
|
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterDefineXML) {
|
||||||
|
virNWFilterPtr ret;
|
||||||
|
ret = conn->nwfilterDriver->nwfilterDefineXML(conn, xmlDesc);
|
||||||
|
if (!ret)
|
||||||
|
goto error;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virReportUnsupportedError();
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNWFilterUndefine:
|
||||||
|
* @nwfilter: a nwfilter object
|
||||||
|
*
|
||||||
|
* Undefine the nwfilter object. This call will not succeed if
|
||||||
|
* a running VM is referencing the filter. This does not free the
|
||||||
|
* associated virNWFilterPtr object.
|
||||||
|
*
|
||||||
|
* Returns 0 in case of success and -1 in case of failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virNWFilterUndefine(virNWFilterPtr nwfilter)
|
||||||
|
{
|
||||||
|
virConnectPtr conn;
|
||||||
|
VIR_DEBUG("nwfilter=%p", nwfilter);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckNWFilterReturn(nwfilter, -1);
|
||||||
|
conn = nwfilter->conn;
|
||||||
|
|
||||||
|
virCheckReadOnlyGoto(conn->flags, error);
|
||||||
|
|
||||||
|
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterUndefine) {
|
||||||
|
int ret;
|
||||||
|
ret = conn->nwfilterDriver->nwfilterUndefine(nwfilter);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virReportUnsupportedError();
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(nwfilter->conn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNWFilterGetXMLDesc:
|
||||||
|
* @nwfilter: a nwfilter 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 *
|
||||||
|
virNWFilterGetXMLDesc(virNWFilterPtr nwfilter, unsigned int flags)
|
||||||
|
{
|
||||||
|
virConnectPtr conn;
|
||||||
|
VIR_DEBUG("nwfilter=%p, flags=%x", nwfilter, flags);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckNWFilterReturn(nwfilter, NULL);
|
||||||
|
conn = nwfilter->conn;
|
||||||
|
|
||||||
|
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterGetXMLDesc) {
|
||||||
|
char *ret;
|
||||||
|
ret = conn->nwfilterDriver->nwfilterGetXMLDesc(nwfilter, flags);
|
||||||
|
if (!ret)
|
||||||
|
goto error;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virReportUnsupportedError();
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(nwfilter->conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNWFilterRef:
|
||||||
|
* @nwfilter: the nwfilter to hold a reference on
|
||||||
|
*
|
||||||
|
* Increment the reference count on the nwfilter. 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 nwfilter would increment
|
||||||
|
* the reference count.
|
||||||
|
*
|
||||||
|
* Returns 0 in case of success, -1 in case of failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virNWFilterRef(virNWFilterPtr nwfilter)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("nwfilter=%p refs=%d", nwfilter,
|
||||||
|
nwfilter ? nwfilter->object.u.s.refs : 0);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckNWFilterReturn(nwfilter, -1);
|
||||||
|
|
||||||
|
virObjectRef(nwfilter);
|
||||||
|
return 0;
|
||||||
|
}
|
487
src/libvirt.c
487
src/libvirt.c
@ -15041,493 +15041,6 @@ virStoragePoolIsPersistent(virStoragePoolPtr pool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virConnectNumOfNWFilters:
|
|
||||||
* @conn: pointer to the hypervisor connection
|
|
||||||
*
|
|
||||||
* Provides the number of nwfilters.
|
|
||||||
*
|
|
||||||
* Returns the number of nwfilters found or -1 in case of error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
virConnectNumOfNWFilters(virConnectPtr conn)
|
|
||||||
{
|
|
||||||
VIR_DEBUG("conn=%p", conn);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckConnectReturn(conn, -1);
|
|
||||||
|
|
||||||
if (conn->nwfilterDriver && conn->nwfilterDriver->connectNumOfNWFilters) {
|
|
||||||
int ret;
|
|
||||||
ret = conn->nwfilterDriver->connectNumOfNWFilters(conn);
|
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
virReportUnsupportedError();
|
|
||||||
|
|
||||||
error:
|
|
||||||
virDispatchError(conn);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virConnectListAllNWFilters:
|
|
||||||
* @conn: Pointer to the hypervisor connection.
|
|
||||||
* @filters: 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
|
|
||||||
virConnectListAllNWFilters(virConnectPtr conn,
|
|
||||||
virNWFilterPtr **filters,
|
|
||||||
unsigned int flags)
|
|
||||||
{
|
|
||||||
VIR_DEBUG("conn=%p, filters=%p, flags=%x", conn, filters, flags);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
if (filters)
|
|
||||||
*filters = NULL;
|
|
||||||
|
|
||||||
virCheckConnectReturn(conn, -1);
|
|
||||||
|
|
||||||
if (conn->nwfilterDriver &&
|
|
||||||
conn->nwfilterDriver->connectListAllNWFilters) {
|
|
||||||
int ret;
|
|
||||||
ret = conn->nwfilterDriver->connectListAllNWFilters(conn, filters, flags);
|
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
virReportUnsupportedError();
|
|
||||||
|
|
||||||
error:
|
|
||||||
virDispatchError(conn);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virConnectListNWFilters:
|
|
||||||
* @conn: pointer to the hypervisor connection
|
|
||||||
* @names: array to collect the list of names of network filters
|
|
||||||
* @maxnames: size of @names
|
|
||||||
*
|
|
||||||
* Collect the list of network filters, and store their names in @names
|
|
||||||
*
|
|
||||||
* Returns the number of network filters found or -1 in case of error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
virConnectListNWFilters(virConnectPtr conn, char **const names, int maxnames)
|
|
||||||
{
|
|
||||||
VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckConnectReturn(conn, -1);
|
|
||||||
virCheckNonNullArgGoto(names, error);
|
|
||||||
virCheckNonNegativeArgGoto(maxnames, error);
|
|
||||||
|
|
||||||
if (conn->nwfilterDriver && conn->nwfilterDriver->connectListNWFilters) {
|
|
||||||
int ret;
|
|
||||||
ret = conn->nwfilterDriver->connectListNWFilters(conn, names, maxnames);
|
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
virReportUnsupportedError();
|
|
||||||
|
|
||||||
error:
|
|
||||||
virDispatchError(conn);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virNWFilterLookupByName:
|
|
||||||
* @conn: pointer to the hypervisor connection
|
|
||||||
* @name: name for the network filter
|
|
||||||
*
|
|
||||||
* Try to lookup a network filter on the given hypervisor based on its name.
|
|
||||||
*
|
|
||||||
* virNWFilterFree should be used to free the resources after the
|
|
||||||
* nwfilter object is no longer needed.
|
|
||||||
*
|
|
||||||
* Returns a new nwfilter object or NULL in case of failure. If the
|
|
||||||
* network filter cannot be found, then VIR_ERR_NO_NWFILTER error is raised.
|
|
||||||
*/
|
|
||||||
virNWFilterPtr
|
|
||||||
virNWFilterLookupByName(virConnectPtr conn, const char *name)
|
|
||||||
{
|
|
||||||
VIR_DEBUG("conn=%p, name=%s", conn, name);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckConnectReturn(conn, NULL);
|
|
||||||
virCheckNonNullArgGoto(name, error);
|
|
||||||
|
|
||||||
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterLookupByName) {
|
|
||||||
virNWFilterPtr ret;
|
|
||||||
ret = conn->nwfilterDriver->nwfilterLookupByName(conn, name);
|
|
||||||
if (!ret)
|
|
||||||
goto error;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
virReportUnsupportedError();
|
|
||||||
|
|
||||||
error:
|
|
||||||
virDispatchError(conn);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virNWFilterLookupByUUID:
|
|
||||||
* @conn: pointer to the hypervisor connection
|
|
||||||
* @uuid: the raw UUID for the network filter
|
|
||||||
*
|
|
||||||
* Try to lookup a network filter on the given hypervisor based on its UUID.
|
|
||||||
*
|
|
||||||
* virNWFilterFree should be used to free the resources after the
|
|
||||||
* nwfilter object is no longer needed.
|
|
||||||
*
|
|
||||||
* Returns a new nwfilter object or NULL in case of failure. If the
|
|
||||||
* nwfdilter cannot be found, then VIR_ERR_NO_NWFILTER error is raised.
|
|
||||||
*/
|
|
||||||
virNWFilterPtr
|
|
||||||
virNWFilterLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
|
|
||||||
{
|
|
||||||
VIR_UUID_DEBUG(conn, uuid);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckConnectReturn(conn, NULL);
|
|
||||||
virCheckNonNullArgGoto(uuid, error);
|
|
||||||
|
|
||||||
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterLookupByUUID) {
|
|
||||||
virNWFilterPtr ret;
|
|
||||||
ret = conn->nwfilterDriver->nwfilterLookupByUUID(conn, uuid);
|
|
||||||
if (!ret)
|
|
||||||
goto error;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
virReportUnsupportedError();
|
|
||||||
|
|
||||||
error:
|
|
||||||
virDispatchError(conn);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virNWFilterLookupByUUIDString:
|
|
||||||
* @conn: pointer to the hypervisor connection
|
|
||||||
* @uuidstr: the string UUID for the nwfilter
|
|
||||||
*
|
|
||||||
* Try to lookup an nwfilter on the given hypervisor based on its UUID.
|
|
||||||
*
|
|
||||||
* virNWFilterFree should be used to free the resources after the
|
|
||||||
* nwfilter object is no longer needed.
|
|
||||||
*
|
|
||||||
* Returns a new nwfilter object or NULL in case of failure. If the
|
|
||||||
* nwfilter cannot be found, then VIR_ERR_NO_NWFILTER error is raised.
|
|
||||||
*/
|
|
||||||
virNWFilterPtr
|
|
||||||
virNWFilterLookupByUUIDString(virConnectPtr conn, const char *uuidstr)
|
|
||||||
{
|
|
||||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
||||||
VIR_DEBUG("conn=%p, uuidstr=%s", conn, NULLSTR(uuidstr));
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckConnectReturn(conn, NULL);
|
|
||||||
virCheckNonNullArgGoto(uuidstr, error);
|
|
||||||
|
|
||||||
if (virUUIDParse(uuidstr, uuid) < 0) {
|
|
||||||
virReportInvalidArg(uuidstr,
|
|
||||||
_("uuidstr in %s must be a valid UUID"),
|
|
||||||
__FUNCTION__);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return virNWFilterLookupByUUID(conn, &uuid[0]);
|
|
||||||
|
|
||||||
error:
|
|
||||||
virDispatchError(conn);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virNWFilterFree:
|
|
||||||
* @nwfilter: a nwfilter object
|
|
||||||
*
|
|
||||||
* Free the nwfilter 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
|
|
||||||
virNWFilterFree(virNWFilterPtr nwfilter)
|
|
||||||
{
|
|
||||||
VIR_DEBUG("nwfilter=%p", nwfilter);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckNWFilterReturn(nwfilter, -1);
|
|
||||||
|
|
||||||
virObjectUnref(nwfilter);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virNWFilterGetName:
|
|
||||||
* @nwfilter: a nwfilter object
|
|
||||||
*
|
|
||||||
* Get the public name for the network filter
|
|
||||||
*
|
|
||||||
* Returns a pointer to the name or NULL, the string need not be deallocated
|
|
||||||
* its lifetime will be the same as the nwfilter object.
|
|
||||||
*/
|
|
||||||
const char *
|
|
||||||
virNWFilterGetName(virNWFilterPtr nwfilter)
|
|
||||||
{
|
|
||||||
VIR_DEBUG("nwfilter=%p", nwfilter);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckNWFilterReturn(nwfilter, NULL);
|
|
||||||
|
|
||||||
return nwfilter->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virNWFilterGetUUID:
|
|
||||||
* @nwfilter: a nwfilter object
|
|
||||||
* @uuid: pointer to a VIR_UUID_BUFLEN bytes array
|
|
||||||
*
|
|
||||||
* Get the UUID for a network filter
|
|
||||||
*
|
|
||||||
* Returns -1 in case of error, 0 in case of success
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
virNWFilterGetUUID(virNWFilterPtr nwfilter, unsigned char *uuid)
|
|
||||||
{
|
|
||||||
VIR_DEBUG("nwfilter=%p, uuid=%p", nwfilter, uuid);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckNWFilterReturn(nwfilter, -1);
|
|
||||||
virCheckNonNullArgGoto(uuid, error);
|
|
||||||
|
|
||||||
memcpy(uuid, &nwfilter->uuid[0], VIR_UUID_BUFLEN);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
virDispatchError(nwfilter->conn);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virNWFilterGetUUIDString:
|
|
||||||
* @nwfilter: a nwfilter object
|
|
||||||
* @buf: pointer to a VIR_UUID_STRING_BUFLEN bytes array
|
|
||||||
*
|
|
||||||
* Get the UUID for a network filter as string. For more information about
|
|
||||||
* UUID see RFC4122.
|
|
||||||
*
|
|
||||||
* Returns -1 in case of error, 0 in case of success
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
virNWFilterGetUUIDString(virNWFilterPtr nwfilter, char *buf)
|
|
||||||
{
|
|
||||||
VIR_DEBUG("nwfilter=%p, buf=%p", nwfilter, buf);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckNWFilterReturn(nwfilter, -1);
|
|
||||||
virCheckNonNullArgGoto(buf, error);
|
|
||||||
|
|
||||||
virUUIDFormat(nwfilter->uuid, buf);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
virDispatchError(nwfilter->conn);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virNWFilterDefineXML:
|
|
||||||
* @conn: pointer to the hypervisor connection
|
|
||||||
* @xmlDesc: an XML description of the nwfilter
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* nwfilter object is no longer needed.
|
|
||||||
*
|
|
||||||
* Returns a new nwfilter object or NULL in case of failure
|
|
||||||
*/
|
|
||||||
virNWFilterPtr
|
|
||||||
virNWFilterDefineXML(virConnectPtr conn, const char *xmlDesc)
|
|
||||||
{
|
|
||||||
VIR_DEBUG("conn=%p, xmlDesc=%s", conn, xmlDesc);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckConnectReturn(conn, NULL);
|
|
||||||
virCheckNonNullArgGoto(xmlDesc, error);
|
|
||||||
virCheckReadOnlyGoto(conn->flags, error);
|
|
||||||
|
|
||||||
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterDefineXML) {
|
|
||||||
virNWFilterPtr ret;
|
|
||||||
ret = conn->nwfilterDriver->nwfilterDefineXML(conn, xmlDesc);
|
|
||||||
if (!ret)
|
|
||||||
goto error;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
virReportUnsupportedError();
|
|
||||||
|
|
||||||
error:
|
|
||||||
virDispatchError(conn);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virNWFilterUndefine:
|
|
||||||
* @nwfilter: a nwfilter object
|
|
||||||
*
|
|
||||||
* Undefine the nwfilter object. This call will not succeed if
|
|
||||||
* a running VM is referencing the filter. This does not free the
|
|
||||||
* associated virNWFilterPtr object.
|
|
||||||
*
|
|
||||||
* Returns 0 in case of success and -1 in case of failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
virNWFilterUndefine(virNWFilterPtr nwfilter)
|
|
||||||
{
|
|
||||||
virConnectPtr conn;
|
|
||||||
VIR_DEBUG("nwfilter=%p", nwfilter);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckNWFilterReturn(nwfilter, -1);
|
|
||||||
conn = nwfilter->conn;
|
|
||||||
|
|
||||||
virCheckReadOnlyGoto(conn->flags, error);
|
|
||||||
|
|
||||||
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterUndefine) {
|
|
||||||
int ret;
|
|
||||||
ret = conn->nwfilterDriver->nwfilterUndefine(nwfilter);
|
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
virReportUnsupportedError();
|
|
||||||
|
|
||||||
error:
|
|
||||||
virDispatchError(nwfilter->conn);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virNWFilterGetXMLDesc:
|
|
||||||
* @nwfilter: a nwfilter 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 *
|
|
||||||
virNWFilterGetXMLDesc(virNWFilterPtr nwfilter, unsigned int flags)
|
|
||||||
{
|
|
||||||
virConnectPtr conn;
|
|
||||||
VIR_DEBUG("nwfilter=%p, flags=%x", nwfilter, flags);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckNWFilterReturn(nwfilter, NULL);
|
|
||||||
conn = nwfilter->conn;
|
|
||||||
|
|
||||||
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterGetXMLDesc) {
|
|
||||||
char *ret;
|
|
||||||
ret = conn->nwfilterDriver->nwfilterGetXMLDesc(nwfilter, flags);
|
|
||||||
if (!ret)
|
|
||||||
goto error;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
virReportUnsupportedError();
|
|
||||||
|
|
||||||
error:
|
|
||||||
virDispatchError(nwfilter->conn);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virNWFilterRef:
|
|
||||||
* @nwfilter: the nwfilter to hold a reference on
|
|
||||||
*
|
|
||||||
* Increment the reference count on the nwfilter. 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 nwfilter would increment
|
|
||||||
* the reference count.
|
|
||||||
*
|
|
||||||
* Returns 0 in case of success, -1 in case of failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
virNWFilterRef(virNWFilterPtr nwfilter)
|
|
||||||
{
|
|
||||||
VIR_DEBUG("nwfilter=%p refs=%d", nwfilter,
|
|
||||||
nwfilter ? nwfilter->object.u.s.refs : 0);
|
|
||||||
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
virCheckNWFilterReturn(nwfilter, -1);
|
|
||||||
|
|
||||||
virObjectRef(nwfilter);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virConnectIsEncrypted:
|
* virConnectIsEncrypted:
|
||||||
* @conn: pointer to the connection object
|
* @conn: pointer to the connection object
|
||||||
|
Loading…
Reference in New Issue
Block a user