Revision: 403
http://vde.svn.sourceforge.net/vde/?rev=403&view=rev
Author: rd235
Date: 2010-04-04 08:57:30 +0000 (Sun, 04 Apr 2010)
Log Message:
-----------
VirtualBox native support for VDE.
Added Paths:
-----------
trunk/vde-2/VirtualBox/
trunk/vde-2/VirtualBox/README
trunk/vde-2/VirtualBox/VirtualBox-3.1.6_OSE_VDE.patch
Added: trunk/vde-2/VirtualBox/README
===================================================================
--- trunk/vde-2/VirtualBox/README (rev 0)
+++ trunk/vde-2/VirtualBox/README 2010-04-04 08:57:30 UTC (rev 403)
@@ -0,0 +1,17 @@
+This directory contains a preliminary patch to add a native support for VDE
+in VirtualBox.
+
+How to compile VirtualBox+VDE support.
+
+Download VirtualBox source code from here:
+http://download.virtualbox.org/virtualbox/
+
+Expand the source tar.bz2.
+
+Apply the patch (in the root dir of the source hierarchy):
+$ patch -p 1 <VirtualBox-3.1.6_OSE_VDE.patch
+
+Follow the instructions to build the binaries:
+http://www.virtualbox.org/wiki/Linux%20build%20instructions
+
+(Renzo Davoli: Apr. 04 2010)
Added: trunk/vde-2/VirtualBox/VirtualBox-3.1.6_OSE_VDE.patch
===================================================================
--- trunk/vde-2/VirtualBox/VirtualBox-3.1.6_OSE_VDE.patch
(rev 0)
+++ trunk/vde-2/VirtualBox/VirtualBox-3.1.6_OSE_VDE.patch 2010-04-04
08:57:30 UTC (rev 403)
@@ -0,0 +1,1201 @@
+diff -Naur VirtualBox-3.1.6_OSE/src/VBox/Devices/Builtins.cpp
VirtualBox-3.1.6_OSE_VDE/src/VBox/Devices/Builtins.cpp
+--- VirtualBox-3.1.6_OSE/src/VBox/Devices/Builtins.cpp 2010-03-25
20:55:45.000000000 +0100
++++ VirtualBox-3.1.6_OSE_VDE/src/VBox/Devices/Builtins.cpp 2010-04-04
10:18:29.000000000 +0200
+@@ -237,6 +237,13 @@
+ if (RT_FAILURE(rc))
+ return rc;
+ #endif
++ /* ENABLE VDE */
++#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
++ rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvVDE);
++ if (RT_FAILURE(rc))
++ return rc;
++#endif
++ /* /ENABLE VDE */
+ rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvIntNet);
+ if (RT_FAILURE(rc))
+ return rc;
+diff -Naur VirtualBox-3.1.6_OSE/src/VBox/Devices/Builtins.h
VirtualBox-3.1.6_OSE_VDE/src/VBox/Devices/Builtins.h
+--- VirtualBox-3.1.6_OSE/src/VBox/Devices/Builtins.h 2010-03-25
20:55:45.000000000 +0100
++++ VirtualBox-3.1.6_OSE_VDE/src/VBox/Devices/Builtins.h 2010-04-04
10:18:29.000000000 +0200
+@@ -106,6 +106,9 @@
+ #if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
+ extern const PDMDRVREG g_DrvHostInterface;
+ #endif
++#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
++extern const PDMDRVREG g_DrvVDE;
++#endif
+ extern const PDMDRVREG g_DrvIntNet;
+ extern const PDMDRVREG g_DrvNAT;
+ extern const PDMDRVREG g_DrvNetSniffer;
+diff -Naur VirtualBox-3.1.6_OSE/src/VBox/Devices/Makefile.kmk
VirtualBox-3.1.6_OSE_VDE/src/VBox/Devices/Makefile.kmk
+--- VirtualBox-3.1.6_OSE/src/VBox/Devices/Makefile.kmk 2010-03-25
20:55:47.000000000 +0100
++++ VirtualBox-3.1.6_OSE_VDE/src/VBox/Devices/Makefile.kmk 2010-04-04
10:18:29.000000000 +0200
+@@ -909,8 +909,10 @@
+ Audio/ossaudio.c
+ endif # l4
+
++# ENABLE VDE: Network/DrvVDE.cpp added
+ Drivers_SOURCES.linux = \
+ Network/DrvTAP.cpp \
++ Network/DrvVDE.cpp \
+ Audio/ossaudio.c \
+ Parallel/DrvHostParallel.cpp \
+ Serial/DrvHostSerial.cpp
+diff -Naur VirtualBox-3.1.6_OSE/src/VBox/Devices/Network/DrvVDE.cpp
VirtualBox-3.1.6_OSE_VDE/src/VBox/Devices/Network/DrvVDE.cpp
+--- VirtualBox-3.1.6_OSE/src/VBox/Devices/Network/DrvVDE.cpp 1970-01-01
01:00:00.000000000 +0100
++++ VirtualBox-3.1.6_OSE_VDE/src/VBox/Devices/Network/DrvVDE.cpp
2010-04-04 10:34:46.000000000 +0200
+@@ -0,0 +1,561 @@
++/** $Id: DrvVDE.cpp $ */
++/** @file
++ * VDE network transport driver.
++ */
++
++/*
++ * Copyright (C) 2010 Renzo Davoli. VirtualSquare. University of Bologna.
++ * Copyright (C) 2006-2007 Sun Microsystems, Inc.
++ *
++ * This file is part of VirtualBox Open Source Edition (OSE), as
++ * available from http://www.virtualbox.org. This file is free software;
++ * you can redistribute it and/or modify it under the terms of the GNU
++ * General Public License (GPL) as published by the Free Software
++ * Foundation, in version 2 as it comes in the "COPYING" file of the
++ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
++ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
++ * Clara, CA 95054 USA or visit http://www.sun.com if you need
++ * additional information or have any questions.
++ */
++
++/*******************************************************************************
++* Header Files
*
++*******************************************************************************/
++#define LOG_GROUP LOG_GROUP_DRV_TUN
++#include <VBox/log.h>
++#include <VBox/pdmdrv.h>
++
++#include <iprt/assert.h>
++#include <iprt/ctype.h>
++#include <iprt/file.h>
++#include <iprt/string.h>
++#include <iprt/path.h>
++#include <iprt/thread.h>
++#include <iprt/asm.h>
++#include <iprt/semaphore.h>
++
++#include <sys/ioctl.h>
++#include <sys/poll.h>
++#include <sys/fcntl.h>
++#include <errno.h>
++#include <unistd.h>
++#include <limits.h>
++
++#include "Builtins.h"
++#include "libvdeplug_dyn.h"
++
++struct vdepluglib vdeplughdl;
++
++/*******************************************************************************
++* Structures and Typedefs
*
++*******************************************************************************/
++/**
++ * Block driver instance data.
++ */
++typedef struct DRVVDE
++{
++ /** The network interface. */
++ PDMINETWORKCONNECTOR INetworkConnector;
++ /** The network interface. */
++ PPDMINETWORKPORT pPort;
++ /** Pointer to the driver instance. */
++ PPDMDRVINS pDrvIns;
++ /** VDE device file handle. */
++ RTFILE FileDevice;
++ /** The configured VDE device name. */
++ char *pszDeviceName;
++ /** VDE setup application. */
++ char *pszSetupApplication;
++ /** VDE terminate application. */
++ char *pszTerminateApplication;
++ /** The write end of the control pipe. */
++ RTFILE PipeWrite;
++ /** The read end of the control pipe. */
++ RTFILE PipeRead;
++ /** Reader thread. */
++ PPDMTHREAD pThread;
++
++ VDECONN *vdeconn;
++#ifdef VBOX_WITH_STATISTICS
++ /** Number of sent packets. */
++ STAMCOUNTER StatPktSent;
++ /** Number of sent bytes. */
++ STAMCOUNTER StatPktSentBytes;
++ /** Number of received packets. */
++ STAMCOUNTER StatPktRecv;
++ /** Number of received bytes. */
++ STAMCOUNTER StatPktRecvBytes;
++ /** Profiling packet transmit runs. */
++ STAMPROFILE StatTransmit;
++ /** Profiling packet receive runs. */
++ STAMPROFILEADV StatReceive;
++#endif /* VBOX_WITH_STATISTICS */
++
++#ifdef LOG_ENABLED
++ /** The nano ts of the last transfer. */
++ uint64_t u64LastTransferTS;
++ /** The nano ts of the last receive. */
++ uint64_t u64LastReceiveTS;
++#endif
++} DRVVDE, *PDRVVDE;
++
++
++/** Converts a pointer to VDE::INetworkConnector to a PRDVVDE. */
++#define PDMINETWORKCONNECTOR_2_DRVVDE(pInterface) (
(PDRVVDE)((uintptr_t)pInterface - RT_OFFSETOF(DRVVDE, INetworkConnector)) )
++
++
++/*******************************************************************************
++* Internal Functions
*
++*******************************************************************************/
++
++/**
++ * Send data to the network.
++ *
++ * @returns VBox status code.
++ * @param pInterface Pointer to the interface structure containing the
called function pointer.
++ * @param pvBuf Data to send.
++ * @param cb Number of bytes to send.
++ * @thread EMT
++ */
++static DECLCALLBACK(int) drvVDESend(PPDMINETWORKCONNECTOR pInterface, const
void *pvBuf, size_t cb)
++{
++ PDRVVDE pThis = PDMINETWORKCONNECTOR_2_DRVVDE(pInterface);
++ STAM_COUNTER_INC(&pThis->StatPktSent);
++ STAM_COUNTER_ADD(&pThis->StatPktSentBytes, cb);
++ STAM_PROFILE_START(&pThis->StatTransmit, a);
++
++#ifdef LOG_ENABLED
++ uint64_t u64Now = RTTimeProgramNanoTS();
++ LogFlow(("drvVDESend: %-4d bytes at %llu ns deltas: r=%llu t=%llu\n",
++ cb, u64Now, u64Now - pThis->u64LastReceiveTS, u64Now -
pThis->u64LastTransferTS));
++ pThis->u64LastTransferTS = u64Now;
++#endif
++ Log2(("drvVDESend: pvBuf=%p cb=%#x\n"
++ "%.*Rhxd\n",
++ pvBuf, cb, cb, pvBuf));
++
++ int rc = vdeplughdl.vde_send(pThis->vdeconn, pvBuf, cb, 0);
++
++ STAM_PROFILE_STOP(&pThis->StatTransmit, a);
++ AssertRC(rc);
++ return rc;
++}
++
++
++/**
++ * Set promiscuous mode.
++ *
++ * This is called when the promiscuous mode is set. This means that there
doesn't have
++ * to be a mode change when it's called.
++ *
++ * @param pInterface Pointer to the interface structure containing the
called function pointer.
++ * @param fPromiscuous Set if the adaptor is now in promiscuous mode.
Clear if it is not.
++ * @thread EMT
++ */
++static DECLCALLBACK(void) drvVDESetPromiscuousMode(PPDMINETWORKCONNECTOR
pInterface, bool fPromiscuous)
++{
++ LogFlow(("drvVDESetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous));
++ /* nothing to do */
++}
++
++
++/**
++ * Notification on link status changes.
++ *
++ * @param pInterface Pointer to the interface structure containing the
called function pointer.
++ * @param enmLinkState The new link state.
++ * @thread EMT
++ */
++static DECLCALLBACK(void) drvVDENotifyLinkChanged(PPDMINETWORKCONNECTOR
pInterface, PDMNETWORKLINKSTATE enmLinkState)
++{
++ LogFlow(("drvNATNotifyLinkChanged: enmLinkState=%d\n", enmLinkState));
++ /** @todo take action on link down and up. Stop the polling and such
like. */
++}
++
++
++/**
++ * Asynchronous I/O thread for handling receive.
++ *
++ * @returns VINF_SUCCESS (ignored).
++ * @param Thread Thread handle.
++ * @param pvUser Pointer to a DRVVDE structure.
++ */
++static DECLCALLBACK(int) drvVDEAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD
pThread)
++{
++ PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE);
++ LogFlow(("drvVDEAsyncIoThread: pThis=%p\n", pThis));
++
++ if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
++ return VINF_SUCCESS;
++
++ STAM_PROFILE_ADV_START(&pThis->StatReceive, a);
++
++ /*
++ * Polling loop.
++ */
++ while (pThread->enmState == PDMTHREADSTATE_RUNNING)
++ {
++ /*
++ * Wait for something to become available.
++ */
++ struct pollfd aFDs[2];
++ aFDs[0].fd = vdeplughdl.vde_datafd(pThis->vdeconn);
++ aFDs[0].events = POLLIN | POLLPRI;
++ aFDs[0].revents = 0;
++ aFDs[1].fd = pThis->PipeRead;
++ aFDs[1].events = POLLIN | POLLPRI | POLLERR | POLLHUP;
++ aFDs[1].revents = 0;
++ STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a);
++ errno=0;
++ int rc = poll(&aFDs[0], RT_ELEMENTS(aFDs), -1 /* infinite */);
++
++ /* this might have changed in the meantime */
++ if (pThread->enmState != PDMTHREADSTATE_RUNNING)
++ break;
++
++ STAM_PROFILE_ADV_START(&pThis->StatReceive, a);
++ if ( rc > 0
++ && (aFDs[0].revents & (POLLIN | POLLPRI))
++ && !aFDs[1].revents)
++ {
++ /*
++ * Read the frame.
++ */
++ char achBuf[16384];
++ ssize_t cbRead = 0;
++ cbRead =
vdeplughdl.vde_recv(pThis->vdeconn, achBuf, sizeof(achBuf), 0);
++ if (cbRead >= 0)
++ {
++ /*
++ * Wait for the device to have space for this frame.
++ * Most guests use frame-sized receive buffers, hence
non-zero cbMax
++ * automatically means there is enough room for entire frame.
Some
++ * guests (eg. Solaris) use large chains of small receive
buffers
++ * (each 128 or so bytes large). We will still start
receiving as soon
++ * as cbMax is non-zero because:
++ * - it would be quite expensive for pfnCanReceive to
accurately
++ * determine free receive buffer space
++ * - if we were waiting for enough free buffers, there is a
risk
++ * of deadlocking because the guest could be waiting for a
receive
++ * overflow error to allocate more receive buffers
++ */
++ STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a);
++ int rc = pThis->pPort->pfnWaitReceiveAvail(pThis->pPort,
RT_INDEFINITE_WAIT);
++
++ STAM_PROFILE_ADV_START(&pThis->StatReceive, a);
++
++ /*
++ * A return code != VINF_SUCCESS means that we were woken up
during a VM
++ * state transistion. Drop the packet and wait for the next
one.
++ */
++ if (RT_FAILURE(rc))
++ continue;
++
++ /*
++ * Pass the data up.
++ */
++#ifdef LOG_ENABLED
++ uint64_t u64Now = RTTimeProgramNanoTS();
++ LogFlow(("drvVDEAsyncIoThread: %-4d bytes at %llu ns deltas:
r=%llu t=%llu\n",
++ cbRead, u64Now, u64Now - pThis->u64LastReceiveTS,
u64Now - pThis->u64LastTransferTS));
++ pThis->u64LastReceiveTS = u64Now;
++#endif
++ Log2(("drvVDEAsyncIoThread: cbRead=%#x\n" "%.*Rhxd\n",
cbRead, cbRead, achBuf));
++ STAM_COUNTER_INC(&pThis->StatPktRecv);
++ STAM_COUNTER_ADD(&pThis->StatPktRecvBytes, cbRead);
++ rc = pThis->pPort->pfnReceive(pThis->pPort, achBuf, cbRead);
++ AssertRC(rc);
++ }
++ else
++ {
++ LogFlow(("drvVDEAsyncIoThread: RTFileRead -> %Rrc\n", rc));
++ if (rc == VERR_INVALID_HANDLE)
++ break;
++ RTThreadYield();
++ }
++ }
++ else if ( rc > 0
++ && aFDs[1].revents)
++ {
++ LogFlow(("drvVDEAsyncIoThread: Control message: enmState=%d
revents=%#x\n", pThread->enmState, aFDs[1].revents));
++ if (aFDs[1].revents & (POLLHUP | POLLERR | POLLNVAL))
++ break;
++
++ /* drain the pipe */
++ char ch;
++ size_t cbRead;
++ RTFileRead(pThis->PipeRead, &ch, 1, &cbRead);
++ }
++ else
++ {
++ /*
++ * poll() failed for some reason. Yield to avoid eating too much
CPU.
++ *
++ * EINTR errors have been seen frequently. They should be
harmless, even
++ * if they are not supposed to occur in our setup.
++ */
++ if (errno == EINTR)
++ Log(("rc=%d revents=%#x,%#x errno=%p %s\n", rc,
aFDs[0].revents, aFDs[1].revents, errno, strerror(errno)));
++ else
++ AssertMsgFailed(("rc=%d revents=%#x,%#x errno=%p %s\n", rc,
aFDs[0].revents, aFDs[1].revents, errno, strerror(errno)));
++ RTThreadYield();
++ }
++ }
++
++
++ LogFlow(("drvVDEAsyncIoThread: returns %Rrc\n", VINF_SUCCESS));
++ STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a);
++ return VINF_SUCCESS;
++}
++
++
++/**
++ * Unblock the send thread so it can respond to a state change.
++ *
++ * @returns VBox status code.
++ * @param pDevIns The pcnet device instance.
++ * @param pThread The send thread.
++ */
++static DECLCALLBACK(int) drvVDEAsyncIoWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD
pThread)
++{
++ PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE);
++
++ int rc = RTFileWrite(pThis->PipeWrite, "", 1, NULL);
++ AssertRC(rc);
++
++ return VINF_SUCCESS;
++}
++
++
++/**
++ * Queries an interface to the driver.
++ *
++ * @returns Pointer to interface.
++ * @returns NULL if the interface was not supported by the driver.
++ * @param pInterface Pointer to this interface structure.
++ * @param enmInterface The requested interface identification.
++ * @thread Any thread.
++ */
++static DECLCALLBACK(void *) drvVDEQueryInterface(PPDMIBASE pInterface,
PDMINTERFACE enmInterface)
++{
++ PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
++ PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE);
++ switch (enmInterface)
++ {
++ case PDMINTERFACE_BASE:
++ return &pDrvIns->IBase;
++ case PDMINTERFACE_NETWORK_CONNECTOR:
++ return &pThis->INetworkConnector;
++ default:
++ return NULL;
++ }
++}
++
++
++/**
++ * Destruct a driver instance.
++ *
++ * Most VM resources are freed by the VM. This callback is provided so that
any non-VM
++ * resources can be freed correctly.
++ *
++ * @param pDrvIns The driver instance data.
++ */
++static DECLCALLBACK(void) drvVDEDestruct(PPDMDRVINS pDrvIns)
++{
++ LogFlow(("drvVDEDestruct\n"));
++ PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE);
++
++ /*
++ * Terminate the control pipe.
++ */
++ if (pThis->PipeWrite != NIL_RTFILE)
++ {
++ int rc = RTFileClose(pThis->PipeWrite);
++ AssertRC(rc);
++ pThis->PipeWrite = NIL_RTFILE;
++ }
++ if (pThis->PipeRead != NIL_RTFILE)
++ {
++ int rc = RTFileClose(pThis->PipeRead);
++ AssertRC(rc);
++ pThis->PipeRead = NIL_RTFILE;
++ }
++
++ MMR3HeapFree(pThis->pszDeviceName);
++ MMR3HeapFree(pThis->pszSetupApplication);
++ MMR3HeapFree(pThis->pszTerminateApplication);
++
++#ifdef VBOX_WITH_STATISTICS
++ /*
++ * Deregister statistics.
++ */
++ PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatPktSent);
++ PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatPktSentBytes);
++ PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatPktRecv);
++ PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatPktRecvBytes);
++ PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatTransmit);
++ PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatReceive);
++#endif /* VBOX_WITH_STATISTICS */
++}
++
++
++/**
++ * Construct a VDE network transport driver instance.
++ *
++ * @copydoc FNPDMDRVCONSTRUCT
++ */
++static DECLCALLBACK(int) drvVDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE
pCfgHandle, uint32_t fFlags)
++{
++ PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE);
++
++ /*
++ * Init the static parts.
++ */
++ pThis->pDrvIns = pDrvIns;
++ pThis->pszDeviceName = NULL;
++ pThis->pszSetupApplication = NULL;
++ pThis->pszTerminateApplication = NULL;
++
++ /* IBase */
++ pDrvIns->IBase.pfnQueryInterface = drvVDEQueryInterface;
++ /* INetwork */
++ pThis->INetworkConnector.pfnSend = drvVDESend;
++ pThis->INetworkConnector.pfnSetPromiscuousMode =
drvVDESetPromiscuousMode;
++ pThis->INetworkConnector.pfnNotifyLinkChanged = drvVDENotifyLinkChanged;
++
++ if (!CFGMR3AreValuesValid(pCfgHandle,
++ "Network\0"
++ "Trunk\0"
++ "TrunkType\0"
++ "ReceiveBufferSize\0"
++ "SendBufferSize\0"
++ "RestrictAccess\0"
++ "SharedMacOnWire\0"
++ "IgnoreAllPromisc\0"
++ "QuietlyIgnoreAllPromisc\0"
++ "IgnoreClientPromisc\0"
++ "QuietlyIgnoreClientPromisc\0"
++ "IgnoreTrunkWirePromisc\0"
++ "QuietlyIgnoreTrunkWirePromisc\0"
++ "IgnoreTrunkHostPromisc\0"
++ "QuietlyIgnoreTrunkHostPromisc\0"
++ "IsService\0"))
++ return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
++
++ /*
++ * Query the network port interface.
++ */
++ pThis->pPort =
(PPDMINETWORKPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase,
PDMINTERFACE_NETWORK_PORT);
++ if (!pThis->pPort)
++ {
++ AssertMsgFailed(("Configuration error: the above
device/driver didn't export the network port interface!\n"));
++ return VERR_PDM_MISSING_INTERFACE_ABOVE;
++ }
++
++ char szNetwork[PATH_MAX]; /* PATH_MAX */
++ int rc = CFGMR3QueryString(pCfgHandle, "Network", szNetwork,
sizeof(szNetwork));
++ if (RT_FAILURE(rc))
++ *szNetwork=0;
++
++ /* LogRel(("VDEXXXXXX %s\n",szNetwork));*/
++
++ /*
++ * Read the configuration.
++ */
++ if (vdeplughdl.dl_handle == NULL)
++ libvdeplug_dynopen(vdeplughdl);
++ if (vdeplughdl.dl_handle == NULL) {
++ return PDMDrvHlpVMSetError(pThis->pDrvIns,
VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
++ N_("VDEplug
library: not found"));
++ }
++ pThis->vdeconn=vdeplughdl.vde_open(szNetwork,"VirtualBOX",NULL);
++ if (pThis->vdeconn == NULL) {
++ return PDMDrvHlpVMSetError(pThis->pDrvIns,
VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
++ N_("Failed
to connect to the VDE SWITCH"));
++ }
++
++
++ rc = VINF_SUCCESS;
++
++ /*
++ * Create the control pipe.
++ */
++ int fds[2];
++ if (pipe(&fds[0]) != 0) /** @todo RTPipeCreate() or something... */
++ {
++ int rc = RTErrConvertFromErrno(errno);
++ AssertRC(rc);
++ return rc;
++ }
++ pThis->PipeRead = fds[0];
++ pThis->PipeWrite = fds[1];
++
++ /*
++ * Create the async I/O thread.
++ */
++ rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pThread, pThis,
drvVDEAsyncIoThread, drvVDEAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "VDE");
++ AssertRCReturn(rc, rc);
++
++#ifdef VBOX_WITH_STATISTICS
++ /*
++ * Statistics.
++ */
++ PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktSent,
STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of
sent packets.", "/Drivers/VDE%d/Packets/Sent", pDrvIns->iInstance);
++ PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktSentBytes,
STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Number of
sent bytes.", "/Drivers/VDE%d/Bytes/Sent", pDrvIns->iInstance);
++ PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktRecv,
STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of
received packets.", "/Drivers/VDE%d/Packets/Received", pDrvIns->iInstance);
++ PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktRecvBytes,
STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Number of
received bytes.", "/Drivers/VDE%d/Bytes/Received", pDrvIns->iInstance);
++ PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatTransmit,
STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling
packet transmit runs.", "/Drivers/VDE%d/Transmit", pDrvIns->iInstance);
++ PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatReceive,
STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling
packet receive runs.", "/Drivers/VDE%d/Receive", pDrvIns->iInstance);
++#endif /* VBOX_WITH_STATISTICS */
++
++ return rc;
++}
++
++
++/**
++ * VDE network transport driver registration record.
++ */
++const PDMDRVREG g_DrvVDE =
++{
++ /* u32Version */
++ PDM_DRVREG_VERSION,
++ /* szDriverName */
++ "VDE",
++ /* pszDescription */
++ "VDE Network Transport Driver",
++ /* fFlags */
++ PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
++ /* fClass. */
++ PDM_DRVREG_CLASS_NETWORK,
++ /* cMaxInstances */
++ ~0,
++ /* cbInstance */
++ sizeof(DRVVDE),
++ /* pfnConstruct */
++ drvVDEConstruct,
++ /* pfnDestruct */
++ drvVDEDestruct,
++ /* pfnIOCtl */
++ NULL,
++ /* pfnPowerOn */
++ NULL,
++ /* pfnReset */
++ NULL,
++ /* pfnSuspend */
++ NULL, /** @todo Do power on, suspend and resume handlers! */
++ /* pfnResume */
++ NULL,
++ /* pfnAttach */
++ NULL,
++ /* pfnDetach */
++ NULL,
++ /* pfnPowerOff */
++ NULL,
++ /* pfnSoftReset */
++ NULL,
++ /* u32EndVersion */
++ PDM_DRVREG_VERSION
++};
++
+diff -Naur VirtualBox-3.1.6_OSE/src/VBox/Devices/Network/libvdeplug_dyn.h
VirtualBox-3.1.6_OSE_VDE/src/VBox/Devices/Network/libvdeplug_dyn.h
+--- VirtualBox-3.1.6_OSE/src/VBox/Devices/Network/libvdeplug_dyn.h
1970-01-01 01:00:00.000000000 +0100
++++ VirtualBox-3.1.6_OSE_VDE/src/VBox/Devices/Network/libvdeplug_dyn.h
2010-04-04 10:34:54.000000000 +0200
+@@ -0,0 +1,119 @@
++/*
++ * libvdeplug - A library to connect to a VDE Switch.
++ * dynamic loading version (requires libdl).
++ *
++ * Copyright (C) 2006,2007,2010 Renzo Davoli, University of Bologna
++ *
++ * This library is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU Lesser General Public License as published by
++ * the Free Software Foundation version 2.1 of the License, or (at
++ * your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
++ */
++
++/* Use this include file when you need to write an application that can
++ * benefit from vde when available.
++ * Linking libvdeplug to your programs you force your application users
++ * to have the library installed (otherway the dynamic linker complies
++ * and the program does not start).
++ *
++ *
++ * usage:
++ * define a struct vdepluglib variable;
++ * eg:
++ * struct vdepluglib vdeplug;
++ *
++ * test the availability of the library and load it:
++ *
++ * libvdeplug_dynopen(vdeplug);
++ * if vdeplug.dl_handle is not NULL the library is ready otherwise it is
++ * not available in the target system.
++ *
++ * if libvdeplug does exist the library function can be called
++ * in this way:
++ * vdeplug.vde_open(....)
++ * vdeplug.vde_read(....)
++ * vdeplug.vde_open(....)
++ * vdeplug.vde_recv(....)
++ * vdeplug.vde_send(....)
++ * vdeplug.vde_datafd(....)
++ * vdeplug.vde_ctlfd(....)
++ * vdeplug.vde_close(....)
++ * libvdeplug_dynclose(vdeplug) can be used to deallocate the dynamic library
++ * when needed.
++ *************************************************/
++
++#ifndef _VDEDYNLIB_H
++#define _VDEDYNLIB_H
++#include <sys/types.h>
++#include <dlfcn.h>
++#define LIBVDEPLUG_INTERFACE_VERSION 1
++
++struct vdeconn;
++
++typedef struct vdeconn VDECONN;
++
++/* Open a VDE connection.
++ * vde_open_options:
++ * port: connect to a specific port of the switch (0=any)
++ * group: change the ownership of the communication port to a specific group
++ * (NULL=no change)
++ * mode: set communication port mode (if 0 standard socket mode applies)
++ */
++struct vde_open_args {
++ int port;
++ char *group;
++ mode_t mode;
++};
++
++/* vde_open args:
++ * vde_switch: switch id (path)
++ * descr: description (it will appear in the port description on the switch)
++ */
++#define vde_open(vde_switch,descr,open_args) \
++
vde_open_real((vde_switch),(descr),LIBVDEPLUG_INTERFACE_VERSION,(open_args))
++
++struct vdepluglib {
++ void *dl_handle;
++ VDECONN * (*vde_open_real)(const char *vde_switch,char *descr,int
interface_version, struct vde_open_args *open_args);
++ size_t (* vde_recv)(VDECONN *conn,void *buf,size_t len,int flags);
++ size_t (* vde_send)(VDECONN *conn,const void *buf,size_t len,int flags);
++ int (* vde_datafd)(VDECONN *conn);
++ int (* vde_ctlfd)(VDECONN *conn);
++ int (* vde_close)(VDECONN *conn);
++};
++
++typedef VDECONN * (* VDE_OPEN_REAL_T)(const char *vde_switch,char *descr,int
interface_version, struct vde_open_args *open_args);
++typedef size_t (* VDE_RECV_T)(VDECONN *conn,void *buf,size_t len,int flags);
++typedef size_t (* VDE_SEND_T)(VDECONN *conn,const void *buf,size_t len,int
flags);
++typedef int (* VDE_INT_FUN)(VDECONN *conn);
++#define libvdeplug_dynopen(x) do { \
++ (x).dl_handle=dlopen("libvdeplug.so",RTLD_NOW); \
++ if ((x).dl_handle) { \
++ (x).vde_open_real=(VDE_OPEN_REAL_T)
dlsym((x).dl_handle,"vde_open_real"); \
++ (x).vde_recv=(VDE_RECV_T) dlsym((x).dl_handle,"vde_recv"); \
++ (x).vde_send=(VDE_SEND_T) dlsym((x).dl_handle,"vde_send"); \
++ (x).vde_datafd=(VDE_INT_FUN) dlsym((x).dl_handle,"vde_datafd");
\
++ (x).vde_ctlfd=(VDE_INT_FUN) dlsym((x).dl_handle,"vde_ctlfd"); \
++ (x).vde_close=(VDE_INT_FUN) dlsym((x).dl_handle,"vde_close"); \
++ } else { \
++ (x).vde_open_real=NULL; \
++ (x).vde_send= NULL; \
++ (x).vde_recv= NULL; \
++ (x).vde_datafd= (x).vde_ctlfd= (x).vde_close= NULL; \
++ }\
++ } while (0)
++
++#define libvdeplug_dynclose(x) do { \
++ dlclose((x).dl_handle); \
++ } while (0)
++
++#endif
+diff -Naur
VirtualBox-3.1.6_OSE/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
VirtualBox-3.1.6_OSE_VDE/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
+---
VirtualBox-3.1.6_OSE/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
2010-03-25 20:56:15.000000000 +0100
++++
VirtualBox-3.1.6_OSE_VDE/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
2010-04-04 10:18:34.000000000 +0200
+@@ -1849,6 +1849,11 @@
+ else if (type == KNetworkAttachmentType_HostOnly)
+ attType = attType.arg (tr ("Host-only adapter, '%1'",
+ "details report (network)").arg
(adapter.GetHostInterface()));
++ /* ENABLE VDE */
++ else if (type == KNetworkAttachmentType_VDE)
++ attType = attType.arg (tr ("VDE network, '%1'",
++ "details report (network)").arg
(adapter.GetVDENetwork()));
++ /* /ENABLE VDE
*/
+ else
+ attType = attType.arg (vboxGlobal().toString (type));
+
+@@ -2796,6 +2801,10 @@
+ tr ("Internal Network", "NetworkAttachmentType");
+ mNetworkAttachmentTypes [KNetworkAttachmentType_HostOnly] =
+ tr ("Host-only Adapter", "NetworkAttachmentType");
++ /* ENABLE VDE */
++ mNetworkAttachmentTypes [KNetworkAttachmentType_VDE] =
++ tr ("VDE Adapter", "NetworkAttachmentType");
++ /* /ENABLE VDE */
+
+ mClipboardTypes [KClipboardMode_Disabled] =
+ tr ("Disabled", "ClipboardType");
+diff -Naur
VirtualBox-3.1.6_OSE/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.cpp
VirtualBox-3.1.6_OSE_VDE/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.cpp
+---
VirtualBox-3.1.6_OSE/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.cpp
2010-03-25 20:56:16.000000000 +0100
++++
VirtualBox-3.1.6_OSE_VDE/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.cpp
2010-04-04 10:18:34.000000000 +0200
+@@ -103,6 +103,12 @@
+ mHoiName = mAdapter.GetHostInterface();
+ if (mHoiName.isEmpty()) mHoiName = QString::null;
+ break;
++ /* ENABLE VDE */
++ case KNetworkAttachmentType_VDE:
++ mVDEName = mAdapter.GetVDENetwork();
++ if (mVDEName.isEmpty()) mVDEName = QString::null;
++ break;
++ /* /ENABLE VDE */
+ default:
+ break;
+ }
+@@ -143,6 +149,12 @@
+ mAdapter.SetHostInterface (alternativeName());
+ mAdapter.AttachToHostOnlyInterface();
+ break;
++ /* ENABLE VDE */
++ case KNetworkAttachmentType_VDE:
++ mAdapter.SetVDENetwork
(alternativeName());
++ mAdapter.AttachToVDE();
++ break;
++ /* /ENABLE VDE */
+ default:
+ break;
+ }
+@@ -255,6 +267,11 @@
+ case KNetworkAttachmentType_HostOnly:
+ result = mHoiName;
+ break;
++ /* ENABLE VDE*/
++ case KNetworkAttachmentType_VDE:
++ result = mVDEName;
++ break;
++ /* /ENABLE VDE*/
+ default:
+ break;
+ }
+@@ -331,6 +348,13 @@
+ mCbAdapterName->insertItems (0, mParent->hoiList());
+ mCbAdapterName->setEditable (false);
+ break;
++ /* ENABLE VDE */
++ case KNetworkAttachmentType_VDE:
++ mCbAdapterName->insertItem(0,
alternativeName());
++ mCbAdapterName->setEditable (true);
++ mCbAdapterName->setCompleter (0);
++ break;
++ /* /ENABLE VDE */
+ default:
+ break;
+ }
+@@ -430,6 +454,20 @@
+ mHoiName = newName;
+ break;
+ }
++ /* ENABLE VDE */
++ case KNetworkAttachmentType_VDE:
++ {
++ QString newName ((mCbAdapterName->itemData
(mCbAdapterName->currentIndex()).toString() ==
++ QString (emptyItemCode) &&
++ mCbAdapterName->currentText() ==
++ mCbAdapterName->itemText
(mCbAdapterName->currentIndex())) ||
++ mCbAdapterName->currentText().isEmpty() ?
++ QString::null : mCbAdapterName->currentText());
++ if (mVDEName != newName)
++ mVDEName = newName;
++ break;
++ }
++ /* /ENABLE VDE */
+ default:
+ break;
+ }
+@@ -546,6 +584,14 @@
+ KNetworkAttachmentType_HostOnly);
+ mCbAttachmentType->setItemData (4,
+ mCbAttachmentType->itemText (4), Qt::ToolTipRole);
++ /* ENABLE VDE */
++ mCbAttachmentType->insertItem (5,
++ vboxGlobal().toString (KNetworkAttachmentType_VDE));
++ mCbAttachmentType->setItemData (5,
++ KNetworkAttachmentType_VDE);
++ mCbAttachmentType->setItemData (5,
++ mCbAttachmentType->itemText (5), Qt::ToolTipRole);
++ /* /ENABLE VDE */
+
+ /* Set the old value */
+ mCbAttachmentType->setCurrentIndex (currentAttachment);
+diff -Naur
VirtualBox-3.1.6_OSE/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.h
VirtualBox-3.1.6_OSE_VDE/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.h
+---
VirtualBox-3.1.6_OSE/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.h
2010-03-25 20:56:16.000000000 +0100
++++
VirtualBox-3.1.6_OSE_VDE/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.h
2010-04-04 10:18:34.000000000 +0200
+@@ -76,6 +76,9 @@
+ QString mBrgName;
+ QString mIntName;
+ QString mHoiName;
++ /* ENABLE VDE */
++ QString mVDEName;
++ /* /ENABLE VDE */
+
+ bool mPolished;
+ bool mDisableStaticControls;
+@@ -92,6 +95,7 @@
+ QStringList brgList (bool aRefresh = false);
+ QStringList intList (bool aRefresh = false);
+ QStringList hoiList (bool aRefresh = false);
++ QStringList vdeList (bool aRefresh = false);
+
+ protected:
+
+diff -Naur
VirtualBox-3.1.6_OSE/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.ui
VirtualBox-3.1.6_OSE_VDE/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.ui
+---
VirtualBox-3.1.6_OSE/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.ui
2010-03-25 20:56:16.000000000 +0100
++++
VirtualBox-3.1.6_OSE_VDE/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.ui
2010-04-04 10:18:34.000000000 +0200
+@@ -110,7 +110,7 @@
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" >
+- <string>Selects the name of the network adapter for <b>Bridged
Adapter</b> or <b>Host-only Adapter</b> attachments and the
name of the network <b>Internal Network</b> attachments.</string>
++ <string>Selects the name of the network adapter for <b>Bridged
Adapter</b> or <b>Host-only Adapter</b> attachments and the
name of the network <b>Internal Network</b> or the switch for
<b>VDE</b> attachments.</string>
+ </property>
+ </widget>
+ </item>
+diff -Naur VirtualBox-3.1.6_OSE/src/VBox/Main/cbinding/VBoxCAPI_v3_0.h
VirtualBox-3.1.6_OSE_VDE/src/VBox/Main/cbinding/VBoxCAPI_v3_0.h
+--- VirtualBox-3.1.6_OSE/src/VBox/Main/cbinding/VBoxCAPI_v3_0.h
2010-03-25 20:56:39.000000000 +0100
++++ VirtualBox-3.1.6_OSE_VDE/src/VBox/Main/cbinding/VBoxCAPI_v3_0.h
2010-04-04 10:18:33.000000000 +0200
+@@ -1657,6 +1657,7 @@
+ NetworkAttachmentType_Bridged = 2,
+ NetworkAttachmentType_Internal = 3,
+ NetworkAttachmentType_HostOnly = 4
++ NetworkAttachmentType_VDE = 5
+ };
+ /* End of enum NetworkAttachmentType Declaration */
+
+@@ -4500,6 +4501,11 @@
+ nsresult (*GetNATNetwork)(INetworkAdapter *pThis, PRUnichar *
*NATNetwork);
+ nsresult (*SetNATNetwork)(INetworkAdapter *pThis, PRUnichar * NATNetwork);
+
++ /* ENABLE VDE */
++ nsresult (*GetVDENetwork)(INetworkAdapter *pThis, PRUnichar *
*NATNetwork);
++ nsresult (*SetVDENetwork)(INetworkAdapter *pThis, PRUnichar * NATNetwork);
++ /* /ENABLE VDE */
++
+ nsresult (*GetCableConnected)(INetworkAdapter *pThis, PRBool
*cableConnected);
+ nsresult (*SetCableConnected)(INetworkAdapter *pThis, PRBool
cableConnected);
+
+diff -Naur VirtualBox-3.1.6_OSE/src/VBox/Main/ConsoleImpl2.cpp
VirtualBox-3.1.6_OSE_VDE/src/VBox/Main/ConsoleImpl2.cpp
+--- VirtualBox-3.1.6_OSE/src/VBox/Main/ConsoleImpl2.cpp 2010-03-25
20:56:37.000000000 +0100
++++ VirtualBox-3.1.6_OSE_VDE/src/VBox/Main/ConsoleImpl2.cpp 2010-04-04
10:18:32.000000000 +0200
+@@ -2798,6 +2798,29 @@
+ break;
+ }
+
++ /* ENABLE VDE */
++ case NetworkAttachmentType_VDE:
++ {
++ hrc = aNetworkAdapter->COMGETTER(VDENetwork)(&str); H();
++#if 0
++ if (str) {
++ Utf8Str strUtf8 = str;
++ LogRel(("VDE Network
%s\n",(char *)strUtf8.raw()));
++ }
++#endif
++ rc = CFGMR3InsertNode(pInst,
"LUN#0", &pLunL0); RC_CHECK();
++ rc = CFGMR3InsertString(pLunL0,
"Driver", "VDE"); RC_CHECK();
++ rc = CFGMR3InsertNode(pLunL0,
"Config", &pCfg); RC_CHECK();
++ if (str && *str) {
++ rc = CFGMR3InsertStringW(pCfg, "Network", str);
RC_CHECK();
++ networkName =
str;
++ }
++ rc = CFGMR3InsertInteger(pCfg,
"TrunkType", kIntNetTrunkType_WhateverNone); RC_CHECK();
++ STR_FREE();
++ break;
++ }
++ /* /ENABLE VDE */
++
+ default:
+ AssertMsgFailed(("should not get here!\n"));
+ break;
+diff -Naur VirtualBox-3.1.6_OSE/src/VBox/Main/idl/VirtualBox.xidl
VirtualBox-3.1.6_OSE_VDE/src/VBox/Main/idl/VirtualBox.xidl
+--- VirtualBox-3.1.6_OSE/src/VBox/Main/idl/VirtualBox.xidl 2010-03-25
20:56:40.000000000 +0100
++++ VirtualBox-3.1.6_OSE_VDE/src/VBox/Main/idl/VirtualBox.xidl 2010-04-04
10:18:33.000000000 +0200
+@@ -11240,6 +11240,9 @@
+ <const name="Bridged" value="2"/>
+ <const name="Internal" value="3"/>
+ <const name="HostOnly" value="4"/>
++ <!-- ENABLE VDE -->
++ <const name="VDE" value="5"/>
++ <!-- /ENABLE VDE -->
+ </enum>
+
+ <enum
+@@ -11342,6 +11345,14 @@
+ </desc>
+ </attribute>
+
++ <!-- ENABLE VDE -->
++ <attribute name="VDENetwork" type="wstring">
++ <desc>
++ Name of the VDE switch the VM is attached to.
++ </desc>
++ </attribute>
++ <!-- /ENABLE VDE -->
++
+ <attribute name="cableConnected" type="boolean">
+ <desc>
+ Flag whether the adapter reports the cable as connected or not.
+@@ -11393,6 +11404,14 @@
+ </desc>
+ </method>
+
++ <!-- ENABLE VDE -->
++ <method name="attachToVDE">
++ <desc>
++ Attach the network adapter to a VDE network.
++ </desc>
++ </method>
++ <!-- /ENABLE VDE -->
++
+ <method name="detach">
+ <desc>
+ Detach the network adapter
+diff -Naur VirtualBox-3.1.6_OSE/src/VBox/Main/include/NetworkAdapterImpl.h
VirtualBox-3.1.6_OSE_VDE/src/VBox/Main/include/NetworkAdapterImpl.h
+--- VirtualBox-3.1.6_OSE/src/VBox/Main/include/NetworkAdapterImpl.h
2010-03-25 20:56:41.000000000 +0100
++++ VirtualBox-3.1.6_OSE_VDE/src/VBox/Main/include/NetworkAdapterImpl.h
2010-04-04 10:18:33.000000000 +0200
+@@ -49,6 +49,9 @@
+ mCableConnected(TRUE), mLineSpeed(0), mTraceEnabled(FALSE),
+ mHostInterface("") /* cannot be null */,
+ mNATNetwork("") /* cannot be null */
++ /* ENABLE VDE
*/
++ , mVDENetwork("") /* can be null */
++ /* /ENABLE VDE
*/
+ {}
+
+ bool operator== (const Data &that) const
+@@ -63,6 +66,9 @@
+ mTraceEnabled == that.mTraceEnabled &&
+ mHostInterface == that.mHostInterface &&
+ mInternalNetwork == that.mInternalNetwork &&
++ /* ENABLE VDE
*/
++
mVDENetwork == that.mVDENetwork &&
++ /* /ENABLE VDE
*/
+ mNATNetwork == that.mNATNetwork);
+ }
+
+@@ -78,6 +84,9 @@
+ Bstr mHostInterface;
+ Bstr mInternalNetwork;
+ Bstr mNATNetwork;
++ /* ENABLE VDE */
++ Bstr mVDENetwork;
++ /* /ENABLE VDE */
+ };
+
+ VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (NetworkAdapter)
+@@ -118,6 +127,10 @@
+ STDMETHOD(COMSETTER(InternalNetwork)) (IN_BSTR aInternalNetwork);
+ STDMETHOD(COMGETTER(NATNetwork)) (BSTR *aNATNetwork);
+ STDMETHOD(COMSETTER(NATNetwork)) (IN_BSTR aNATNetwork);
++ /* ENABLE VDE */
++ STDMETHOD(COMGETTER(VDENetwork)) (BSTR *aVDENetwork);
++ STDMETHOD(COMSETTER(VDENetwork)) (IN_BSTR aVDENetwork);
++ /* /ENABLE VDE */
+ STDMETHOD(COMGETTER(CableConnected)) (BOOL *aConnected);
+ STDMETHOD(COMSETTER(CableConnected)) (BOOL aConnected);
+ STDMETHOD(COMGETTER(TraceEnabled)) (BOOL *aEnabled);
+@@ -132,6 +145,9 @@
+ STDMETHOD(AttachToBridgedInterface)();
+ STDMETHOD(AttachToInternalNetwork)();
+ STDMETHOD(AttachToHostOnlyInterface)();
++ /* ENABLE VDE */
++ STDMETHOD(AttachToVDE)();
++ /* /ENABLE VDE */
+ STDMETHOD(Detach)();
+
+ // public methods only for internal purposes
+diff -Naur VirtualBox-3.1.6_OSE/src/VBox/Main/NetworkAdapterImpl.cpp
VirtualBox-3.1.6_OSE_VDE/src/VBox/Main/NetworkAdapterImpl.cpp
+--- VirtualBox-3.1.6_OSE/src/VBox/Main/NetworkAdapterImpl.cpp 2010-03-25
20:56:38.000000000 +0100
++++ VirtualBox-3.1.6_OSE_VDE/src/VBox/Main/NetworkAdapterImpl.cpp
2010-04-04 10:18:33.000000000 +0200
+@@ -532,6 +532,52 @@
+ return S_OK;
+ }
+
++/* ENABLE VDE */
++STDMETHODIMP NetworkAdapter::COMGETTER(VDENetwork) (BSTR *aVDENetwork)
++{
++ CheckComArgOutPointerValid(aVDENetwork);
++
++ AutoCaller autoCaller(this);
++ CheckComRCReturnRC(autoCaller.rc());
++
++ AutoReadLock alock(this);
++
++ mData->mVDENetwork.cloneTo(aVDENetwork);
++
++ return S_OK;
++}
++
++STDMETHODIMP NetworkAdapter::COMSETTER(VDENetwork) (IN_BSTR aVDENetwork)
++{
++ Bstr bstrEmpty("");
++ if (!aVDENetwork)
++ aVDENetwork = bstrEmpty;
++
++ AutoCaller autoCaller(this);
++ CheckComRCReturnRC(autoCaller.rc());
++
++ /* the machine needs to be mutable */
++ Machine::AutoMutableStateDependency adep (mParent);
++ CheckComRCReturnRC(adep.rc());
++
++ AutoWriteLock alock(this);
++
++ if (mData->mVDENetwork != aVDENetwork)
++ {
++ mData.backup();
++ mData->mVDENetwork = aVDENetwork;
++
++ /* leave the lock before informing callbacks */
++ alock.unlock();
++
++ mParent->onNetworkAdapterChange (this, FALSE);
++ }
++
++ return S_OK;
++}
++
++/* /ENABLE VDE */
++
+ STDMETHODIMP NetworkAdapter::COMGETTER(CableConnected) (BOOL *aConnected)
+ {
+ CheckComArgOutPointerValid(aConnected);
+@@ -864,6 +910,51 @@
+ return S_OK;
+ }
+
++/* ENABLE VDE */
++STDMETHODIMP NetworkAdapter::AttachToVDE()
++{
++ AutoCaller autoCaller(this);
++ CheckComRCReturnRC(autoCaller.rc());
++
++ /* the machine needs to be mutable */
++ Machine::AutoMutableStateDependency adep (mParent);
++ CheckComRCReturnRC(adep.rc());
++
++ AutoWriteLock alock(this);
++
++ /* don't do anything if we're already host interface attached */
++ if (mData->mAttachmentType != NetworkAttachmentType_VDE)
++ {
++ mData.backup();
++
++ /* first detach the current attachment */
++ // Commented this for now as it reset the parameter
mData->mHostInterface
++ // which is essential while changing the Attachment dynamically.
++ //detach();
++
++ mData->mAttachmentType = NetworkAttachmentType_VDE;
++
++ /* leave the lock before informing callbacks */
++ alock.unlock();
++
++ HRESULT rc = mParent->onNetworkAdapterChange (this, TRUE);
++ if (FAILED (rc))
++ {
++ /* If changing the attachment failed then we can't
assume
++ * that the previous attachment will attach correctly
++ * and thus return error along with dettaching all
++ * attachments.
++ */
++ Detach();
++ return rc;
++ }
++ }
++
++ return S_OK;
++}
++
++/* /ENABLE VDE */
++
+ STDMETHODIMP NetworkAdapter::Detach()
+ {
+ AutoCaller autoCaller(this);
+@@ -966,6 +1057,15 @@
+ CheckComRCReturnRC(rc);
+ break;
+
++ /* ENABLE VDE */
++ case NetworkAttachmentType_VDE:
++ mData->mVDENetwork = data.strName;
++ rc = AttachToVDE();
++ CheckComRCReturnRC(rc);
++ break;
++ /* ENABLE VDE */
++
++
+ case NetworkAttachmentType_Null:
+ rc = Detach();
+ CheckComRCReturnRC(rc);
+@@ -1024,6 +1124,10 @@
+ case NetworkAttachmentType_HostOnly:
+ data.strName = mData->mHostInterface;
+ break;
++
++ case NetworkAttachmentType_VDE:
++ data.strName = mData->mVDENetwork;
++ break;
+ }
+
+ return S_OK;
+diff -Naur VirtualBox-3.1.6_OSE/src/VBox/Main/xml/Settings.cpp
VirtualBox-3.1.6_OSE_VDE/src/VBox/Main/xml/Settings.cpp
+--- VirtualBox-3.1.6_OSE/src/VBox/Main/xml/Settings.cpp 2010-03-25
20:56:45.000000000 +0100
++++ VirtualBox-3.1.6_OSE_VDE/src/VBox/Main/xml/Settings.cpp 2010-04-04
10:18:33.000000000 +0200
+@@ -1371,6 +1371,13 @@
+ if (!pelmAdapterChild->getAttributeValue("name", nic.strName))
// required network name
+ throw ConfigFileError(this, pelmAdapterChild, N_("Required
HostOnlyInterface/@name element is missing"));
+ }
++ /* ENABLE VDE */
++ else if ((pelmAdapterChild = pelmAdapter->findChildElement("VDE")))
++ {
++ nic.mode = NetworkAttachmentType_VDE;
++ pelmAdapterChild->getAttributeValue("network", nic.strName);
// optional network name
++ }
++ /* /ENABLE VDE */
+ // else: default is NetworkAttachmentType_Null
+
+ ll.push_back(nic);
+@@ -2701,6 +2708,13 @@
+
pelmAdapter->createChild("HostOnlyInterface")->setAttribute("name",
nic.strName);
+ break;
+
++ /* ENABLE VDE */
++ case NetworkAttachmentType_VDE:
++ pelmNAT = pelmAdapter->createChild("VDE");
++ if
(nic.strName.length())
++
pelmNAT->setAttribute("network", nic.strName);
++ /* /ENABLE VDE */
++
+ default: /*case NetworkAttachmentType_Null:*/
+ break;
+ }
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
vde-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vde-users