提交 67cc35ad 编写于 作者: D Daniel Veillard

Finish hostonly networks support in vbox

* src/vbox/vbox_driver.c src/vbox/vbox_tmpl.c: last patch for
  hostonly networks support in vbox driver, patch by Pritesh Kothari
daniel
上级 37623bf4
Fri May 15 15:59:08 CEST 2009 Daniel Veillard <veillard@redhat.com>
* src/vbox/vbox_driver.c src/vbox/vbox_tmpl.c: last patch for
hostonly networks support in vbox driver, patch by Pritesh Kothari
Fri May 15 15:44:01 CEST 2009 Daniel Veillard <veillard@redhat.com>
* src/vbox/vbox_tmpl.c: implement vbox vrdp/sdl/gui support,
......
......@@ -40,8 +40,10 @@
extern virDriver vbox22Driver;
extern virNetworkDriver vbox22NetworkDriver;
#if 0
extern virDriver vbox25Driver;
extern virNetworkDriver vbox25NetworkDriver;
#endif
static virDriver vboxDriverDummy;
......@@ -54,6 +56,7 @@ static virDriver vboxDriverDummy;
int vboxRegister(void) {
virDriverPtr driver;
virNetworkDriverPtr networkDriver;
uint32_t uVersion;
/*
......@@ -63,6 +66,7 @@ int vboxRegister(void) {
* never work
*/
driver = &vboxDriverDummy;
networkDriver = &vbox22NetworkDriver;
/* Init the glue and get the API version. */
if (VBoxCGlueInit() == 0) {
......@@ -80,10 +84,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");
......@@ -95,6 +101,8 @@ int vboxRegister(void) {
if (virRegisterDriver(driver) < 0)
return -1;
if (virRegisterNetworkDriver(networkDriver) < 0)
return -1;
return 0;
}
......
......@@ -3881,6 +3881,1024 @@ 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);
if (names[numActive] == NULL) {
vboxError(conn, VIR_ERR_SYSTEM_ERROR, "%s", "strdup failed");
} else {
numActive++;
}
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);
if (names[numActive] == NULL) {
vboxError(conn, VIR_ERR_SYSTEM_ERROR, "%s", "strdup failed");
} else {
numActive++;
}
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) {
def->name = strdup(network->name);
if (def->name != NULL) {
nsID *vboxnet0IID = NULL;
PRUnichar *networkNameUtf16 = NULL;
IDHCPServer *dhcpServer = NULL;
data->pFuncs->pfnUtf8ToUtf16(networkNameUtf8 , &networkNameUtf16);
networkInterface->vtbl->GetId(networkInterface, &vboxnet0IID);
nsIDtoChar(def->uuid, vboxnet0IID);
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 ) {
def->hosts[0].name = strdup(network->name);
if (def->hosts[0].name == NULL) {
VIR_FREE(def->hosts);
def->nhosts = 0;
vboxError(network->conn,
VIR_ERR_SYSTEM_ERROR,
"%s", "strdup failed");
} else {
PRUnichar *macAddressUtf16 = NULL;
PRUnichar *ipAddressUtf16 = NULL;
networkInterface->vtbl->GetHardwareAddress(networkInterface, &macAddressUtf16);
networkInterface->vtbl->GetIPAddress(networkInterface, &ipAddressUtf16);
data->pFuncs->pfnUtf16ToUtf8(macAddressUtf16, &def->hosts[0].mac);
data->pFuncs->pfnUtf16ToUtf8(ipAddressUtf16, &def->hosts[0].ip);
data->pFuncs->pfnUtf16Free(macAddressUtf16);
data->pFuncs->pfnUtf16Free(ipAddressUtf16);
}
} else {
def->nhosts = 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);
} else {
vboxError(network->conn, VIR_ERR_SYSTEM_ERROR,
"%s", "strdup failed");
}
}
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",
......@@ -3943,3 +4961,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
};
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册