]> xenbits.xensource.com Git - libvirt.git/commitdiff
Implementation of the public API
authorStefan Berger <stefanb@us.ibm.com>
Thu, 25 Mar 2010 17:46:02 +0000 (13:46 -0400)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 26 Mar 2010 18:01:15 +0000 (18:01 +0000)
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>
include/libvirt/virterror.h
src/datatypes.c
src/datatypes.h
src/libvirt.c
src/libvirt_private.syms
src/libvirt_public.syms
src/util/virterror.c

index d298447382ab7e5ff3929ce57345db75ad7b5dbf..8cf30be373c7e60f9a40e8c7b154c86df5ed3267 100644 (file)
@@ -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 */
index 01601d8caf2a4bc826df970e8f174b245b4e49ab..a361da6cd4ecefa7ebf4d90b6188595adbedef5c 100644 (file)
@@ -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);
+}
index e19c99ab23a317a431380dac3e3bbe435fbc1298..c22111997190fd4059bf8938993918ccdf773b65 100644 (file)
 # 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
index 8424eaf381ad507486f58d2f2a535b60194cf88a..1ee299ab741cbf538ea05386b9d2e00447aeec72 100644 (file)
@@ -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
index 0033d2a3733cc4603ce249b9da24152966b10341..4fe542704561fc59004a51fa883f985db53e4a0d 100644 (file)
@@ -105,6 +105,8 @@ virUnrefConnect;
 virUnrefSecret;
 virGetStream;
 virUnrefStream;
+virGetNWFilter;
+virUnrefNWFilter;
 
 
 # domain_conf.h
@@ -311,6 +313,7 @@ virRegisterNetworkDriver;
 virRegisterStorageDriver;
 virRegisterDeviceMonitor;
 virRegisterSecretDriver;
+virRegisterNWFilterDriver;
 
 
 # json.h
index f1491e9afa5e46f9082e514a78acb9d4184d8d5a..ad7577cd3028f4ef120ffda8f34f990eaa2b72dc 100644 (file)
@@ -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 ....
index 0e8bdb31945e16974c29ed6a944e2ac83e187b17..d82c2c6dfe4886e77302addcf4817f914bc9a5a0 100644 (file)
@@ -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");