[libvirt] [PATCH 2/3] First level of plumbing for virInterface*.

laine at laine.org laine at laine.org
Thu Apr 2 18:18:39 UTC 2009


From: Laine Stump <laine at redhat.com>

---
 include/libvirt/libvirt.h    |   18 ++
 include/libvirt/libvirt.h.in |   18 ++
 include/libvirt/virterror.h  |    4 +
 src/datatypes.h              |   25 ++
 src/driver.h                 |   73 +++++
 src/libvirt.c                |  628 ++++++++++++++++++++++++++++++++++++++++++
 src/util.h                   |    2 -
 src/virterror.c              |    3 +
 8 files changed, 769 insertions(+), 2 deletions(-)

diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h
index f2e695a..886c400 100644
--- a/include/libvirt/libvirt.h
+++ b/include/libvirt/libvirt.h
@@ -433,6 +433,24 @@ extern virConnectAuthPtr virConnectAuthPtrDefault;
 
 #define VIR_UUID_STRING_BUFLEN (36+1)
 
+/**
+ * VIR_MAC_BUFLEN:
+ *
+ * This macro provides the length of the buffer required
+ * for an interface MAC address
+ */
+
+#define VIR_MAC_BUFLEN (6)
+
+/**
+ * VIR_MAC_STRING_BUFLEN:
+ *
+ * This macro provides the length of the buffer required
+ * for virInterfaceGetMACString()
+ */
+
+#define VIR_MAC_STRING_BUFLEN (VIR_MAC_BUFLEN * 3)
+
 /* library versioning */
 
 /**
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index f2656a3..77b00b3 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -433,6 +433,24 @@ extern virConnectAuthPtr virConnectAuthPtrDefault;
 
 #define VIR_UUID_STRING_BUFLEN (36+1)
 
+/**
+ * VIR_MAC_BUFLEN:
+ *
+ * This macro provides the length of the buffer required
+ * for an interface MAC address
+ */
+
+#define VIR_MAC_BUFLEN (6)
+
+/**
+ * VIR_MAC_STRING_BUFLEN:
+ *
+ * This macro provides the length of the buffer required
+ * for virInterfaceGetMACString()
+ */
+
+#define VIR_MAC_STRING_BUFLEN (VIR_MAC_BUFLEN * 3)
+
 /* library versioning */
 
 /**
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index 2c3777d..b8a9cad 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -62,6 +62,7 @@ typedef enum {
     VIR_FROM_NODEDEV, /* Error from node device monitor */
     VIR_FROM_XEN_INOTIFY, /* Error from xen inotify layer */
     VIR_FROM_SECURITY,  /* Error from security framework */
+    VIR_FROM_INTERFACE, /* Error when operating on an interface */
 } virErrorDomain;
 
 
@@ -156,6 +157,9 @@ typedef enum {
     VIR_ERR_INVALID_NODE_DEVICE,/* invalid node device object */
     VIR_ERR_NO_NODE_DEVICE,/* node device not found */
     VIR_ERR_NO_SECURITY_MODEL, /* security model not found */
+    VIR_WAR_NO_INTERFACE, /* failed to start interface driver */
+    VIR_ERR_NO_INTERFACE, /* interface driver not running */
+    VIR_ERR_INVALID_INTERFACE, /* invalid interface object */
 } virErrorNumber;
 
 /**
diff --git a/src/datatypes.h b/src/datatypes.h
index 5956c5d..deac9df 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -59,6 +59,16 @@
 #define VIR_IS_CONNECTED_NETWORK(obj)	(VIR_IS_NETWORK(obj) && VIR_IS_CONNECT((obj)->conn))
 
 /**
+ * VIR_INTERFACE_MAGIC:
+ *
+ * magic value used to protect the API when pointers to interface structures
+ * are passed down by the users.
+ */
+#define VIR_INTERFACE_MAGIC		0xDEAD5309
+#define VIR_IS_INTERFACE(obj)		((obj) && (obj)->magic==VIR_INTERFACE_MAGIC)
+#define VIR_IS_CONNECTED_INTERFACE(obj)	(VIR_IS_INTERFACE(obj) && VIR_IS_CONNECT((obj)->conn))
+
+/**
  * VIR_STORAGE_POOL_MAGIC:
  *
  * magic value used to protect the API when pointers to storage pool structures
@@ -106,6 +116,7 @@ struct _virConnect {
     /* The underlying hypervisor driver and network driver. */
     virDriverPtr      driver;
     virNetworkDriverPtr networkDriver;
