Changeset 28406 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Apr 16, 2010 10:45:18 AM (15 years ago)
- Location:
- trunk/src/VBox/Devices/Network
- Files:
-
- 4 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DrvVDE.cpp
r28315 r28406 1 1 /* $Id$ */ 2 2 /** @file 3 * DrvTAP - Universial TAPnetwork transport driver.3 * VDE network transport driver. 4 4 */ 5 5 6 6 /* 7 * Contributed by Renzo Davoli. VirtualSquare. University of Bologna, 2010 7 8 * Copyright (C) 2006-2010 Sun Microsystems, Inc. 8 9 * … … 34 35 #include <iprt/file.h> 35 36 #include <iprt/mem.h> 37 #include <iprt/param.h> 36 38 #include <iprt/path.h> 37 39 #include <iprt/semaphore.h> … … 39 41 #include <iprt/thread.h> 40 42 #include <iprt/uuid.h> 41 #ifdef RT_OS_SOLARIS42 # include <iprt/process.h>43 # include <iprt/env.h>44 # ifdef VBOX_WITH_CROSSBOW45 # include <iprt/mem.h>46 # endif47 #endif48 43 49 44 #include <sys/ioctl.h> 50 45 #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> 72 47 #include <errno.h> 73 48 #include <unistd.h> 74 49 75 #ifdef RT_OS_L476 # include <l4/vboxserver/file.h>77 #endif78 79 50 #include "Builtins.h" 51 #include "VDEPlug.h" 80 52 81 53 … … 84 56 *******************************************************************************/ 85 57 /** 86 * TAPdriver instance data.58 * VDE driver instance data. 87 59 * 88 60 * @implements PDMINETWORKUP 89 61 */ 90 typedef struct DRV TAP62 typedef struct DRVVDE 91 63 { 92 64 /** The network interface. */ … … 96 68 /** Pointer to the driver instance. */ 97 69 PPDMDRVINS pDrvIns; 98 /** TAPdevice file handle. */70 /** VDE device file handle. */ 99 71 RTFILE FileDevice; 100 /** The configured TAPdevice name. */72 /** The configured VDE device name. */ 101 73 char *pszDeviceName; 102 #ifdef RT_OS_SOLARIS103 # ifdef VBOX_WITH_CROSSBOW104 /** Crossbow: MAC address of the device. */105 RTMAC MacAddress;106 /** Crossbow: Handle of the NIC. */107 dlpi_handle_t pDeviceHandle;108 # else109 /** IP device file handle (/dev/udp). */110 RTFILE IPFileDevice;111 # endif112 /** Whether device name is obtained from setup application. */113 bool fStatic;114 #endif115 /** TAP setup application. */116 char *pszSetupApplication;117 /** TAP terminate application. */118 char *pszTerminateApplication;119 74 /** The write end of the control pipe. */ 120 75 RTFILE PipeWrite; … … 123 78 /** Reader thread. */ 124 79 PPDMTHREAD pThread; 80 /** The connection to the VDE switch */ 81 VDECONN *vdeconn; 125 82 126 83 /** @todo The transmit thread. */ … … 149 106 uint64_t u64LastReceiveTS; 150 107 #endif 151 } DRV TAP, *PDRVTAP;152 153 154 /** Converts a pointer to TAP::INetworkUp to a PRDVTAP. */155 #define PDMINETWORKUP_2_DRV TAP(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)) ) 156 113 157 114 … … 159 116 * Internal Functions * 160 117 *******************************************************************************/ 161 #ifdef RT_OS_SOLARIS162 # ifdef VBOX_WITH_CROSSBOW163 static int SolarisOpenVNIC(PDRVTAP pThis);164 static int SolarisDLPIErr2VBoxErr(int rc);165 # else166 static int SolarisTAPAttach(PDRVTAP pThis);167 # endif168 #endif169 118 170 119 … … 173 122 * @interface_method_impl{PDMINETWORKUP,pfnBeginXmit} 174 123 */ 175 static DECLCALLBACK(int) drv TAPNetworkUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread)176 { 177 PDRV TAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);124 static DECLCALLBACK(int) drvVDENetworkUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread) 125 { 126 PDRVVDE pThis = PDMINETWORKUP_2_DRVVDE(pInterface); 178 127 int rc = RTCritSectTryEnter(&pThis->XmitLock); 179 128 if (RT_FAILURE(rc)) … … 189 138 * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf} 190 139 */ 191 static DECLCALLBACK(int) drv TAPNetworkUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,140 static DECLCALLBACK(int) drvVDENetworkUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin, 192 141 PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf) 193 142 { 194 PDRV TAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);143 PDRVVDE pThis = PDMINETWORKUP_2_DRVVDE(pInterface); 195 144 Assert(RTCritSectIsOwner(&pThis->XmitLock)); 196 145 … … 235 184 * @interface_method_impl{PDMINETWORKUP,pfnFreeBuf} 236 185 */ 237 static DECLCALLBACK(int) drv TAPNetworkUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf)238 { 239 PDRV TAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);186 static DECLCALLBACK(int) drvVDENetworkUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf) 187 { 188 PDRVVDE pThis = PDMINETWORKUP_2_DRVVDE(pInterface); 240 189 Assert(RTCritSectIsOwner(&pThis->XmitLock)); 241 190 if (pSgBuf) … … 252 201 * @interface_method_impl{PDMINETWORKUP,pfnSendBuf} 253 202 */ 254 static DECLCALLBACK(int) drv TAPNetworkUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread)255 { 256 PDRV TAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);203 static DECLCALLBACK(int) drvVDENetworkUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread) 204 { 205 PDRVVDE pThis = PDMINETWORKUP_2_DRVVDE(pInterface); 257 206 STAM_COUNTER_INC(&pThis->StatPktSent); 258 207 STAM_COUNTER_ADD(&pThis->StatPktSentBytes, pSgBuf->cbUsed); … … 268 217 #ifdef LOG_ENABLED 269 218 uint64_t u64Now = RTTimeProgramNanoTS(); 270 LogFlow(("drv TAPSend: %-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", 271 220 pSgBuf->cbUsed, u64Now, u64Now - pThis->u64LastReceiveTS, u64Now - pThis->u64LastTransferTS)); 272 221 pThis->u64LastTransferTS = u64Now; 273 222 #endif 274 Log2(("drv TAPSend: pSgBuf->aSegs[0].pvSeg=%p pSgBuf->cbUsed=%#x\n"223 Log2(("drvVDESend: pSgBuf->aSegs[0].pvSeg=%p pSgBuf->cbUsed=%#x\n" 275 224 "%.*Rhxd\n", 276 225 pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, pSgBuf->cbUsed, pSgBuf->aSegs[0].pvSeg)); 277 226 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; 279 230 } 280 231 else … … 289 240 void *pvSegFrame = PDMNetGsoCarveSegmentQD(pGso, (uint8_t *)pbFrame, pSgBuf->cbUsed, abHdrScratch, 290 241 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; 292 245 if (RT_FAILURE(rc)) 293 246 break; … … 309 262 * @interface_method_impl{PDMINETWORKUP,pfnEndXmit} 310 263 */ 311 static DECLCALLBACK(void) drv TAPNetworkUp_EndXmit(PPDMINETWORKUP pInterface)312 { 313 PDRV TAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);264 static DECLCALLBACK(void) drvVDENetworkUp_EndXmit(PPDMINETWORKUP pInterface) 265 { 266 PDRVVDE pThis = PDMINETWORKUP_2_DRVVDE(pInterface); 314 267 RTCritSectLeave(&pThis->XmitLock); 315 268 } … … 319 272 * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode} 320 273 */ 321 static DECLCALLBACK(void) drv TAPNetworkUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)322 { 323 LogFlow(("drv TAPNetworkUp_SetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous));274 static DECLCALLBACK(void) drvVDENetworkUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous) 275 { 276 LogFlow(("drvVDESetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous)); 324 277 /* nothing to do */ 325 278 } … … 333 286 * @thread EMT 334 287 */ 335 static DECLCALLBACK(void) drv TAPNetworkUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)336 { 337 LogFlow(("drv TAPNetworkUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState));288 static DECLCALLBACK(void) drvVDENetworkUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState) 289 { 290 LogFlow(("drvNATNetworkUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState)); 338 291 /** @todo take action on link down and up. Stop the polling and such like. */ 339 292 } … … 345 298 * @returns VINF_SUCCESS (ignored). 346 299 * @param Thread Thread handle. 347 * @param pvUser Pointer to a DRV TAPstructure.348 */ 349 static DECLCALLBACK(int) drv TAPAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)350 { 351 PDRV TAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);352 LogFlow(("drv TAPAsyncIoThread: pThis=%p\n", pThis));300 * @param pvUser Pointer to a DRVVDE structure. 301 */ 302 static DECLCALLBACK(int) drvVDEAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 303 { 304 PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE); 305 LogFlow(("drvVDEAsyncIoThread: pThis=%p\n", pThis)); 353 306 354 307 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) … … 366 319 */ 367 320 struct pollfd aFDs[2]; 368 aFDs[0].fd = pThis->FileDevice;321 aFDs[0].fd = vde_datafd(pThis->vdeconn); 369 322 aFDs[0].events = POLLIN | POLLPRI; 370 323 aFDs[0].revents = 0; … … 389 342 */ 390 343 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; 402 347 if (RT_SUCCESS(rc)) 403 348 { … … 431 376 #ifdef LOG_ENABLED 432 377 uint64_t u64Now = RTTimeProgramNanoTS(); 433 LogFlow(("drv TAPAsyncIoThread: %-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", 434 379 cbRead, u64Now, u64Now - pThis->u64LastReceiveTS, u64Now - pThis->u64LastTransferTS)); 435 380 pThis->u64LastReceiveTS = u64Now; 436 381 #endif 437 Log2(("drv TAPAsyncIoThread: cbRead=%#x\n" "%.*Rhxd\n", cbRead, cbRead, achBuf));382 Log2(("drvVDEAsyncIoThread: cbRead=%#x\n" "%.*Rhxd\n", cbRead, cbRead, achBuf)); 438 383 STAM_COUNTER_INC(&pThis->StatPktRecv); 439 384 STAM_COUNTER_ADD(&pThis->StatPktRecvBytes, cbRead); … … 443 388 else 444 389 { 445 LogFlow(("drv TAPAsyncIoThread: RTFileRead -> %Rrc\n", rc));390 LogFlow(("drvVDEAsyncIoThread: RTFileRead -> %Rrc\n", rc)); 446 391 if (rc == VERR_INVALID_HANDLE) 447 392 break; … … 452 397 && aFDs[1].revents) 453 398 { 454 LogFlow(("drv TAPAsyncIoThread: 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)); 455 400 if (aFDs[1].revents & (POLLHUP | POLLERR | POLLNVAL)) 456 401 break; … … 478 423 479 424 480 LogFlow(("drv TAPAsyncIoThread: returns %Rrc\n", VINF_SUCCESS));425 LogFlow(("drvVDEAsyncIoThread: returns %Rrc\n", VINF_SUCCESS)); 481 426 STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a); 482 427 return VINF_SUCCESS; … … 491 436 * @param pThread The send thread. 492 437 */ 493 static DECLCALLBACK(int) drv TapAsyncIoWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)494 { 495 PDRV TAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);438 static DECLCALLBACK(int) drvVDEAsyncIoWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 439 { 440 PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE); 496 441 497 442 int rc = RTFileWrite(pThis->PipeWrite, "", 1, NULL); … … 502 447 503 448 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_CROSSBOW516 /* 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 #else532 RTStrPrintf(szCommand, sizeof(szCommand), "%s %s", pThis->pszSetupApplication,533 pThis->fStatic ? pThis->pszDeviceName : "");534 #endif535 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 the553 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 == 0602 && 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 else608 LogRel(("TAP#%d: RTProcWait failed for: %s\n", pThis->pDrvIns->iInstance, pThis->pszTerminateApplication));609 }610 else611 {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_SOLARIS623 # ifdef VBOX_WITH_CROSSBOW624 /**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 else670 rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,671 N_("Failed to set appropriate promiscous mode"));672 }673 else674 rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,675 N_("Failed to activate promiscous mode for VNIC"));676 }677 else678 rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,679 N_("Failed to set physical address for VNIC"));680 }681 else682 rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,683 N_("Failed to bind VNIC"));684 }685 else686 rc = PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,687 N_("VNIC type is not ethernet"));688 }689 else690 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 1738 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_ARP809 /* 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 #endif835 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_ARP845 close(ARPFileDes);846 #endif847 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_ARP853 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 #endif859 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_ARP866 ifReq.lifr_arp_muxid = ARPMuxID;867 #endif868 869 if (ioctl(IPFileDes, SIOCSLIFMUXID, &ifReq) == -1)870 {871 #ifdef VBOX_SOLARIS_TAP_ARP872 ioctl(IPFileDes, I_PUNLINK, ARPMuxID);873 #endif874 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 890 449 /* -=-=-=-=- PDMIBASE -=-=-=-=- */ 891 450 … … 893 452 * @interface_method_impl{PDMIBASE,pfnQueryInterface} 894 453 */ 895 static DECLCALLBACK(void *) drv TAPQueryInterface(PPDMIBASE pInterface, const char *pszIID)454 static DECLCALLBACK(void *) drvVDEQueryInterface(PPDMIBASE pInterface, const char *pszIID) 896 455 { 897 456 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface); 898 PDRV TAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);457 PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE); 899 458 900 459 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase); … … 913 472 * @param pDrvIns The driver instance data. 914 473 */ 915 static DECLCALLBACK(void) drv TAPDestruct(PPDMDRVINS pDrvIns)916 { 917 LogFlow(("drv TAPDestruct\n"));918 PDRV TAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);474 static DECLCALLBACK(void) drvVDEDestruct(PPDMDRVINS pDrvIns) 475 { 476 LogFlow(("drvVDEDestruct\n")); 477 PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE); 919 478 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns); 920 479 … … 935 494 } 936 495 937 #ifdef RT_OS_SOLARIS938 /** @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_CROSSBOW947 if (pThis->IPFileDevice != NIL_RTFILE)948 {949 int rc = RTFileClose(pThis->IPFileDevice);950 AssertRC(rc);951 pThis->IPFileDevice = NIL_RTFILE;952 }953 # endif954 955 /*956 * Call TerminateApplication after closing the device otherwise957 * 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_SOLARIS965 if (!pThis->fStatic)966 RTStrFree(pThis->pszDeviceName); /* allocated by drvTAPSetupApplication */967 else968 MMR3HeapFree(pThis->pszDeviceName);969 #else970 496 MMR3HeapFree(pThis->pszDeviceName); 971 #endif972 MMR3HeapFree(pThis->pszSetupApplication);973 MMR3HeapFree(pThis->pszTerminateApplication);974 497 975 498 /* … … 994 517 995 518 /** 996 * Construct a TAPnetwork transport driver instance.519 * Construct a VDE network transport driver instance. 997 520 * 998 521 * @copydoc FNPDMDRVCONSTRUCT 999 522 */ 1000 static DECLCALLBACK(int) drv TAPConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)1001 { 1002 PDRV TAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);523 static DECLCALLBACK(int) drvVDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) 524 { 525 PDRVVDE pThis = PDMINS_2_DATA(pDrvIns, PDRVVDE); 1003 526 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); 1004 527 … … 1009 532 pThis->FileDevice = NIL_RTFILE; 1010 533 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; 1021 536 1022 537 /* IBase */ 1023 pDrvIns->IBase.pfnQueryInterface = drv TAPQueryInterface;538 pDrvIns->IBase.pfnQueryInterface = drvVDEQueryInterface; 1024 539 /* INetwork */ 1025 pThis->INetworkUp.pfnBeginXmit = drv TAPNetworkUp_BeginXmit;1026 pThis->INetworkUp.pfnAllocBuf = drv TAPNetworkUp_AllocBuf;1027 pThis->INetworkUp.pfnFreeBuf = drv TAPNetworkUp_FreeBuf;1028 pThis->INetworkUp.pfnSendBuf = drv TAPNetworkUp_SendBuf;1029 pThis->INetworkUp.pfnEndXmit = drv TAPNetworkUp_EndXmit;1030 pThis->INetworkUp.pfnSetPromiscuousMode = drv TAPNetworkUp_SetPromiscuousMode;1031 pThis->INetworkUp.pfnNotifyLinkChanged = drv TAPNetworkUp_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; 1032 547 1033 548 /* 1034 549 * Validate the config. 1035 550 */ 1036 if (!CFGMR3AreValuesValid(pCfg, " Device\0InitProg\0TermProg\0FileHandle\0TAPSetupApplication\0TAPTerminateApplication\0MAC"))551 if (!CFGMR3AreValuesValid(pCfg, "Network")) 1037 552 return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES, ""); 1038 553 … … 1056 571 */ 1057 572 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)); 1081 575 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")); 1097 585 1098 586 /* … … 1103 591 1104 592 /* 1105 * Do the setup.1106 */1107 # ifdef VBOX_WITH_CROSSBOW1108 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 # else1115 rc = SolarisTAPAttach(pThis);1116 # endif1117 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't1137 * 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 /*1147 593 * Create the control pipe. 1148 594 */ 1149 595 int fds[2]; 1150 #ifdef RT_OS_L41151 /* XXX We need to tell the library which interface we are using */1152 fds[0] = vboxrtLinuxFd2VBoxFd(VBOXRT_FT_TAP, 0);1153 #endif1154 596 if (pipe(&fds[0]) != 0) /** @todo RTPipeCreate() or something... */ 1155 597 { … … 1164 606 * Create the async I/O thread. 1165 607 */ 1166 rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pThread, pThis, drv TAPAsyncIoThread, drvTapAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "TAP");608 rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pThread, pThis, drvVDEAsyncIoThread, drvVDEAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "VDE"); 1167 609 AssertRCReturn(rc, rc); 1168 610 … … 1171 613 * Statistics. 1172 614 */ 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); 1179 621 #endif /* VBOX_WITH_STATISTICS */ 1180 622 … … 1184 626 1185 627 /** 1186 * TAPnetwork transport driver registration record.1187 */ 1188 const PDMDRVREG g_Drv HostInterface=628 * VDE network transport driver registration record. 629 */ 630 const PDMDRVREG g_DrvVDE = 1189 631 { 1190 632 /* u32Version */ 1191 633 PDM_DRVREG_VERSION, 1192 634 /* szName */ 1193 " HostInterface",635 "VDE", 1194 636 /* szRCMod */ 1195 637 "", … … 1197 639 "", 1198 640 /* pszDescription */ 1199 " TAPNetwork Transport Driver",641 "VDE Network Transport Driver", 1200 642 /* fFlags */ 1201 643 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT, … … 1205 647 ~0, 1206 648 /* cbInstance */ 1207 sizeof(DRV TAP),649 sizeof(DRVVDE), 1208 650 /* pfnConstruct */ 1209 drv TAPConstruct,651 drvVDEConstruct, 1210 652 /* pfnDestruct */ 1211 drv TAPDestruct,653 drvVDEDestruct, 1212 654 /* pfnRelocate */ 1213 655 NULL, -
trunk/src/VBox/Devices/Network/VDEPlug.cpp
r28357 r28406 1 1 /** @file 2 2 * 3 * Module to dynamically load lib dbusand load all symbols3 * Module to dynamically load libvdeplug and load all symbols 4 4 * which are needed by VirtualBox. 5 5 */ 6 6 7 7 /* 8 * Copyright (C) 2008 Sun Microsystems, Inc.8 * Copyright (C) 2008-2010 Sun Microsystems, Inc. 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 31 31 32 32 #define LOG_GROUP RTLOGGROUP_LDR 33 #include <VBox/dbus.h>34 35 33 /* Declarations of the functions that we need from libdbus-1 */ 36 #define V BOX_DBUS_GENERATE_BODY37 #include <VBox/dbus-calls.h>34 #define VDEPLUG_GENERATE_BODY 35 #include "VDEPlugSymDefs.h" -
trunk/src/VBox/Devices/Network/VDEPlug.h
r28357 r28406 1 1 /** @file 2 2 * 3 * Module to dynamically load lib dbusand load all symbols4 * which are needed by VirtualBox .3 * Module to dynamically load libvdeplug and load all symbols 4 * which are needed by VirtualBox - header file. 5 5 */ 6 6 7 7 /* 8 * Copyright (C) 2008 Sun Microsystems, Inc.8 * Copyright (C) 2008-2010 Sun Microsystems, Inc. 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 30 30 */ 31 31 32 #ifndef ___VBox_ DBus_h33 #define ___VBox_ DBus_h32 #ifndef ___VBox_VDEPlug_h 33 #define ___VBox_VDEPlug_h 34 34 35 #include <iprt/types.h> 36 #include <iprt/stdarg.h> 35 #define LIBVDEPLUG_INTERFACE_VERSION 1 37 36 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)) 52 39 53 struct DBusConnection; 54 typedef struct DBusConnection DBusConnection; 40 /* Declarations of the functions that we need from the library */ 41 #define VDEPLUG_GENERATE_HEADER 55 42 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" 59 44 60 struct DBusMessage; 61 typedef struct DBusMessage DBusMessage; 45 #undef VDEPLUG_GENERATE_HEADER 62 46 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 */ 116 48 /* vi: set tabstop=4 shiftwidth=4 expandtab: */ 117 -
trunk/src/VBox/Devices/Network/VDEPlugSymDefs.h
r28357 r28406 1 1 /** @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 5 3 */ 6 4 7 5 /* 8 * Copyright (C) 2008 Sun Microsystems, Inc.6 * Copyright (C) 2008-2010 Sun Microsystems, Inc. 9 7 * 10 8 * This file is part of VirtualBox Open Source Edition (OSE), as … … 30 28 */ 31 29 30 #include <stddef.h> 31 #include <sys/types.h> 32 /** Opaque connection type */ 33 struct vdeconn; 34 typedef 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. */ 38 struct 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 32 48 /** The file name of the DBus library */ 33 #define RT_RUNTIME_LOADER_LIB_NAME "lib dbus-1.so.3"49 #define RT_RUNTIME_LOADER_LIB_NAME "libvdeplug.so.2" 34 50 35 51 /** The name of the loader function */ 36 #define RT_RUNTIME_LOADER_FUNCTION RTDBusLoadLib52 #define RT_RUNTIME_LOADER_FUNCTION DrvVDELoadVDEPlug 37 53 38 /** The following are the symbols which we need from the DBuslibrary. */54 /** The following are the symbols which we need from the library. */ 39 55 #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)) 132 66 133 #ifdef V BOX_DBUS_GENERATE_HEADER67 #ifdef VDEPLUG_GENERATE_HEADER 134 68 # define RT_RUNTIME_LOADER_GENERATE_HEADER 135 69 # define RT_RUNTIME_LOADER_GENERATE_DECLS … … 137 71 # undef RT_RUNTIME_LOADER_GENERATE_HEADER 138 72 # undef RT_RUNTIME_LOADER_GENERATE_DECLS 139 #elif defined (V BOX_DBUS_GENERATE_BODY)73 #elif defined (VDEPLUG_GENERATE_BODY) 140 74 # define RT_RUNTIME_LOADER_GENERATE_BODY_STUBS 141 75 # include <iprt/runtime-loader.h> … … 143 77 #else 144 78 # error This file should only be included to generate stubs for loading the \ 145 DBuslibrary at runtime79 libvdeplug library at runtime 146 80 #endif 147 81
Note:
See TracChangeset
for help on using the changeset viewer.