VirtualBox

Changeset 28406 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Apr 16, 2010 10:45:18 AM (15 years ago)
Author:
vboxsync
Message:

Devices, Main, FE/Qt: re-committed support for VDE virtual network switches for Linux and FreeBSD hosts. Contributed by Renzo Davoli, VirtualSquare, University of Bologna

Location:
trunk/src/VBox/Devices/Network
Files:
4 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DrvVDE.cpp

    r28315 r28406  
    11/* $Id$ */
    22/** @file
    3  * DrvTAP - Universial TAP network transport driver.
     3 * VDE network transport driver.
    44 */
    55
    66/*
     7 * Contributed by Renzo Davoli. VirtualSquare. University of Bologna, 2010
    78 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    89 *
     
    3435#include <iprt/file.h>
    3536#include <iprt/mem.h>
     37#include <iprt/param.h>
    3638#include <iprt/path.h>
    3739#include <iprt/semaphore.h>
     
    3941#include <iprt/thread.h>
    4042#include <iprt/uuid.h>
    41 #ifdef RT_OS_SOLARIS
    42 # include <iprt/process.h>
    43 # include <iprt/env.h>
    44 # ifdef VBOX_WITH_CROSSBOW
    45 #  include <iprt/mem.h>
    46 # endif
    47 #endif
    4843
    4944#include <sys/ioctl.h>
    5045#include <sys/poll.h>
    51 #ifdef RT_OS_SOLARIS
    52 # include <sys/stat.h>
    53 # include <sys/ethernet.h>
    54 # include <sys/sockio.h>
    55 # include <netinet/in.h>
    56 # include <netinet/in_systm.h>
    57 # include <netinet/ip.h>
    58 # include <netinet/ip_icmp.h>
    59 # include <netinet/udp.h>
    60 # include <netinet/tcp.h>
    61 # include <net/if.h>
    62 # include <stropts.h>
    63 # include <fcntl.h>
    64 # include <stdlib.h>
    65 # include <stdio.h>
    66 # ifdef VBOX_WITH_CROSSBOW
    67 #  include "solaris/vbox-libdlpi.h"
    68 # endif
    69 #else
    70 # include <sys/fcntl.h>
    71 #endif
     46#include <sys/fcntl.h>
    7247#include <errno.h>
    7348#include <unistd.h>
    7449
    75 #ifdef RT_OS_L4
    76 # include <l4/vboxserver/file.h>
    77 #endif
    78 
    7950#include "Builtins.h"
     51#include "VDEPlug.h"
    8052
    8153
     
    8456*******************************************************************************/
    8557/**
    86  * TAP driver instance data.
     58 * VDE driver instance data.
    8759 *
    8860 * @implements PDMINETWORKUP
    8961 */
    90 typedef struct DRVTAP
     62typedef struct DRVVDE
    9163{
    9264    /** The network interface. */
     
    9668    /** Pointer to the driver instance. */
    9769    PPDMDRVINS              pDrvIns;
    98     /** TAP device file handle. */
     70    /** VDE device file handle. */
    9971    RTFILE                  FileDevice;
    100     /** The configured TAP device name. */
     72    /** The configured VDE device name. */
    10173    char                   *pszDeviceName;
    102 #ifdef RT_OS_SOLARIS
    103 # ifdef VBOX_WITH_CROSSBOW
    104     /** Crossbow: MAC address of the device. */
    105     RTMAC                   MacAddress;
    106     /** Crossbow: Handle of the NIC. */
    107     dlpi_handle_t           pDeviceHandle;
    108 # else
    109     /** IP device file handle (/dev/udp). */
    110     RTFILE                  IPFileDevice;
    111 # endif
    112     /** Whether device name is obtained from setup application. */
    113     bool                    fStatic;
    114 #endif
    115     /** TAP setup application. */
    116     char                   *pszSetupApplication;
    117     /** TAP terminate application. */
    118     char                   *pszTerminateApplication;
    11974    /** The write end of the control pipe. */
    12075    RTFILE                  PipeWrite;
     
    12378    /** Reader thread. */
    12479    PPDMTHREAD              pThread;
     80    /** The connection to the VDE switch */
     81    VDECONN                *vdeconn;
    12582
    12683    /** @todo The transmit thread. */
     
    149106    uint64_t                u64LastReceiveTS;
    150107#endif
    151 } DRVTAP, *PDRVTAP;
    152 
    153 
    154 /** Converts a pointer to TAP::INetworkUp to a PRDVTAP. */
    155 #define PDMINETWORKUP_2_DRVTAP(pInterface) ( (PDRVTAP)((uintptr_t)pInterface - RT_OFFSETOF(DRVTAP, INetworkUp)) )
     108} DRVVDE, *PDRVVDE;
     109
     110
     111/** Converts a pointer to VDE::INetworkUp to a PRDVVDE. */
     112#define PDMINETWORKUP_2_DRVVDE(pInterface) ( (PDRVVDE)((uintptr_t)pInterface - RT_OFFSETOF(DRVVDE, INetworkUp)) )
    156113
    157114
     
    159116*   Internal Functions                                                         *
    160117*******************************************************************************/
    161 #ifdef RT_OS_SOLARIS
    162 # ifdef VBOX_WITH_CROSSBOW
    163 static int              SolarisOpenVNIC(PDRVTAP pThis);
    164 static int              SolarisDLPIErr2VBoxErr(int rc);
    165 # else
    166 static int              SolarisTAPAttach(PDRVTAP pThis);
    167 # endif
    168 #endif
    169118
    170119
     
    173122 * @interface_method_impl{PDMINETWORKUP,pfnBeginXmit}
    174123 */
    175 static DECLCALLBACK(int) drvTAPNetworkUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread)
    176 {
    177     PDRVTAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);
     124static DECLCALLBACK(int) drvVDENetworkUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread)
     125{
     126    PDRVVDE pThis = PDMINETWORKUP_2_DRVVDE(pInterface);
    178127    int rc = RTCritSectTryEnter(&pThis->XmitLock);
    179128    if (RT_FAILURE(rc))
     
    189138 * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf}
    190139 */
    191 static DECLCALLBACK(int) drvTAPNetworkUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,
     140static DECLCALLBACK(int) drvVDENetworkUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,
    192141                                                  PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf)
    193142{
    194     PDRVTAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);
     143    PDRVVDE pThis = PDMINETWORKUP_2_DRVVDE(pInterface);
    195144    Assert(RTCritSectIsOwner(&pThis->XmitLock));
    196145
     
    235184 * @interface_method_impl{PDMINETWORKUP,pfnFreeBuf}
    236185 */
    237 static DECLCALLBACK(int) drvTAPNetworkUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf)
    238 {
    239     PDRVTAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);
     186static DECLCALLBACK(int) drvVDENetworkUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf)
     187{
     188    PDRVVDE pThis = PDMINETWORKUP_2_DRVVDE(pInterface);
    240189    Assert(RTCritSectIsOwner(&pThis->XmitLock));
    241190    if (pSgBuf)
     
    252201 * @interface_method_impl{PDMINETWORKUP,pfnSendBuf}
    253202 */
    254 static DECLCALLBACK(int) drvTAPNetworkUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread)
    255 {
    256     PDRVTAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);
     203static DECLCALLBACK(int) drvVDENetworkUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread)
     204{
     205    PDRVVDE pThis = PDMINETWORKUP_2_DRVVDE(pInterface);
    257206    STAM_COUNTER_INC(&pThis->StatPktSent);
    258207    STAM_COUNTER_ADD(&pThis->StatPktSentBytes, pSgBuf->cbUsed);
     
    268217#ifdef LOG_ENABLED
    269218        uint64_t u64Now = RTTimeProgramNanoTS();
    270         LogFlow(("drvTAPSend: %-4d bytes at %llu ns  deltas: r=%llu t=%llu\n",
     219        LogFlow(("drvVDESend: %-4d bytes at %llu ns  deltas: r=%llu t=%llu\n",
    271220                 pSgBuf->cbUsed, u64Now, u64Now - pThis->u64LastReceiveTS, u64Now - pThis->u64LastTransferTS));
    272221        pThis->u64LastTransferTS = u64Now;
    273222#endif
    274         Log2(("drvTAPSend: pSgBuf->aSegs[0].pvSeg=%p pSgBuf->cbUsed=%#x\n"
     223        Log2(("drvVDESend: pSgBuf->aSegs[0].pvSeg=%p pSgBuf->cbUsed=%#x\n"
    275224              "%.*Rhxd\n",
    276225              pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, pSgBuf->cbUsed, pSgBuf->aSegs[0].pvSeg));
    277226
    278         rc = RTFileWrite(pThis->FileDevice, pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, NULL);
     227        ssize_t cbSent;
     228        cbSent = vde_send(pThis->vdeconn, pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, 0);
     229        rc = cbSent < 0 ? RTErrConvertFromErrno(-cbSent) : VINF_SUCCESS;
    279230    }
    280231    else
     
    289240            void *pvSegFrame = PDMNetGsoCarveSegmentQD(pGso, (uint8_t *)pbFrame, pSgBuf->cbUsed, abHdrScratch,
    290241                                                       iSeg, cSegs, &cbSegFrame);
    291             rc = RTFileWrite(pThis->FileDevice, pvSegFrame, cbSegFrame, NULL);
     242            ssize_t cbSent;
     243            cbSent = vde_send(pThis->vdeconn, pvSegFrame, cbSegFrame, 0);
     244            rc = cbSent < 0 ? RTErrConvertFromErrno(-cbSent) : VINF_SUCCESS;
    292245            if (RT_FAILURE(rc))
    293246                break;
     
    309262 * @interface_method_impl{PDMINETWORKUP,pfnEndXmit}
    310263 */
    311 static DECLCALLBACK(void) drvTAPNetworkUp_EndXmit(PPDMINETWORKUP pInterface)
    312 {
    313     PDRVTAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);
     264static DECLCALLBACK(void) drvVDENetworkUp_EndXmit(PPDMINETWORKUP pInterface)
     265{
     266    PDRVVDE pThis = PDMINETWORKUP_2_DRVVDE(pInterface);
    314267    RTCritSectLeave(&pThis->XmitLock);
    315268}
     
    319272 * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode}
    320273 */
    321 static DECLCALLBACK(void) drvTAPNetworkUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)
    322 {
    323     LogFlow(("drvTAPNetworkUp_SetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous));
     274static DECLCALLBACK(void) drvVDENetworkUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)
     275{
     276    LogFlow(("drvVDESetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous));
    324277    /* nothing to do */
    325278}
     
    333286 * @thread  EMT
    334287 */
    335 static DECLCALLBACK(void) drvTAPNetworkUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)
    336 {
    337     LogFlow(("drvTAPNetworkUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState));
     288static DECLCALLBACK(void) drvVDENetworkUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)
     289{
     290    LogFlow(("drvNATNetworkUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState));
    338291    /** @todo take action on link down and up. Stop the polling and such like. */
    339292}
     
    345298 * @returns VINF_SUCCESS (ignored).
    346299 * @param   Thread          Thread handle.
    347  * @param   pvUser          Pointer to a DRVTAP structure.
    348  */
    349 static DECLCALLBACK(int) drvTAPAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
    350 {
    351     PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
    352     LogFlow(("drvTAPAsyncIoThread: pThis=%p\n", pThis));
     300 * @param   pvUser          Pointer to a DRVVDE structure.
     301 */
     302static DECLCALLBACK(int) drvVDEAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
     303{
     304    PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE);
     305    LogFlow(("drvVDEAsyncIoThread: pThis=%p\n", pThis));
    353306
    354307    if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
     
    366319         */
    367320        struct pollfd aFDs[2];
    368         aFDs[0].fd      = pThis->FileDevice;
     321        aFDs[0].fd      = vde_datafd(pThis->vdeconn);
    369322        aFDs[0].events  = POLLIN | POLLPRI;
    370323        aFDs[0].revents = 0;
     
    389342             */
    390343            char achBuf[16384];
    391             size_t cbRead = 0;
    392 #ifdef VBOX_WITH_CROSSBOW
    393             cbRead = sizeof(achBuf);
    394             rc = g_pfnLibDlpiRecv(pThis->pDeviceHandle, NULL, NULL, achBuf, &cbRead, -1, NULL);
    395             rc = RT_LIKELY(rc == DLPI_SUCCESS) ? VINF_SUCCESS : SolarisDLPIErr2VBoxErr(rc);
    396 #else
    397             /** @note At least on Linux we will never receive more than one network packet
    398              *        after poll() returned successfully. I don't know why but a second
    399              *        RTFileRead() operation will return with VERR_TRY_AGAIN in any case. */
    400             rc = RTFileRead(pThis->FileDevice, achBuf, sizeof(achBuf), &cbRead);
    401 #endif
     344            ssize_t cbRead = 0;
     345            cbRead = vde_recv(pThis->vdeconn, achBuf, sizeof(achBuf), 0);
     346            rc = cbRead < 0 ? RTErrConvertFromErrno(-cbRead) : VINF_SUCCESS;
    402347            if (RT_SUCCESS(rc))
    403348            {
     
    431376#ifdef LOG_ENABLED
    432377                uint64_t u64Now = RTTimeProgramNanoTS();
    433                 LogFlow(("drvTAPAsyncIoThread: %-4d bytes at %llu ns  deltas: r=%llu t=%llu\n",
     378                LogFlow(("drvVDEAsyncIoThread: %-4d bytes at %llu ns  deltas: r=%llu t=%llu\n",
    434379                         cbRead, u64Now, u64Now - pThis->u64LastReceiveTS, u64Now - pThis->u64LastTransferTS));
    435380                pThis->u64LastReceiveTS = u64Now;
    436381#endif
    437                 Log2(("drvTAPAsyncIoThread: cbRead=%#x\n" "%.*Rhxd\n", cbRead, cbRead, achBuf));
     382                Log2(("drvVDEAsyncIoThread: cbRead=%#x\n" "%.*Rhxd\n", cbRead, cbRead, achBuf));
    438383                STAM_COUNTER_INC(&pThis->StatPktRecv);
    439384                STAM_COUNTER_ADD(&pThis->StatPktRecvBytes, cbRead);
     
    443388            else
    444389            {
    445                 LogFlow(("drvTAPAsyncIoThread: RTFileRead -> %Rrc\n", rc));
     390                LogFlow(("drvVDEAsyncIoThread: RTFileRead -> %Rrc\n", rc));
    446391                if (rc == VERR_INVALID_HANDLE)
    447392                    break;
     
    452397                 && aFDs[1].revents)
    453398        {
    454             LogFlow(("drvTAPAsyncIoThread: Control message: enmState=%d revents=%#x\n", pThread->enmState, aFDs[1].revents));
     399            LogFlow(("drvVDEAsyncIoThread: Control message: enmState=%d revents=%#x\n", pThread->enmState, aFDs[1].revents));
    455400            if (aFDs[1].revents & (POLLHUP | POLLERR | POLLNVAL))
    456401                break;
     
    478423
    479424
    480     LogFlow(("drvTAPAsyncIoThread: returns %Rrc\n", VINF_SUCCESS));
     425    LogFlow(("drvVDEAsyncIoThread: returns %Rrc\n", VINF_SUCCESS));
    481426    STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a);
    482427    return VINF_SUCCESS;
     
    491436 * @param   pThread     The send thread.
    492437 */
    493 static DECLCALLBACK(int) drvTapAsyncIoWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
    494 {
    495     PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
     438static DECLCALLBACK(int) drvVDEAsyncIoWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
     439{
     440    PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE);
    496441
    497442    int rc = RTFileWrite(pThis->PipeWrite, "", 1, NULL);
     
    502447
    503448
    504 #if defined(RT_OS_SOLARIS)
    505 /**
    506  * Calls OS-specific TAP setup application/script.
    507  *
    508  * @returns VBox error code.
    509  * @param   pThis           The instance data.
    510  */
    511 static int drvTAPSetupApplication(PDRVTAP pThis)
    512 {
    513     char szCommand[4096];
    514 
    515 #ifdef VBOX_WITH_CROSSBOW
    516     /* Convert MAC address bytes to string (required by Solaris' dladm). */
    517     char *pszHex = "0123456789abcdef";
    518     uint8_t *pMacAddr8 = pThis->MacAddress.au8;
    519     char szMacAddress[3 * sizeof(RTMAC)];
    520     for (unsigned int i = 0; i < sizeof(RTMAC); i++)
    521     {
    522         szMacAddress[3 * i] = pszHex[((*pMacAddr8 >> 4) & 0x0f)];
    523         szMacAddress[3 * i + 1] = pszHex[(*pMacAddr8 & 0x0f)];
    524         szMacAddress[3 * i + 2] = ':';
    525         *pMacAddr8++;
    526     }
    527     szMacAddress[sizeof(szMacAddress) - 1] =  0;
    528 
    529     RTStrPrintf(szCommand, sizeof(szCommand), "%s %s %s", pThis->pszSetupApplication,
    530             szMacAddress, pThis->fStatic ? pThis->pszDeviceName : "");
    531 #else
    532     RTStrPrintf(szCommand, sizeof(szCommand), "%s %s", pThis->pszSetupApplication,
    533             pThis->fStatic ? pThis->pszDeviceName : "");
    534 #endif
    535 
    536     /* Pipe open the setup application. */
    537     Log2(("Starting TAP setup application: %s\n", szCommand));
    538     FILE* pfSetupHandle = popen(szCommand, "r");
    539     if (pfSetupHandle == 0)
    540     {
    541         LogRel(("TAP#%d: Failed to run TAP setup application: %s\n", pThis->pDrvIns->iInstance,
    542               pThis->pszSetupApplication, strerror(errno)));
    543         return VERR_HOSTIF_INIT_FAILED;
    544     }
    545     if (!pThis->fStatic)
    546     {
    547         /* Obtain device name from setup application. */
    548         char acBuffer[64];
    549         size_t cBufSize;
    550         fgets(acBuffer, sizeof(acBuffer), pfSetupHandle);
    551         cBufSize = strlen(acBuffer);
    552         /* The script must return the name of the interface followed by a carriage return as the
    553           first line of its output.  We need a null-terminated string. */
    554         if ((cBufSize < 2) || (acBuffer[cBufSize - 1] != '\n'))
    555         {
    556             pclose(pfSetupHandle);
    557             LogRel(("The TAP interface setup script did not return the name of a TAP device.\n"));
    558             return VERR_HOSTIF_INIT_FAILED;
    559         }
    560         /* Overwrite the terminating newline character. */
    561         acBuffer[cBufSize - 1] = 0;
    562         RTStrAPrintf(&pThis->pszDeviceName, "%s", acBuffer);
    563     }
    564     int rc = pclose(pfSetupHandle);
    565     if (!WIFEXITED(rc))
    566     {
    567         LogRel(("The TAP interface setup script terminated abnormally.\n"));
    568         return VERR_HOSTIF_INIT_FAILED;
    569     }
    570     if (WEXITSTATUS(rc) != 0)
    571     {
    572         LogRel(("The TAP interface setup script returned a non-zero exit code.\n"));
    573         return VERR_HOSTIF_INIT_FAILED;
    574     }
    575     return VINF_SUCCESS;
    576 }
    577 
    578 
    579 /**
    580  * Calls OS-specific TAP terminate application/script.
    581  *
    582  * @returns VBox error code.
    583  * @param   pThis           The instance data.
    584  */
    585 static int drvTAPTerminateApplication(PDRVTAP pThis)
    586 {
    587     char *pszArgs[3];
    588     pszArgs[0] = pThis->pszTerminateApplication;
    589     pszArgs[1] = pThis->pszDeviceName;
    590     pszArgs[2] = NULL;
    591 
    592     Log2(("Starting TAP terminate application: %s %s\n", pThis->pszTerminateApplication, pThis->pszDeviceName));
    593     RTPROCESS pid = NIL_RTPROCESS;
    594     int rc = RTProcCreate(pszArgs[0], pszArgs, RTENV_DEFAULT, 0, &pid);
    595     if (RT_SUCCESS(rc))
    596     {
    597         RTPROCSTATUS Status;
    598         rc = RTProcWait(pid, 0, &Status);
    599         if (RT_SUCCESS(rc))
    600         {
    601             if (    Status.iStatus == 0
    602                 &&  Status.enmReason == RTPROCEXITREASON_NORMAL)
    603                 return VINF_SUCCESS;
    604 
    605             LogRel(("TAP#%d: Error running TAP terminate application: %s\n", pThis->pDrvIns->iInstance, pThis->pszTerminateApplication));
    606         }
    607         else
    608             LogRel(("TAP#%d: RTProcWait failed for: %s\n", pThis->pDrvIns->iInstance, pThis->pszTerminateApplication));
    609     }
    610     else
    611     {
    612         /* Bad. RTProcCreate() failed! */
    613         LogRel(("TAP#%d: Failed to fork() process for running TAP terminate application: %s\n", pThis->pDrvIns->iInstance,
    614               pThis->pszTerminateApplication, strerror(errno)));
    615     }
    616     return VERR_HOSTIF_TERM_FAILED;
    617 }
    618 
    619 #endif /* RT_OS_SOLARIS */
    620 
    621 
    622 #ifdef RT_OS_SOLARIS
    623 # ifdef VBOX_WITH_CROSSBOW
    624 /**
    625  * Crossbow: Open & configure the virtual NIC.
    626  *
    627  * @returns VBox error code.
    628  * @param   pThis           The instance data.
    629  */
    630 static int SolarisOpenVNIC(PDRVTAP pThis)
    631 {
    632     /*
    633      * Open & bind the NIC using the datalink provider routine.
    634      */
    635     int rc = g_pfnLibDlpiOpen(pThis->pszDeviceName, &pThis->pDeviceHandle, DLPI_RAW);
    636     if (rc != DLPI_SUCCESS)
    637         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    638                            N_("Failed to open VNIC \"%s\" in raw mode"), pThis->pszDeviceName);
    639 
    640     dlpi_info_t vnicInfo;
    641     rc = g_pfnLibDlpiInfo(pThis->pDeviceHandle, &vnicInfo, 0);
    642     if (rc == DLPI_SUCCESS)
    643     {
    644         if (vnicInfo.di_mactype == DL_ETHER)
    645         {
    646             rc = g_pfnLibDlpiBind(pThis->pDeviceHandle, DLPI_ANY_SAP, NULL);
    647             if (rc == DLPI_SUCCESS)
    648             {
    649                 rc = g_pfnLibDlpiSetPhysAddr(pThis->pDeviceHandle, DL_CURR_PHYS_ADDR, &pThis->MacAddress, ETHERADDRL);
    650                 if (rc == DLPI_SUCCESS)
    651                 {
    652                     rc = g_pfnLibDlpiPromiscon(pThis->pDeviceHandle, DL_PROMISC_SAP);
    653                     if (rc == DLPI_SUCCESS)
    654                     {
    655                         /* Need to use DL_PROMIS_PHYS (not multicast) as we cannot be sure what the guest needs. */
    656                         rc = g_pfnLibDlpiPromiscon(pThis->pDeviceHandle, DL_PROMISC_PHYS);
    657                         if (rc == DLPI_SUCCESS)
    658                         {
    659                             pThis->FileDevice = g_pfnLibDlpiFd(pThis->pDeviceHandle);
    660                             if (pThis->FileDevice >= 0)
    661                             {
    662                                 Log(("SolarisOpenVNIC: %s -> %d\n", pThis->pszDeviceName, pThis->FileDevice));
    663                                 return VINF_SUCCESS;
    664                             }
    665 
    666                             rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    667                                                      N_("Failed to obtain file descriptor for VNIC"));
    668                         }
    669                         else
    670                             rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    671                                                      N_("Failed to set appropriate promiscous mode"));
    672                     }
    673                     else
    674                         rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    675                                                  N_("Failed to activate promiscous mode for VNIC"));
    676                 }
    677                 else
    678                     rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    679                                              N_("Failed to set physical address for VNIC"));
    680             }
    681             else
    682                 rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    683                                          N_("Failed to bind VNIC"));
    684         }
    685         else
    686             rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    687                                          N_("VNIC type is not ethernet"));
    688     }
    689     else
    690         rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    691                                          N_("Failed to obtain VNIC info"));
    692     g_pfnLibDlpiClose(pThis->pDeviceHandle);
    693     return rc;
    694 }
    695 
    696 
    697 /**
    698  * Crossbow: Converts a Solaris DLPI error code to a VBox error code.
    699  *
    700  * @returns corresponding VBox error code.
    701  * @param   rc  DLPI error code (DLPI_* defines).
    702  */
    703 static int SolarisDLPIErr2VBoxErr(int rc)
    704 {
    705     switch (rc)
    706     {
    707         case DLPI_SUCCESS:          return VINF_SUCCESS;
    708         case DLPI_EINVAL:           return VERR_INVALID_PARAMETER;
    709         case DLPI_ELINKNAMEINVAL:   return VERR_INVALID_NAME;
    710         case DLPI_EINHANDLE:        return VERR_INVALID_HANDLE;
    711         case DLPI_ETIMEDOUT:        return VERR_TIMEOUT;
    712         case DLPI_FAILURE:          return VERR_GENERAL_FAILURE;
    713 
    714         case DLPI_EVERNOTSUP:
    715         case DLPI_EMODENOTSUP:
    716         case DLPI_ERAWNOTSUP:
    717         /* case DLPI_ENOTENOTSUP: */
    718         case DLPI_EUNAVAILSAP:      return VERR_NOT_SUPPORTED;
    719 
    720         /*  Define VBox error codes for these, if really needed. */
    721         case DLPI_ENOLINK:
    722         case DLPI_EBADLINK:
    723         /* case DLPI_ENOTEIDINVAL: */
    724         case DLPI_EBADMSG:
    725         case DLPI_ENOTSTYLE2:       return VERR_GENERAL_FAILURE;
    726     }
    727 
    728     AssertMsgFailed(("SolarisDLPIErr2VBoxErr: Unhandled error %d\n", rc));
    729     return VERR_UNRESOLVED_ERROR;
    730 }
    731 
    732 # else  /* VBOX_WITH_CROSSBOW */
    733 
    734 /** From net/if_tun.h, installed by Universal TUN/TAP driver */
    735 # define TUNNEWPPA                   (('T'<<16) | 0x0001)
    736 /** Whether to enable ARP for TAP. */
    737 # define VBOX_SOLARIS_TAP_ARP        1
    738 
    739 /**
    740  * Creates/Attaches TAP device to IP.
    741  *
    742  * @returns VBox error code.
    743  * @param   pThis            The instance data.
    744  */
    745 static DECLCALLBACK(int) SolarisTAPAttach(PDRVTAP pThis)
    746 {
    747     LogFlow(("SolarisTapAttach: pThis=%p\n", pThis));
    748 
    749 
    750     int IPFileDes = open("/dev/udp", O_RDWR, 0);
    751     if (IPFileDes < 0)
    752         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    753                                    N_("Failed to open /dev/udp. errno=%d"), errno);
    754 
    755     int TapFileDes = open("/dev/tap", O_RDWR, 0);
    756     if (TapFileDes < 0)
    757         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    758                                    N_("Failed to open /dev/tap for TAP. errno=%d"), errno);
    759 
    760     /* Use the PPA from the ifname if possible (e.g "tap2", then use 2 as PPA) */
    761     int iPPA = -1;
    762     if (pThis->pszDeviceName)
    763     {
    764         size_t cch = strlen(pThis->pszDeviceName);
    765         if (cch > 1 && RT_C_IS_DIGIT(pThis->pszDeviceName[cch - 1]) != 0)
    766             iPPA = pThis->pszDeviceName[cch - 1] - '0';
    767     }
    768 
    769     struct strioctl ioIF;
    770     ioIF.ic_cmd = TUNNEWPPA;
    771     ioIF.ic_len = sizeof(iPPA);
    772     ioIF.ic_dp = (char *)(&iPPA);
    773     ioIF.ic_timout = 0;
    774     iPPA = ioctl(TapFileDes, I_STR, &ioIF);
    775     if (iPPA < 0)
    776     {
    777         close(TapFileDes);
    778         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
    779                                    N_("Failed to get new interface. errno=%d"), errno);
    780     }
    781 
    782     int InterfaceFD = open("/dev/tap", O_RDWR, 0);
    783     if (!InterfaceFD)
    784         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
    785                                    N_("Failed to open interface /dev/tap. errno=%d"), errno);
    786 
    787     if (ioctl(InterfaceFD, I_PUSH, "ip") == -1)
    788     {
    789         close(InterfaceFD);
    790         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
    791                                    N_("Failed to push IP. errno=%d"), errno);
    792     }
    793 
    794     struct lifreq ifReq;
    795     memset(&ifReq, 0, sizeof(ifReq));
    796     if (ioctl(InterfaceFD, SIOCGLIFFLAGS, &ifReq) == -1)
    797         LogRel(("TAP#%d: Failed to get interface flags.\n", pThis->pDrvIns->iInstance));
    798 
    799     ifReq.lifr_ppa = iPPA;
    800     RTStrPrintf (ifReq.lifr_name, sizeof(ifReq.lifr_name), pThis->pszDeviceName);
    801 
    802     if (ioctl(InterfaceFD, SIOCSLIFNAME, &ifReq) == -1)
    803         LogRel(("TAP#%d: Failed to set PPA. errno=%d\n", pThis->pDrvIns->iInstance, errno));
    804 
    805     if (ioctl(InterfaceFD, SIOCGLIFFLAGS, &ifReq) == -1)
    806         LogRel(("TAP#%d: Failed to get interface flags after setting PPA. errno=%d\n", pThis->pDrvIns->iInstance, errno));
    807 
    808 #ifdef VBOX_SOLARIS_TAP_ARP
    809     /* Interface */
    810     if (ioctl(InterfaceFD, I_PUSH, "arp") == -1)
    811         LogRel(("TAP#%d: Failed to push ARP to Interface FD. errno=%d\n", pThis->pDrvIns->iInstance, errno));
    812 
    813     /* IP */
    814     if (ioctl(IPFileDes, I_POP, NULL) == -1)
    815         LogRel(("TAP#%d: Failed I_POP from IP FD. errno=%d\n", pThis->pDrvIns->iInstance, errno));
    816 
    817     if (ioctl(IPFileDes, I_PUSH, "arp") == -1)
    818         LogRel(("TAP#%d: Failed to push ARP to IP FD. errno=%d\n", pThis->pDrvIns->iInstance, errno));
    819 
    820     /* ARP */
    821     int ARPFileDes = open("/dev/tap", O_RDWR, 0);
    822     if (ARPFileDes < 0)
    823         LogRel(("TAP#%d: Failed to open for /dev/tap for ARP. errno=%d", pThis->pDrvIns->iInstance, errno));
    824 
    825     if (ioctl(ARPFileDes, I_PUSH, "arp") == -1)
    826         LogRel(("TAP#%d: Failed to push ARP to ARP FD. errno=%d\n", pThis->pDrvIns->iInstance, errno));
    827 
    828     ioIF.ic_cmd = SIOCSLIFNAME;
    829     ioIF.ic_timout = 0;
    830     ioIF.ic_len = sizeof(ifReq);
    831     ioIF.ic_dp = (char *)&ifReq;
    832     if (ioctl(ARPFileDes, I_STR, &ioIF) == -1)
    833         LogRel(("TAP#%d: Failed to set interface name to ARP.\n", pThis->pDrvIns->iInstance));
    834 #endif
    835 
    836     /* We must use I_LINK and not I_PLINK as I_PLINK makes the link persistent.
    837      * Then we would not be able unlink the interface if we reuse it.
    838      * Even 'unplumb' won't work after that.
    839      */
    840     int IPMuxID = ioctl(IPFileDes, I_LINK, InterfaceFD);
    841     if (IPMuxID == -1)
    842     {
    843         close(InterfaceFD);
    844 #ifdef VBOX_SOLARIS_TAP_ARP
    845         close(ARPFileDes);
    846 #endif
    847         LogRel(("TAP#%d: Cannot link TAP device to IP.\n", pThis->pDrvIns->iInstance));
    848         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
    849                     N_("Failed to link TAP device to IP. Check TAP interface name. errno=%d"), errno);
    850     }
    851 
    852 #ifdef VBOX_SOLARIS_TAP_ARP
    853     int ARPMuxID = ioctl(IPFileDes, I_LINK, ARPFileDes);
    854     if (ARPMuxID == -1)
    855         LogRel(("TAP#%d: Failed to link TAP device to ARP\n", pThis->pDrvIns->iInstance));
    856 
    857     close(ARPFileDes);
    858 #endif
    859     close(InterfaceFD);
    860 
    861     /* Reuse ifReq */
    862     memset(&ifReq, 0, sizeof(ifReq));
    863     RTStrPrintf (ifReq.lifr_name, sizeof(ifReq.lifr_name), pThis->pszDeviceName);
    864     ifReq.lifr_ip_muxid  = IPMuxID;
    865 #ifdef VBOX_SOLARIS_TAP_ARP
    866     ifReq.lifr_arp_muxid = ARPMuxID;
    867 #endif
    868 
    869     if (ioctl(IPFileDes, SIOCSLIFMUXID, &ifReq) == -1)
    870     {
    871 #ifdef VBOX_SOLARIS_TAP_ARP
    872         ioctl(IPFileDes, I_PUNLINK, ARPMuxID);
    873 #endif
    874         ioctl(IPFileDes, I_PUNLINK, IPMuxID);
    875         close(IPFileDes);
    876         LogRel(("TAP#%d: Failed to set Mux ID.\n", pThis->pDrvIns->iInstance));
    877         return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
    878                                    N_("Failed to set Mux ID. Check TAP interface name. errno=%d"), errno);
    879     }
    880 
    881     pThis->FileDevice = (RTFILE)TapFileDes;
    882     pThis->IPFileDevice = (RTFILE)IPFileDes;
    883 
    884     return VINF_SUCCESS;
    885 }
    886 
    887 # endif /* VBOX_WITH_CROSSBOW */
    888 #endif  /* RT_OS_SOLARIS */
    889 
    890449/* -=-=-=-=- PDMIBASE -=-=-=-=- */
    891450
     
    893452 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
    894453 */
    895 static DECLCALLBACK(void *) drvTAPQueryInterface(PPDMIBASE pInterface, const char *pszIID)
     454static DECLCALLBACK(void *) drvVDEQueryInterface(PPDMIBASE pInterface, const char *pszIID)
    896455{
    897456    PPDMDRVINS  pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
    898     PDRVTAP     pThis   = PDMINS_2_DATA(pDrvIns, PDRVTAP);
     457    PDRVVDE     pThis   = PDMINS_2_DATA(pDrvIns, PDRVVDE);
    899458
    900459    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
     
    913472 * @param   pDrvIns     The driver instance data.
    914473 */
    915 static DECLCALLBACK(void) drvTAPDestruct(PPDMDRVINS pDrvIns)
    916 {
    917     LogFlow(("drvTAPDestruct\n"));
    918     PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
     474static DECLCALLBACK(void) drvVDEDestruct(PPDMDRVINS pDrvIns)
     475{
     476    LogFlow(("drvVDEDestruct\n"));
     477    PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE);
    919478    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    920479
     
    935494    }
    936495
    937 #ifdef RT_OS_SOLARIS
    938     /** @todo r=bird: This *does* need checking against ConsoleImpl2.cpp if used on non-solaris systems. */
    939     if (pThis->FileDevice != NIL_RTFILE)
    940     {
    941         int rc = RTFileClose(pThis->FileDevice);
    942         AssertRC(rc);
    943         pThis->FileDevice = NIL_RTFILE;
    944     }
    945 
    946 # ifndef VBOX_WITH_CROSSBOW
    947     if (pThis->IPFileDevice != NIL_RTFILE)
    948     {
    949         int rc = RTFileClose(pThis->IPFileDevice);
    950         AssertRC(rc);
    951         pThis->IPFileDevice = NIL_RTFILE;
    952     }
    953 # endif
    954 
    955     /*
    956      * Call TerminateApplication after closing the device otherwise
    957      * TerminateApplication would not be able to unplumb it.
    958      */
    959     if (pThis->pszTerminateApplication)
    960         drvTAPTerminateApplication(pThis);
    961 
    962 #endif  /* RT_OS_SOLARIS */
    963 
    964 #ifdef RT_OS_SOLARIS
    965     if (!pThis->fStatic)
    966         RTStrFree(pThis->pszDeviceName);    /* allocated by drvTAPSetupApplication */
    967     else
    968         MMR3HeapFree(pThis->pszDeviceName);
    969 #else
    970496    MMR3HeapFree(pThis->pszDeviceName);
    971 #endif
    972     MMR3HeapFree(pThis->pszSetupApplication);
    973     MMR3HeapFree(pThis->pszTerminateApplication);
    974497
    975498    /*
     
    994517
    995518/**
    996  * Construct a TAP network transport driver instance.
     519 * Construct a VDE network transport driver instance.
    997520 *
    998521 * @copydoc FNPDMDRVCONSTRUCT
    999522 */
    1000 static DECLCALLBACK(int) drvTAPConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
    1001 {
    1002     PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
     523static DECLCALLBACK(int) drvVDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
     524{
     525    PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE);
    1003526    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    1004527
     
    1009532    pThis->FileDevice                   = NIL_RTFILE;
    1010533    pThis->pszDeviceName                = NULL;
    1011 #ifdef RT_OS_SOLARIS
    1012 # ifdef VBOX_WITH_CROSSBOW
    1013     pThis->pDeviceHandle                = NULL;
    1014 # else
    1015     pThis->IPFileDevice                 = NIL_RTFILE;
    1016 # endif
    1017     pThis->fStatic                      = true;
    1018 #endif
    1019     pThis->pszSetupApplication          = NULL;
    1020     pThis->pszTerminateApplication      = NULL;
     534    pThis->PipeRead                     = NIL_RTFILE;
     535    pThis->PipeWrite                    = NIL_RTFILE;
    1021536
    1022537    /* IBase */
    1023     pDrvIns->IBase.pfnQueryInterface    = drvTAPQueryInterface;
     538    pDrvIns->IBase.pfnQueryInterface    = drvVDEQueryInterface;
    1024539    /* INetwork */
    1025     pThis->INetworkUp.pfnBeginXmit              = drvTAPNetworkUp_BeginXmit;
    1026     pThis->INetworkUp.pfnAllocBuf               = drvTAPNetworkUp_AllocBuf;
    1027     pThis->INetworkUp.pfnFreeBuf                = drvTAPNetworkUp_FreeBuf;
    1028     pThis->INetworkUp.pfnSendBuf                = drvTAPNetworkUp_SendBuf;
    1029     pThis->INetworkUp.pfnEndXmit                = drvTAPNetworkUp_EndXmit;
    1030     pThis->INetworkUp.pfnSetPromiscuousMode     = drvTAPNetworkUp_SetPromiscuousMode;
    1031     pThis->INetworkUp.pfnNotifyLinkChanged      = drvTAPNetworkUp_NotifyLinkChanged;
     540    pThis->INetworkUp.pfnBeginXmit              = drvVDENetworkUp_BeginXmit;
     541    pThis->INetworkUp.pfnAllocBuf               = drvVDENetworkUp_AllocBuf;
     542    pThis->INetworkUp.pfnFreeBuf                = drvVDENetworkUp_FreeBuf;
     543    pThis->INetworkUp.pfnSendBuf                = drvVDENetworkUp_SendBuf;
     544    pThis->INetworkUp.pfnEndXmit                = drvVDENetworkUp_EndXmit;
     545    pThis->INetworkUp.pfnSetPromiscuousMode     = drvVDENetworkUp_SetPromiscuousMode;
     546    pThis->INetworkUp.pfnNotifyLinkChanged      = drvVDENetworkUp_NotifyLinkChanged;
    1032547
    1033548    /*
    1034549     * Validate the config.
    1035550     */
    1036     if (!CFGMR3AreValuesValid(pCfg, "Device\0InitProg\0TermProg\0FileHandle\0TAPSetupApplication\0TAPTerminateApplication\0MAC"))
     551    if (!CFGMR3AreValuesValid(pCfg, "Network"))
    1037552        return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES, "");
    1038553
     
    1056571     */
    1057572    int rc;
    1058 #if defined(RT_OS_SOLARIS)   /** @todo Other platforms' TAP code should be moved here from ConsoleImpl & VBoxBFE. */
    1059     rc = CFGMR3QueryStringAlloc(pCfg, "TAPSetupApplication", &pThis->pszSetupApplication);
    1060     if (RT_SUCCESS(rc))
    1061     {
    1062         if (!RTPathExists(pThis->pszSetupApplication))
    1063             return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    1064                                        N_("Invalid TAP setup program path: %s"), pThis->pszSetupApplication);
    1065     }
    1066     else if (rc != VERR_CFGM_VALUE_NOT_FOUND)
    1067         return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Configuration error: failed to query \"TAPTerminateApplication\""));
    1068 
    1069     rc = CFGMR3QueryStringAlloc(pCfg, "TAPTerminateApplication", &pThis->pszTerminateApplication);
    1070     if (RT_SUCCESS(rc))
    1071     {
    1072         if (!RTPathExists(pThis->pszTerminateApplication))
    1073             return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    1074                                        N_("Invalid TAP terminate program path: %s"), pThis->pszTerminateApplication);
    1075     }
    1076     else if (rc != VERR_CFGM_VALUE_NOT_FOUND)
    1077         return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Configuration error: failed to query \"TAPTerminateApplication\""));
    1078 
    1079 # ifdef VBOX_WITH_CROSSBOW
    1080     rc = CFGMR3QueryBytes(pCfg, "MAC", &pThis->MacAddress, sizeof(pThis->MacAddress));
     573    char szNetwork[RTPATH_MAX];
     574    rc = CFGMR3QueryString(pCfg, "Network", szNetwork, sizeof(szNetwork));
    1081575    if (RT_FAILURE(rc))
    1082         return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Configuration error: Failed to query \"MAC\""));
    1083 # endif
    1084 
    1085     rc = CFGMR3QueryStringAlloc(pCfg, "Device", &pThis->pszDeviceName);
    1086     if (RT_FAILURE(rc))
    1087         pThis->fStatic = false;
    1088 
    1089     /* Obtain the device name from the setup application (if none was specified). */
    1090     if (pThis->pszSetupApplication)
    1091     {
    1092         rc = drvTAPSetupApplication(pThis);
    1093         if (RT_FAILURE(rc))
    1094             return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    1095                                        N_("Error running TAP setup application. rc=%d"), rc);
    1096     }
     576        *szNetwork=0;
     577
     578    if (RT_FAILURE(DrvVDELoadVDEPlug()))
     579        return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
     580                                   N_("VDEplug library: not found"));
     581    pThis->vdeconn = vde_open(szNetwork, "VirtualBOX", NULL);
     582    if (pThis->vdeconn == NULL)
     583        return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
     584                                   N_("Failed to connect to the VDE SWITCH"));
    1097585
    1098586    /*
     
    1103591
    1104592    /*
    1105      * Do the setup.
    1106      */
    1107 # ifdef VBOX_WITH_CROSSBOW
    1108     if (!VBoxLibDlpiFound())
    1109     {
    1110         return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
    1111                                        N_("Failed to load library %s required for host interface networking."), LIB_DLPI);
    1112     }
    1113     rc = SolarisOpenVNIC(pThis);
    1114 # else
    1115     rc = SolarisTAPAttach(pThis);
    1116 # endif
    1117     if (RT_FAILURE(rc))
    1118         return rc;
    1119 
    1120 #else /* !RT_OS_SOLARIS */
    1121 
    1122     int32_t iFile;
    1123     rc = CFGMR3QueryS32(pCfg, "FileHandle", &iFile);
    1124     if (RT_FAILURE(rc))
    1125         return PDMDRV_SET_ERROR(pDrvIns, rc,
    1126                                 N_("Configuration error: Query for \"FileHandle\" 32-bit signed integer failed"));
    1127     pThis->FileDevice = (RTFILE)iFile;
    1128     if (!RTFileIsValid(pThis->FileDevice))
    1129         return PDMDrvHlpVMSetError(pDrvIns, VERR_INVALID_HANDLE, RT_SRC_POS,
    1130                                    N_("The TAP file handle %RTfile is not valid"), pThis->FileDevice);
    1131 #endif /* !RT_OS_SOLARIS */
    1132 
    1133     /*
    1134      * Make sure the descriptor is non-blocking and valid.
    1135      *
    1136      * We should actually query if it's a TAP device, but I haven't
    1137      * found any way to do that.
    1138      */
    1139     if (fcntl(pThis->FileDevice, F_SETFL, O_NONBLOCK) == -1)
    1140         return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
    1141                                    N_("Configuration error: Failed to configure /dev/net/tun. errno=%d"), errno);
    1142     /** @todo determine device name. This can be done by reading the link /proc/<pid>/fd/<fd> */
    1143     Log(("drvTAPContruct: %d (from fd)\n", pThis->FileDevice));
    1144     rc = VINF_SUCCESS;
    1145 
    1146     /*
    1147593     * Create the control pipe.
    1148594     */
    1149595    int fds[2];
    1150 #ifdef RT_OS_L4
    1151     /* XXX We need to tell the library which interface we are using */
    1152     fds[0] = vboxrtLinuxFd2VBoxFd(VBOXRT_FT_TAP, 0);
    1153 #endif
    1154596    if (pipe(&fds[0]) != 0) /** @todo RTPipeCreate() or something... */
    1155597    {
     
    1164606     * Create the async I/O thread.
    1165607     */
    1166     rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pThread, pThis, drvTAPAsyncIoThread, drvTapAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "TAP");
     608    rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pThread, pThis, drvVDEAsyncIoThread, drvVDEAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "VDE");
    1167609    AssertRCReturn(rc, rc);
    1168610
     
    1171613     * Statistics.
    1172614     */
    1173     PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktSent,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,        "Number of sent packets.",          "/Drivers/TAP%d/Packets/Sent", pDrvIns->iInstance);
    1174     PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktSentBytes,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,             "Number of sent bytes.",            "/Drivers/TAP%d/Bytes/Sent", pDrvIns->iInstance);
    1175     PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktRecv,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,        "Number of received packets.",      "/Drivers/TAP%d/Packets/Received", pDrvIns->iInstance);
    1176     PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktRecvBytes,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,             "Number of received bytes.",        "/Drivers/TAP%d/Bytes/Received", pDrvIns->iInstance);
    1177     PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatTransmit,      STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,    "Profiling packet transmit runs.",  "/Drivers/TAP%d/Transmit", pDrvIns->iInstance);
    1178     PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatReceive,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,    "Profiling packet receive runs.",   "/Drivers/TAP%d/Receive", pDrvIns->iInstance);
     615    PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktSent,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,        "Number of sent packets.",          "/Drivers/VDE%d/Packets/Sent", pDrvIns->iInstance);
     616    PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktSentBytes,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,             "Number of sent bytes.",            "/Drivers/VDE%d/Bytes/Sent", pDrvIns->iInstance);
     617    PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktRecv,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,        "Number of received packets.",      "/Drivers/VDE%d/Packets/Received", pDrvIns->iInstance);
     618    PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatPktRecvBytes,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,             "Number of received bytes.",        "/Drivers/VDE%d/Bytes/Received", pDrvIns->iInstance);
     619    PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatTransmit,      STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,    "Profiling packet transmit runs.",  "/Drivers/VDE%d/Transmit", pDrvIns->iInstance);
     620    PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatReceive,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,    "Profiling packet receive runs.",   "/Drivers/VDE%d/Receive", pDrvIns->iInstance);
    1179621#endif /* VBOX_WITH_STATISTICS */
    1180622
     
    1184626
    1185627/**
    1186  * TAP network transport driver registration record.
    1187  */
    1188 const PDMDRVREG g_DrvHostInterface =
     628 * VDE network transport driver registration record.
     629 */
     630const PDMDRVREG g_DrvVDE =
    1189631{
    1190632    /* u32Version */
    1191633    PDM_DRVREG_VERSION,
    1192634    /* szName */
    1193     "HostInterface",
     635    "VDE",
    1194636    /* szRCMod */
    1195637    "",
     
    1197639    "",
    1198640    /* pszDescription */
    1199     "TAP Network Transport Driver",
     641    "VDE Network Transport Driver",
    1200642    /* fFlags */
    1201643    PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
     
    1205647    ~0,
    1206648    /* cbInstance */
    1207     sizeof(DRVTAP),
     649    sizeof(DRVVDE),
    1208650    /* pfnConstruct */
    1209     drvTAPConstruct,
     651    drvVDEConstruct,
    1210652    /* pfnDestruct */
    1211     drvTAPDestruct,
     653    drvVDEDestruct,
    1212654    /* pfnRelocate */
    1213655    NULL,
  • trunk/src/VBox/Devices/Network/VDEPlug.cpp

    r28357 r28406  
    11/** @file
    22 *
    3  * Module to dynamically load libdbus and load all symbols
     3 * Module to dynamically load libvdeplug and load all symbols
    44 * which are needed by VirtualBox.
    55 */
    66
    77/*
    8  * Copyright (C) 2008 Sun Microsystems, Inc.
     8 * Copyright (C) 2008-2010 Sun Microsystems, Inc.
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3131
    3232#define LOG_GROUP RTLOGGROUP_LDR
    33 #include <VBox/dbus.h>
    34 
    3533/* Declarations of the functions that we need from libdbus-1 */
    36 #define VBOX_DBUS_GENERATE_BODY
    37 #include <VBox/dbus-calls.h>
     34#define VDEPLUG_GENERATE_BODY
     35#include "VDEPlugSymDefs.h"
  • trunk/src/VBox/Devices/Network/VDEPlug.h

    r28357 r28406  
    11/** @file
    22 *
    3  * Module to dynamically load libdbus and load all symbols
    4  * which are needed by VirtualBox.
     3 * Module to dynamically load libvdeplug and load all symbols
     4 * which are needed by VirtualBox - header file.
    55 */
    66
    77/*
    8  * Copyright (C) 2008 Sun Microsystems, Inc.
     8 * Copyright (C) 2008-2010 Sun Microsystems, Inc.
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3030 */
    3131
    32 #ifndef ___VBox_DBus_h
    33 #define ___VBox_DBus_h
     32#ifndef ___VBox_VDEPlug_h
     33#define ___VBox_VDEPlug_h
    3434
    35 #include <iprt/types.h>
    36 #include <iprt/stdarg.h>
     35#define LIBVDEPLUG_INTERFACE_VERSION 1
    3736
    38 /** Types and defines from the dbus header files which we need.  These are
    39  * taken more or less verbatim from the DBus public interface header files. */
    40 struct DBusError
    41 {
    42     const char *name;
    43     const char *message;
    44     unsigned int dummy1 : 1;
    45     unsigned int dummy2 : 1;
    46     unsigned int dummy3 : 1;
    47     unsigned int dummy4 : 1;
    48     unsigned int dummy5 : 1;
    49     void *padding1;
    50 };
    51 typedef struct DBusError DBusError;
     37#define vde_open(vde_switch, descr, open_args) \
     38    vde_open_real((vde_switch), (descr), LIBVDEPLUG_INTERFACE_VERSION, (open_args))
    5239
    53 struct DBusConnection;
    54 typedef struct DBusConnection DBusConnection;
     40/* Declarations of the functions that we need from the library */
     41#define VDEPLUG_GENERATE_HEADER
    5542
    56 typedef uint32_t dbus_bool_t;
    57 typedef uint32_t dbus_uint32_t;
    58 typedef enum { DBUS_BUS_SESSON, DBUS_BUS_SYSTEM, DBUS_BUS_STARTER } DBusBusType;
     43#include "VDEPlugSymDefs.h"
    5944
    60 struct DBusMessage;
    61 typedef struct DBusMessage DBusMessage;
     45#undef VDEPLUG_GENERATE_HEADER
    6246
    63 struct DBusMessageIter
    64 {
    65     void *dummy1;
    66     void *dummy2;
    67     dbus_uint32_t dummy3;
    68     int dummy4;
    69     int dummy5;
    70     int dummy6;
    71     int dummy7;
    72     int dummy8;
    73     int dummy9;
    74     int dummy10;
    75     int dummy11;
    76     int pad1;
    77     int pad2;
    78     void *pad3;
    79 };
    80 typedef struct DBusMessageIter DBusMessageIter;
    81 
    82 #define DBUS_ERROR_NO_MEMORY                "org.freedesktop.DBus.Error.NoMemory"
    83 
    84 /* Primitive types */
    85 #define DBUS_TYPE_INVALID                   ((int) '\0')
    86 #define DBUS_TYPE_INT32                     ((int) 'i')
    87 #define DBUS_TYPE_UINT32                    ((int) 'u')
    88 #define DBUS_TYPE_STRING                    ((int) 's')
    89 #define DBUS_TYPE_STRING_AS_STRING          "s"
    90 
    91 /* Compound types */
    92 #define DBUS_TYPE_ARRAY                     ((int) 'a')
    93 #define DBUS_TYPE_ARRAY_AS_STRING           "a"
    94 #define DBUS_TYPE_DICT_ENTRY                ((int) 'e')
    95 #define DBUS_TYPE_DICT_ENTRY_AS_STRING      "e"
    96 
    97 typedef enum
    98 {
    99   DBUS_HANDLER_RESULT_HANDLED,
    100   DBUS_HANDLER_RESULT_NOT_YET_HANDLED,
    101   DBUS_HANDLER_RESULT_NEED_MEMORY
    102 } DBusHandlerResult;
    103 
    104 typedef DBusHandlerResult (*DBusHandleMessageFunction) (DBusConnection *,
    105                                                         DBusMessage *, void *);
    106 typedef void (*DBusFreeFunction) (void *);
    107 
    108 /* Declarations of the functions that we need from libdbus-1 */
    109 #define VBOX_DBUS_GENERATE_HEADER
    110 
    111 #include <VBox/dbus-calls.h>
    112 
    113 #undef VBOX_DBUS_GENERATE_HEADER
    114 
    115 #endif /* ___VBox_DBus_h not defined */
     47#endif /* ___VBox_VDEPlug_h not defined */
    11648/* vi: set tabstop=4 shiftwidth=4 expandtab: */
    117 
  • trunk/src/VBox/Devices/Network/VDEPlugSymDefs.h

    r28357 r28406  
    11/** @file
    2  *
    3  * Stubs for dynamically loading libdbus-1 and the symbols
    4  * which are needed by VirtualBox.
     2 * Symbols from libvdeplug.so.2 to be loaded at runtime for DrvVDE.cpp
    53 */
    64
    75/*
    8  * Copyright (C) 2008 Sun Microsystems, Inc.
     6 * Copyright (C) 2008-2010 Sun Microsystems, Inc.
    97 *
    108 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3028 */
    3129
     30#include <stddef.h>
     31#include <sys/types.h>
     32/** Opaque connection type */
     33struct vdeconn;
     34typedef struct vdeconn VDECONN;
     35
     36/** Structure to be passed to the open function describing the connection.
     37 * All members can be left zero to use the default values. */
     38struct vde_open_args
     39{
     40    /** The port of the switch to connect to */
     41    int port;
     42    /** The group to set ownership of the port socket to */
     43    char *group;
     44    /** The file mode to set the port socket to */
     45    mode_t mode;
     46};
     47
    3248/** The file name of the DBus library */
    33 #define RT_RUNTIME_LOADER_LIB_NAME "libdbus-1.so.3"
     49#define RT_RUNTIME_LOADER_LIB_NAME "libvdeplug.so.2"
    3450
    3551/** The name of the loader function */
    36 #define RT_RUNTIME_LOADER_FUNCTION RTDBusLoadLib
     52#define RT_RUNTIME_LOADER_FUNCTION DrvVDELoadVDEPlug
    3753
    38 /** The following are the symbols which we need from the DBus library. */
     54/** The following are the symbols which we need from the library. */
    3955#define RT_RUNTIME_LOADER_INSERT_SYMBOLS \
    40  RT_PROXY_STUB(dbus_error_init, void, (DBusError *error), \
    41                  (error)) \
    42  RT_PROXY_STUB(dbus_error_is_set, dbus_bool_t, (const DBusError *error), \
    43                  (error)) \
    44  RT_PROXY_STUB(dbus_bus_get, DBusConnection *, \
    45                  (DBusBusType type, DBusError *error), (type, error)) \
    46  RT_PROXY_STUB(dbus_bus_get_private, DBusConnection *, \
    47                  (DBusBusType type, DBusError *error), (type, error)) \
    48  RT_PROXY_STUB(dbus_error_free, void, (DBusError *error), \
    49                  (error)) \
    50  RT_PROXY_STUB(dbus_connection_unref, void, (DBusConnection *connection), \
    51                  (connection)) \
    52  RT_PROXY_STUB(dbus_connection_close, void, (DBusConnection *connection), \
    53                  (connection)) \
    54  RT_PROXY_STUB(dbus_connection_send, dbus_bool_t, \
    55                  (DBusConnection *connection, DBusMessage *message, dbus_uint32_t *serial), \
    56                  (connection, message, serial)) \
    57  RT_PROXY_STUB(dbus_connection_flush, void, (DBusConnection *connection), \
    58                  (connection)) \
    59  RT_PROXY_STUB(dbus_connection_set_exit_on_disconnect, void, \
    60                  (DBusConnection *connection, dbus_bool_t boolean), \
    61                  (connection, boolean)) \
    62  RT_PROXY_STUB(dbus_bus_name_has_owner, dbus_bool_t, \
    63                  (DBusConnection *connection, const char *string, DBusError *error), \
    64                  (connection, string, error)) \
    65  RT_PROXY_STUB(dbus_bus_add_match, void, \
    66                  (DBusConnection *connection, const char *string, \
    67                   DBusError *error), \
    68                  (connection, string, error)) \
    69  RT_PROXY_STUB(dbus_bus_remove_match, void, \
    70                  (DBusConnection *connection, const char *string, \
    71                   DBusError *error), \
    72                  (connection, string, error)) \
    73  RT_PROXY_STUB(dbus_message_append_args_valist, dbus_bool_t, \
    74                  (DBusMessage *message, int first_arg_type, va_list var_args), \
    75                  (message, first_arg_type, var_args)) \
    76  RT_PROXY_STUB(dbus_message_iter_open_container, dbus_bool_t, \
    77                  (DBusMessageIter *iter, int type, const char *contained_signature, DBusMessageIter *sub), \
    78                  (iter, type, contained_signature, sub)) \
    79  RT_PROXY_STUB(dbus_message_iter_close_container, dbus_bool_t, \
    80                  (DBusMessageIter *iter, DBusMessageIter *sub), \
    81                  (iter, sub)) \
    82  RT_PROXY_STUB(dbus_message_iter_append_fixed_array, dbus_bool_t, \
    83                  (DBusMessageIter *iter, int element_type, const void *value, int n_elements), \
    84                  (iter, element_type, value, n_elements)) \
    85  RT_PROXY_STUB(dbus_message_unref, void, (DBusMessage *message), \
    86                  (message)) \
    87  RT_PROXY_STUB(dbus_message_new_method_call, DBusMessage*, \
    88                  (const char *string1, const char *string2, const char *string3, \
    89                   const char *string4), \
    90                  (string1, string2, string3, string4)) \
    91  RT_PROXY_STUB(dbus_message_iter_init_append, void, \
    92                  (DBusMessage *message, DBusMessageIter *iter), \
    93                  (message, iter)) \
    94  RT_PROXY_STUB(dbus_message_iter_append_basic, dbus_bool_t, \
    95                  (DBusMessageIter *iter, int val, const void *string), \
    96                  (iter, val, string)) \
    97  RT_PROXY_STUB(dbus_connection_send_with_reply_and_block, DBusMessage *, \
    98                  (DBusConnection *connection, DBusMessage *message, int val, \
    99                   DBusError *error), \
    100                  (connection, message, val, error)) \
    101  RT_PROXY_STUB(dbus_message_iter_init, dbus_bool_t, \
    102                  (DBusMessage *message, DBusMessageIter *iter), \
    103                  (message, iter)) \
    104  RT_PROXY_STUB(dbus_message_iter_get_arg_type, int, (DBusMessageIter *iter), \
    105                  (iter)) \
    106  RT_PROXY_STUB(dbus_message_iter_get_element_type, int, \
    107                  (DBusMessageIter *iter), (iter)) \
    108  RT_PROXY_STUB(dbus_message_iter_recurse, void, \
    109                  (DBusMessageIter *iter1, DBusMessageIter *iter2), \
    110                  (iter1, iter2)) \
    111  RT_PROXY_STUB(dbus_message_iter_get_basic, void, \
    112                  (DBusMessageIter *iter, void *pvoid), (iter, pvoid)) \
    113  RT_PROXY_STUB(dbus_message_iter_next, dbus_bool_t, (DBusMessageIter *iter), \
    114                  (iter)) \
    115  RT_PROXY_STUB(dbus_connection_add_filter, dbus_bool_t, \
    116                  (DBusConnection *connection, \
    117                   DBusHandleMessageFunction function1, void *pvoid, \
    118                   DBusFreeFunction function2), \
    119                  (connection, function1, pvoid, function2)) \
    120  RT_PROXY_STUB(dbus_connection_remove_filter, void, \
    121                  (DBusConnection *connection, \
    122                   DBusHandleMessageFunction function, void *pvoid), \
    123                  (connection, function, pvoid)) \
    124  RT_PROXY_STUB(dbus_connection_read_write_dispatch, dbus_bool_t, \
    125                  (DBusConnection *connection, int val), (connection, val)) \
    126  RT_PROXY_STUB(dbus_message_is_signal, dbus_bool_t, \
    127                  (DBusMessage *message, const char *string1, \
    128                   const char *string2), \
    129                  (message, string1, string2)) \
    130  RT_PROXY_STUB(dbus_connection_pop_message, DBusMessage *, \
    131                  (DBusConnection *connection), (connection))
     56 RT_PROXY_STUB(vde_open_real, VDECONN *, \
     57               (const char *vde_switch, const char *descr, int interface_version, struct vde_open_args *open_args), \
     58               (vde_switch, descr, interface_version, open_args)) \
     59 RT_PROXY_STUB(vde_recv, size_t, \
     60               (VDECONN *conn,void *buf,size_t len,int flags), \
     61               (conn, buf, len, flags)) \
     62 RT_PROXY_STUB(vde_send, size_t, \
     63               (VDECONN *conn,const void *buf,size_t len,int flags), \
     64               (conn, buf, len, flags)) \
     65 RT_PROXY_STUB(vde_datafd, int, (VDECONN *conn), (conn))
    13266
    133 #ifdef VBOX_DBUS_GENERATE_HEADER
     67#ifdef VDEPLUG_GENERATE_HEADER
    13468# define RT_RUNTIME_LOADER_GENERATE_HEADER
    13569# define RT_RUNTIME_LOADER_GENERATE_DECLS
     
    13771# undef RT_RUNTIME_LOADER_GENERATE_HEADER
    13872# undef RT_RUNTIME_LOADER_GENERATE_DECLS
    139 #elif defined (VBOX_DBUS_GENERATE_BODY)
     73#elif defined (VDEPLUG_GENERATE_BODY)
    14074# define RT_RUNTIME_LOADER_GENERATE_BODY_STUBS
    14175# include <iprt/runtime-loader.h>
     
    14377#else
    14478# error This file should only be included to generate stubs for loading the \
    145 DBus library at runtime
     79libvdeplug library at runtime
    14680#endif
    14781
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette