[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH 3/3] networking API for hostonly networks in VirtualBox driver in libvirt



>   You really don't need to keep any data about the networking driver
> in libvirt(d) itself ?
>

as danpb explained it :)

> > +                        /* 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)) {

Fixed this to def->nranges >= 1 instead of above.

>   The patch is large but reuses the common routines for conversion
> to/from XML, a lot of the code is vbox internal structures peek/poke
> which are a bit hard to follow but this looks regular, the patch looks
> fine to me but feedback on previous points would be appreciated :-)

Reposting the patch as below with all the fix's mentioned on the list.

Regards,
Pritesh.
commit ec631aa294a08bca13543289368449886d5398b0
Author: pk221555 <pk221555 krishna (none)>
Date:   Mon May 11 14:15:31 2009 +0200

    libvirt: networking API for hostonly networks

diff --git a/src/vbox/vbox_driver.c b/src/vbox/vbox_driver.c
index 7db437c..6b782b1 100644
--- a/src/vbox/vbox_driver.c
+++ b/src/vbox/vbox_driver.c
@@ -39,19 +39,23 @@
 
 
 extern virDriver vbox22Driver;
+extern virNetworkDriver vbox22NetworkDriver;
 #if 0
 extern virDriver vbox25Driver;
+extern virNetworkDriver vbox25NetworkDriver;
 #endif
 
 
 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) {
@@ -69,10 +73,12 @@ int vboxRegister(void) {
         if (uVersion >= 2001052 && uVersion < 2002051) {
             DEBUG0("VirtualBox API version: 2.2");
             driver        = &vbox22Driver;
+            networkDriver = &vbox22NetworkDriver;
 #if 0
         } else if (uVersion >= 2002051 && uVersion < 2005051) {
             DEBUG0("VirtualBox API version: 2.5");
             driver        = &vbox25Driver;
+            networkDriver = &vbox25NetworkDriver;
 #endif
         } else {
             DEBUG0("Unsupport VirtualBox API version");
@@ -84,6 +90,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 a27eada..8e42958 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -3633,6 +3633,1001 @@ 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;
+
+    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) {
+                        PRUint32 status = HostNetworkInterfaceStatus_Unknown;
+
+                        networkInterfaces[i]->vtbl->GetStatus(networkInterfaces[i], &status);
+
+                        if (status == HostNetworkInterfaceStatus_Up) {
+                            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;
+
+    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) {
+                        PRUint32 status = HostNetworkInterfaceStatus_Unknown;
+
+                        networkInterfaces[i]->vtbl->GetStatus(networkInterfaces[i], &status);
+
+                        if (status == HostNetworkInterfaceStatus_Up) {
+                            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 int vboxNumOfDefinedNetworks(virConnectPtr conn) {
+    vboxGlobalData *data = conn->privateData;
+    int numActive = 0;
+
+    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) {
+                        PRUint32 status = HostNetworkInterfaceStatus_Unknown;
+
+                        networkInterfaces[i]->vtbl->GetStatus(networkInterfaces[i], &status);
+
+                        if (status == HostNetworkInterfaceStatus_Down) {
+                            numActive++;
+                        }
+                    }
+
+                    networkInterfaces[i]->vtbl->nsisupports.Release((nsISupports *) networkInterfaces[i]);
+                }
+            }
+
+            host->vtbl->nsisupports.Release((nsISupports *) host);
+        }
+    }
+
+    DEBUG("numActive: %d", numActive);
+    return numActive;
+}
+
+static int vboxListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) {
+    vboxGlobalData *data = conn->privateData;
+    int numActive = 0;
+
+    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) {
+                        PRUint32 status = HostNetworkInterfaceStatus_Unknown;
+
+                        networkInterfaces[i]->vtbl->GetStatus(networkInterfaces[i], &status);
+
+                        if (status == HostNetworkInterfaceStatus_Down) {
+                            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;
+    }
+
+    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;
+
+    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;
+
+    if ((def = virNetworkDefParseString(conn, xml)) == NULL)
+        goto cleanup;
+
+    if (VIR_ALLOC(iid) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+
+    if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", def->name) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+
+    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]);
+
+    if ((data->vboxObj) && (def->forwardType == VIR_NETWORK_FORWARD_NONE)) {
+        /* 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;
+
+    /* 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.
+     */
+    if ((def = virNetworkDefParseString(conn, xml)) == NULL)
+        goto cleanup;
+
+    if (VIR_ALLOC(iid) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+
+    if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", def->name) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+
+    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]);
+
+    if ((data->vboxObj) && (def->forwardType == VIR_NETWORK_FORWARD_NONE)) {
+        /* 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 (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", network->name) < 0) {
+        virReportOOMError(network->conn);
+        goto cleanup;
+    }
+
+    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 (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", network->name) < 0) {
+        virReportOOMError(network->conn);
+        goto cleanup;
+    }
+
+    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 (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", network->name) < 0) {
+        virReportOOMError(network->conn);
+        goto cleanup;
+    }
+
+    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 (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", network->name) < 0) {
+        virReportOOMError(network->conn);
+        goto cleanup;
+    }
+
+    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_NONE;
+
+                    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",
@@ -3695,3 +4690,24 @@ virDriver NAME(Driver) = {
     .domainMigratePrepare2         = NULL,
     .domainMigrateFinish2          = NULL,
 };
+
+virNetworkDriver NAME(NetworkDriver) = {
+    "VBOX",
+    .open                   = vboxNetworkOpen,
+    .close                  = vboxNetworkClose,
+    .numOfNetworks          = vboxNumOfNetworks,
+    .listNetworks           = vboxListNetworks,
+    .numOfDefinedNetworks   = vboxNumOfDefinedNetworks,
+    .listDefinedNetworks    = vboxListDefinedNetworks,
+    .networkLookupByUUID    = vboxNetworkLookupByUUID,
+    .networkLookupByName    = vboxNetworkLookupByName,
+    .networkCreateXML       = vboxNetworkCreateXML,
+    .networkDefineXML       = vboxNetworkDefineXML,
+    .networkUndefine        = vboxNetworkUndefine,
+    .networkCreate          = vboxNetworkCreate,
+    .networkDestroy         = vboxNetworkDestroy,
+    .networkDumpXML         = vboxNetworkDumpXML,
+    .networkGetBridgeName   = NULL,
+    .networkGetAutostart    = NULL,
+    .networkSetAutostart    = NULL
+};

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]