mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 12:35:17 +00:00
Implementation of the public API
This patch adds the implementation of the public API for the network filtering (ACL) extensions to libvirt.c . Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
This commit is contained in:
parent
f0c1c3f86a
commit
46e9b0fb4e
@ -69,7 +69,8 @@ typedef enum {
|
||||
VIR_FROM_PHYP, /* Error from IBM power hypervisor */
|
||||
VIR_FROM_SECRET, /* Error from secret storage */
|
||||
VIR_FROM_CPU, /* Error from CPU driver */
|
||||
VIR_FROM_XENAPI /* Error from XenAPI */
|
||||
VIR_FROM_XENAPI, /* Error from XenAPI */
|
||||
VIR_FROM_NWFILTER /* Error from network filter driver */
|
||||
} virErrorDomain;
|
||||
|
||||
|
||||
@ -169,6 +170,10 @@ typedef enum {
|
||||
VIR_ERR_NO_INTERFACE, /* interface driver not running */
|
||||
VIR_ERR_INVALID_INTERFACE, /* invalid interface object */
|
||||
VIR_ERR_MULTIPLE_INTERFACES, /* more than one matching interface found */
|
||||
VIR_WAR_NO_NWFILTER, /* failed to start nwfilter driver */
|
||||
VIR_ERR_INVALID_NWFILTER, /* invalid nwfilter object */
|
||||
VIR_ERR_NO_NWFILTER, /* nw filter pool not found */
|
||||
VIR_ERR_BUILD_FIREWALL, /* nw filter pool not found */
|
||||
VIR_WAR_NO_SECRET, /* failed to start secret storage */
|
||||
VIR_ERR_INVALID_SECRET, /* invalid secret */
|
||||
VIR_ERR_NO_SECRET, /* secret not found */
|
||||
|
142
src/datatypes.c
142
src/datatypes.c
@ -175,6 +175,9 @@ virGetConnect(void) {
|
||||
ret->secrets = virHashCreate(20);
|
||||
if (ret->secrets == NULL)
|
||||
goto failed;
|
||||
ret->nwfilterPools = virHashCreate(20);
|
||||
if (ret->nwfilterPools == NULL)
|
||||
goto failed;
|
||||
|
||||
ret->refs = 1;
|
||||
return(ret);
|
||||
@ -1362,3 +1365,142 @@ int virUnrefStream(virStreamPtr st) {
|
||||
virMutexUnlock(&st->conn->lock);
|
||||
return (refs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virGetNWFilter:
|
||||
* @conn: the hypervisor connection
|
||||
* @name: pointer to the network filter pool name
|
||||
* @uuid: pointer to the uuid
|
||||
*
|
||||
* Lookup if the network filter is already registered for that connection,
|
||||
* if yes return a new pointer to it, if no allocate a new structure,
|
||||
* and register it in the table. In any case a corresponding call to
|
||||
* virFreeNWFilterPool() is needed to not leak data.
|
||||
*
|
||||
* Returns a pointer to the network, or NULL in case of failure
|
||||
*/
|
||||
virNWFilterPtr
|
||||
virGetNWFilter(virConnectPtr conn, const char *name, const unsigned char *uuid) {
|
||||
virNWFilterPtr ret = NULL;
|
||||
|
||||
if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (uuid == NULL)) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
return(NULL);
|
||||
}
|
||||
virMutexLock(&conn->lock);
|
||||
|
||||
/* TODO search by UUID first as they are better differenciators */
|
||||
|
||||
ret = (virNWFilterPtr) virHashLookup(conn->nwfilterPools, name);
|
||||
/* TODO check the UUID */
|
||||
if (ret == NULL) {
|
||||
if (VIR_ALLOC(ret) < 0) {
|
||||
virMutexUnlock(&conn->lock);
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
ret->name = strdup(name);
|
||||
if (ret->name == NULL) {
|
||||
virMutexUnlock(&conn->lock);
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
ret->magic = VIR_NWFILTER_MAGIC;
|
||||
ret->conn = conn;
|
||||
if (uuid != NULL)
|
||||
memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
|
||||
|
||||
if (virHashAddEntry(conn->nwfilterPools, name, ret) < 0) {
|
||||
virMutexUnlock(&conn->lock);
|
||||
virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("failed to add network filter pool to connection hash table"));
|
||||
goto error;
|
||||
}
|
||||
conn->refs++;
|
||||
}
|
||||
ret->refs++;
|
||||
virMutexUnlock(&conn->lock);
|
||||
return(ret);
|
||||
|
||||
error:
|
||||
if (ret != NULL) {
|
||||
VIR_FREE(ret->name);
|
||||
VIR_FREE(ret);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virReleaseNWFilterPool:
|
||||
* @pool: the pool to release
|
||||
*
|
||||
* Unconditionally release all memory associated with a pool.
|
||||
* The conn.lock mutex must be held prior to calling this, and will
|
||||
* be released prior to this returning. The pool obj 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
|
||||
virReleaseNWFilterPool(virNWFilterPtr pool) {
|
||||
virConnectPtr conn = pool->conn;
|
||||
DEBUG("release pool %p %s", pool, pool->name);
|
||||
|
||||
/* TODO search by UUID first as they are better differenciators */
|
||||
if (virHashRemoveEntry(conn->nwfilterPools, pool->name, NULL) < 0) {
|
||||
virMutexUnlock(&conn->lock);
|
||||
virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("pool missing from connection hash table"));
|
||||
conn = NULL;
|
||||
}
|
||||
|
||||
pool->magic = -1;
|
||||
VIR_FREE(pool->name);
|
||||
VIR_FREE(pool);
|
||||
|
||||
if (conn) {
|
||||
DEBUG("unref connection %p %d", conn, conn->refs);
|
||||
conn->refs--;
|
||||
if (conn->refs == 0) {
|
||||
virReleaseConnect(conn);
|
||||
/* Already unlocked mutex */
|
||||
return;
|
||||
}
|
||||
virMutexUnlock(&conn->lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virUnrefNWFilter:
|
||||
* @pool: the nwfilter to unreference
|
||||
*
|
||||
* Unreference the networkf itler. If the use count drops to zero, the
|
||||
* structure is actually freed.
|
||||
*
|
||||
* Returns the reference count or -1 in case of failure.
|
||||
*/
|
||||
int
|
||||
virUnrefNWFilter(virNWFilterPtr pool) {
|
||||
int refs;
|
||||
|
||||
if (!VIR_IS_CONNECTED_NWFILTER(pool)) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
virMutexLock(&pool->conn->lock);
|
||||
DEBUG("unref pool %p %s %d", pool, pool->name, pool->refs);
|
||||
pool->refs--;
|
||||
refs = pool->refs;
|
||||
if (refs == 0) {
|
||||
virReleaseNWFilterPool(pool);
|
||||
/* Already unlocked mutex */
|
||||
return (0);
|
||||
}
|
||||
|
||||
virMutexUnlock(&pool->conn->lock);
|
||||
return (refs);
|
||||
}
|
||||
|
@ -120,6 +120,17 @@
|
||||
# define VIR_IS_CONNECTED_STREAM(obj) (VIR_IS_STREAM(obj) && VIR_IS_CONNECT((obj)->conn))
|
||||
|
||||
|
||||
/**
|
||||
* VIR_NWFILTER_MAGIC:
|
||||
*
|
||||
* magic value used to protect the API when pointers to network filter
|
||||
* pool structures are passed down by the users.
|
||||
*/
|
||||
#define VIR_NWFILTER_MAGIC 0xDEAD7777
|
||||
#define VIR_IS_NWFILTER(obj) ((obj) && (obj)->magic==VIR_NWFILTER_MAGIC)
|
||||
#define VIR_IS_CONNECTED_NWFILTER(obj) (VIR_IS_NWFILTER(obj) && VIR_IS_CONNECT((obj)->conn))
|
||||
|
||||
|
||||
/**
|
||||
* _virConnect:
|
||||
*
|
||||
@ -141,6 +152,7 @@ struct _virConnect {
|
||||
virStorageDriverPtr storageDriver;
|
||||
virDeviceMonitorPtr deviceMonitor;
|
||||
virSecretDriverPtr secretDriver;
|
||||
virNWFilterDriverPtr nwfilterDriver;
|
||||
|
||||
/* Private data pointer which can be used by driver and
|
||||
* network driver as they wish.
|
||||
@ -152,6 +164,7 @@ struct _virConnect {
|
||||
void * storagePrivateData;
|
||||
void * devMonPrivateData;
|
||||
void * secretPrivateData;
|
||||
void * nwfilterPrivateData;
|
||||
|
||||
/*
|
||||
* The lock mutex must be acquired before accessing/changing
|
||||
@ -173,6 +186,7 @@ struct _virConnect {
|
||||
virHashTablePtr storageVols;/* hash table for known storage vols */
|
||||
virHashTablePtr nodeDevices; /* hash table for known node devices */
|
||||
virHashTablePtr secrets; /* hash taboe for known secrets */
|
||||
virHashTablePtr nwfilterPools; /* hash tables ofr known nw filter pools */
|
||||
int refs; /* reference count */
|
||||
};
|
||||
|
||||
@ -336,4 +350,22 @@ int virUnrefSecret(virSecretPtr secret);
|
||||
virStreamPtr virGetStream(virConnectPtr conn);
|
||||
int virUnrefStream(virStreamPtr st);
|
||||
|
||||
/**
|
||||
* _virNWFilter:
|
||||
*
|
||||
* Internal structure associated to a network filter
|
||||
*/
|
||||
struct _virNWFilter {
|
||||
unsigned int magic; /* specific value to check */
|
||||
int refs; /* reference count */
|
||||
virConnectPtr conn; /* pointer back to the connection */
|
||||
char *name; /* the network filter external name */
|
||||
unsigned char uuid[VIR_UUID_BUFLEN]; /* the network filter unique identifier */
|
||||
};
|
||||
|
||||
virNWFilterPtr virGetNWFilter(virConnectPtr conn,
|
||||
const char *name,
|
||||
const unsigned char *uuid);
|
||||
int virUnrefNWFilter(virNWFilterPtr pool);
|
||||
|
||||
#endif
|
||||
|
586
src/libvirt.c
586
src/libvirt.c
@ -91,6 +91,8 @@ static virDeviceMonitorPtr virDeviceMonitorTab[MAX_DRIVERS];
|
||||
static int virDeviceMonitorTabCount = 0;
|
||||
static virSecretDriverPtr virSecretDriverTab[MAX_DRIVERS];
|
||||
static int virSecretDriverTabCount = 0;
|
||||
static virNWFilterDriverPtr virNWFilterDriverTab[MAX_DRIVERS];
|
||||
static int virNWFilterDriverTabCount = 0;
|
||||
#ifdef WITH_LIBVIRTD
|
||||
static virStateDriverPtr virStateDriverTab[MAX_DRIVERS];
|
||||
static int virStateDriverTabCount = 0;
|
||||
@ -654,6 +656,32 @@ virLibSecretError(virSecretPtr secret, virErrorNumber error, const char *info)
|
||||
errmsg, info, NULL, 0, 0, errmsg, info);
|
||||
}
|
||||
|
||||
/**
|
||||
* virLibNWFilterError:
|
||||
* @conn: the connection if available
|
||||
* @error: the error number
|
||||
* @info: extra information string
|
||||
*
|
||||
* Handle an error at the connection level
|
||||
*/
|
||||
static void
|
||||
virLibNWFilterError(virNWFilterPtr pool, virErrorNumber error,
|
||||
const char *info)
|
||||
{
|
||||
virConnectPtr conn = NULL;
|
||||
const char *errmsg;
|
||||
|
||||
if (error == VIR_ERR_OK)
|
||||
return;
|
||||
|
||||
errmsg = virErrorMsg(error, info);
|
||||
if (error != VIR_ERR_INVALID_NWFILTER)
|
||||
conn = pool->conn;
|
||||
|
||||
virRaiseError(conn, NULL, NULL, VIR_FROM_NWFILTER, error, VIR_ERR_ERROR,
|
||||
errmsg, info, NULL, 0, 0, errmsg, info);
|
||||
}
|
||||
|
||||
/**
|
||||
* virRegisterNetworkDriver:
|
||||
* @driver: pointer to a network driver block
|
||||
@ -809,6 +837,38 @@ virRegisterSecretDriver(virSecretDriverPtr driver)
|
||||
return virSecretDriverTabCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* virRegisterNWFilterDriver:
|
||||
* @driver: pointer to a network filter driver block
|
||||
*
|
||||
* Register a network filter virtualization driver
|
||||
*
|
||||
* Returns the driver priority or -1 in case of error.
|
||||
*/
|
||||
int
|
||||
virRegisterNWFilterDriver(virNWFilterDriverPtr driver)
|
||||
{
|
||||
if (virInitialize() < 0)
|
||||
return -1;
|
||||
|
||||
if (driver == NULL) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virNWFilterDriverTabCount >= MAX_DRIVERS) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG ("registering %s as network filter driver %d",
|
||||
driver->name, virNWFilterDriverTabCount);
|
||||
|
||||
virNWFilterDriverTab[virNWFilterDriverTabCount] = driver;
|
||||
return virNWFilterDriverTabCount++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virRegisterDriver:
|
||||
* @driver: pointer to a driver block
|
||||
@ -1253,6 +1313,26 @@ do_open (const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
/* Network filter driver. Optional */
|
||||
for (i = 0; i < virNWFilterDriverTabCount; i++) {
|
||||
res = virNWFilterDriverTab[i]->open (ret, auth, flags);
|
||||
DEBUG("nwfilter driver %d %s returned %s",
|
||||
i, virNWFilterDriverTab[i]->name,
|
||||
res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
|
||||
(res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
|
||||
(res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown status")));
|
||||
if (res == VIR_DRV_OPEN_ERROR) {
|
||||
if (STREQ(virNWFilterDriverTab[i]->name, "remote")) {
|
||||
virLibConnWarning (NULL, VIR_WAR_NO_NWFILTER,
|
||||
_("Is the daemon running ?"));
|
||||
}
|
||||
break;
|
||||
} else if (res == VIR_DRV_OPEN_SUCCESS) {
|
||||
ret->nwfilterDriver = virNWFilterDriverTab[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
failed:
|
||||
@ -11084,6 +11164,512 @@ error:
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
DEBUG("conn=%p", conn);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_CONNECT(conn)) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conn->nwfilterDriver && conn->nwfilterDriver->numOfNWFilters) {
|
||||
int ret;
|
||||
ret = conn->nwfilterDriver->numOfNWFilters (conn);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
|
||||
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)
|
||||
{
|
||||
DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_CONNECT(conn)) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((names == NULL) || (maxnames < 0)) {
|
||||
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (conn->nwfilterDriver && conn->nwfilterDriver->listNWFilters) {
|
||||
int ret;
|
||||
ret = conn->nwfilterDriver->listNWFilters (conn, names, maxnames);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
|
||||
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.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
DEBUG("conn=%p, name=%s", conn, name);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_CONNECT(conn)) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return (NULL);
|
||||
}
|
||||
if (name == NULL) {
|
||||
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterLookupByName) {
|
||||
virNWFilterPtr ret;
|
||||
ret = conn->nwfilterDriver->nwfilterLookupByName (conn, name);
|
||||
if (!ret)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
|
||||
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.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
DEBUG("conn=%p, uuid=%s", conn, uuid);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_CONNECT(conn)) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return (NULL);
|
||||
}
|
||||
if (uuid == NULL) {
|
||||
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterLookupByUUID){
|
||||
virNWFilterPtr ret;
|
||||
ret = conn->nwfilterDriver->nwfilterLookupByUUID (conn, uuid);
|
||||
if (!ret)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
|
||||
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.
|
||||
*
|
||||
* 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];
|
||||
DEBUG("conn=%p, uuidstr=%s", conn, uuidstr);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_CONNECT(conn)) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return (NULL);
|
||||
}
|
||||
if (uuidstr == NULL) {
|
||||
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (virUUIDParse(uuidstr, uuid) < 0) {
|
||||
virLibConnError(conn, VIR_ERR_INVALID_ARG, __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)
|
||||
{
|
||||
DEBUG("nwfilter=%p", nwfilter);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_CONNECTED_NWFILTER(nwfilter)) {
|
||||
virLibNWFilterError(NULL, VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return -1;
|
||||
}
|
||||
if (virUnrefNWFilter(nwfilter) < 0) {
|
||||
virDispatchError(NULL);
|
||||
return -1;
|
||||
}
|
||||
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)
|
||||
{
|
||||
DEBUG("nwfilter=%p", nwfilter);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_NWFILTER(nwfilter)) {
|
||||
virLibNWFilterError(NULL, VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return (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)
|
||||
{
|
||||
DEBUG("nwfilter=%p, uuid=%p", nwfilter, uuid);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_NWFILTER(nwfilter)) {
|
||||
virLibNWFilterError(NULL, VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return -1;
|
||||
}
|
||||
if (uuid == NULL) {
|
||||
virLibNWFilterError(nwfilter, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
goto 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)
|
||||
{
|
||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||
DEBUG("nwfilter=%p, buf=%p", nwfilter, buf);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_NWFILTER(nwfilter)) {
|
||||
virLibNWFilterError(NULL, VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return -1;
|
||||
}
|
||||
if (buf == NULL) {
|
||||
virLibNWFilterError(nwfilter, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (virNWFilterGetUUID(nwfilter, &uuid[0]))
|
||||
goto error;
|
||||
|
||||
virUUIDFormat(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()
|
||||
*
|
||||
* Returns a new nwfilter object or NULL in case of failure
|
||||
*/
|
||||
virNWFilterPtr
|
||||
virNWFilterDefineXML(virConnectPtr conn, const char *xmlDesc)
|
||||
{
|
||||
DEBUG("conn=%p, xmlDesc=%s", conn, xmlDesc);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_CONNECT(conn)) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return (NULL);
|
||||
}
|
||||
if (xmlDesc == NULL) {
|
||||
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
if (conn->flags & VIR_CONNECT_RO) {
|
||||
virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (conn->nwfilterDriver && conn->nwfilterDriver->defineXML) {
|
||||
virNWFilterPtr ret;
|
||||
ret = conn->nwfilterDriver->defineXML (conn, xmlDesc, 0);
|
||||
if (!ret)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
|
||||
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;
|
||||
DEBUG("nwfilter=%p", nwfilter);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_CONNECTED_NWFILTER(nwfilter)) {
|
||||
virLibNWFilterError(NULL, VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
conn = nwfilter->conn;
|
||||
if (conn->flags & VIR_CONNECT_RO) {
|
||||
virLibNWFilterError(nwfilter, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (conn->nwfilterDriver && conn->nwfilterDriver->undefine) {
|
||||
int ret;
|
||||
ret = conn->nwfilterDriver->undefine (nwfilter);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
|
||||
error:
|
||||
virDispatchError(nwfilter->conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virNWFilterGetXMLDesc:
|
||||
* @nwfilter: a nwfilter object
|
||||
* @flags: an OR'ed set of extraction flags, not used yet
|
||||
*
|
||||
* 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, int flags)
|
||||
{
|
||||
virConnectPtr conn;
|
||||
DEBUG("nwfilter=%p, flags=%d", nwfilter, flags);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (!VIR_IS_CONNECTED_NWFILTER(nwfilter)) {
|
||||
virLibNWFilterError(NULL, VIR_ERR_INVALID_NWFILTER, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return (NULL);
|
||||
}
|
||||
if (flags != 0) {
|
||||
virLibNWFilterError(nwfilter, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
conn = nwfilter->conn;
|
||||
|
||||
if (conn->nwfilterDriver && conn->nwfilterDriver->getXMLDesc) {
|
||||
char *ret;
|
||||
ret = conn->nwfilterDriver->getXMLDesc (nwfilter, flags);
|
||||
if (!ret)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
|
||||
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)
|
||||
{
|
||||
if ((!VIR_IS_CONNECTED_NWFILTER(nwfilter))) {
|
||||
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
virDispatchError(NULL);
|
||||
return -1;
|
||||
}
|
||||
virMutexLock(&nwfilter->conn->lock);
|
||||
DEBUG("nwfilter=%p refs=%d", nwfilter, nwfilter->refs);
|
||||
nwfilter->refs++;
|
||||
virMutexUnlock(&nwfilter->conn->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virInterfaceIsActive:
|
||||
* @iface: pointer to the interface object
|
||||
|
@ -105,6 +105,8 @@ virUnrefConnect;
|
||||
virUnrefSecret;
|
||||
virGetStream;
|
||||
virUnrefStream;
|
||||
virGetNWFilter;
|
||||
virUnrefNWFilter;
|
||||
|
||||
|
||||
# domain_conf.h
|
||||
@ -311,6 +313,7 @@ virRegisterNetworkDriver;
|
||||
virRegisterStorageDriver;
|
||||
virRegisterDeviceMonitor;
|
||||
virRegisterSecretDriver;
|
||||
virRegisterNWFilterDriver;
|
||||
|
||||
|
||||
# json.h
|
||||
|
@ -365,6 +365,19 @@ LIBVIRT_0.7.8 {
|
||||
virConnectDomainEventRegisterAny;
|
||||
virConnectDomainEventDeregisterAny;
|
||||
virDomainUpdateDeviceFlags;
|
||||
virConnectListNWFilters;
|
||||
virConnectNumOfNWFilters;
|
||||
virNWFilterLookupByName;
|
||||
virNWFilterLookupByUUID;
|
||||
virNWFilterLookupByUUIDString;
|
||||
virNWFilterFree;
|
||||
virNWFilterGetName;
|
||||
virNWFilterGetUUID;
|
||||
virNWFilterGetUUIDString;
|
||||
virNWFilterGetXMLDesc;
|
||||
virNWFilterRef;
|
||||
virNWFilterDefineXML;
|
||||
virNWFilterUndefine;
|
||||
} LIBVIRT_0.7.7;
|
||||
|
||||
# .... define new API here using predicted next version number ....
|
||||
|
@ -178,6 +178,9 @@ static const char *virErrorDomainName(virErrorDomain domain) {
|
||||
case VIR_FROM_CPU:
|
||||
dom = "CPU ";
|
||||
break;
|
||||
case VIR_FROM_NWFILTER:
|
||||
dom = "Network Filter";
|
||||
break;
|
||||
}
|
||||
return(dom);
|
||||
}
|
||||
@ -1100,6 +1103,30 @@ virErrorMsg(virErrorNumber error, const char *info)
|
||||
else
|
||||
errmsg = _("Secret not found: %s");
|
||||
break;
|
||||
case VIR_WAR_NO_NWFILTER:
|
||||
if (info == NULL)
|
||||
errmsg = _("Failed to start the nwfilter driver");
|
||||
else
|
||||
errmsg = _("Failed to start the nwfilter driver: %s");
|
||||
break;
|
||||
case VIR_ERR_INVALID_NWFILTER:
|
||||
if (info == NULL)
|
||||
errmsg = _("Invalid network filter");
|
||||
else
|
||||
errmsg = _("Invalid network filter: %s");
|
||||
break;
|
||||
case VIR_ERR_NO_NWFILTER:
|
||||
if (info == NULL)
|
||||
errmsg = _("Network filter not found");
|
||||
else
|
||||
errmsg = _("Network filter not found: %s");
|
||||
break;
|
||||
case VIR_ERR_BUILD_FIREWALL:
|
||||
if (info == NULL)
|
||||
errmsg = _("Error while building firewall");
|
||||
else
|
||||
errmsg = _("Error while building firewall: %s");
|
||||
break;
|
||||
case VIR_ERR_CONFIG_UNSUPPORTED:
|
||||
if (info == NULL)
|
||||
errmsg = _("unsupported configuration");
|
||||
|
Loading…
x
Reference in New Issue
Block a user