+    virInterfaceDriverPtr interfaceDriver;
     virStorageDriverPtr storageDriver;
     virDeviceMonitorPtr  deviceMonitor;
 
@@ -115,6 +126,7 @@ struct _virConnect {
      */
     void *            privateData;
     void *            networkPrivateData;
+    void *            interfacePrivateData;
     void *            storagePrivateData;
     void *            devMonPrivateData;
 
@@ -167,6 +179,19 @@ struct _virNetwork {
 };
 
 /**
+* _virInterface:
+*
+* Internal structure associated to a physical host interface
+*/
+struct _virInterface {
+    unsigned int magic;                  /* specific value to check */
+    int refs;                            /* reference count */
+    virConnectPtr conn;                  /* pointer back to the connection */
+    char *name;                          /* the network external name */
+    unsigned char mac[VIR_MAC_BUFLEN];  /* the interface MAC address */
+};
+
+/**
 * _virStoragePool:
 *
 * Internal structure associated to a storage pool
diff --git a/src/driver.h b/src/driver.h
index 88c2b0a..50c9b64 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -487,6 +487,78 @@ struct _virNetworkDriver {
         virDrvNetworkSetAutostart	networkSetAutostart;
 };
 
+/*-------*/
+typedef int
+        (*virDrvNumOfInterfaces)        (virConnectPtr conn);
+typedef int
+        (*virDrvListInterfaces)         (virConnectPtr conn,
+                                         char **const names,
+                                         int maxnames);
+typedef virInterfacePtr
+        (*virDrvInterfaceLookupByName)  (virConnectPtr conn,
+                                         const char *name);
+typedef virInterfacePtr
+        (*virDrvInterfaceLookupByMAC)   (virConnectPtr conn,
+                                         const unsigned char *mac);
+typedef virInterfacePtr
+        (*virDrvInterfaceLookupByMACString) (virConnectPtr conn,
+                                             const char *mac);
+typedef virInterfacePtr
+        (*virDrvInterfaceDefineXML)     (virConnectPtr conn,
+                                         const char *xmlDesc,
+                                         int flags);
+typedef int
+        (*virDrvInterfaceUndefine)      (virInterfacePtr interface);
+typedef int
+        (*virDrvInterfaceCreate)        (virInterfacePtr interface,
+                                         int flags);
+typedef int
+        (*virDrvInterfaceDestroy)       (virInterfacePtr interface,
+                                         int flags);
+typedef const char*
+        (*virDrvInterfaceGetName)       (virInterfacePtr interface);
+typedef int
+        (*virDrvInterfaceGetMAC)        (virInterfacePtr interface,
+                                         unsigned char *mac);
+typedef int
+        (*virDrvInterfaceGetMACString)  (virInterfacePtr interface,
+                                         char *mac);
+typedef char *
+        (*virDrvInterfaceGetXMLDesc)    (virInterfacePtr interface,
+                                         int flags);
+
+typedef struct _virInterfaceDriver virInterfaceDriver;
+typedef virInterfaceDriver *virInterfaceDriverPtr;
+
+/**
+ * _virInterfaceDriver:
+ *
+ * Structure associated to a network virtualization driver, defining the various
+ * entry points for it.
+ *
+ * All drivers must support the following fields/methods:
+ *  - open
+ *  - close
+ */
+struct _virInterfaceDriver {
+    const char                      *name; /* the name of the driver */
+    virDrvOpen                       open;
+    virDrvClose                      close;
+    virDrvNumOfInterfaces            numOfInterfaces;
+    virDrvListInterfaces             listInterfaces;
+    virDrvInterfaceLookupByName      interfaceLookupByName;
+    virDrvInterfaceLookupByMAC       interfaceLookupByMAC;
+    virDrvInterfaceLookupByMACString interfaceLookupByMACString;
+    virDrvInterfaceDefineXML         interfaceDefineXML;
+    virDrvInterfaceUndefine          interfaceUndefine;
+    virDrvInterfaceCreate            interfaceCreate;
+    virDrvInterfaceDestroy           interfaceDestroy;
+    virDrvInterfaceGetName           interfaceGetName;
+    virDrvInterfaceGetMAC            interfaceGetMAC;
+    virDrvInterfaceGetMACString      interfaceGetMACString;
+    virDrvInterfaceGetXMLDesc        interfaceGetXMLDesc;
+};
+
 
 typedef int
     (*virDrvConnectNumOfStoragePools)        (virConnectPtr conn);
@@ -710,6 +782,7 @@ struct _virDeviceMonitor {
  */
 int virRegisterDriver(virDriverPtr);
 int virRegisterNetworkDriver(virNetworkDriverPtr);
+int virRegisterInterfaceDriver(virInterfaceDriverPtr);
 int virRegisterStorageDriver(virStorageDriverPtr);
 int virRegisterDeviceMonitor(virDeviceMonitorPtr);
 #ifdef WITH_LIBVIRTD
diff --git a/src/libvirt.c b/src/libvirt.c
index d6de773..af46c31 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -71,6 +71,8 @@ static virDriverPtr virDriverTab[MAX_DRIVERS];
 static int virDriverTabCount = 0;
 static virNetworkDriverPtr virNetworkDriverTab[MAX_DRIVERS];
 static int virNetworkDriverTabCount = 0;
+static virInterfaceDriverPtr virInterfaceDriverTab[MAX_DRIVERS];
+static int virInterfaceDriverTabCount = 0;
 static virStorageDriverPtr virStorageDriverTab[MAX_DRIVERS];
 static int virStorageDriverTabCount = 0;
 static virDeviceMonitorPtr virDeviceMonitorTab[MAX_DRIVERS];
@@ -455,6 +457,32 @@ virLibNetworkError(virNetworkPtr network, virErrorNumber error,
 }
 
 /**
+ * virLibInterfaceError:
+ * @conn: the connection if available
+ * @error: the error number
+ * @info: extra information string
+ *
+ * Handle an error at the connection level
+ */
+static void
+virLibInterfaceError(virInterfacePtr interface, 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_INTERFACE) {
+        conn = interface->conn;
+    }
+    virRaiseError(conn, NULL, NULL, VIR_FROM_INTERFACE, error, VIR_ERR_ERROR,
+                  errmsg, info, NULL, 0, 0, errmsg, info);
+}
+
+/**
  * virLibStoragePoolError:
  * @conn: the connection if available
  * @error: the error number
@@ -564,6 +592,37 @@ virRegisterNetworkDriver(virNetworkDriverPtr driver)
 }
 
 /**
+ * virRegisterInterfaceDriver:
+ * @driver: pointer to a interface driver block
+ *
+ * Register a interface virtualization driver
+ *
+ * Returns the driver priority or -1 in case of error.
+ */
+int
+virRegisterInterfaceDriver(virInterfaceDriverPtr driver)
+{
+    if (virInitialize() < 0)
+      return -1;
+
+    if (driver == NULL) {
+        virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(-1);
+    }
+
+    if (virInterfaceDriverTabCount >= MAX_DRIVERS) {
+        virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(-1);
+    }
+
+    DEBUG ("registering %s as interface driver %d",
+           driver->name, virInterfaceDriverTabCount);
+
+    virInterfaceDriverTab[virInterfaceDriverTabCount] = driver;
+    return virInterfaceDriverTabCount++;
+}
+
+/**
  * virRegisterStorageDriver:
  * @driver: pointer to a storage driver block
  *
@@ -955,6 +1014,24 @@ do_open (const char *name,
         }
     }
 
+    for (i = 0; i < virInterfaceDriverTabCount; i++) {
+        res = virInterfaceDriverTab[i]->open (ret, auth, flags);
+        DEBUG("interface driver %d %s returned %s",
+              i, virInterfaceDriverTab[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(virInterfaceDriverTab[i]->name, "remote")) {
+                virLibConnWarning (NULL, VIR_WAR_NO_INTERFACE,
+                                   "Is the daemon running ?");
+            }
+            break;
+        } else if (res == VIR_DRV_OPEN_SUCCESS) {
+            ret->interfaceDriver = virInterfaceDriverTab[i];
+            break;
+        }
+    }
 
     /* Secondary driver for storage. Optional */
     for (i = 0; i < virStorageDriverTabCount; i++) {
@@ -1115,6 +1192,8 @@ virConnectClose(virConnectPtr conn)
 
     if (conn->networkDriver)
         conn->networkDriver->close (conn);
+    if (conn->interfaceDriver)
+        conn->interfaceDriver->close (conn);
     if (conn->storageDriver)
         conn->storageDriver->close (conn);
     if (conn->deviceMonitor)
@@ -5258,6 +5337,555 @@ error:
     return -1;
 }
 
+/**
+ * virInterfaceGetConnect:
+ * @net: pointer to a interface
+ *
+ * Provides the connection pointer associated with an interface.  The
+ * reference counter on the connection is not increased by this
+ * call.
+ *
+ * WARNING: When writing libvirt bindings in other languages, do
+ * not use this function.  Instead, store the connection and
+ * the interface object together.
+ *
+ * Returns the virConnectPtr or NULL in case of failure.
+ */
+virConnectPtr
+virInterfaceGetConnect (virInterfacePtr interface)
+{
+    DEBUG("interface=%p", interface);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_INTERFACE (interface)) {
+        virLibInterfaceError (NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+        return NULL;
+    }
+    return interface->conn;
+}
+
+/**
+ * virConnectNumOfInterfaces:
+ * @conn: pointer to the hypervisor connection
+ *
+ * Provides the number of interfaces on the physical host.
+ *
+ * Returns the number of interface found or -1 in case of error
+ */
+int
+virConnectNumOfInterfaces(virConnectPtr conn)
+{
+    DEBUG("conn=%p", conn);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    if (conn->interfaceDriver && conn->interfaceDriver->numOfInterfaces) {
+        int ret;
+        ret = conn->interfaceDriver->numOfInterfaces (conn);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(conn);
+    return -1;
+}
+
+/**
+ * virConnectListInterfaces:
+ * @conn: pointer to the hypervisor connection
+ * @names: array to collect the list of names of interfaces
+ * @maxnames: size of @names
+ *
+ * Collect the list of physical host interfaces, and store their names in @names
+ *
+ * Returns the number of interfaces found or -1 in case of error
+ */
+int
+virConnectListInterfaces(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__);
+        return (-1);
+    }
+
+    if ((names == NULL) || (maxnames < 0)) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    if (conn->interfaceDriver && conn->interfaceDriver->listInterfaces) {
+        int ret;
+        ret = conn->interfaceDriver->listInterfaces (conn, names, maxnames);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(conn);
+    return -1;
+}
+
+/**
+ * virInterfaceLookupByName:
+ * @conn: pointer to the hypervisor connection
+ * @name: name for the interface
+ *
+ * Try to lookup an interface on the given hypervisor based on its name.
+ *
+ * Returns a new interface object or NULL in case of failure.  If the
+ * interface cannot be found, then VIR_ERR_NO_INTERFACE error is raised.
+ */
+virInterfacePtr
+virInterfaceLookupByName(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__);
+        return (NULL);
+    }
+    if (name == NULL) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto  error;
+    }
+
+    if (conn->interfaceDriver && conn->interfaceDriver->interfaceLookupByName) {
+        virInterfacePtr ret;
+        ret = conn->interfaceDriver->interfaceLookupByName (conn, name);
+        if (!ret)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(conn);
+    return NULL;
+}
+
+/**
+ * virInterfaceLookupByMAC:
+ * @conn: pointer to the hypervisor connection
+ * @mac: the raw MAC for the interface
+ *
+ * Try to lookup an interface on the given hypervisor based on its MAC.
+ *
+ * Returns a new interface object or NULL in case of failure.  If the
+ * interface cannot be found, then VIR_ERR_NO_INTERFACE error is raised.
+ */
+virInterfacePtr
+virInterfaceLookupByMAC(virConnectPtr conn, const unsigned char *mac)
+{
+    DEBUG("conn=%p, mac=%02X:%02X:%02X:%02X:%02X:%02X", conn, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (NULL);
+    }
+    if (mac == NULL) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    if (conn->interfaceDriver && conn->interfaceDriver->interfaceLookupByMAC){
+        virInterfacePtr ret;
+        ret = conn->interfaceDriver->interfaceLookupByMAC (conn, mac);
+        if (!ret)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(conn);
+    return NULL;
+}
+
+/**
+ * virInterfaceLookupByMACString:
+ * @conn: pointer to the hypervisor connection
+ * @macstr: the string MAC for the interface
+ *
+ * Try to lookup an interface on the given hypervisor based on its MAC.
+ *
+ * Returns a new interface object or NULL in case of failure.  If the
+ * interface cannot be found, then VIR_ERR_NO_INTERFACE error is raised.
+ */
+virInterfacePtr
+virInterfaceLookupByMACString(virConnectPtr conn, const char *macstr)
+{
+    unsigned char mac[VIR_MAC_BUFLEN];
+    int ret;
+    DEBUG("conn=%p, macstr=%s", conn, macstr);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (NULL);
+    }
+    if (macstr == NULL) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    ret = virParseMacAddr (macstr, mac);
+    if (ret == -1) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    return virInterfaceLookupByMAC(conn, &mac[0]);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(conn);
+    return NULL;
+}
+
+/**
+ * virInterfaceDefineXML:
+ * @conn: pointer to the hypervisor connection
+ * @xml: the XML description for the interface, preferably in UTF-8
+ *
+ * Define an interface (or modify existing interface configuration)
+ *
+ * Returns NULL in case of error, a pointer to the interface otherwise
+ */
+virInterfacePtr
+virInterfaceDefineXML(virConnectPtr conn, const char *xml, int flags)
+{
+    DEBUG("conn=%p, xml=%s, flags=%d", conn, xml, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (NULL);
+    }
+    if (conn->flags & VIR_CONNECT_RO) {
+        virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+    if (xml == NULL) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    if (conn->interfaceDriver && conn->interfaceDriver->interfaceDefineXML) {
+        virInterfacePtr ret;
+        ret = conn->interfaceDriver->interfaceDefineXML (conn, xml, flags);
+        if (!ret)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(conn);
+    return NULL;
+}
+
+/**
+ * virInterfaceUndefine:
+ * @interface: pointer to a defined interface
+ *
+ * Undefine an interface, ie remove it from the config
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+virInterfaceUndefine(virInterfacePtr interface) {
+    virConnectPtr conn;
+    DEBUG("interface=%p", interface);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_INTERFACE(interface)) {
+        virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+        return (-1);
+    }
+    conn = interface->conn;
+    if (conn->flags & VIR_CONNECT_RO) {
+        virLibInterfaceError(interface, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+
+    if (conn->interfaceDriver && conn->interfaceDriver->interfaceUndefine) {
+        int ret;
+        ret = conn->interfaceDriver->interfaceUndefine (interface);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(interface->conn);
+    return -1;
+}
+
+/**
+ * virInterfaceCreate:
+ * @interface: pointer to a defined interface
+ *
+ * Activate an interface (ie call "ifup")
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+virInterfaceCreate(virInterfacePtr interface, int flags)
+{
+    virConnectPtr conn;
+    DEBUG("interface=%p, flags=%d", interface, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_INTERFACE(interface)) {
+        virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+        return (-1);
+    }
+    conn = interface->conn;
+    if (conn->flags & VIR_CONNECT_RO) {
+        virLibInterfaceError(interface, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+
+    if (conn->interfaceDriver && conn->interfaceDriver->interfaceCreate) {
+        int ret;
+        ret = conn->interfaceDriver->interfaceCreate (interface, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(interface->conn);
+    return -1;
+}
+
+/**
+ * virInterfaceDestroy:
+ * @interface: an interface object
+ *
+ * Destroy the interface object. The running instance is shutdown if not down
+ * already and all resources used by it are given back to the hypervisor. This
+ * does not free the associated virInterfacePtr object.
+ * This function may require privileged access
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virInterfaceDestroy(virInterfacePtr interface, int flags)
+{
+    virConnectPtr conn;
+    DEBUG("interface=%p, flags=%d", interface, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_INTERFACE(interface)) {
+        virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+        return (-1);
+    }
+
+    conn = interface->conn;
+    if (conn->flags & VIR_CONNECT_RO) {
+        virLibInterfaceError(interface, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+
+    if (conn->interfaceDriver && conn->interfaceDriver->interfaceDestroy) {
+        int ret;
+        ret = conn->interfaceDriver->interfaceDestroy (interface, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(interface->conn);
+    return -1;
+}
+
+/**
+ * virInterfaceGetName:
+ * @interface: a interface object
+ *
+ * Get the public name for that interface
+ *
+ * Returns a pointer to the name or NULL, the string need not be deallocated
+ * its lifetime will be the same as the interface object.
+ */
+const char *
+virInterfaceGetName(virInterfacePtr interface)
+{
+    DEBUG("interface=%p", interface);
+
+    virResetLastError();
+
+    if (!VIR_IS_INTERFACE(interface)) {
+        virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+        return (NULL);
+    }
+    return (interface->name);
+}
+
+/**
+ * virInterfaceGetMAC:
+ * @interface: a interface object
+ * @mac: pointer to a VIR_MAC_BUFLEN bytes array
+ *
+ * Get the MAC for a interface
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virInterfaceGetMAC(virInterfacePtr interface, unsigned char *mac)
+{
+    DEBUG("interface=%p, mac=%p", interface, mac);
+
+    virResetLastError();
+
+    if (!VIR_IS_INTERFACE(interface)) {
+        virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+        return (-1);
+    }
+    if (mac == NULL) {
+        virLibInterfaceError(interface, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    memcpy(mac, &interface->mac[0], VIR_MAC_BUFLEN);
+
+    return (0);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(interface->conn);
+    return -1;
+}
+
+/**
+ * virInterfaceGetMACString:
+ * @interface: a interface object
+ * @buf: pointer to a VIR_MAC_STRING_BUFLEN bytes array
+ *
+ * Get the MAC for a interface as string. For more information about
+ * MAC see RFC4122.
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virInterfaceGetMACString(virInterfacePtr interface, char *buf)
+{
+    unsigned char mac[VIR_MAC_BUFLEN];
+    DEBUG("interface=%p, buf=%p", interface, buf);
+
+    virResetLastError();
+
+    if (!VIR_IS_INTERFACE(interface)) {
+        virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+        return (-1);
+    }
+    if (buf == NULL) {
+        virLibInterfaceError(interface, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    if (virInterfaceGetMAC(interface, &mac[0]))
+        return (-1);
+
+    virFormatMacAddr(mac, buf);
+    return (0);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(interface->conn);
+    return -1;
+}
+
+/**
+ * virInterfaceGetXMLDesc:
+ * @interface: a interface object
+ * @flags: and OR'ed set of extraction flags, not used yet
+ *
+ * Provide an XML description of the interface. The description may be reused
+ * later to relaunch the interface with virInterfaceCreateXML().
+ *
+ * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
+ *         the caller must free() the returned value.
+ */
+char *
+virInterfaceGetXMLDesc(virInterfacePtr interface, int flags)
+{
+    virConnectPtr conn;
+    DEBUG("interface=%p, flags=%d", interface, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_INTERFACE(interface)) {
+        virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+        return (NULL);
+    }
+    if (flags != 0) {
+        virLibInterfaceError(interface, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    conn = interface->conn;
+
+    if (conn->interfaceDriver && conn->interfaceDriver->interfaceGetXMLDesc) {
+        char *ret;
+        ret = conn->interfaceDriver->interfaceGetXMLDesc (interface, flags);
+        if (!ret)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    /* Copy to connection error object for back compatability */
+    virSetConnError(interface->conn);
+    return NULL;
+}
 
 /**
  * virStoragePoolGetConnect:
diff --git a/src/util.h b/src/util.h
index 6fe03b6..99327cd 100644
--- a/src/util.h
+++ b/src/util.h
@@ -142,9 +142,7 @@ int virParseNumber(const char **str);
 int virAsprintf(char **strp, const char *fmt, ...)
     ATTRIBUTE_FORMAT(printf, 2, 3);
 
-#define VIR_MAC_BUFLEN 6
 #define VIR_MAC_PREFIX_BUFLEN 3
-#define VIR_MAC_STRING_BUFLEN VIR_MAC_BUFLEN * 3
 
 int virParseMacAddr(const char* str,
                     unsigned char *addr);
diff --git a/src/virterror.c b/src/virterror.c
index d2514db..e7a0acf 100644
--- a/src/virterror.c
+++ b/src/virterror.c
@@ -154,6 +154,9 @@ static const char *virErrorDomainName(virErrorDomain domain) {
         case VIR_FROM_SECURITY:
             dom = "Security Labeling ";
             break;
+        case VIR_FROM_INTERFACE:
+            dom = "Interface ";
+            break;
     }
     return(dom);
 }
-- 
1.6.0.6




More information about the libvir-list mailing list