Changeset 26574 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Feb 16, 2010 12:44:10 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 57756
- Location:
- trunk/src/VBox/Devices/Network
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevE1000.cpp
r26408 r26574 4695 4695 //SSMR3GetBool(pSSM, pState->fIntMaskUsed); 4696 4696 SSMR3GetU16(pSSM, &pState->u16TxPktLen); 4697 SSMR3GetMem(pSSM, &pState->aTxPacket , pState->u16TxPktLen);4697 SSMR3GetMem(pSSM, &pState->aTxPacket[0], pState->u16TxPktLen); 4698 4698 SSMR3GetBool(pSSM, &pState->fIPcsum); 4699 4699 SSMR3GetBool(pSSM, &pState->fTCPcsum); -
trunk/src/VBox/Devices/Network/DrvIntNet.cpp
r26305 r26574 28 28 #include <VBox/cfgm.h> 29 29 #include <VBox/intnet.h> 30 #include <VBox/intnetinline.h> 30 31 #include <VBox/vmm.h> 31 32 #include <VBox/err.h> … … 35 36 #include <iprt/assert.h> 36 37 #include <iprt/ctype.h> 38 #include <iprt/memcache.h> 37 39 #include <iprt/net.h> 38 40 #include <iprt/semaphore.h> … … 89 91 RTTHREAD Thread; 90 92 /** Event semaphore the Thread waits on while the VM is suspended. */ 91 RTSEMEVENT EventSuspended; 93 RTSEMEVENT hEvtSuspended; 94 /** Scatter/gather descriptor cache. */ 95 RTMEMCACHE hSgCache; 92 96 /** Set if the link is down. 93 97 * When the link is down all incoming packets will be dropped. */ … … 127 131 /* -=-=-=-=- PDMINETWORKUP -=-=-=-=- */ 128 132 129 /** Converts a pointer to DRVINTNET::INetworkUpR3 to a PDRVINTNET. */130 #define PDMINETWORKUP_2_DRVINTNET(pInterface) \131 RT_FROM_MEMBER(pInterface, DRVINTNET, INetworkUpR3)132 133 133 134 /** … … 187 188 188 189 /** 189 * Writes a frame packet to the buffer. 190 * 191 * @returns VBox status code. 192 * @param pBuf The buffer. 193 * @param pRingBuf The ring buffer to read from. 194 * @param pvFrame The frame to write. 195 * @param cbFrame The size of the frame. 196 * @remark This is the same as INTNETRingWriteFrame 197 */ 198 static int drvR3IntNetRingWriteFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, const void *pvFrame, uint32_t cbFrame) 199 { 200 /* 201 * Validate input. 202 */ 203 Assert(pBuf); 204 Assert(pRingBuf); 205 Assert(pvFrame); 206 Assert(cbFrame >= sizeof(RTMAC) * 2); 207 uint32_t offWrite = pRingBuf->offWrite; 208 Assert(offWrite == RT_ALIGN_32(offWrite, sizeof(INTNETHDR))); 209 uint32_t offRead = pRingBuf->offRead; 210 Assert(offRead == RT_ALIGN_32(offRead, sizeof(INTNETHDR))); 211 212 const uint32_t cb = RT_ALIGN_32(cbFrame, sizeof(INTNETHDR)); 213 if (offRead <= offWrite) 214 { 215 /* 216 * Try fit it all before the end of the buffer. 217 */ 218 if (pRingBuf->offEnd - offWrite >= cb + sizeof(INTNETHDR)) 190 * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf} 191 */ 192 static DECLCALLBACK(int) drvR3IntNetUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin, PPPDMSCATTERGATHER ppSgBuf) 193 { 194 PDRVINTNET pThis = RT_FROM_MEMBER(pInterface, DRVINTNET, INetworkUpR3); 195 int rc = VINF_SUCCESS; 196 Assert(cbMin < UINT32_MAX / 2); 197 198 /* 199 * Allocate a S/G buffer. 200 */ 201 PPDMSCATTERGATHER pSgBuf = (PPDMSCATTERGATHER)RTMemCacheAlloc(pThis->hSgCache); 202 if (pSgBuf) 203 { 204 PINTNETHDR pHdr; 205 rc = INTNETRingAllocateFrame(&pThis->pBufR3->Send, (uint32_t)cbMin, 206 &pHdr, &pSgBuf->aSegs[0].pvSeg); 207 #if 1 /** @todo implement VERR_TRY_AGAIN once this moves to EMT. */ 208 if ( RT_FAILURE(rc) 209 && pThis->pBufR3->cbSend >= cbMin * 2 + sizeof(INTNETHDR)) 219 210 { 220 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 221 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 222 pHdr->cbFrame = cbFrame; 223 pHdr->offFrame = sizeof(INTNETHDR); 224 225 memcpy(pHdr + 1, pvFrame, cbFrame); 226 227 offWrite += cb + sizeof(INTNETHDR); 228 Assert(offWrite <= pRingBuf->offEnd && offWrite >= pRingBuf->offStart); 229 if (offWrite >= pRingBuf->offEnd) 230 offWrite = pRingBuf->offStart; 231 Log2(("WriteFrame: offWrite: %#x -> %#x (1)\n", pRingBuf->offWrite, offWrite)); 232 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite); 211 INTNETIFSENDREQ SendReq; 212 SendReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 213 SendReq.Hdr.cbReq = sizeof(SendReq); 214 SendReq.pSession = NIL_RTR0PTR; 215 SendReq.hIf = pThis->hIf; 216 PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, VMMR0_DO_INTNET_IF_SEND, &SendReq, sizeof(SendReq)); 217 218 rc = INTNETRingAllocateFrame(&pThis->pBufR3->Send, (uint32_t)cbMin, 219 &pHdr, &pSgBuf->aSegs[0].pvSeg); 220 } 221 #endif 222 if (RT_SUCCESS(rc)) 223 { 224 pSgBuf->fFlags = PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1; 225 pSgBuf->cbUsed = 0; 226 pSgBuf->cbAvailable = cbMin; 227 pSgBuf->pvUser = pHdr; 228 pSgBuf->cSegs = 1; 229 pSgBuf->aSegs[0].cbSeg = cbMin; 230 231 *ppSgBuf = pSgBuf; 233 232 return VINF_SUCCESS; 234 233 } 235 234 236 235 /* 237 * Try fit the frame at the start of the buffer. 238 * (The header fits before the end of the buffer because of alignment.) 236 * Arm the try again stuff. 239 237 */ 240 AssertMsg(pRingBuf->offEnd - offWrite >= sizeof(INTNETHDR), ("offEnd=%x offWrite=%x\n", pRingBuf->offEnd, offWrite)); 241 if (offRead - pRingBuf->offStart > cb) /* not >= ! */ 242 { 243 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 244 void *pvFrameOut = (PINTNETHDR)((uint8_t *)pBuf + pRingBuf->offStart); 245 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 246 pHdr->cbFrame = cbFrame; 247 pHdr->offFrame = (intptr_t)pvFrameOut - (intptr_t)pHdr; 248 249 memcpy(pvFrameOut, pvFrame, cbFrame); 250 251 offWrite = pRingBuf->offStart + cb; 252 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite); 253 Log2(("WriteFrame: offWrite: %#x -> %#x (2)\n", pRingBuf->offWrite, offWrite)); 254 return VINF_SUCCESS; 255 } 256 } 257 /* 258 * The reader is ahead of the writer, try fit it into that space. 259 */ 260 else if (offRead - offWrite > cb + sizeof(INTNETHDR)) /* not >= ! */ 261 { 262 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 263 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 264 pHdr->cbFrame = cbFrame; 265 pHdr->offFrame = sizeof(INTNETHDR); 266 267 memcpy(pHdr + 1, pvFrame, cbFrame); 268 269 offWrite += cb + sizeof(INTNETHDR); 270 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite); 271 Log2(("WriteFrame: offWrite: %#x -> %#x (3)\n", pRingBuf->offWrite, offWrite)); 272 return VINF_SUCCESS; 273 } 274 275 /* (it didn't fit) */ 276 /** @todo stats */ 277 return VERR_BUFFER_OVERFLOW; 278 } 279 238 /** @todo if (pThis->pBufR3->cbSend >= cbMin * 2 + sizeof(INTNETHDR)) 239 rc = VERR_TRY_AGAIN; 240 else */ 241 rc = VERR_NO_MEMORY; 242 243 RTMemCacheFree(pThis->hSgCache, pSgBuf); 244 } 245 else 246 rc = VERR_NO_MEMORY; 247 /** @todo implement VERR_TRY_AGAIN */ 248 return rc; 249 } 250 251 /** 252 * @interface_method_impl{PDMINETWORKUP,pfnSendBuf} 253 */ 254 static DECLCALLBACK(int) drvR3IntNetUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread) 255 { 256 return VERR_NOT_IMPLEMENTED; 257 } 280 258 281 259 /** 282 260 * @interface_method_impl{PDMINETWORKUP,pfnSendDeprecated} 283 261 */ 284 static DECLCALLBACK(int) drvR3IntNet SendDeprecated(PPDMINETWORKUP pInterface, const void *pvBuf, size_t cb)285 { 286 PDRVINTNET pThis = PDMINETWORKUP_2_DRVINTNET(pInterface);262 static DECLCALLBACK(int) drvR3IntNetUp_SendDeprecated(PPDMINETWORKUP pInterface, const void *pvBuf, size_t cb) 263 { 264 PDRVINTNET pThis = RT_FROM_MEMBER(pInterface, DRVINTNET, INetworkUpR3); 287 265 STAM_PROFILE_START(&pThis->StatTransmit, a); 288 266 … … 300 278 * Add the frame to the send buffer and push it onto the network. 301 279 */ 302 int rc = drvR3IntNetRingWriteFrame(pThis->pBufR3,&pThis->pBufR3->Send, pvBuf, (uint32_t)cb);280 int rc = INTNETRingWriteFrame(&pThis->pBufR3->Send, pvBuf, (uint32_t)cb); 303 281 if ( rc == VERR_BUFFER_OVERFLOW 304 282 && pThis->pBufR3->cbSend < cb) … … 311 289 PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, VMMR0_DO_INTNET_IF_SEND, &SendReq, sizeof(SendReq)); 312 290 313 rc = drvR3IntNetRingWriteFrame(pThis->pBufR3,&pThis->pBufR3->Send, pvBuf, (uint32_t)cb);291 rc = INTNETRingWriteFrame(&pThis->pBufR3->Send, pvBuf, (uint32_t)cb); 314 292 } 315 293 … … 333 311 * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode} 334 312 */ 335 static DECLCALLBACK(void) drvR3IntNet SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)336 { 337 PDRVINTNET pThis = PDMINETWORKUP_2_DRVINTNET(pInterface);313 static DECLCALLBACK(void) drvR3IntNetUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous) 314 { 315 PDRVINTNET pThis = RT_FROM_MEMBER(pInterface, DRVINTNET, INetworkUpR3); 338 316 INTNETIFSETPROMISCUOUSMODEREQ Req; 339 317 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; … … 343 321 Req.fPromiscuous = fPromiscuous; 344 322 int rc = PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE, &Req, sizeof(Req)); 345 LogFlow(("drvR3IntNet SetPromiscuousMode: fPromiscuous=%RTbool\n", fPromiscuous));323 LogFlow(("drvR3IntNetUp_SetPromiscuousMode: fPromiscuous=%RTbool\n", fPromiscuous)); 346 324 AssertRC(rc); 347 325 } … … 351 329 * @interface_method_impl{PDMINETWORKUP,pfnNotifyLinkChanged} 352 330 */ 353 static DECLCALLBACK(void) drvR3IntNet NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)354 { 355 PDRVINTNET pThis = PDMINETWORKUP_2_DRVINTNET(pInterface);331 static DECLCALLBACK(void) drvR3IntNetUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState) 332 { 333 PDRVINTNET pThis = RT_FROM_MEMBER(pInterface, DRVINTNET, INetworkUpR3); 356 334 bool fLinkDown; 357 335 switch (enmLinkState) … … 367 345 break; 368 346 } 369 LogFlow(("drvR3IntNet NotifyLinkChanged: enmLinkState=%d %d->%d\n", enmLinkState, pThis->fLinkDown, fLinkDown));347 LogFlow(("drvR3IntNetUp_NotifyLinkChanged: enmLinkState=%d %d->%d\n", enmLinkState, pThis->fLinkDown, fLinkDown)); 370 348 ASMAtomicXchgSize(&pThis->fLinkDown, fLinkDown); 371 349 } … … 414 392 * Process the receive buffer. 415 393 */ 416 while (INTNETRingGetReadable(pRingBuf) > 0) 394 PINTNETHDR pHdr; 395 while ((pHdr = INTNETRingGetNextFrameToRead(pRingBuf)) != NULL) 417 396 { 418 397 /* … … 426 405 } 427 406 428 PINTNETHDR pHdr = (PINTNETHDR)((uintptr_t)pBuf + pRingBuf->offRead); 429 Log2(("pHdr=%p offRead=%#x: %.8Rhxs\n", pHdr, pRingBuf->offRead, pHdr)); 407 Log2(("pHdr=%p offRead=%#x: %.8Rhxs\n", pHdr, pRingBuf->offReadX, pHdr)); 430 408 if ( pHdr->u16Type == INTNETHDR_TYPE_FRAME 431 409 && !pThis->fLinkDown) … … 451 429 452 430 /* skip to the next frame. */ 453 INTNETRingSkipFrame(p Buf, pRingBuf);431 INTNETRingSkipFrame(pRingBuf); 454 432 } 455 433 else … … 467 445 */ 468 446 AssertMsg(pHdr->u16Type == INTNETHDR_TYPE_FRAME, ("Unknown frame type %RX16! offRead=%#x\n", 469 pHdr->u16Type, pRingBuf->offRead ));470 INTNETRingSkipFrame(p Buf, pRingBuf);447 pHdr->u16Type, pRingBuf->offReadX)); 448 INTNETRingSkipFrame(pRingBuf); 471 449 } 472 450 else … … 485 463 */ 486 464 AssertMsg(pHdr->u16Type == INTNETHDR_TYPE_FRAME, ("Unknown frame type %RX16! offRead=%#x\n", 487 pHdr->u16Type, pRingBuf->offRead)); 488 INTNETRingSkipFrame(pBuf, pRingBuf); 465 pHdr->u16Type, pRingBuf->offReadX)); 466 INTNETRingSkipFrame(pRingBuf); 467 STAM_REL_COUNTER_INC(&pBuf->cStatBadFrames); 489 468 } 490 469 } /* while more received data */ … … 542 521 case ASYNCSTATE_SUSPENDED: 543 522 { 544 int rc = RTSemEventWait(pThis-> EventSuspended, 30000);523 int rc = RTSemEventWait(pThis->hEvtSuspended, 30000); 545 524 if ( RT_FAILURE(rc) 546 525 && rc != VERR_TIMEOUT) … … 647 626 { 648 627 ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_RUNNING); 649 RTSemEventSignal(pThis-> EventSuspended);628 RTSemEventSignal(pThis->hEvtSuspended); 650 629 drvR3IntNetUpdateMacAddress(pThis); /* (could be a state restore) */ 651 630 drvR3IntNetSetActive(pThis, true /* fActive */); … … 673 652 int rc = pThis->pIAboveConfigR3->pfnGetMac(pThis->pIAboveConfigR3, &Frame.Hdr.SrcMac); 674 653 if (RT_SUCCESS(rc)) 675 rc = drvR3IntNet SendDeprecated(&pThis->INetworkUpR3, &Frame, sizeof(Frame));654 rc = drvR3IntNetUp_SendDeprecated(&pThis->INetworkUpR3, &Frame, sizeof(Frame)); 676 655 if (RT_FAILURE(rc)) 677 656 LogRel(("IntNet#%u: Sending dummy frame failed: %Rrc\n", pDrvIns->iInstance, rc)); … … 709 688 { 710 689 ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_RUNNING); 711 RTSemEventSignal(pThis-> EventSuspended);690 RTSemEventSignal(pThis->hEvtSuspended); 712 691 drvR3IntNetUpdateMacAddress(pThis); 713 692 drvR3IntNetSetActive(pThis, true /* fActive */); … … 735 714 ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_TERMINATE); 736 715 ASMAtomicXchgSize(&pThis->fLinkDown, true); 737 RTSEMEVENT EventSuspended = pThis->EventSuspended;738 pThis-> EventSuspended = NIL_RTSEMEVENT;716 RTSEMEVENT hEvtSuspended = pThis->hEvtSuspended; 717 pThis->hEvtSuspended = NIL_RTSEMEVENT; 739 718 740 719 /* … … 758 737 if (pThis->Thread != NIL_RTTHREAD) 759 738 { 760 if ( EventSuspended != NIL_RTSEMEVENT)761 RTSemEventSignal( EventSuspended);739 if (hEvtSuspended != NIL_RTSEMEVENT) 740 RTSemEventSignal(hEvtSuspended); 762 741 int rc = RTThreadWait(pThis->Thread, 5000, NULL); 763 742 AssertRC(rc); … … 766 745 767 746 /* 768 * Destroy the semaphores. 769 */ 770 if (EventSuspended != NIL_RTSEMEVENT) 771 RTSemEventDestroy(EventSuspended); 747 * Destroy the semaphore and S/G cache. 748 */ 749 if (hEvtSuspended != NIL_RTSEMEVENT) 750 RTSemEventDestroy(hEvtSuspended); 751 752 RTMemCacheDestroy(pThis->hSgCache); 753 pThis->hSgCache = NIL_RTMEMCACHE; 772 754 773 755 /* 774 756 * Deregister statistics in case we're being detached. 775 757 */ 776 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->cbStatRecv); 777 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->cbStatSend); 778 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->cStatRecvs); 779 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->cStatSends); 758 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->Recv.cStatFrames); 759 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->Recv.cbStatWritten); 760 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->Recv.cOverflows); 761 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->Send.cStatFrames); 762 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->Send.cbStatWritten); 763 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->Send.cOverflows); 764 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->cStatYieldsOk); 765 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->cStatYieldsNok); 780 766 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->cStatLost); 781 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->cStat YieldsNok);767 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->pBufR3->cStatBadFrames); 782 768 #ifdef VBOX_WITH_STATISTICS 783 769 PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->StatReceive); … … 804 790 pThis->hIf = INTNET_HANDLE_INVALID; 805 791 pThis->Thread = NIL_RTTHREAD; 806 pThis->EventSuspended = NIL_RTSEMEVENT; 792 pThis->hEvtSuspended = NIL_RTSEMEVENT; 793 pThis->hSgCache = NIL_RTMEMCACHE; 807 794 pThis->enmState = ASYNCSTATE_SUSPENDED; 808 795 pThis->fActivateEarlyDeactivateLate = false; … … 812 799 pThis->IBaseRC.pfnQueryInterface = drvR3IntNetIBaseRC_QueryInterface; 813 800 /* INetworkUp */ 814 pThis->INetworkUpR3.pfnSendDeprecated = drvR3IntNetSendDeprecated; 815 pThis->INetworkUpR3.pfnSetPromiscuousMode = drvR3IntNetSetPromiscuousMode; 816 pThis->INetworkUpR3.pfnNotifyLinkChanged = drvR3IntNetNotifyLinkChanged; 801 pThis->INetworkUpR3.pfnAllocBuf = drvR3IntNetUp_AllocBuf; 802 pThis->INetworkUpR3.pfnSendBuf = drvR3IntNetUp_SendBuf; 803 pThis->INetworkUpR3.pfnSendDeprecated = drvR3IntNetUp_SendDeprecated; 804 pThis->INetworkUpR3.pfnSetPromiscuousMode = drvR3IntNetUp_SetPromiscuousMode; 805 pThis->INetworkUpR3.pfnNotifyLinkChanged = drvR3IntNetUp_NotifyLinkChanged; 817 806 818 807 /* … … 1079 1068 1080 1069 /* 1081 * Create the event semaphores 1082 */ 1083 rc = RTSemEventCreate(&pThis->EventSuspended); 1070 * Create the event semaphore and S/G cache. 1071 */ 1072 rc = RTSemEventCreate(&pThis->hEvtSuspended); 1073 if (RT_FAILURE(rc)) 1074 return rc; 1075 rc = RTMemCacheCreate(&pThis->hSgCache, sizeof(PDMSCATTERGATHER), 0, UINT32_MAX, NULL, NULL, pThis, 0); 1084 1076 if (RT_FAILURE(rc)) 1085 1077 return rc; … … 1123 1115 return rc; 1124 1116 } 1125 1126 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->cbStatRecv, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Number of received bytes.", "/Net/IntNet%d/Bytes/Received", pDrvIns->iInstance); 1127 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->cbStatSend, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Number of sent bytes.", "/Net/IntNet%d/Bytes/Sent", pDrvIns->iInstance); 1128 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->cStatRecvs, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of received packets.", "/Net/IntNet%d/Packets/Received", pDrvIns->iInstance); 1129 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->cStatSends, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of sent packets.", "/Net/IntNet%d/Packets/Sent", pDrvIns->iInstance); 1130 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->cStatLost, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of lost packets.", "/Net/IntNet%d/Packets/Lost", pDrvIns->iInstance); 1131 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->cStatYieldsNok, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of times yielding didn't help fix an overflow.", "/Net/IntNet%d/YieldNok", pDrvIns->iInstance); 1117 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->Recv.cbStatWritten, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Number of received bytes.", "/Net/IntNet%d/Bytes/Received", pDrvIns->iInstance); 1118 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->Send.cbStatWritten, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Number of sent bytes.", "/Net/IntNet%d/Bytes/Sent", pDrvIns->iInstance); 1119 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->Recv.cOverflows, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number overflows.", "/Net/IntNet%d/Overflows/Recv", pDrvIns->iInstance); 1120 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->Send.cOverflows, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number overflows.", "/Net/IntNet%d/Overflows/Sent", pDrvIns->iInstance); 1121 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->Recv.cStatFrames, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of received packets.", "/Net/IntNet%d/Packets/Received", pDrvIns->iInstance); 1122 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->Send.cStatFrames, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of sent packets.", "/Net/IntNet%d/Packets/Sent", pDrvIns->iInstance); 1123 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->cStatLost, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of lost packets.", "/Net/IntNet%d/Packets/Lost", pDrvIns->iInstance); 1124 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->cStatYieldsNok, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of times yielding helped fix an overflow.", "/Net/IntNet%d/YieldOk", pDrvIns->iInstance); 1125 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->cStatYieldsOk, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of times yielding didn't help fix an overflow.", "/Net/IntNet%d/YieldNok", pDrvIns->iInstance); 1126 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->pBufR3->cStatBadFrames, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of bad frames seed by the consumers.", "/Net/IntNet%d/BadFrames", pDrvIns->iInstance); 1132 1127 #ifdef VBOX_WITH_STATISTICS 1133 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatReceive, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling packet receive runs.", "/Net/IntNet%d/Receive", pDrvIns->iInstance);1134 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatTransmit, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling packet transmit runs.", "/Net/IntNet%d/Transmit", pDrvIns->iInstance);1128 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatReceive, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling packet receive runs.", "/Net/IntNet%d/Receive", pDrvIns->iInstance); 1129 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatTransmit, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling packet transmit runs.", "/Net/IntNet%d/Transmit", pDrvIns->iInstance); 1135 1130 #endif 1136 1131 … … 1141 1136 { 1142 1137 ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_RUNNING); 1143 RTSemEventSignal(pThis-> EventSuspended);1138 RTSemEventSignal(pThis->hEvtSuspended); 1144 1139 drvR3IntNetUpdateMacAddress(pThis); 1145 1140 drvR3IntNetSetActive(pThis, true /* fActive */); -
trunk/src/VBox/Devices/Network/DrvNAT.cpp
r26495 r26574 217 217 218 218 219 /** Converts a pointer to NAT::INetworkUp to a PRDVNAT. */220 #define PDMINETWORKUP_2_DRVNAT(pInterface) ( (PDRVNAT)((uintptr_t)pInterface - RT_OFFSETOF(DRVNAT, INetworkUp)) )221 219 222 220 static DECLCALLBACK(void) drvNATSlowTimer(PPDMDRVINS pDrvIns, PTMTIMER pTimer, void *pvUser) … … 280 278 return VINF_SUCCESS; 281 279 } 280 282 281 static DECLCALLBACK(int) drvNATUrgRecvWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 283 282 { … … 289 288 } 290 289 291 static DECLCALLBACK(void) drvNATUrgRecvWorker(PDRVNAT pThis, uint8_t *pu8Buf, int cb, void *pvArg)290 static DECLCALLBACK(void) drvNATUrgRecvWorker(PDRVNAT pThis, uint8_t *pu8Buf, int cb, struct mbuf *m) 292 291 { 293 292 int rc = RTCritSectEnter(&pThis->csDevAccess); … … 309 308 AssertRC(rc); 310 309 311 slirp_ext_m_free(pThis->pNATState, pvArg);310 slirp_ext_m_free(pThis->pNATState, m); 312 311 #ifdef VBOX_WITH_SLIRP_BSD_MBUF 313 312 RTMemFree(pu8Buf); … … 321 320 322 321 323 static DECLCALLBACK(void) drvNATRecvWorker(PDRVNAT pThis, uint8_t *pu8Buf, int cb, void *pvArg)322 static DECLCALLBACK(void) drvNATRecvWorker(PDRVNAT pThis, uint8_t *pu8Buf, int cb, struct mbuf *m) 324 323 { 325 324 int rc; … … 357 356 358 357 done_unlocked: 359 slirp_ext_m_free(pThis->pNATState, pvArg);358 slirp_ext_m_free(pThis->pNATState, m); 360 359 #ifdef VBOX_WITH_SLIRP_BSD_MBUF 361 360 RTMemFree(pu8Buf); … … 370 369 371 370 /** 371 * Frees a S/G buffer allocated by drvNATNetworkUp_AllocBuf. 372 * 373 * @param pThis Pointer to the NAT instance. 374 * @param pSgBuf The S/G buffer to free. 375 */ 376 static void drvNATFreeSgBuf(PDRVNAT pThis, PPDMSCATTERGATHER pSgBuf) 377 { 378 Assert((pSgBuf->fFlags & PDMSCATTERGATHER_FLAGS_MAGIC_MASK) == PDMSCATTERGATHER_FLAGS_MAGIC); 379 pSgBuf->fFlags = 0; 380 if (pSgBuf->pvAllocator) 381 { 382 slirp_ext_m_free(pThis->pNATState, (struct mbuf *)pSgBuf->pvAllocator); 383 pSgBuf->pvAllocator = NULL; 384 } 385 RTMemFree(pSgBuf); 386 } 387 388 /** 372 389 * Worker function for drvNATSend(). 373 * @thread "NAT" thread. 374 */ 375 static void drvNATSendWorker(PDRVNAT pThis, void *pvBuf, size_t cb) 390 * 391 * @param pThis Pointer to the NAT instance. 392 * @param pSgBuf The scatter/gather buffer. 393 * @thread NAT 394 */ 395 static void drvNATSendWorker(PDRVNAT pThis, PPDMSCATTERGATHER pSgBuf) 376 396 { 377 397 Assert(pThis->enmLinkState == PDMNETWORKLINKSTATE_UP); 378 398 if (pThis->enmLinkState == PDMNETWORKLINKSTATE_UP) 379 slirp_input(pThis->pNATState, (uint8_t *)pvBuf); 380 } 381 399 { 400 struct mbuf *m = (struct mbuf *)pSgBuf->pvAllocator; 401 pSgBuf->pvAllocator = NULL; 402 slirp_input(pThis->pNATState, m, pSgBuf->cbUsed); 403 } 404 drvNATFreeSgBuf(pThis, pSgBuf); 405 406 /** @todo Implement the VERR_TRY_AGAIN drvNATNetworkUp_AllocBuf sematics. */ 407 } 408 409 /** 410 * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf} 411 */ 412 static DECLCALLBACK(int) drvNATNetworkUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin, PPPDMSCATTERGATHER ppSgBuf) 413 { 414 PDRVNAT pThis = RT_FROM_MEMBER(pInterface, DRVNAT, INetworkUp); 415 416 /* 417 * Drop the incoming frame if the NAT thread isn't running. 418 */ 419 if (pThis->pSlirpThread->enmState != PDMTHREADSTATE_RUNNING) 420 { 421 Log(("drvNATNetowrkUp_AllocBuf: returns VERR_NET_NO_NETWORK\n")); 422 return VERR_NET_NO_NETWORK; 423 } 424 425 /* 426 * Allocate a scatter/gather buffer and an mbuf. 427 */ 428 PPDMSCATTERGATHER pSgBuf = (PPDMSCATTERGATHER)RTMemAlloc(sizeof(*pSgBuf)); 429 if (!pSgBuf) 430 return VERR_NO_MEMORY; 431 pSgBuf->pvAllocator = slirp_ext_m_get(pThis->pNATState, cbMin, 432 &pSgBuf->aSegs[0].pvSeg, &pSgBuf->aSegs[0].cbSeg); 433 if (!pSgBuf->pvAllocator) 434 { 435 RTMemFree(pSgBuf); 436 /** @todo Implement the VERR_TRY_AGAIN sematics. */ 437 return VERR_NO_MEMORY; 438 } 439 440 /* 441 * Initialize the S/G buffer and return. 442 */ 443 pSgBuf->fFlags = PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1; 444 pSgBuf->cbUsed = 0; 445 pSgBuf->cbAvailable = pSgBuf->aSegs[0].cbSeg; 446 pSgBuf->pvUser = NULL; 447 pSgBuf->cSegs = 1; 448 449 *ppSgBuf = pSgBuf; 450 return VINF_SUCCESS; 451 } 452 453 /** 454 * @interface_method_impl{PDMINETWORKUP,pfnSendBuf} 455 */ 456 static DECLCALLBACK(int) drvNATNetworkUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread) 457 { 458 PDRVNAT pThis = RT_FROM_MEMBER(pInterface, DRVNAT, INetworkUp); 459 Assert((pSgBuf->fFlags & PDMSCATTERGATHER_FLAGS_OWNER_MASK) == PDMSCATTERGATHER_FLAGS_OWNER_1); 460 461 int rc; 462 if (pThis->pSlirpThread->enmState == PDMTHREADSTATE_RUNNING) 463 { 464 #ifdef VBOX_WITH_SLIRP_MT 465 PRTREQQUEUE pQueue = (PRTREQQUEUE)slirp_get_queue(pThis->pNATState); 466 #else 467 PRTREQQUEUE pQueue = pThis->pSlirpReqQueue; 468 #endif 469 rc = RTReqCallEx(pQueue, NULL /*ppReq*/, 0 /*cMillies*/, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT, 470 (PFNRT)drvNATSendWorker, 2, pThis, pSgBuf); 471 if (RT_SUCCESS(rc)) 472 { 473 drvNATNotifyNATThread(pThis); 474 return VINF_SUCCESS; 475 } 476 477 rc = VERR_NET_NO_BUFFER_SPACE; 478 } 479 else 480 rc = VERR_NET_DOWN; 481 drvNATFreeSgBuf(pThis, pSgBuf); 482 return rc; 483 } 382 484 383 485 /** 384 486 * @interface_method_impl{PDMINETWORKUP,pfnSendDeprecated} 385 487 */ 386 static DECLCALLBACK(int) drvNATSendDeprecated(PPDMINETWORKUP pInterface, const void *pvBuf, size_t cb) 387 { 388 PDRVNAT pThis = PDMINETWORKUP_2_DRVNAT(pInterface); 389 390 LogFlow(("drvNATSend: pvBuf=%p cb=%#x\n", pvBuf, cb)); 391 Log2(("drvNATSend: pvBuf=%p cb=%#x\n%.*Rhxd\n", pvBuf, cb, cb, pvBuf)); 392 393 PRTREQ pReq = NULL; 394 int rc; 395 void *buf; 396 397 /* don't queue new requests when the NAT thread is about to stop */ 398 if (pThis->pSlirpThread->enmState != PDMTHREADSTATE_RUNNING) 399 return VINF_SUCCESS; 400 401 #ifndef VBOX_WITH_SLIRP_MT 402 rc = RTReqAlloc(pThis->pSlirpReqQueue, &pReq, RTREQTYPE_INTERNAL); 403 #else 404 rc = RTReqAlloc((PRTREQQUEUE)slirp_get_queue(pThis->pNATState), &pReq, RTREQTYPE_INTERNAL); 405 #endif 406 AssertRC(rc); 407 408 /* @todo: Here we should get mbuf instead temporal buffer */ 409 #ifndef VBOX_WITH_SLIRP_BSD_MBUF 410 void *pvmBuf = slirp_ext_m_get(pThis->pNATState); 411 Assert(pvmBuf); 412 slirp_ext_m_append(pThis->pNATState, pvmBuf, (uint8_t *)pvBuf, cb); 413 #else 414 void *pvmBuf = slirp_ext_m_get(pThis->pNATState, (uint8_t *)pvBuf, cb); 415 Assert(pvmBuf); 416 #endif 417 418 pReq->u.Internal.pfn = (PFNRT)drvNATSendWorker; 419 pReq->u.Internal.cArgs = 2; 420 pReq->u.Internal.aArgs[0] = (uintptr_t)pThis; 421 pReq->u.Internal.aArgs[1] = (uintptr_t)pvmBuf; 422 pReq->fFlags = RTREQFLAGS_VOID|RTREQFLAGS_NO_WAIT; 423 424 rc = RTReqQueue(pReq, 0); /* don't wait, we have to wakeup the NAT thread fist */ 425 AssertRC(rc); 426 drvNATNotifyNATThread(pThis); 427 LogFlow(("drvNATSend: end\n")); 488 static DECLCALLBACK(int) drvNATNetworkUp_SendDeprecated(PPDMINETWORKUP pInterface, const void *pvBuf, size_t cb) 489 { 490 PPDMSCATTERGATHER pSgBuf; 491 int rc = drvNATNetworkUp_AllocBuf(pInterface, cb, &pSgBuf); 492 if (RT_SUCCESS(rc)) 493 { 494 memcpy(pSgBuf->aSegs[0].pvSeg, pvBuf, cb); 495 pSgBuf->cbUsed = cb; 496 rc = drvNATNetworkUp_SendBuf(pInterface, pSgBuf, false); 497 } 498 LogFlow(("drvNATNetworkUp_SendDeprecated: (rc=%Rrc)\n", rc)); 428 499 return VINF_SUCCESS; 429 500 } 430 431 501 432 502 /** … … 446 516 } 447 517 448 449 518 /** 450 519 * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode} 451 520 */ 452 static DECLCALLBACK(void) drvNAT SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)453 { 454 LogFlow(("drvNAT SetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous));521 static DECLCALLBACK(void) drvNATNetworkUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous) 522 { 523 LogFlow(("drvNATNetworkUp_SetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous)); 455 524 /* nothing to do */ 456 525 } 457 526 458 527 /** 459 * Worker function for drvNATN otifyLinkChanged().528 * Worker function for drvNATNetworkUp_NotifyLinkChanged(). 460 529 * @thread "NAT" thread. 461 530 */ … … 478 547 479 548 default: 480 AssertMsgFailed(("drvNATNotifyLinkChanged: unexpected link state %d\n", enmLinkState)); 481 } 482 } 483 549 AssertMsgFailed(("drvNATNetworkUp_NotifyLinkChanged: unexpected link state %d\n", enmLinkState)); 550 } 551 } 484 552 485 553 /** … … 490 558 * @thread EMT 491 559 */ 492 static DECLCALLBACK(void) drvNATNotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState) 493 { 494 PDRVNAT pThis = PDMINETWORKUP_2_DRVNAT(pInterface); 495 496 LogFlow(("drvNATNotifyLinkChanged: enmLinkState=%d\n", enmLinkState)); 497 498 PRTREQ pReq = NULL; 560 static DECLCALLBACK(void) drvNATNetworkUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState) 561 { 562 PDRVNAT pThis = RT_FROM_MEMBER(pInterface, DRVNAT, INetworkUp); 563 564 LogFlow(("drvNATNetworkUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState)); 499 565 500 566 /* don't queue new requests when the NAT thread is about to stop */ … … 502 568 return; 503 569 504 int rc = RTReqAlloc(pThis->pSlirpReqQueue, &pReq, RTREQTYPE_INTERNAL); 505 AssertRC(rc); 506 pReq->u.Internal.pfn = (PFNRT)drvNATNotifyLinkChangedWorker; 507 pReq->u.Internal.cArgs = 2; 508 pReq->u.Internal.aArgs[0] = (uintptr_t)pThis; 509 pReq->u.Internal.aArgs[1] = (uintptr_t)enmLinkState; 510 pReq->fFlags = RTREQFLAGS_VOID; 511 rc = RTReqQueue(pReq, 0); /* don't wait, we have to wakeup the NAT thread fist */ 570 PRTREQ pReq; 571 int rc = RTReqCallEx(pThis->pSlirpReqQueue, &pReq, 0 /*cMillies*/, RTREQFLAGS_VOID, 572 (PFNRT)drvNATNotifyLinkChangedWorker, 2, pThis, enmLinkState); 512 573 if (RT_LIKELY(rc == VERR_TIMEOUT)) 513 574 { … … 522 583 523 584 /** 524 * NAT thread handling the slirp stuff. The slirp implementation is single-threaded 525 * so we execute this enginre in a dedicated thread. We take care that this thread 526 * does not become the bottleneck: If the guest wants to send, a request is enqueued 527 * into the pSlirpReqQueue and handled asynchronously by this thread. If this thread 528 * wants to deliver packets to the guest, it enqueues a request into pRecvReqQueue 529 * which is later handled by the Recv thread. 585 * NAT thread handling the slirp stuff. 586 * 587 * The slirp implementation is single-threaded so we execute this enginre in a 588 * dedicated thread. We take care that this thread does not become the 589 * bottleneck: If the guest wants to send, a request is enqueued into the 590 * pSlirpReqQueue and handled asynchronously by this thread. If this thread 591 * wants to deliver packets to the guest, it enqueues a request into 592 * pRecvReqQueue which is later handled by the Recv thread. 530 593 */ 531 594 static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) … … 736 799 } 737 800 738 void slirp_urg_output(void *pvUser, void *pvArg, const uint8_t *pu8Buf, int cb)801 void slirp_urg_output(void *pvUser, struct mbuf *m, const uint8_t *pu8Buf, int cb) 739 802 { 740 803 PDRVNAT pThis = (PDRVNAT)pvUser; … … 747 810 return; 748 811 749 int rc = RTReqAlloc(pThis->pUrgRecvReqQueue, &pReq, RTREQTYPE_INTERNAL);750 AssertRC(rc);751 812 ASMAtomicIncU32(&pThis->cUrgPkt); 752 pReq->u.Internal.pfn = (PFNRT)drvNATUrgRecvWorker; 753 pReq->u.Internal.cArgs = 4; 754 pReq->u.Internal.aArgs[0] = (uintptr_t)pThis; 755 pReq->u.Internal.aArgs[1] = (uintptr_t)pu8Buf; 756 pReq->u.Internal.aArgs[2] = (uintptr_t)cb; 757 pReq->u.Internal.aArgs[3] = (uintptr_t)pvArg; 758 pReq->fFlags = RTREQFLAGS_VOID|RTREQFLAGS_NO_WAIT; 759 rc = RTReqQueue(pReq, 0); 813 int rc = RTReqCallEx(pThis->pUrgRecvReqQueue, NULL /*ppReq*/, 0 /*cMillies*/, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT, 814 (PFNRT)drvNATUrgRecvWorker, 4, pThis, pu8Buf, cb, m); 760 815 AssertRC(rc); 761 816 drvNATUrgRecvWakeup(pThis->pDrvIns, pThis->pUrgRecvThread); … … 763 818 764 819 /** 765 * Function called by slirp to feed incoming data to the network port.766 */ 767 void slirp_output(void *pvUser, void *pvArg, const uint8_t *pu8Buf, int cb)820 * Function called by slirp to feed incoming data to the NIC. 821 */ 822 void slirp_output(void *pvUser, struct mbuf *m, const uint8_t *pu8Buf, int cb) 768 823 { 769 824 PDRVNAT pThis = (PDRVNAT)pvUser; … … 779 834 return; 780 835 781 int rc = RTReqAlloc(pThis->pRecvReqQueue, &pReq, RTREQTYPE_INTERNAL);782 AssertRC(rc);783 836 ASMAtomicIncU32(&pThis->cPkt); 784 pReq->u.Internal.pfn = (PFNRT)drvNATRecvWorker; 785 pReq->u.Internal.cArgs = 4; 786 pReq->u.Internal.aArgs[0] = (uintptr_t)pThis; 787 pReq->u.Internal.aArgs[1] = (uintptr_t)pu8Buf; 788 pReq->u.Internal.aArgs[2] = (uintptr_t)cb; 789 pReq->u.Internal.aArgs[3] = (uintptr_t)pvArg; 790 pReq->fFlags = RTREQFLAGS_VOID|RTREQFLAGS_NO_WAIT; 791 rc = RTReqQueue(pReq, 0); 837 int rc = RTReqCallEx(pThis->pRecvReqQueue, NULL /*ppReq*/, 0 /*cMillies*/, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT, 838 (PFNRT)drvNATRecvWorker, 4, pThis, pu8Buf, cb, m); 792 839 AssertRC(rc); 793 840 drvNATRecvWakeup(pThis->pDrvIns, pThis->pRecvThread); … … 986 1033 pDrvIns->IBase.pfnQueryInterface = drvNATQueryInterface; 987 1034 /* INetwork */ 988 /** @todo implement the new INetworkUp interfaces. */ 989 pThis->INetworkUp.pfnSendDeprecated = drvNATSendDeprecated; 990 pThis->INetworkUp.pfnSetPromiscuousMode = drvNATSetPromiscuousMode; 991 pThis->INetworkUp.pfnNotifyLinkChanged = drvNATNotifyLinkChanged; 1035 pThis->INetworkUp.pfnAllocBuf = drvNATNetworkUp_AllocBuf; 1036 pThis->INetworkUp.pfnSendBuf = drvNATNetworkUp_SendBuf; 1037 pThis->INetworkUp.pfnSendDeprecated = drvNATNetworkUp_SendDeprecated; 1038 pThis->INetworkUp.pfnSetPromiscuousMode = drvNATNetworkUp_SetPromiscuousMode; 1039 pThis->INetworkUp.pfnNotifyLinkChanged = drvNATNetworkUp_NotifyLinkChanged; 992 1040 993 1041 /* -
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r25339 r26574 26 26 #define LOG_GROUP LOG_GROUP_SRV_INTNET 27 27 #include <VBox/intnet.h> 28 #include <VBox/intnetinline.h> 28 29 #include <VBox/sup.h> 29 30 #include <VBox/pdm.h> … … 1536 1537 1537 1538 1538 #ifdef IN_INTNET_TESTCASE 1539 /** 1540 * Reads the next frame in the buffer. 1541 * The caller is responsible for ensuring that there is a valid frame in the buffer. 1542 * 1543 * @returns Size of the frame in bytes. 1544 * @param pBuf The buffer. 1545 * @param pRingBuff The ring buffer to read from. 1546 * @param pvFrame Where to put the frame. The caller is responsible for 1547 * ensuring that there is sufficient space for the frame. 1548 */ 1549 static unsigned intnetR0RingReadFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, void *pvFrame) 1550 { 1551 Assert(pRingBuf->offRead < pBuf->cbBuf); 1552 Assert(pRingBuf->offRead >= pRingBuf->offStart); 1553 Assert(pRingBuf->offRead < pRingBuf->offEnd); 1554 uint32_t offRead = pRingBuf->offRead; 1555 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offRead); 1556 const void *pvFrameIn = INTNETHdrGetFramePtr(pHdr, pBuf); 1557 unsigned cb = pHdr->cbFrame; 1558 memcpy(pvFrame, pvFrameIn, cb); 1559 1560 /* skip the frame */ 1561 offRead += pHdr->offFrame + cb; 1562 offRead = RT_ALIGN_32(offRead, sizeof(INTNETHDR)); 1563 Assert(offRead <= pRingBuf->offEnd && offRead >= pRingBuf->offStart); 1564 if (offRead >= pRingBuf->offEnd) 1565 offRead = pRingBuf->offStart; 1566 ASMAtomicXchgU32(&pRingBuf->offRead, offRead); 1567 return cb; 1568 } 1569 #endif /* IN_INTNET_TESTCASE */ 1570 1571 1572 /** 1573 * Writes a frame packet to the buffer. 1539 /** 1540 * Writes a frame packet to the ring buffer. 1574 1541 * 1575 1542 * @returns VBox status code. … … 1579 1546 * @param pNewDstMac Set the destination MAC address to the address if specified. 1580 1547 */ 1581 static int intnetR0RingWriteFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, PCINTNETSG pSG, PCRTMAC pNewDstMac) 1582 { 1583 /* 1584 * Validate input. 1585 */ 1586 AssertPtr(pBuf); 1587 AssertPtr(pRingBuf); 1588 AssertPtr(pSG); 1589 Assert(pSG->cbTotal >= sizeof(RTMAC) * 2); 1590 uint32_t offWrite = pRingBuf->offWrite; 1591 Assert(offWrite == RT_ALIGN_32(offWrite, sizeof(INTNETHDR))); 1592 uint32_t offRead = pRingBuf->offRead; 1593 Assert(offRead == RT_ALIGN_32(offRead, sizeof(INTNETHDR))); 1594 1595 const uint32_t cb = RT_ALIGN_32(pSG->cbTotal, sizeof(INTNETHDR)); 1596 if (offRead <= offWrite) 1597 { 1598 /* 1599 * Try fit it all before the end of the buffer. 1600 */ 1601 if (pRingBuf->offEnd - offWrite >= cb + sizeof(INTNETHDR)) 1602 { 1603 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 1604 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 1605 pHdr->cbFrame = pSG->cbTotal; 1606 pHdr->offFrame = sizeof(INTNETHDR); 1607 1608 intnetR0SgRead(pSG, pHdr + 1); 1609 if (pNewDstMac) 1610 ((PRTNETETHERHDR)(pHdr + 1))->DstMac = *pNewDstMac; 1611 1612 offWrite += cb + sizeof(INTNETHDR); 1613 Assert(offWrite <= pRingBuf->offEnd && offWrite >= pRingBuf->offStart); 1614 if (offWrite >= pRingBuf->offEnd) 1615 offWrite = pRingBuf->offStart; 1616 Log2(("WriteFrame: offWrite: %#x -> %#x (1)\n", pRingBuf->offWrite, offWrite)); 1617 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite); 1618 return VINF_SUCCESS; 1619 } 1620 1621 /* 1622 * Try fit the frame at the start of the buffer. 1623 * (The header fits before the end of the buffer because of alignment.) 1624 */ 1625 AssertMsg(pRingBuf->offEnd - offWrite >= sizeof(INTNETHDR), ("offEnd=%x offWrite=%x\n", pRingBuf->offEnd, offWrite)); 1626 if (offRead - pRingBuf->offStart > cb) /* not >= ! */ 1627 { 1628 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 1629 void *pvFrameOut = (PINTNETHDR)((uint8_t *)pBuf + pRingBuf->offStart); 1630 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 1631 pHdr->cbFrame = pSG->cbTotal; 1632 pHdr->offFrame = (intptr_t)pvFrameOut - (intptr_t)pHdr; 1633 1634 intnetR0SgRead(pSG, pvFrameOut); 1635 if (pNewDstMac) 1636 ((PRTNETETHERHDR)pvFrameOut)->DstMac = *pNewDstMac; 1637 1638 offWrite = pRingBuf->offStart + cb; 1639 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite); 1640 Log2(("WriteFrame: offWrite: %#x -> %#x (2)\n", pRingBuf->offWrite, offWrite)); 1641 return VINF_SUCCESS; 1642 } 1643 } 1644 /* 1645 * The reader is ahead of the writer, try fit it into that space. 1646 */ 1647 else if (offRead - offWrite > cb + sizeof(INTNETHDR)) /* not >= ! */ 1648 { 1649 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 1650 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 1651 pHdr->cbFrame = pSG->cbTotal; 1652 pHdr->offFrame = sizeof(INTNETHDR); 1653 1654 intnetR0SgRead(pSG, pHdr + 1); 1548 static int intnetR0RingWriteFrame(PINTNETRINGBUF pRingBuf, PCINTNETSG pSG, PCRTMAC pNewDstMac) 1549 { 1550 PINTNETHDR pHdr; 1551 void *pvDst; 1552 int rc = INTNETRingAllocateFrame(pRingBuf, pSG->cbTotal, &pHdr, &pvDst); 1553 if (RT_SUCCESS(rc)) 1554 { 1555 intnetR0SgRead(pSG, pvDst); 1655 1556 if (pNewDstMac) 1656 ((PRTNETETHERHDR)(pHdr + 1))->DstMac = *pNewDstMac; 1657 1658 offWrite += cb + sizeof(INTNETHDR); 1659 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite); 1660 Log2(("WriteFrame: offWrite: %#x -> %#x (3)\n", pRingBuf->offWrite, offWrite)); 1557 ((PRTNETETHERHDR)pvDst)->DstMac = *pNewDstMac; 1558 1559 INTNETRingCommitFrame(pRingBuf, pHdr); 1661 1560 return VINF_SUCCESS; 1662 1561 } 1663 1664 /* (it didn't fit) */ 1665 /** @todo stats */ 1666 return VERR_BUFFER_OVERFLOW; 1562 return rc; 1667 1563 } 1668 1564 … … 1679 1575 { 1680 1576 // LogFlow(("intnetR0IfSend: pIf=%p:{.hIf=%RX32}\n", pIf, pIf->hIf)); 1681 int rc = intnetR0RingWriteFrame( pIf->pIntBuf,&pIf->pIntBuf->Recv, pSG, pNewDstMac);1577 int rc = intnetR0RingWriteFrame(&pIf->pIntBuf->Recv, pSG, pNewDstMac); 1682 1578 if (RT_SUCCESS(rc)) 1683 1579 { 1684 1580 pIf->cYields = 0; 1685 STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatRecvs);1686 STAM_REL_COUNTER_ADD(&pIf->pIntBuf->cbStatRecv, pSG->cbTotal);1687 1581 RTSemEventSignal(pIf->Event); 1688 1582 return; … … 1717 1611 RTSemEventSignal(pIf->Event); 1718 1612 RTThreadYield(); 1719 rc = intnetR0RingWriteFrame( pIf->pIntBuf,&pIf->pIntBuf->Recv, pSG, pNewDstMac);1613 rc = intnetR0RingWriteFrame(&pIf->pIntBuf->Recv, pSG, pNewDstMac); 1720 1614 if (RT_SUCCESS(rc)) 1721 1615 { 1722 1616 STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatYieldsOk); 1723 STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatRecvs);1724 STAM_REL_COUNTER_ADD(&pIf->pIntBuf->cbStatRecv, pSG->cbTotal);1725 1617 RTSemEventSignal(pIf->Event); 1726 1618 return; … … 2373 2265 2374 2266 /* 2375 * Send statistics.2376 */2377 if (pIfSender)2378 {2379 STAM_REL_COUNTER_INC(&pIfSender->pIntBuf->cStatSends);2380 STAM_REL_COUNTER_ADD(&pIfSender->pIntBuf->cbStatSend, pSG->cbTotal);2381 }2382 2383 /*2384 2267 * Get the ethernet header (might theoretically involve multiple segments). 2385 2268 */ … … 2518 2401 * Process the send buffer. 2519 2402 */ 2520 while (pIf->pIntBuf->Send.offRead != pIf->pIntBuf->Send.offWrite) 2403 PINTNETHDR pHdr; 2404 while ((pHdr = INTNETRingGetNextFrameToRead(&pIf->pIntBuf->Send)) != NULL) 2521 2405 { 2522 2406 /* Send the frame if the type is sane. */ 2523 PINTNETHDR pHdr = (PINTNETHDR)((uintptr_t)pIf->pIntBuf + pIf->pIntBuf->Send.offRead);2524 2407 if (pHdr->u16Type == INTNETHDR_TYPE_FRAME) 2525 2408 { … … 2533 2416 } 2534 2417 } 2535 /* else: ignore the frame */ 2418 else 2419 STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatBadFrames); /* ignore */ 2536 2420 2537 2421 /* Skip to the next frame. */ 2538 INTNETRingSkipFrame( pIf->pIntBuf,&pIf->pIntBuf->Send);2422 INTNETRingSkipFrame(&pIf->pIntBuf->Send); 2539 2423 } 2540 2424 … … 3337 3221 */ 3338 3222 /** @todo adjust with minimums and apply defaults here. */ 3339 cbRecv = RT_ALIGN(RT_MAX(cbRecv, sizeof(INTNETHDR) * 4), sizeof(INTNETHDR));3340 cbSend = RT_ALIGN(RT_MAX(cbSend, sizeof(INTNETHDR) * 4), sizeof(INTNETHDR));3341 const unsigned cbBuf = RT_ALIGN(sizeof(*pIf->pIntBuf), sizeof(INTNETHDR)) + cbRecv + cbSend;3223 cbRecv = RT_ALIGN(RT_MAX(cbRecv, sizeof(INTNETHDR) * 4), INTNETRINGBUF_ALIGNMENT); 3224 cbSend = RT_ALIGN(RT_MAX(cbSend, sizeof(INTNETHDR) * 4), INTNETRINGBUF_ALIGNMENT); 3225 const unsigned cbBuf = RT_ALIGN(sizeof(*pIf->pIntBuf), INTNETRINGBUF_ALIGNMENT) + cbRecv + cbSend; 3342 3226 rc = SUPR0MemAlloc(pIf->pSession, cbBuf, (PRTR0PTR)&pIf->pIntBufDefault, (PRTR3PTR)&pIf->pIntBufDefaultR3); 3343 3227 if (RT_SUCCESS(rc)) … … 3347 3231 pIf->pIntBuf = pIf->pIntBufDefault; 3348 3232 pIf->pIntBufR3 = pIf->pIntBufDefaultR3; 3349 pIf->pIntBuf->cbBuf = cbBuf; 3350 pIf->pIntBuf->cbRecv = cbRecv; 3351 pIf->pIntBuf->cbSend = cbSend; 3352 /* receive ring buffer. */ 3353 pIf->pIntBuf->Recv.offStart = RT_ALIGN_32(sizeof(*pIf->pIntBuf), sizeof(INTNETHDR)); 3354 pIf->pIntBuf->Recv.offRead = pIf->pIntBuf->Recv.offStart; 3355 pIf->pIntBuf->Recv.offWrite = pIf->pIntBuf->Recv.offStart; 3356 pIf->pIntBuf->Recv.offEnd = pIf->pIntBuf->Recv.offStart + cbRecv; 3357 /* send ring buffer. */ 3358 pIf->pIntBuf->Send.offStart = pIf->pIntBuf->Recv.offEnd; 3359 pIf->pIntBuf->Send.offRead = pIf->pIntBuf->Send.offStart; 3360 pIf->pIntBuf->Send.offWrite = pIf->pIntBuf->Send.offStart; 3361 pIf->pIntBuf->Send.offEnd = pIf->pIntBuf->Send.offStart + cbSend; 3233 INTNETBufInit(pIf->pIntBuf, cbBuf, cbRecv, cbSend); 3362 3234 3363 3235 /* … … 4107 3979 case kIntNetTrunkType_None: 4108 3980 case kIntNetTrunkType_WhateverNone: 4109 AssertReturn(!*pszTrunk, VERR_INVALID_PARAMETER); 3981 if (*pszTrunk) 3982 return VERR_INVALID_PARAMETER; 4110 3983 break; 4111 3984 4112 3985 case kIntNetTrunkType_NetFlt: 4113 3986 case kIntNetTrunkType_NetAdp: 4114 AssertReturn(pszTrunk, VERR_INVALID_PARAMETER); 3987 if (!*pszTrunk) 3988 return VERR_INVALID_PARAMETER; 4115 3989 break; 4116 3990 … … 4130 4004 4131 4005 /* 4132 * Try open / create the network and create an interface on it for the caller to use. 4006 * Try open / create the network and create an interface on it for the 4007 * caller to use. 4133 4008 * 4134 * Note that because of the destructors grabbing INTNET::FastMutex and us being required 4135 * to own this semaphore for the entire network opening / creation and interface creation 4136 * sequence, intnetR0CreateNetwork will have to defer the network cleanup to us on failure. 4009 * Note! Because of the destructors grabbing INTNET::FastMutex and us being 4010 * required to own this semaphore for the entire network opening / creation 4011 * and interface creation sequence, intnetR0CreateNetwork will have to 4012 * defer the network cleanup to us on failure. 4137 4013 */ 4138 4014 PINTNETNETWORK pNetwork = NULL; … … 4231 4107 if (pIntNet) 4232 4108 { 4233 //pIntNet->pNetworks 4109 //pIntNet->pNetworks = NULL; 4234 4110 4235 4111 rc = RTSemFastMutexCreate(&pIntNet->FastMutex); -
trunk/src/VBox/Devices/Network/slirp/ip_icmp.c
r26405 r26574 587 587 new_m_size = sizeof(struct ip) + ICMP_MINLEN + msrc->m_len + ICMP_MAXDATALEN; 588 588 if (new_m_size > m->m_size) 589 { 589 590 m_inc(m, new_m_size); 591 if (new_m_size > m->m_size) 592 goto end_error_free_m; 593 } 590 594 #endif 591 595 … … 667 671 return; 668 672 673 end_error_free_m: 674 m_free(pData, m); 669 675 end_error: 670 676 LogRel(("NAT: error occurred while sending ICMP error message \n")); -
trunk/src/VBox/Devices/Network/slirp/libslirp.h
r26404 r26574 23 23 24 24 typedef struct NATState *PNATState; 25 struct mbuf; 25 26 26 27 #ifdef __cplusplus … … 48 49 #endif /* !RT_OS_WINDOWS */ 49 50 50 void slirp_input(PNATState pData, void *pvData);51 void slirp_input(PNATState pData, struct mbuf *m, size_t cbBuf); 51 52 void slirp_set_ethaddr_and_activate_port_forwarding(PNATState pData, const uint8_t *ethaddr, uint32_t GuestIP); 52 53 … … 55 56 void slirp_arm_slow_timer(void *pvUser); 56 57 int slirp_can_output(void * pvUser); 57 void slirp_output(void * pvUser, void *pvArg, const uint8_t *pkt, int pkt_len);58 void slirp_urg_output(void *pvUser, void *pvArg, const uint8_t *pu8Buf, int cb);58 void slirp_output(void * pvUser, struct mbuf *m, const uint8_t *pkt, int pkt_len); 59 void slirp_urg_output(void *pvUser, struct mbuf *, const uint8_t *pu8Buf, int cb); 59 60 void slirp_post_sent(PNATState pData, void *pvArg); 60 61 … … 114 115 void *slirp_get_queue(PNATState pData); 115 116 #endif 117 116 118 #ifndef VBOX_WITH_SLIRP_BSD_MBUF 117 void *slirp_ext_m_get(PNATState pData);118 void slirp_ext_m_free(PNATState pData, void*);119 void slirp_ext_m_append(PNATState pData, void*, uint8_t *, size_t);119 struct mbuf *slirp_ext_m_get(PNATState pData, size_t cbMin, void **ppvBuf, size_t *pcbBuf); 120 void slirp_ext_m_free(PNATState pData, struct mbuf *); 121 void slirp_ext_m_append(PNATState pData, struct mbuf *, uint8_t *, size_t); 120 122 void slirp_push_recv_thread(void *pvUser); 121 123 #else -
trunk/src/VBox/Devices/Network/slirp/mbuf.c
r26495 r26574 267 267 if (m->m_flags & M_EXT) 268 268 { 269 void *pvNew; 269 270 datasize = m->m_data - m->m_ext; 270 m->m_ext = (char *)RTMemRealloc(m->m_ext, size); 271 #if 0 272 if (m->m_ext == NULL) 273 return (struct mbuf *)NULL; 274 #endif 271 pvNew = (char *)RTMemRealloc(m->m_ext, size); 272 if (pvNew) 273 return; /** @todo better error reporting. */ 274 m->m_ext = (char *)pvNew; 275 275 m->m_data = m->m_ext + datasize; 276 276 } … … 280 280 datasize = m->m_data - m->m_dat; 281 281 dat = (char *)RTMemAlloc(size); 282 #if 0 283 if (dat == NULL) 284 return (struct mbuf *)NULL; 285 #endif 282 if (!dat) 283 return; /** @todo better error reporting. */ 286 284 memcpy(dat, m->m_dat, m->m_size); 287 285 … … 365 363 return (struct mbuf *)0; 366 364 } 365 367 366 #ifndef VBOX_WITH_SLIRP_BSD_MBUF 368 void *slirp_ext_m_get(PNATState pData) 369 { 370 return (void *)m_get(pData); 371 } 372 373 void slirp_ext_m_free(PNATState pData, void *arg) 374 { 375 struct mbuf *m = (struct mbuf *)arg; 367 368 /** 369 * Interface that DrvNAT.cpp uses for allocating a buffer. 370 * 371 * @returns Opaque m_buf pointer. 372 * 373 * @param pData The NAT state. 374 * @param cbMin The minimum buffer size. 375 * @param ppvBuf Where to return the pointer to the start of the data 376 * buffer. 377 * @param pcbBuf Where to return the actual buffer size. 378 */ 379 struct mbuf *slirp_ext_m_get(PNATState pData, size_t cbMin, void **ppvBuf, size_t *pcbBuf) 380 { 381 struct mbuf *m = m_get(pData); 382 if (!m) 383 return NULL; 384 if (cbMin > M_FREEROOM(m)) 385 { 386 m_inc(m, cbMin); 387 if (RT_UNLIKELY(cbMin > M_FREEROOM(m))) 388 { 389 m_free(pData, m); 390 return NULL; 391 } 392 } 393 394 *ppvBuf = mtod(m, void *); 395 *pcbBuf = M_FREEROOM(m); 396 return m; 397 } 398 399 void slirp_ext_m_free(PNATState pData, struct mbuf *m) 400 { 376 401 m_free(pData, m); 377 402 } 378 void slirp_ext_m_append(PNATState pData, void *arg, uint8_t *pu8Buf, size_t cbBuf) 403 404 void slirp_ext_m_append(PNATState pData, struct mbuf *m, uint8_t *pu8Buf, size_t cbBuf) 379 405 { 380 406 char *c; 381 struct mbuf *m = (struct mbuf *)arg;382 407 if (cbBuf > M_FREEROOM(m)) 383 408 { 384 409 m_inc(m, cbBuf); 410 if (RT_UNLIKELY(cbBuf > M_FREEROOM(m))) 411 cbBuf = M_FREEROOM(m); 385 412 } 386 413 c = mtod(m, char *); … … 388 415 m->m_len = cbBuf; 389 416 } 390 #endif 417 418 #endif /* VBOX_WITH_SLIRP_BSD_MBUF */ -
trunk/src/VBox/Devices/Network/slirp/slirp.c
r26495 r26574 1561 1561 } 1562 1562 1563 void slirp_input(PNATState pData, void *pvArg) 1564 { 1565 struct mbuf *m; 1563 /** 1564 * Feed a packet into the slirp engine. 1565 * 1566 * @param m Data buffer, m_len is not valid. 1567 * @param cbBuf The length of the data in m. 1568 */ 1569 void slirp_input(PNATState pData, struct mbuf *m, size_t cbBuf) 1570 { 1566 1571 int proto; 1567 1572 static bool fWarnedIpv6; … … 1569 1574 uint8_t au8Ether[ETH_ALEN]; 1570 1575 1571 m = (struct mbuf *)pvArg;1572 if ( m->m_len< ETH_HLEN)1573 { 1574 LogRel(("NAT: packet having size %d has been i ngnored\n", m->m_len));1576 m->m_len = cbBuf; 1577 if (cbBuf < ETH_HLEN) 1578 { 1579 LogRel(("NAT: packet having size %d has been ignored\n", m->m_len)); 1575 1580 m_free(pData, m); 1576 1581 return; -
trunk/src/VBox/Devices/Network/testcase/tstIntNet-1.cpp
r26517 r26574 24 24 *******************************************************************************/ 25 25 #include <VBox/intnet.h> 26 #include <VBox/intnetinline.h> 26 27 #include <VBox/sup.h> 27 28 #include <VBox/vmm.h> … … 167 168 168 169 /** 169 * Writes a frame packet to the buffer.170 *171 * @returns VBox status code.172 * @param pBuf The buffer.173 * @param pRingBuf The ring buffer to read from.174 * @param pvFrame The frame to write.175 * @param cbFrame The size of the frame.176 * @remark This is the same as INTNETRingWriteFrame and drvIntNetRingWriteFrame.177 */178 static int tstIntNetWriteFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, const void *pvFrame, uint32_t cbFrame)179 {180 /*181 * Validate input.182 */183 Assert(pBuf);184 Assert(pRingBuf);185 Assert(pvFrame);186 Assert(cbFrame >= sizeof(RTMAC) * 2);187 uint32_t offWrite = pRingBuf->offWrite;188 Assert(offWrite == RT_ALIGN_32(offWrite, sizeof(INTNETHDR)));189 uint32_t offRead = pRingBuf->offRead;190 Assert(offRead == RT_ALIGN_32(offRead, sizeof(INTNETHDR)));191 192 const uint32_t cb = RT_ALIGN_32(cbFrame, sizeof(INTNETHDR));193 if (offRead <= offWrite)194 {195 /*196 * Try fit it all before the end of the buffer.197 */198 if (pRingBuf->offEnd - offWrite >= cb + sizeof(INTNETHDR))199 {200 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite);201 pHdr->u16Type = INTNETHDR_TYPE_FRAME;202 pHdr->cbFrame = cbFrame;203 pHdr->offFrame = sizeof(INTNETHDR);204 205 memcpy(pHdr + 1, pvFrame, cbFrame);206 207 offWrite += cb + sizeof(INTNETHDR);208 Assert(offWrite <= pRingBuf->offEnd && offWrite >= pRingBuf->offStart);209 if (offWrite >= pRingBuf->offEnd)210 offWrite = pRingBuf->offStart;211 Log2(("WriteFrame: offWrite: %#x -> %#x (1)\n", pRingBuf->offWrite, offWrite));212 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite);213 return VINF_SUCCESS;214 }215 216 /*217 * Try fit the frame at the start of the buffer.218 * (The header fits before the end of the buffer because of alignment.)219 */220 AssertMsg(pRingBuf->offEnd - offWrite >= sizeof(INTNETHDR), ("offEnd=%x offWrite=%x\n", pRingBuf->offEnd, offWrite));221 if (offRead - pRingBuf->offStart > cb) /* not >= ! */222 {223 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite);224 void *pvFrameOut = (PINTNETHDR)((uint8_t *)pBuf + pRingBuf->offStart);225 pHdr->u16Type = INTNETHDR_TYPE_FRAME;226 pHdr->cbFrame = cbFrame;227 pHdr->offFrame = (intptr_t)pvFrameOut - (intptr_t)pHdr;228 229 memcpy(pvFrameOut, pvFrame, cbFrame);230 231 offWrite = pRingBuf->offStart + cb;232 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite);233 Log2(("WriteFrame: offWrite: %#x -> %#x (2)\n", pRingBuf->offWrite, offWrite));234 return VINF_SUCCESS;235 }236 }237 /*238 * The reader is ahead of the writer, try fit it into that space.239 */240 else if (offRead - offWrite > cb + sizeof(INTNETHDR)) /* not >= ! */241 {242 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite);243 pHdr->u16Type = INTNETHDR_TYPE_FRAME;244 pHdr->cbFrame = cbFrame;245 pHdr->offFrame = sizeof(INTNETHDR);246 247 memcpy(pHdr + 1, pvFrame, cbFrame);248 249 offWrite += cb + sizeof(INTNETHDR);250 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite);251 Log2(("WriteFrame: offWrite: %#x -> %#x (3)\n", pRingBuf->offWrite, offWrite));252 return VINF_SUCCESS;253 }254 255 /* (it didn't fit) */256 /** @todo stats */257 return VERR_BUFFER_OVERFLOW;258 }259 260 261 /**262 170 * Transmits one frame after appending the CRC. 263 171 * … … 295 203 * it's not supposed to happen here in this testcase. 296 204 */ 297 int rc = tstIntNetWriteFrame(pBuf, &pBuf->Send, pvFrame, (uint32_t)cbFrame);205 int rc = INTNETRingWriteFrame(&pBuf->Send, pvFrame, cbFrame); 298 206 if (RT_SUCCESS(rc)) 299 207 { … … 303 211 else 304 212 { 305 RTPrintf("tstIntNet-1: tstIntNetWriteFrame failed, %Rrc; cbFrame=%d pBuf->cbSend=%d\n", rc, cbFrame, pBuf->cbSend);213 RTPrintf("tstIntNet-1: INTNETRingWriteFrame failed, %Rrc; cbFrame=%d pBuf->cbSend=%d\n", rc, cbFrame, pBuf->cbSend); 306 214 g_cErrors++; 307 215 } … … 555 463 * Process the receive buffer. 556 464 */ 557 while (INTNETRingGetReadable(pRingBuf) > 0) 465 PINTNETHDR pHdr; 466 while ((pHdr = INTNETRingGetNextFrameToRead(pRingBuf))) 558 467 { 559 PINTNETHDR pHdr = (PINTNETHDR)((uintptr_t)pBuf + pRingBuf->offRead);560 468 if (pHdr->u16Type == INTNETHDR_TYPE_FRAME) 561 469 { 562 470 size_t cbFrame = pHdr->cbFrame; 563 471 const void *pvFrame = INTNETHdrGetFramePtr(pHdr, pBuf); 564 uint64_t NanoTS = RTTimeNanoTS() - g_StartTS;472 uint64_t NanoTS = RTTimeNanoTS() - g_StartTS; 565 473 566 474 if (pFileRaw) … … 638 546 { 639 547 RTPrintf("tstIntNet-1: Unknown frame type %d\n", pHdr->u16Type); 548 STAM_REL_COUNTER_INC(&pBuf->cStatBadFrames); 640 549 g_cErrors++; 641 550 } 642 551 643 552 /* Advance to the next frame. */ 644 INTNETRingSkipFrame(p Buf, pRingBuf);553 INTNETRingSkipFrame(pRingBuf); 645 554 } 646 555 } … … 650 559 "%3RU64.%09u: stopped. cRecvs=%RU64 cbRecv=%RU64 cLost=%RU64 cOYs=%RU64 cNYs=%RU64\n", 651 560 NanoTS / 1000000000, (uint32_t)(NanoTS % 1000000000), 652 pBuf-> cStatRecvs.c,653 pBuf-> cbStatRecv.c,561 pBuf->Recv.cStatFrames.c, 562 pBuf->Recv.cbStatWritten.c, 654 563 pBuf->cStatLost.c, 655 564 pBuf->cStatYieldsOk.c, -
trunk/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp
r26517 r26574 27 27 * Header Files * 28 28 *******************************************************************************/ 29 #define RTMEM_WRAP_TO_EF_APIS // debugging debugging remove 30 #define INTNET_POISON_READ_FRAMES // debugging debugging remove 29 31 #define IN_INTNET_TESTCASE 30 32 #define IN_INTNET_R3 … … 212 214 #include "../SrvIntNetR0.cpp" 213 215 214 typedef struct ARGS216 typedef struct MYARGS 215 217 { 216 218 PINTNET pIntNet; … … 220 222 uint64_t u64Start; 221 223 uint64_t u64End; 222 } ARGS, *PARGS;224 } MYARGS, *PMYARGS; 223 225 224 226 … … 231 233 DECLCALLBACK(int) SendThread(RTTHREAD Thread, void *pvArg) 232 234 { 233 P ARGS pArgs = (PARGS)pvArg;235 PMYARGS pArgs = (PMYARGS)pvArg; 234 236 235 237 /* … … 237 239 */ 238 240 uint8_t abBuf[4096] = {0}; 239 PRTMAC pMacSrc = (PRTMAC)&abBuf[0];240 PRTMAC pMacDst = pMacSrc + 1;241 PRTMAC pMacSrc = (PRTMAC)&abBuf[0]; 242 PRTMAC pMacDst = pMacSrc + 1; 241 243 *pMacSrc = pArgs->Mac; 242 244 *pMacDst = pArgs->Mac; … … 244 246 unsigned *puFrame = (unsigned *)(pMacDst + 1); 245 247 unsigned iFrame = 0; 246 unsigned cbSent = 0; 248 uint32_t cbSent = 0; 249 uint32_t cSend = 0; 247 250 pArgs->u64Start = RTTimeNanoTS(); 248 251 for (; cbSent < TEST_TRANSFER_SIZE; iFrame++) … … 255 258 INTNETSG Sg; 256 259 intnetR0SgInitTemp(&Sg, abBuf, cb); 257 int rc = intnetR0RingWriteFrame( pArgs->pBuf,&pArgs->pBuf->Send, &Sg, NULL);260 int rc = intnetR0RingWriteFrame(&pArgs->pBuf->Send, &Sg, NULL); 258 261 if (RT_SUCCESS(rc)) 259 262 rc = INTNETR0IfSend(pArgs->pIntNet, pArgs->hIf, g_pSession, NULL, 0); … … 285 288 } 286 289 287 RTPrintf("tstIntNetR0: sender thread %.6Rhxs terminating. iFrame=%d cbSent=%d\n", &pArgs->Mac, iFrame, cbSent); 290 RTPrintf("tstIntNetR0: sender thread %.6Rhxs terminating.\n" 291 "tstIntNetR0: iFrame=%u cb=%'u\n", 292 &pArgs->Mac, iFrame, cbSent); 288 293 return 0; 289 294 } … … 299 304 DECLCALLBACK(int) ReceiveThread(RTTHREAD Thread, void *pvArg) 300 305 { 301 u nsigned cbReceived= 0;302 u nsignedcLostFrames = 0;303 u nsigned iFrame = ~0;304 P ARGS pArgs = (PARGS)pvArg;306 uint32_t cbReceived = 0; 307 uint32_t cLostFrames = 0; 308 uint32_t iFrame = UINT32_MAX; 309 PMYARGS pArgs = (PMYARGS)pvArg; 305 310 for (;;) 306 311 { … … 315 320 break; 316 321 case VERR_SEM_DESTROYED: 317 RTPrintf("tstIntNetR0: receiver thread %.6Rhxs terminating. cbReceived=%u cLostFrames=%u iFrame=%u\n",318 &pArgs->Mac, cbReceived, cLostFrames, iFrame);322 RTPrintf("tstIntNetR0: receiver thread %.6Rhxs terminating. iFrame=%u cb=%'u c=%'u cLost=%'u\n", 323 &pArgs->Mac, iFrame, cbReceived, iFrame - cLostFrames, cLostFrames); 319 324 return VINF_SUCCESS; 320 325 321 326 default: 322 RTPrintf("tstIntNetR0: receiver thread %.6Rhxs got odd return value %Rrc! cbReceived=%u cLostFrames=%u iFrame=%u\n",323 &pArgs->Mac, rc, cbReceived, cLostFrames, iFrame);327 RTPrintf("tstIntNetR0: receiver thread %.6Rhxs got odd return value %Rrc! iFrame=%u cb=%'u c=%'u cLost=%'u\n", 328 &pArgs->Mac, rc, iFrame, cbReceived, iFrame - cLostFrames, cLostFrames); 324 329 g_cErrors++; 325 330 return rc; … … 329 334 * Read data. 330 335 */ 331 while (INTNETRing GetReadable(&pArgs->pBuf->Recv))336 while (INTNETRingHasMoreToRead(&pArgs->pBuf->Recv)) 332 337 { 333 338 uint8_t abBuf[16384]; 334 u nsigned cb = intnetR0RingReadFrame(pArgs->pBuf,&pArgs->pBuf->Recv, abBuf);339 uint32_t cb = INTNETRingReadAndSkipFrame(&pArgs->pBuf->Recv, abBuf); 335 340 unsigned *puFrame = (unsigned *)&abBuf[sizeof(RTMAC) * 2]; 336 341 … … 342 347 && puFrame[3] == 0xffffdead) 343 348 { 344 RTPrintf("tstIntNetR0: receiver thread %.6Rhxs terminating. cbReceived=%u cLostFrames=%u iFrame=%u\n",345 &pArgs->Mac, cbReceived, cLostFrames, iFrame);346 349 pArgs->u64End = RTTimeNanoTS(); 350 RTPrintf("tstIntNetR0: receiver thread %.6Rhxs terminating.\n" 351 "tstIntNetR0: iFrame=%u cb=%'u c=%'u %'uKB/s %'ufps cLost=%'u \n", 352 &pArgs->Mac, iFrame, cbReceived, iFrame - cLostFrames, 353 (unsigned)(cbReceived * 1000000000.0 / 1024 / (pArgs->u64End - pArgs->u64Start)), 354 (unsigned)((iFrame - cLostFrames) * 1000000000.0 / (pArgs->u64End - pArgs->u64Start)), 355 cLostFrames); 347 356 return VINF_SUCCESS; 348 357 } … … 523 532 g_cErrors++; 524 533 } 525 u nsigned cb = intnetR0RingReadFrame(pBuf1,&pBuf1->Recv, abBuf);534 uint32_t cb = INTNETRingReadAndSkipFrame(&pBuf1->Recv, abBuf); 526 535 if (cb != sizeof(g_TestFrame0)) 527 536 { … … 555 564 if (!g_cErrors) 556 565 { 557 ARGS Args0;566 MYARGS Args0; 558 567 RT_ZERO(Args0); 559 568 Args0.hIf = hIf0; … … 564 573 Args0.Mac.au16[2] = 0; 565 574 566 ARGS Args1;575 MYARGS Args1; 567 576 RT_ZERO(Args1); 568 577 Args1.hIf = hIf1; … … 588 597 int rc2 = VINF_SUCCESS; 589 598 rc = RTThreadWait(ThreadSend0, 5*60*1000, &rc2); 590 #if 1 /** @todo it looks like I'm subject to some false wakeup calls here (2.6.23-gentoo-r3 amd64). See #3023.*/591 for (int cTries = 100; rc == VERR_TIMEOUT && cTries > 0; cTries--)592 {593 RTThreadSleep(1);594 rc = RTThreadWait(ThreadSend0, 1, &rc2);595 }596 #endif597 599 AssertRC(rc); 598 600 if (RT_SUCCESS(rc)) … … 600 602 ThreadSend0 = NIL_RTTHREAD; 601 603 rc = RTThreadWait(ThreadSend1, 5*60*1000, RT_SUCCESS(rc2) ? &rc2 : NULL); 602 #if 1 /** @todo it looks like I'm subject to some false wakeup calls here (2.6.23-gentoo-r3 amd64). See #3023.*/603 for (int cTries = 100; rc == VERR_TIMEOUT && cTries > 0; cTries--)604 {605 RTThreadSleep(1);606 rc = RTThreadWait(ThreadSend1, 1, &rc2);607 }608 #endif609 604 AssertRC(rc); 610 605 if (RT_SUCCESS(rc)) … … 618 613 */ 619 614 unsigned cYields = 100000; 620 while ( ( INTNETRingGetReadable(&pBuf0->Recv)621 || INTNETRingGetReadable(&pBuf1->Recv))615 while ( ( INTNETRingHasMoreToRead(&pBuf0->Recv) 616 || INTNETRingHasMoreToRead(&pBuf1->Recv)) 622 617 && cYields-- > 0) 623 618 RTThreadYield(); … … 625 620 uint64_t u64Elapsed = RT_MAX(Args0.u64End, Args1.u64End) - RT_MIN(Args0.u64Start, Args1.u64Start); 626 621 uint64_t u64Speed = (uint64_t)((2 * TEST_TRANSFER_SIZE / 1024) / (u64Elapsed / 1000000000.0)); 627 RTPrintf("tstIntNetR0: transfered %d bytes in % RU64 ns (%RU64 KB/s)\n",622 RTPrintf("tstIntNetR0: transfered %d bytes in %'RU64 ns (%'RU64 KB/s)\n", 628 623 2 * TEST_TRANSFER_SIZE, u64Elapsed, u64Speed); 629 624
Note:
See TracChangeset
for help on using the changeset viewer.