Changeset 52134 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Jul 22, 2014 5:39:46 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r49480 r52134 450 450 451 451 452 #ifdef VBOX_WITH_INTNET_DISCONNECT 453 /******************************************************************************* 454 * Forward Declarations * 455 *******************************************************************************/ 456 static void intnetR0TrunkIfDestroy(PINTNETTRUNKIF pThis, PINTNETNETWORK pNetwork); 457 458 459 /** 460 * Checks if a pointer belongs to the list of known networks without 461 * accessing memory it points to. 462 * 463 * @returns true, if such network is in the list. 464 * @param pIntNet The pointer to the internal network instance (global). 465 * @param pNetwork The pointer that must be validated. 466 */ 467 DECLINLINE(bool) intnetR0NetworkIsValid(PINTNET pIntNet, PINTNETNETWORK pNetwork) 468 { 469 for (PINTNETNETWORK pCurr = pIntNet->pNetworks; pCurr; pCurr = pCurr->pNext) 470 if (pCurr == pNetwork) 471 return true; 472 return false; 473 } 474 #endif /* VBOX_WITH_INTNET_DISCONNECT */ 475 452 476 453 477 /** … … 716 740 DECLINLINE(void) intnetR0BusyDecTrunk(PINTNETTRUNKIF pTrunk) 717 741 { 718 intnetR0BusyDec(pTrunk->pNetwork, &pTrunk->cBusy); 742 if (pTrunk) 743 intnetR0BusyDec(pTrunk->pNetwork, &pTrunk->cBusy); 719 744 } 720 745 … … 744 769 DECLINLINE(void) intnetR0BusyIncTrunk(PINTNETTRUNKIF pTrunk) 745 770 { 771 if (!pTrunk) return; 746 772 uint32_t cNewBusy = ASMAtomicIncU32(&pTrunk->cBusy); 747 773 AssertMsg((cNewBusy & ~INTNET_BUSY_WAKEUP_MASK) < INTNET_MAX_IFS * 3, ("%#x\n", cNewBusy)); … … 3097 3123 * since we modified the MAC in the initial request the guest made. 3098 3124 */ 3125 RTSpinlockAcquire(pNetwork->hAddrSpinlock); 3126 RTMAC MacAddrTrunk; 3127 if (pNetwork->MacTab.pTrunk) 3128 MacAddrTrunk = pNetwork->MacTab.pTrunk->MacAddr; 3129 else 3130 memset(&MacAddrTrunk, 0, sizeof(MacAddrTrunk)); 3131 RTSpinlockReleaseNoInts(pNetwork->hAddrSpinlock); 3099 3132 if ( ar_oper == RTNET_ARPOP_REPLY 3100 && !memcmp(&pArpIPv4->ar_tha, & pNetwork->MacTab.pTrunk->MacAddr, sizeof(RTMAC)))3133 && !memcmp(&pArpIPv4->ar_tha, &MacAddrTrunk, sizeof(RTMAC))) 3101 3134 { 3102 3135 PINTNETIF pIf = intnetR0NetworkAddrCacheLookupIf(pNetwork, (PCRTNETADDRU)&pArpIPv4->ar_tpa, … … 3106 3139 Log6(("fw: ar_tha %.6Rhxs -> %.6Rhxs\n", &pArpIPv4->ar_tha, &pIf->MacAddr)); 3107 3140 pArpIPv4->ar_tha = pIf->MacAddr; 3108 if (!memcmp(&pEthHdr->DstMac, & pNetwork->MacTab.pTrunk->MacAddr, sizeof(RTMAC)))3141 if (!memcmp(&pEthHdr->DstMac, &MacAddrTrunk, sizeof(RTMAC))) 3109 3142 { 3110 3143 Log6(("fw: DstMac %.6Rhxs -> %.6Rhxs\n", &pEthHdr->DstMac, &pIf->MacAddr)); … … 3272 3305 /* ASSUMES: that the trunk won't change its report while we're checking. */ 3273 3306 PINTNETTRUNKIF pTrunk = pDstTab->pTrunk; 3274 if ( (fTrunkDst & pTrunk->fNoPreemptDsts) == fTrunkDst)3307 if (pTrunk && (fTrunkDst & pTrunk->fNoPreemptDsts) == fTrunkDst) 3275 3308 return true; 3276 3309 … … 3517 3550 { 3518 3551 PINTNETTRUNKIF pTrunk = pDstTab->pTrunk; 3519 intnetR0BusyDec(pNetwork, &pTrunk->cBusy); 3552 if (pTrunk) 3553 intnetR0BusyDec(pNetwork, &pTrunk->cBusy); 3520 3554 pDstTab->pTrunk = NULL; 3521 3555 pDstTab->fTrunkDst = 0; … … 3574 3608 { 3575 3609 PINTNETTRUNKIF pTrunk = pDstTab->pTrunk; 3576 if (pIfSender) 3577 intnetR0TrunkIfSend(pTrunk, pNetwork, pIfSender, pDstTab->fTrunkDst, pSG); 3578 intnetR0BusyDec(pNetwork, &pTrunk->cBusy); 3610 if (pTrunk) 3611 { 3612 if (pIfSender) 3613 intnetR0TrunkIfSend(pTrunk, pNetwork, pIfSender, pDstTab->fTrunkDst, pSG); 3614 intnetR0BusyDec(pNetwork, &pTrunk->cBusy); 3615 } 3579 3616 pDstTab->pTrunk = NULL; 3580 3617 pDstTab->fTrunkDst = 0; … … 4971 5008 pThis->fNoPreemptDsts = fNoPreemptDsts; 4972 5009 } 5010 5011 5012 #ifdef VBOX_WITH_INTNET_DISCONNECT 5013 /** @copydoc INTNETTRUNKSWPORT::pfnDisconnect */ 5014 static DECLCALLBACK(void) intnetR0TrunkIfPortDisconnect(PINTNETTRUNKSWPORT pSwitchPort) 5015 { 5016 PINTNETTRUNKIF pThis = INTNET_SWITCHPORT_2_TRUNKIF(pSwitchPort); 5017 /* 5018 * We intentionally do not increase the busy count of the trunk as it will cause a deadlock 5019 * with a racing intnetR0NetworkDestruct. It is safe to do only due to the fact that our 5020 * caller must have increased the busy count of the corresponding netflt instance thus 5021 * preventing intnetR0NetworkDestruct from destroying the trunk. 5022 */ 5023 PINTNETNETWORK pNetwork = pThis->pNetwork; 5024 if (pNetwork) 5025 { 5026 /* 5027 * We need to save pIntNet too in case pNetwork becomes invalid while we are waiting 5028 * on pIntNet->hMtxCreateOpenDestroy. 5029 */ 5030 PINTNET pIntNet = pNetwork->pIntNet; 5031 Assert(pNetwork->pIntNet); 5032 /* 5033 * We must decrease the busy count of corresponing netflt instance here allowing 5034 * intnetR0NetworkDestruct to proceed with destruction. 5035 */ 5036 pThis->pIfPort->pfnRelease(pThis->pIfPort, true); 5037 /* Take the big create/open/destroy sem. */ 5038 RTSemMutexRequest(pIntNet->hMtxCreateOpenDestroy, RT_INDEFINITE_WAIT); 5039 /* 5040 * At this point pNetwork may no longer exist, being destroyed by intnetR0NetworkDestruct 5041 * so we need to make sure it is still valid by looking it up in pIntNet->pNetworks. 5042 */ 5043 if (intnetR0NetworkIsValid(pIntNet, pNetwork)) 5044 { 5045 pThis->pIfPort->pfnSetState(pThis->pIfPort, INTNETTRUNKIFSTATE_DISCONNECTING); 5046 5047 RTSpinlockAcquire(pNetwork->hAddrSpinlock); 5048 pNetwork->MacTab.pTrunk = NULL; 5049 RTSpinlockReleaseNoInts(pNetwork->hAddrSpinlock); 5050 5051 intnetR0TrunkIfDestroy(pThis, pNetwork); 5052 } 5053 5054 RTSemMutexRelease(pNetwork->pIntNet->hMtxCreateOpenDestroy); 5055 } 5056 } 5057 #endif /* VBOX_WITH_INTNET_DISCONNECT */ 4973 5058 4974 5059 … … 5332 5417 pTrunk->SwitchPort.pfnReportGsoCapabilities = intnetR0TrunkIfPortReportGsoCapabilities; 5333 5418 pTrunk->SwitchPort.pfnReportNoPreemptDsts = intnetR0TrunkIfPortReportNoPreemptDsts; 5419 #ifdef VBOX_WITH_INTNET_DISCONNECT 5420 pTrunk->SwitchPort.pfnDisconnect = intnetR0TrunkIfPortDisconnect; 5421 #endif /* VBOX_WITH_INTNET_DISCONNECT */ 5334 5422 pTrunk->SwitchPort.u32VersionEnd = INTNETTRUNKSWPORT_VERSION; 5335 5423 //pTrunk->pIfPort = NULL;
Note:
See TracChangeset
for help on using the changeset viewer.