[prev in list] [next in list] [prev in thread] [next in thread] 

List:       libvir-list
Subject:    [libvirt] [PATCH 1/1] Added Networking API to change/create/etc. hostonly/internal network in Virtua
From:       Pritesh Kothari <Pritesh.Kothari () Sun ! COM>
Date:       2009-04-29 11:14:07
Message-ID: 200904291314.07554.pritesh.kothari () sun ! com
[Download RAW message or body]

Hi All:

[PATCH 0/1]: Contains sample xml file showing features supported so far.
[PATCH 1/1]: Contains the patch for adding Networking API to 
change/create/etc. hostonly/internal network in VirtualBox

Regards,
Pritesh

["vbox_2009_04_29_5.patch1;" (text/x-diff)]

diff --git a/src/network_conf.c b/src/network_conf.c
index b4da3fb..b4e0b39 100644
--- a/src/network_conf.c
+++ b/src/network_conf.c
@@ -50,7 +50,11 @@ VIR_ENUM_DECL(virNetworkForward)
 
 VIR_ENUM_IMPL(virNetworkForward,
               VIR_NETWORK_FORWARD_LAST,
-              "none", "nat", "route" )
+              "none",
+              "nat",
+              "route",
+              "hostonly",
+              "internal")
 
 #define virNetworkReportError(conn, code, fmt...)                            \
         virReportErrorHelper(conn, VIR_FROM_NETWORK, code, __FILE__,       \
diff --git a/src/network_conf.h b/src/network_conf.h
index 365d469..32db7c2 100644
--- a/src/network_conf.h
+++ b/src/network_conf.h
@@ -36,6 +36,8 @@ enum virNetworkForwardType {
     VIR_NETWORK_FORWARD_NONE   = 0,
     VIR_NETWORK_FORWARD_NAT,
     VIR_NETWORK_FORWARD_ROUTE,
+    VIR_NETWORK_FORWARD_HOSTONLY,
+    VIR_NETWORK_FORWARD_INTERNAL,
 
     VIR_NETWORK_FORWARD_LAST,
 };
diff --git a/src/vbox/vbox_driver.c b/src/vbox/vbox_driver.c
index 1d2d3ed..eef67a7 100644
--- a/src/vbox/vbox_driver.c
+++ b/src/vbox/vbox_driver.c
@@ -41,15 +41,19 @@
 extern virDriver vbox22Driver;
 extern virDriver vbox25Driver;
 
+extern virNetworkDriver vbox22NetworkDriver;
+extern virNetworkDriver vbox25NetworkDriver;
 
 int vboxRegister(void) {
     virDriverPtr        driver;
+    virNetworkDriverPtr networkDriver;
     uint32_t            uVersion;
 
     /* vboxRegister() shouldn't fail as that will render libvirt unless.
      * So, we use the v2.2 driver as a fallback/dummy.
      */
     driver        = &vbox22Driver;
+    networkDriver = &vbox22NetworkDriver;
 
     /* Init the glue and get the API version. */
     if (VBoxCGlueInit() == 0) {
@@ -67,9 +71,11 @@ int vboxRegister(void) {
         if (uVersion >= 2001052 && uVersion < 2002051) {
             DEBUG0("VirtualBox API version: 2.2");
             driver        = &vbox22Driver;
+            networkDriver = &vbox22NetworkDriver;
         } else if (uVersion >= 2002051 && uVersion < 2005051) {
             DEBUG0("VirtualBox API version: 2.5");
             driver        = &vbox25Driver;
+            networkDriver = &vbox25NetworkDriver;
         } else {
             DEBUG0("Unsupport VirtualBox API version");
         }
@@ -80,6 +86,8 @@ int vboxRegister(void) {
 
     if (virRegisterDriver(driver) < 0)
         return -1;
+    if (virRegisterNetworkDriver(networkDriver) < 0)
+        return -1;
 
     return 0;
 }
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 9cc883f..9854e5b 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -3635,6 +3635,963 @@ cleanup:
     return ret;
 }
 
+/**
+ * The Network Functions here on
+ */
+static virDrvOpenStatus vboxNetworkOpen(virConnectPtr conn,
+                                        virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+                                        int flags ATTRIBUTE_UNUSED) {
+    vboxGlobalData *data = conn->privateData;
+
+    if (STRNEQ(conn->driver->name, "VBOX"))
+        goto cleanup;
+
+    if ((data->pFuncs      == NULL) ||
+        (data->vboxObj     == NULL) ||
+        (data->vboxSession == NULL))
+        goto cleanup;
+
+    DEBUG0("network intialized");
+    /* conn->networkPrivateData = some network specific data */
+    return VIR_DRV_OPEN_SUCCESS;
+
+cleanup:
+    return VIR_DRV_OPEN_DECLINED;
+}
+
+static int vboxNetworkClose(virConnectPtr conn) {
+    DEBUG0("network unintialized");
+    conn->networkPrivateData = NULL;
+    return 0;
+}
+
+static int vboxNumOfNetworks(virConnectPtr conn) {
+    vboxGlobalData *data = conn->privateData;
+    int numActive = 0;
+
+    /* TODO: "internal" networks are just strings and
+     * thus can't do much with them
+     */
+    if (data->vboxObj) {
+        IHost *host = NULL;
+
+        data->vboxObj->vtbl->GetHost(data->vboxObj, &host);
+        if (host) {
+            int i = 0;
+            PRUint32 networkInterfacesSize = 0;
+            IHostNetworkInterface **networkInterfaces = NULL;
+
+            host->vtbl->GetNetworkInterfaces(host, &networkInterfacesSize, \
&networkInterfaces); +
+            for (i = 0; i < networkInterfacesSize; i++) {
+                if (networkInterfaces[i]) {
+                    PRUint32 interfaceType = 0;
+
+                    \
networkInterfaces[i]->vtbl->GetInterfaceType(networkInterfaces[i], &interfaceType); + \
if (interfaceType == HostNetworkInterfaceType_HostOnly) +                        \
numActive++; +
+                    networkInterfaces[i]->vtbl->nsisupports.Release((nsISupports *) \
networkInterfaces[i]); +                }
+            }
+
+            host->vtbl->nsisupports.Release((nsISupports *) host);
+        }
+    }
+
+    DEBUG("numActive: %d", numActive);
+    return numActive;
+}
+
+static int vboxListNetworks(virConnectPtr conn, char **const names, int nnames) {
+    vboxGlobalData *data = conn->privateData;
+    int numActive = 0;
+
+    /* TODO: "internal" networks are just strings and
+     * thus can't do much with them
+     */
+    if (data->vboxObj) {
+        IHost *host = NULL;
+
+        data->vboxObj->vtbl->GetHost(data->vboxObj, &host);
+        if (host) {
+            int i = 0;
+            PRUint32 networkInterfacesSize = 0;
+            IHostNetworkInterface **networkInterfaces = NULL;
+
+            host->vtbl->GetNetworkInterfaces(host, &networkInterfacesSize, \
&networkInterfaces); +
+            for (i = 0; (numActive < nnames) && (i < networkInterfacesSize); i++) {
+                if (networkInterfaces[i]) {
+                    PRUint32 interfaceType = 0;
+
+                    \
networkInterfaces[i]->vtbl->GetInterfaceType(networkInterfaces[i], &interfaceType); +
+                    if (interfaceType == HostNetworkInterfaceType_HostOnly) {
+                        char *nameUtf8       = NULL;
+                        PRUnichar *nameUtf16 = NULL;
+
+                        networkInterfaces[i]->vtbl->GetName(networkInterfaces[i], \
&nameUtf16); +                        data->pFuncs->pfnUtf16ToUtf8(nameUtf16, \
&nameUtf8); +
+                        DEBUG("nnames[%d]: %s", numActive, nameUtf8);
+                        names[numActive++] = strdup(nameUtf8);
+
+                        data->pFuncs->pfnUtf8Free(nameUtf8);
+                        data->pFuncs->pfnUtf16Free(nameUtf16);
+                    }
+                }
+            }
+
+            for (i = 0; i < networkInterfacesSize; i++) {
+                if (networkInterfaces[i]) {
+                    networkInterfaces[i]->vtbl->nsisupports.Release((nsISupports *) \
networkInterfaces[i]); +                }
+            }
+
+            host->vtbl->nsisupports.Release((nsISupports *) host);
+        }
+    }
+
+    return numActive;
+}
+
+static virNetworkPtr vboxNetworkLookupByUUID(virConnectPtr conn, const unsigned char \
*uuid) { +    vboxGlobalData *data = conn->privateData;
+    virNetworkPtr ret    = NULL;
+    nsID *iid            = NULL;
+
+    if (VIR_ALLOC(iid) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+
+    /* TODO: "internal" networks are just strings and
+     * thus can't do much with them
+     */
+    if (data->vboxObj) {
+        IHost *host = NULL;
+
+        data->vboxObj->vtbl->GetHost(data->vboxObj, &host);
+        if (host) {
+            IHostNetworkInterface *networkInterface = NULL;
+
+            nsIDFromChar(iid, uuid);
+            host->vtbl->FindHostNetworkInterfaceById(host, iid, &networkInterface);
+            if (networkInterface) {
+                PRUint32 interfaceType = 0;
+
+                networkInterface->vtbl->GetInterfaceType(networkInterface, \
&interfaceType); +
+                if (interfaceType == HostNetworkInterfaceType_HostOnly) {
+                    char *nameUtf8       = NULL;
+                    PRUnichar *nameUtf16 = NULL;
+
+                    networkInterface->vtbl->GetName(networkInterface, &nameUtf16);
+                    data->pFuncs->pfnUtf16ToUtf8(nameUtf16, &nameUtf8);
+
+                    ret = virGetNetwork(conn, nameUtf8, uuid);
+
+                    DEBUG("Network Name: %s", nameUtf8);
+                    DEBUG("Network UUID: "
+                          "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+                          (unsigned)iid->m0,    (unsigned)iid->m1,
+                          (unsigned)iid->m2,    (unsigned)iid->m3[0],
+                          (unsigned)iid->m3[1], (unsigned)iid->m3[2],
+                          (unsigned)iid->m3[3], (unsigned)iid->m3[4],
+                          (unsigned)iid->m3[5], (unsigned)iid->m3[6],
+                          (unsigned)iid->m3[7]);
+
+                    data->pFuncs->pfnUtf8Free(nameUtf8);
+                    data->pFuncs->pfnUtf16Free(nameUtf16);
+                }
+
+                networkInterface->vtbl->nsisupports.Release((nsISupports *) \
networkInterface); +            }
+
+            host->vtbl->nsisupports.Release((nsISupports *) host);
+        }
+    }
+
+cleanup:
+    VIR_FREE(iid);
+    return ret;
+}
+
+static virNetworkPtr vboxNetworkLookupByName(virConnectPtr conn, const char *name) {
+    vboxGlobalData *data = conn->privateData;
+    virNetworkPtr ret    = NULL;
+
+    /* TODO: "internal" networks are just strings and
+     * thus can't do much with them
+     */
+    if (data->vboxObj) {
+        IHost *host = NULL;
+
+        data->vboxObj->vtbl->GetHost(data->vboxObj, &host);
+        if (host) {
+            PRUnichar *nameUtf16                    = NULL;
+            IHostNetworkInterface *networkInterface = NULL;
+
+            data->pFuncs->pfnUtf8ToUtf16(name, &nameUtf16);
+
+            host->vtbl->FindHostNetworkInterfaceByName(host, nameUtf16, \
&networkInterface); +
+            if (networkInterface) {
+                PRUint32 interfaceType = 0;
+
+                networkInterface->vtbl->GetInterfaceType(networkInterface, \
&interfaceType); +
+                if (interfaceType == HostNetworkInterfaceType_HostOnly) {
+                    unsigned char uuid[VIR_UUID_BUFLEN];
+                    nsID *iid = NULL;
+
+                    networkInterface->vtbl->GetId(networkInterface, &iid);
+
+                    nsIDtoChar(uuid, iid);
+
+                    ret = virGetNetwork(conn, name, uuid);
+
+                    DEBUG("Network Name: %s", name);
+                    DEBUG("Network UUID: "
+                          "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+                          (unsigned)iid->m0,    (unsigned)iid->m1,
+                          (unsigned)iid->m2,    (unsigned)iid->m3[0],
+                          (unsigned)iid->m3[1], (unsigned)iid->m3[2],
+                          (unsigned)iid->m3[3], (unsigned)iid->m3[4],
+                          (unsigned)iid->m3[5], (unsigned)iid->m3[6],
+                          (unsigned)iid->m3[7]);
+
+                    data->pFuncs->pfnComUnallocMem(iid);
+                }
+
+                networkInterface->vtbl->nsisupports.Release((nsISupports *) \
networkInterface); +            }
+
+            data->pFuncs->pfnUtf16Free(nameUtf16);
+            host->vtbl->nsisupports.Release((nsISupports *) host);
+        }
+    }
+
+    return ret;
+}
+
+static virNetworkPtr vboxNetworkCreateXML(virConnectPtr conn, const char *xml) {
+    vboxGlobalData *data  = conn->privateData;
+    virNetworkDefPtr def  = NULL;
+    virNetworkPtr ret     = NULL;
+    nsID *iid             = NULL;
+    char *networkNameUtf8 = NULL;
+    int i = 0;
+
+    /* TODO: "internal" networks are just strings and
+     * thus can't do much with them
+     */
+    if ((def = virNetworkDefParseString(conn, xml)) == NULL)
+        goto cleanup;
+
+    if (VIR_ALLOC(iid) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+
+    if (VIR_ALLOC_N(networkNameUtf8, sizeof("HostInterfaceNetworking-") +
+                                     sizeof(def->name) + 1) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+
+    strcpy (networkNameUtf8, "HostInterfaceNetworking-");
+    strcat (networkNameUtf8, def->name);
+
+    nsIDFromChar(iid, def->uuid);
+
+    DEBUG("Network Name: %s", def->name);
+    DEBUG("Network UUID: "
+          "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+          (unsigned)iid->m0,    (unsigned)iid->m1,
+          (unsigned)iid->m2,    (unsigned)iid->m3[0],
+          (unsigned)iid->m3[1], (unsigned)iid->m3[2],
+          (unsigned)iid->m3[3], (unsigned)iid->m3[4],
+          (unsigned)iid->m3[5], (unsigned)iid->m3[6],
+          (unsigned)iid->m3[7]);
+    DEBUG("bridge : %s", def->bridge);
+    DEBUG("domain : %s", def->domain);
+    DEBUG("forwardType : %d", def->forwardType);
+    DEBUG("forwardDev : %s", def->forwardDev);
+    DEBUG("ipAddress : %s", def->ipAddress);
+    DEBUG("netmask : %s", def->netmask);
+    DEBUG("network : %s", def->network);
+    for (i = 0; i < def->nranges; i++) {
+        DEBUG("DHCP(%d) start: %s", i, def->ranges[i].start);
+        DEBUG("DHCP(%d) end  : %s", i, def->ranges[i].end);
+    }
+    for (i = 0; i < def->nhosts; i++) {
+        DEBUG("DHCP Host(%d) mac : %s", i, def->hosts[i].mac);
+        DEBUG("DHCP Host(%d) name: %s", i, def->hosts[i].name);
+        DEBUG("DHCP Host(%d) ip  : %s", i, def->hosts[i].ip);
+    }
+
+    if ((data->vboxObj) && (def->forwardType == VIR_NETWORK_FORWARD_HOSTONLY)) {
+        /* VirtualBox version 2.2.* has only one "hostonly"
+         * network called "vboxnet0" for linux
+         */
+        if (STREQ(def->name, "vboxnet0")) {
+            IHost *host = NULL;
+
+            data->vboxObj->vtbl->GetHost(data->vboxObj, &host);
+            if (host) {
+                PRUnichar *networkInterfaceNameUtf16    = NULL;
+                IHostNetworkInterface *networkInterface = NULL;
+
+                data->pFuncs->pfnUtf8ToUtf16(def->name, &networkInterfaceNameUtf16);
+
+                host->vtbl->FindHostNetworkInterfaceByName(host, \
networkInterfaceNameUtf16, &networkInterface); +
+                if (networkInterface) {
+                    PRUint32 interfaceType = 0;
+
+                    networkInterface->vtbl->GetInterfaceType(networkInterface, \
&interfaceType); +
+                    if (interfaceType == HostNetworkInterfaceType_HostOnly) {
+                        unsigned char uuid[VIR_UUID_BUFLEN];
+                        nsID *vboxnet0IID           = NULL;
+                        PRUnichar *networkNameUtf16 = NULL;
+
+                        data->pFuncs->pfnUtf8ToUtf16(networkNameUtf8 , \
&networkNameUtf16); +
+                        networkInterface->vtbl->GetId(networkInterface, \
&vboxnet0IID); +
+                        nsIDtoChar(uuid, vboxnet0IID);
+
+                        /* Currently support only one dhcp server per network
+                         * with contigious address space from start to end
+                         */
+                        if ((def->nranges == 1) &&
+                            (def->ranges[0].start) &&
+                            (def->ranges[0].end)) {
+                            IDHCPServer *dhcpServer = NULL;
+
+                            \
data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj, +                     \
networkNameUtf16, +                                                                   \
&dhcpServer); +                            if (!dhcpServer) {
+                                /* create a dhcp server */
+                                data->vboxObj->vtbl->CreateDHCPServer(data->vboxObj,
+                                                                      \
networkNameUtf16, +                                                                   \
&dhcpServer); +                                DEBUG0("couldn't find dhcp server so \
creating one"); +                            }
+                            if (dhcpServer) {
+                                PRUnichar *ipAddressUtf16     = NULL;
+                                PRUnichar *networkMaskUtf16   = NULL;
+                                PRUnichar *fromIPAddressUtf16 = NULL;
+                                PRUnichar *toIPAddressUtf16   = NULL;
+                                PRUnichar *trunkTypeUtf16     = NULL;
+
+
+                                data->pFuncs->pfnUtf8ToUtf16(def->ipAddress, \
&ipAddressUtf16); +                                \
data->pFuncs->pfnUtf8ToUtf16(def->netmask, &networkMaskUtf16); +                      \
data->pFuncs->pfnUtf8ToUtf16(def->ranges[0].start, &fromIPAddressUtf16); +            \
data->pFuncs->pfnUtf8ToUtf16(def->ranges[0].end, &toIPAddressUtf16); +                \
data->pFuncs->pfnUtf8ToUtf16("netflt", &trunkTypeUtf16); +
+                                dhcpServer->vtbl->SetEnabled(dhcpServer, PR_TRUE);
+
+                                dhcpServer->vtbl->SetConfiguration(dhcpServer,
+                                                                   ipAddressUtf16,
+                                                                   networkMaskUtf16,
+                                                                   \
fromIPAddressUtf16, +                                                                 \
toIPAddressUtf16); +
+                                dhcpServer->vtbl->Start(dhcpServer,
+                                                        networkNameUtf16,
+                                                        networkInterfaceNameUtf16,
+                                                        trunkTypeUtf16);
+
+                                data->pFuncs->pfnUtf16Free(ipAddressUtf16);
+                                data->pFuncs->pfnUtf16Free(networkMaskUtf16);
+                                data->pFuncs->pfnUtf16Free(fromIPAddressUtf16);
+                                data->pFuncs->pfnUtf16Free(toIPAddressUtf16);
+                                data->pFuncs->pfnUtf16Free(trunkTypeUtf16);
+                                dhcpServer->vtbl->nsisupports.Release((nsISupports \
*) dhcpServer); +                            }
+                        }
+
+                        ret = virGetNetwork(conn, def->name, uuid);
+
+                        DEBUG("Real Network UUID: "
+                              "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+                              (unsigned)vboxnet0IID->m0,    \
(unsigned)vboxnet0IID->m1, +                              (unsigned)vboxnet0IID->m2,  \
(unsigned)vboxnet0IID->m3[0], +                              \
(unsigned)vboxnet0IID->m3[1], (unsigned)vboxnet0IID->m3[2], +                         \
(unsigned)vboxnet0IID->m3[3], (unsigned)vboxnet0IID->m3[4], +                         \
(unsigned)vboxnet0IID->m3[5], (unsigned)vboxnet0IID->m3[6], +                         \
(unsigned)vboxnet0IID->m3[7]); +
+                        data->pFuncs->pfnComUnallocMem(vboxnet0IID);
+                        data->pFuncs->pfnUtf16Free(networkNameUtf16);
+                    }
+
+                    networkInterface->vtbl->nsisupports.Release((nsISupports *) \
networkInterface); +                }
+
+                data->pFuncs->pfnUtf16Free(networkInterfaceNameUtf16);
+                host->vtbl->nsisupports.Release((nsISupports *) host);
+            }
+        }
+    }
+
+cleanup:
+    VIR_FREE(iid);
+    VIR_FREE(networkNameUtf8);
+    virNetworkDefFree(def);
+    return ret;
+}
+
+static virNetworkPtr vboxNetworkDefineXML(virConnectPtr conn, const char *xml) {
+    vboxGlobalData *data  = conn->privateData;
+    virNetworkDefPtr def  = NULL;
+    virNetworkPtr ret     = NULL;
+    nsID *iid             = NULL;
+    char *networkNameUtf8 = NULL;
+    int i = 0;
+
+    /* vboxNetworkDefineXML() is not exactly "network definition"
+     * as the network is up and running, only the DHCP server is off,
+     * so you can always assign static IP and get the network running.
+     */
+    /* TODO: "internal" networks are just strings and
+     * thus can't do much with them
+     */
+    if ((def = virNetworkDefParseString(conn, xml)) == NULL)
+        goto cleanup;
+
+    if (VIR_ALLOC(iid) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+
+    if (VIR_ALLOC_N(networkNameUtf8, sizeof("HostInterfaceNetworking-") +
+                                     sizeof(def->name) + 1) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+
+    strcpy (networkNameUtf8, "HostInterfaceNetworking-");
+    strcat (networkNameUtf8, def->name);
+
+    nsIDFromChar(iid, def->uuid);
+
+    DEBUG("Network Name: %s", def->name);
+    DEBUG("Network UUID: "
+          "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+          (unsigned)iid->m0,    (unsigned)iid->m1,
+          (unsigned)iid->m2,    (unsigned)iid->m3[0],
+          (unsigned)iid->m3[1], (unsigned)iid->m3[2],
+          (unsigned)iid->m3[3], (unsigned)iid->m3[4],
+          (unsigned)iid->m3[5], (unsigned)iid->m3[6],
+          (unsigned)iid->m3[7]);
+    DEBUG("bridge : %s", def->bridge);
+    DEBUG("domain : %s", def->domain);
+    DEBUG("forwardType : %d", def->forwardType);
+    DEBUG("forwardDev : %s", def->forwardDev);
+    DEBUG("ipAddress : %s", def->ipAddress);
+    DEBUG("netmask : %s", def->netmask);
+    DEBUG("network : %s", def->network);
+    for (i = 0; i < def->nranges; i++) {
+        DEBUG("DHCP(%d) start: %s", i, def->ranges[i].start);
+        DEBUG("DHCP(%d) end  : %s", i, def->ranges[i].end);
+    }
+    for (i = 0; i < def->nhosts; i++) {
+        DEBUG("DHCP Host(%d) mac : %s", i, def->hosts[i].mac);
+        DEBUG("DHCP Host(%d) name: %s", i, def->hosts[i].name);
+        DEBUG("DHCP Host(%d) ip  : %s", i, def->hosts[i].ip);
+    }
+
+    if ((data->vboxObj) && (def->forwardType == VIR_NETWORK_FORWARD_HOSTONLY)) {
+        /* VirtualBox version 2.2.* has only one "hostonly"
+         * network called "vboxnet0" for linux
+         */
+        if (STREQ(def->name, "vboxnet0")) {
+            IHost *host = NULL;
+
+            data->vboxObj->vtbl->GetHost(data->vboxObj, &host);
+            if (host) {
+                PRUnichar *networkInterfaceNameUtf16    = NULL;
+                IHostNetworkInterface *networkInterface = NULL;
+
+                data->pFuncs->pfnUtf8ToUtf16(def->name, &networkInterfaceNameUtf16);
+
+                host->vtbl->FindHostNetworkInterfaceByName(host, \
networkInterfaceNameUtf16, &networkInterface); +
+                if (networkInterface) {
+                    PRUint32 interfaceType = 0;
+
+                    networkInterface->vtbl->GetInterfaceType(networkInterface, \
&interfaceType); +
+                    if (interfaceType == HostNetworkInterfaceType_HostOnly) {
+                        unsigned char uuid[VIR_UUID_BUFLEN];
+                        nsID *vboxnet0IID           = NULL;
+                        PRUnichar *networkNameUtf16 = NULL;
+
+                        data->pFuncs->pfnUtf8ToUtf16(networkNameUtf8 , \
&networkNameUtf16); +
+                        networkInterface->vtbl->GetId(networkInterface, \
&vboxnet0IID); +
+                        nsIDtoChar(uuid, vboxnet0IID);
+
+                        /* Currently support only one dhcp server per network
+                         * with contigious address space from start to end
+                         */
+                        if ((def->nranges == 1) &&
+                            (def->ranges[0].start) &&
+                            (def->ranges[0].end)) {
+                            IDHCPServer *dhcpServer = NULL;
+
+                            \
data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj, +                     \
networkNameUtf16, +                                                                   \
&dhcpServer); +                            if (!dhcpServer) {
+                                /* create a dhcp server */
+                                data->vboxObj->vtbl->CreateDHCPServer(data->vboxObj,
+                                                                      \
networkNameUtf16, +                                                                   \
&dhcpServer); +                                DEBUG0("couldn't find dhcp server so \
creating one"); +                            }
+                            if (dhcpServer) {
+                                PRUnichar *ipAddressUtf16     = NULL;
+                                PRUnichar *networkMaskUtf16   = NULL;
+                                PRUnichar *fromIPAddressUtf16 = NULL;
+                                PRUnichar *toIPAddressUtf16   = NULL;
+
+
+                                data->pFuncs->pfnUtf8ToUtf16(def->ipAddress, \
&ipAddressUtf16); +                                \
data->pFuncs->pfnUtf8ToUtf16(def->netmask, &networkMaskUtf16); +                      \
data->pFuncs->pfnUtf8ToUtf16(def->ranges[0].start, &fromIPAddressUtf16); +            \
data->pFuncs->pfnUtf8ToUtf16(def->ranges[0].end, &toIPAddressUtf16); +
+                                dhcpServer->vtbl->SetEnabled(dhcpServer, PR_FALSE);
+
+                                dhcpServer->vtbl->SetConfiguration(dhcpServer,
+                                                                   ipAddressUtf16,
+                                                                   networkMaskUtf16,
+                                                                   \
fromIPAddressUtf16, +                                                                 \
toIPAddressUtf16); +
+                                data->pFuncs->pfnUtf16Free(ipAddressUtf16);
+                                data->pFuncs->pfnUtf16Free(networkMaskUtf16);
+                                data->pFuncs->pfnUtf16Free(fromIPAddressUtf16);
+                                data->pFuncs->pfnUtf16Free(toIPAddressUtf16);
+                                dhcpServer->vtbl->nsisupports.Release((nsISupports \
*) dhcpServer); +                            }
+                        }
+
+                        ret = virGetNetwork(conn, def->name, uuid);
+
+                        DEBUG("Real Network UUID: "
+                              "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+                              (unsigned)vboxnet0IID->m0,    \
(unsigned)vboxnet0IID->m1, +                              (unsigned)vboxnet0IID->m2,  \
(unsigned)vboxnet0IID->m3[0], +                              \
(unsigned)vboxnet0IID->m3[1], (unsigned)vboxnet0IID->m3[2], +                         \
(unsigned)vboxnet0IID->m3[3], (unsigned)vboxnet0IID->m3[4], +                         \
(unsigned)vboxnet0IID->m3[5], (unsigned)vboxnet0IID->m3[6], +                         \
(unsigned)vboxnet0IID->m3[7]); +
+                        data->pFuncs->pfnComUnallocMem(vboxnet0IID);
+                        data->pFuncs->pfnUtf16Free(networkNameUtf16);
+                    }
+
+                    networkInterface->vtbl->nsisupports.Release((nsISupports *) \
networkInterface); +                }
+
+                data->pFuncs->pfnUtf16Free(networkInterfaceNameUtf16);
+                host->vtbl->nsisupports.Release((nsISupports *) host);
+            }
+        }
+    }
+
+cleanup:
+    VIR_FREE(iid);
+    VIR_FREE(networkNameUtf8);
+    virNetworkDefFree(def);
+    return ret;
+}
+
+static int vboxNetworkUndefine(virNetworkPtr network) {
+    vboxGlobalData *data  = network->conn->privateData;
+    char *networkNameUtf8 = NULL;
+    int ret = -1;
+
+    /* Current limitation of the function for VirtualBox 2.2.* is
+     * that you can't delete the default hostonly adaptor namely:
+     * vboxnet0 and thus all this functions does is remove the
+     * dhcp server configuration, but the network can still be used
+     * by giving the machine static IP and also it will still
+     * show up in the net-list in virsh
+     */
+    if (VIR_ALLOC_N(networkNameUtf8, sizeof("HostInterfaceNetworking-") +
+                                     sizeof(network->name) + 1) < 0) {
+        virReportOOMError(network->conn);
+        goto cleanup;
+    }
+
+    strcpy (networkNameUtf8, "HostInterfaceNetworking-");
+    strcat (networkNameUtf8, network->name);
+
+    if (data->vboxObj) {
+        IHost *host = NULL;
+
+        data->vboxObj->vtbl->GetHost(data->vboxObj, &host);
+        if (host) {
+            PRUnichar *networkInterfaceNameUtf16    = NULL;
+            IHostNetworkInterface *networkInterface = NULL;
+
+            data->pFuncs->pfnUtf8ToUtf16(network->name, &networkInterfaceNameUtf16);
+
+            host->vtbl->FindHostNetworkInterfaceByName(host, \
networkInterfaceNameUtf16, &networkInterface); +
+            if (networkInterface) {
+                PRUint32 interfaceType = 0;
+
+                networkInterface->vtbl->GetInterfaceType(networkInterface, \
&interfaceType); +
+                if (interfaceType == HostNetworkInterfaceType_HostOnly) {
+                    PRUnichar *networkNameUtf16 = NULL;
+                    IDHCPServer *dhcpServer     = NULL;
+
+                    data->pFuncs->pfnUtf8ToUtf16(networkNameUtf8 , \
&networkNameUtf16); +
+                    data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj,
+                                                                     \
networkNameUtf16, +                                                                   \
&dhcpServer); +                    if (dhcpServer) {
+                        data->vboxObj->vtbl->RemoveDHCPServer(data->vboxObj, \
dhcpServer); +                        \
dhcpServer->vtbl->nsisupports.Release((nsISupports *) dhcpServer); +                  \
} +
+                    data->pFuncs->pfnUtf16Free(networkNameUtf16);
+                }
+
+                networkInterface->vtbl->nsisupports.Release((nsISupports *) \
networkInterface); +            }
+
+            data->pFuncs->pfnUtf16Free(networkInterfaceNameUtf16);
+            host->vtbl->nsisupports.Release((nsISupports *) host);
+        }
+    }
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(networkNameUtf8);
+    return ret;
+}
+
+static int vboxNetworkCreate(virNetworkPtr network) {
+    vboxGlobalData *data  = network->conn->privateData;
+    char *networkNameUtf8 = NULL;
+    int ret = -1;
+
+    /* Current limitation of the function for VirtualBox 2.2.* is
+     * that the default hostonly network "vboxnet0" is always active
+     * and thus all this functions does is start the dhcp server,
+     * but the network can still be used without starting the dhcp
+     * server by giving the machine static IP
+     */
+    if (VIR_ALLOC_N(networkNameUtf8, sizeof("HostInterfaceNetworking-") +
+                                     sizeof(network->name) + 1) < 0) {
+        virReportOOMError(network->conn);
+        goto cleanup;
+    }
+
+    strcpy (networkNameUtf8, "HostInterfaceNetworking-");
+    strcat (networkNameUtf8, network->name);
+
+    if (data->vboxObj) {
+        IHost *host = NULL;
+
+        data->vboxObj->vtbl->GetHost(data->vboxObj, &host);
+        if (host) {
+            PRUnichar *networkInterfaceNameUtf16    = NULL;
+            IHostNetworkInterface *networkInterface = NULL;
+
+            data->pFuncs->pfnUtf8ToUtf16(network->name, &networkInterfaceNameUtf16);
+
+            host->vtbl->FindHostNetworkInterfaceByName(host, \
networkInterfaceNameUtf16, &networkInterface); +
+            if (networkInterface) {
+                PRUint32 interfaceType = 0;
+
+                networkInterface->vtbl->GetInterfaceType(networkInterface, \
&interfaceType); +
+                if (interfaceType == HostNetworkInterfaceType_HostOnly) {
+                    PRUnichar *networkNameUtf16 = NULL;
+                    IDHCPServer *dhcpServer     = NULL;
+
+
+                    data->pFuncs->pfnUtf8ToUtf16(networkNameUtf8 , \
&networkNameUtf16); +
+                    data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj,
+                                                                     \
networkNameUtf16, +                                                                   \
&dhcpServer); +                    if (dhcpServer) {
+                        PRUnichar *trunkTypeUtf16 = NULL;
+
+                        dhcpServer->vtbl->SetEnabled(dhcpServer, PR_TRUE);
+
+                        data->pFuncs->pfnUtf8ToUtf16("netflt", &trunkTypeUtf16);
+
+                        dhcpServer->vtbl->Start(dhcpServer,
+                                                networkNameUtf16,
+                                                networkInterfaceNameUtf16,
+                                                trunkTypeUtf16);
+
+                        data->pFuncs->pfnUtf16Free(trunkTypeUtf16);
+                        dhcpServer->vtbl->nsisupports.Release((nsISupports *) \
dhcpServer); +                    }
+
+                    data->pFuncs->pfnUtf16Free(networkNameUtf16);
+                }
+
+                networkInterface->vtbl->nsisupports.Release((nsISupports *) \
networkInterface); +            }
+
+            data->pFuncs->pfnUtf16Free(networkInterfaceNameUtf16);
+            host->vtbl->nsisupports.Release((nsISupports *) host);
+        }
+    }
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(networkNameUtf8);
+    return ret;
+}
+
+static int vboxNetworkDestroy(virNetworkPtr network) {
+    vboxGlobalData *data  = network->conn->privateData;
+    char *networkNameUtf8 = NULL;
+    int ret = -1;
+
+    /* Current limitation of the function for VirtualBox 2.2.* is
+     * that the default hostonly network "vboxnet0" is always active
+     * and thus all this functions does is stop the dhcp server,
+     * but the network can still be used without the dhcp server
+     * by giving the machine static IP
+     */
+    if (VIR_ALLOC_N(networkNameUtf8, sizeof("HostInterfaceNetworking-") +
+                                     sizeof(network->name) + 1) < 0) {
+        virReportOOMError(network->conn);
+        goto cleanup;
+    }
+
+    strcpy (networkNameUtf8, "HostInterfaceNetworking-");
+    strcat (networkNameUtf8, network->name);
+
+    if (data->vboxObj) {
+        IHost *host = NULL;
+
+        data->vboxObj->vtbl->GetHost(data->vboxObj, &host);
+        if (host) {
+            PRUnichar *networkInterfaceNameUtf16    = NULL;
+            IHostNetworkInterface *networkInterface = NULL;
+
+            data->pFuncs->pfnUtf8ToUtf16(network->name, &networkInterfaceNameUtf16);
+
+            host->vtbl->FindHostNetworkInterfaceByName(host, \
networkInterfaceNameUtf16, &networkInterface); +
+            if (networkInterface) {
+                PRUint32 interfaceType = 0;
+
+                networkInterface->vtbl->GetInterfaceType(networkInterface, \
&interfaceType); +
+                if (interfaceType == HostNetworkInterfaceType_HostOnly) {
+                    PRUnichar *networkNameUtf16 = NULL;
+                    IDHCPServer *dhcpServer     = NULL;
+
+
+                    data->pFuncs->pfnUtf8ToUtf16(networkNameUtf8 , \
&networkNameUtf16); +
+                    data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj,
+                                                                     \
networkNameUtf16, +                                                                   \
&dhcpServer); +                    if (dhcpServer) {
+
+                        dhcpServer->vtbl->SetEnabled(dhcpServer, PR_FALSE);
+
+                        dhcpServer->vtbl->Stop(dhcpServer);
+
+                        dhcpServer->vtbl->nsisupports.Release((nsISupports *) \
dhcpServer); +                    }
+
+                    data->pFuncs->pfnUtf16Free(networkNameUtf16);
+                }
+
+                networkInterface->vtbl->nsisupports.Release((nsISupports *) \
networkInterface); +            }
+
+            data->pFuncs->pfnUtf16Free(networkInterfaceNameUtf16);
+            host->vtbl->nsisupports.Release((nsISupports *) host);
+        }
+    }
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(networkNameUtf8);
+    return ret;
+}
+
+static char *vboxNetworkDumpXML(virNetworkPtr network, int flags ATTRIBUTE_UNUSED) {
+    vboxGlobalData *data  = network->conn->privateData;
+    virNetworkDefPtr def  = NULL;
+    char *ret             = NULL;
+    char *networkNameUtf8 = NULL;
+
+    if (VIR_ALLOC(def) < 0) {
+        virReportOOMError(network->conn);
+        goto cleanup;
+    }
+
+    if (VIR_ALLOC_N(networkNameUtf8, sizeof("HostInterfaceNetworking-") +
+                                     sizeof(network->name) + 1) < 0) {
+        virReportOOMError(network->conn);
+        goto cleanup;
+    }
+
+    strcpy (networkNameUtf8, "HostInterfaceNetworking-");
+    strcat (networkNameUtf8, network->name);
+
+    if (data->vboxObj) {
+        IHost *host = NULL;
+
+        data->vboxObj->vtbl->GetHost(data->vboxObj, &host);
+        if (host) {
+            PRUnichar *networkInterfaceNameUtf16    = NULL;
+            IHostNetworkInterface *networkInterface = NULL;
+
+            data->pFuncs->pfnUtf8ToUtf16(network->name, &networkInterfaceNameUtf16);
+
+            host->vtbl->FindHostNetworkInterfaceByName(host, \
networkInterfaceNameUtf16, &networkInterface); +
+            if (networkInterface) {
+                PRUint32 interfaceType = 0;
+
+                networkInterface->vtbl->GetInterfaceType(networkInterface, \
&interfaceType); +
+                if (interfaceType == HostNetworkInterfaceType_HostOnly) {
+                    nsID *vboxnet0IID           = NULL;
+                    PRUnichar *networkNameUtf16 = NULL;
+                    IDHCPServer *dhcpServer     = NULL;
+
+                    data->pFuncs->pfnUtf8ToUtf16(networkNameUtf8 , \
&networkNameUtf16); +
+                    networkInterface->vtbl->GetId(networkInterface, &vboxnet0IID);
+
+                    nsIDtoChar(def->uuid, vboxnet0IID);
+
+                    def->name = strdup(network->name);
+                    def->forwardType = VIR_NETWORK_FORWARD_HOSTONLY;
+
+                    data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj,
+                                                                     \
networkNameUtf16, +                                                                   \
&dhcpServer); +                    if (dhcpServer) {
+                        def->nranges = 1;
+                        if (VIR_ALLOC_N(def->ranges, def->nranges) >=0 ) {
+                            PRUnichar *ipAddressUtf16     = NULL;
+                            PRUnichar *networkMaskUtf16   = NULL;
+                            PRUnichar *fromIPAddressUtf16 = NULL;
+                            PRUnichar *toIPAddressUtf16   = NULL;
+
+                            dhcpServer->vtbl->GetIPAddress(dhcpServer, \
&ipAddressUtf16); +                            \
dhcpServer->vtbl->GetNetworkMask(dhcpServer, &networkMaskUtf16); +                    \
dhcpServer->vtbl->GetLowerIP(dhcpServer, &fromIPAddressUtf16); +                      \
dhcpServer->vtbl->GetUpperIP(dhcpServer, &toIPAddressUtf16); +                        \
/* Currently virtualbox supports only one dhcp server per network +                   \
* with contigious address space from start to end +                             */
+                            data->pFuncs->pfnUtf16ToUtf8(ipAddressUtf16, \
&def->ipAddress); +                            \
data->pFuncs->pfnUtf16ToUtf8(networkMaskUtf16, &def->netmask); +                      \
data->pFuncs->pfnUtf16ToUtf8(fromIPAddressUtf16, &def->ranges[0].start); +            \
data->pFuncs->pfnUtf16ToUtf8(toIPAddressUtf16, &def->ranges[0].end); +
+                            data->pFuncs->pfnUtf16Free(ipAddressUtf16);
+                            data->pFuncs->pfnUtf16Free(networkMaskUtf16);
+                            data->pFuncs->pfnUtf16Free(fromIPAddressUtf16);
+                            data->pFuncs->pfnUtf16Free(toIPAddressUtf16);
+                        } else {
+                            def->nranges = 0;
+                        }
+
+                        def->nhosts = 1;
+                        if (VIR_ALLOC_N(def->hosts, def->nhosts) >=0 ) {
+                            PRUnichar *macAddressUtf16 = NULL;
+                            PRUnichar *ipAddressUtf16  = NULL;
+
+                            \
networkInterface->vtbl->GetHardwareAddress(networkInterface, &macAddressUtf16); +     \
networkInterface->vtbl->GetIPAddress(networkInterface, &ipAddressUtf16); +
+                            data->pFuncs->pfnUtf16ToUtf8(macAddressUtf16, \
&def->hosts[0].mac); +                            def->hosts[0].name = \
strdup(network->name); +                            \
data->pFuncs->pfnUtf16ToUtf8(ipAddressUtf16, &def->hosts[0].ip); +
+                            data->pFuncs->pfnUtf16Free(macAddressUtf16);
+                            data->pFuncs->pfnUtf16Free(ipAddressUtf16);
+                        } else {
+                            def->nranges = 0;
+                        }
+
+                        dhcpServer->vtbl->nsisupports.Release((nsISupports *) \
dhcpServer); +                    } else {
+                        PRUnichar *networkMaskUtf16 = NULL;
+                        PRUnichar *ipAddressUtf16   = NULL;
+
+                        networkInterface->vtbl->GetNetworkMask(networkInterface, \
&networkMaskUtf16); +                        \
networkInterface->vtbl->GetIPAddress(networkInterface, &ipAddressUtf16); +
+                        data->pFuncs->pfnUtf16ToUtf8(networkMaskUtf16, \
&def->netmask); +                        data->pFuncs->pfnUtf16ToUtf8(ipAddressUtf16, \
&def->ipAddress); +
+                        data->pFuncs->pfnUtf16Free(networkMaskUtf16);
+                        data->pFuncs->pfnUtf16Free(ipAddressUtf16);
+                    }
+
+
+                    DEBUG("Network UUID: "
+                          "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+                          (unsigned)vboxnet0IID->m0,    (unsigned)vboxnet0IID->m1,
+                          (unsigned)vboxnet0IID->m2,    \
(unsigned)vboxnet0IID->m3[0], +                          \
(unsigned)vboxnet0IID->m3[1], (unsigned)vboxnet0IID->m3[2], +                         \
(unsigned)vboxnet0IID->m3[3], (unsigned)vboxnet0IID->m3[4], +                         \
(unsigned)vboxnet0IID->m3[5], (unsigned)vboxnet0IID->m3[6], +                         \
(unsigned)vboxnet0IID->m3[7]); +
+                    data->pFuncs->pfnComUnallocMem(vboxnet0IID);
+                    data->pFuncs->pfnUtf16Free(networkNameUtf16);
+                }
+
+                networkInterface->vtbl->nsisupports.Release((nsISupports *) \
networkInterface); +            }
+
+            data->pFuncs->pfnUtf16Free(networkInterfaceNameUtf16);
+            host->vtbl->nsisupports.Release((nsISupports *) host);
+        }
+    }
+
+    ret = virNetworkDefFormat(network->conn, def);
+
+cleanup:
+    VIR_FREE(networkNameUtf8);
+    return ret;
+}
+
+
+/**
+ * Function Tables
+ */
+
 virDriver NAME(Driver) = {
     VIR_DRV_VBOX,
     "VBOX",
@@ -3697,3 +4654,24 @@ virDriver NAME(Driver) = {
     .domainMigratePrepare2         = NULL,
     .domainMigrateFinish2          = NULL,
 };
+
+virNetworkDriver NAME(NetworkDriver) = {
+    "VBOX",
+    .open                   = vboxNetworkOpen,
+    .close                  = vboxNetworkClose,
+    .numOfNetworks          = vboxNumOfNetworks,
+    .listNetworks           = vboxListNetworks,
+    .numOfDefinedNetworks   = NULL,
+    .listDefinedNetworks    = NULL,
+    .networkLookupByUUID    = vboxNetworkLookupByUUID,
+    .networkLookupByName    = vboxNetworkLookupByName,
+    .networkCreateXML       = vboxNetworkCreateXML,
+    .networkDefineXML       = vboxNetworkDefineXML,
+    .networkUndefine        = vboxNetworkUndefine,
+    .networkCreate          = vboxNetworkCreate,
+    .networkDestroy         = vboxNetworkDestroy,
+    .networkDumpXML         = vboxNetworkDumpXML,
+    .networkGetBridgeName   = NULL,
+    .networkGetAutostart    = NULL,
+    .networkSetAutostart    = NULL
+};



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic