Changeset 28430 in vbox
- Timestamp:
- Apr 17, 2010 2:30:31 AM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 60201
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r28208 r28430 50 50 #define INTNET_WITH_DHCP_SNOOPING 51 51 52 #if 0 53 /** Enables the new code - temporarily while doing the rewrite. */ 54 # define WITH_NEW_STUFF 55 #endif 56 57 52 58 53 59 /******************************************************************************* 54 60 * Structures and Typedefs * 55 61 *******************************************************************************/ 62 #ifdef WITH_NEW_STUFF 63 /** 64 * MAC address lookup table entry. 65 */ 66 typedef struct INTNETMACTABENTRY 67 { 68 /** The MAC address of this entry. */ 69 RTMAC MacAddr; 70 /** Is it promiscuous. */ 71 bool fPromiscuous; 72 /** Is it active. 73 * We ignore the entry if this is clear and may end up sending packets addressed 74 * to this interface onto the trunk. The reasoning for this is that this could 75 * be the interface of a VM that just has been teleported to a different host. */ 76 bool fActive; 77 /** Pointer to the network interface. */ 78 struct INTNETIF *pIf; 79 } INTNETMACTABENTRY; 80 /** Pointer to a MAC address lookup table entry. */ 81 typedef INTNETMACTABENTRY *PINTNETMACTABENTRY; 82 /** Pointer to a const MAC address lookup table entry. */ 83 typedef INTNETMACTABENTRY const *PCINTNETMACTABENTRY; 84 85 /** 86 * MAC address lookup table. 87 */ 88 typedef struct INTNETMACTAB 89 { 90 /** The spinlock protecting the table, interrupt safe. */ 91 RTSPINLOCK hSpinlock; 92 /** The current number of entries. */ 93 uint32_t cEntries; 94 /** The number of entries we've allocated space for. */ 95 uint32_t cEntriesAllocated; 96 /** Table entries. */ 97 PCINTNETMACTABENTRY paEntries; 98 99 /** The host MAC address. */ 100 RTMAC HostMac; 101 /** The host promiscous setting. */ 102 bool fHostPromiscuous; 103 /** Whether the host is active. */ 104 bool fHostActive; 105 106 /** Whether the wire is promiscuous. */ 107 bool fWirePromiscuous; 108 /** Whether the wire is active. */ 109 bool fWireActive; 110 111 /** Pointer to the the trunk interface. */ 112 struct INTNETTRUNKIF *pTrunk; 113 } INTNETMACTAB; 114 /** Pointer to a MAC address . */ 115 typedef INTNETMACTAB *PINTNETMACTAB; 116 117 /** 118 * Destination table. 119 */ 120 typedef struct INTNETDSTTAB 121 { 122 /** The trunk destinations. */ 123 uint32_t fTrunkDst; 124 /** Pointer to the trunk interface (referenced) if fTrunkDst is non-zero. */ 125 struct INTNETTRUNKIF *pTrunk; 126 /** The number of destination interfaces. */ 127 uint32_t cIfs; 128 /** The interfaces (referenced). Variable sized array. */ 129 struct INTNETIF *apIfs[1]; 130 } INTNETDSTTAB; 131 /** Pointer to a destination table. */ 132 typedef INTNETDSTTAB *PINTNETDSTTAB; 133 #endif /* WITH_NEW_STUFF */ 134 135 136 /** Network layer address type. */ 56 137 typedef enum INTNETADDRTYPE 57 138 { … … 79 160 { 80 161 /** The address type. */ 81 INTNETADDRTYPE enmType;162 INTNETADDRTYPE enmType; 82 163 /** The address. */ 83 RTNETADDRU Addr;164 RTNETADDRU Addr; 84 165 } INTNETADDR; 85 166 /** Pointer to an address. */ … … 95 176 { 96 177 /** Pointer to the table of addresses. */ 97 uint8_t *pbEntries;178 uint8_t *pbEntries; 98 179 /** The number of valid address entries. */ 99 uint8_t cEntries;180 uint8_t cEntries; 100 181 /** The number of allocated address entries. */ 101 uint8_t cEntriesAlloc;182 uint8_t cEntriesAlloc; 102 183 /** The address size. */ 103 uint8_t cbAddress;184 uint8_t cbAddress; 104 185 /** The size of an entry. */ 105 uint8_t cbEntry;186 uint8_t cbEntry; 106 187 } INTNETADDRCACHE; 107 188 /** Pointer to an address cache. */ … … 121 202 * This is protected by the INTNET::FastMutex. */ 122 203 struct INTNETIF *pNext; 123 /** The current MAC address for the interface. */ 204 /** The current MAC address for the interface. (reported or learned) 205 * Updated while owning the switch table spinlock. */ 124 206 RTMAC Mac; 125 207 /** Set if the INTNET::Mac member is valid. */ … … 133 215 bool volatile fDestroying; 134 216 /** Number of yields done to try make the interface read pending data. 135 * We will stop y eilding when this reaches a threshold assuming that the VM is paused or136 * that it simply isn't worth all the delay. It is cleared when a successful send has been done.137 * /217 * We will stop yielding when this reaches a threshold assuming that the VM is 218 * paused or that it simply isn't worth all the delay. It is cleared when a 219 * successful send has been done. */ 138 220 uint32_t cYields; 139 221 /** Pointer to the current exchange buffer (ring-0). */ … … 162 244 /** The network layer address cache. (Indexed by type, 0 entry isn't used.) */ 163 245 INTNETADDRCACHE aAddrCache[kIntNetAddrType_End]; 246 #ifdef WITH_NEW_STUFF 247 /** Spinlock protecting the input (producer) side of the receive ring. */ 248 RTSPINLOCK hRecvInSpinlock; 249 /** Busy count for tracking destination table references and active sends. 250 * Incremented while owning the switch table spinlock. */ 251 uint32_t volatile cBusy; 252 /** Set if a someone is waiting on INTNETNETWORK::hEvtBusyIf for cBusy to 253 * reach zero. */ 254 bool volatile fBusyZeroWakeup; 255 /** The preallocated destination table. 256 * This is NULL when it's in use as a precaution against unserialized 257 * transmitting. This is grown when new interfaces are added to the network. */ 258 PINTNETDSTTAB volatile pDstTab; 259 #endif /* WITH_NEW_STUFF */ 164 260 } INTNETIF; 165 261 /** Pointer to an internal network interface. */ … … 176 272 /** The port interface we get from the component. */ 177 273 PINTNETTRUNKIFPORT pIfPort; 274 #ifdef WITH_NEW_STUFF 275 /** @todo This won't quite cut the mustard any longer. That said, GSO 276 * segmentation needs to be serialized because of the header buffer. */ 277 RTSEMFASTMUTEX FastMutex; 278 #else 178 279 /** The trunk mutex that serializes all calls <b>to</b> the component. */ 179 280 RTSEMFASTMUTEX FastMutex; 281 #endif 180 282 /** Pointer to the network we're connect to. 181 283 * This may be NULL if we're orphaned? */ 182 284 struct INTNETNETWORK *pNetwork; 285 #ifdef WITH_NEW_STUFF 286 /** The current MAC address for the interface. (reported) 287 * Updated while owning the switch table spinlock. 288 * @todo rename to Mac */ 289 RTMAC CachedMac; 290 #else 183 291 /** The cached MAC address of the interface the trunk is attached to. 184 292 * This is for the situations where we cannot take the out-bound 185 293 * semaphore (the recv case) but need to make frame edits (ARP). */ 186 294 RTMAC CachedMac; 187 /** Whether to supply physical addresses with the outbound SGs. */ 295 #endif 296 #ifndef WITH_NEW_STUFF 297 /** Whether to supply physical addresses with the outbound SGs. (reported) */ 188 298 bool volatile fPhysSG; 189 299 /** Set if the 'wire' is in promiscuous mode. 190 300 * The state of the 'host' is queried each time. */ 191 bool fPromiscuousWire; 192 /** The GSO capabilities of the host destination. 301 bool fWirePromiscuous; 302 #else /* WITH_NEW_STUFF */ 303 /** Set if the 'wire' is in promiscuous mode. (config) */ 304 bool fWirePromiscuous; 305 /** Set if the 'host' is in promiscuous mode. (reported) */ 306 bool volatile fHostPromiscuous; 307 /** Can pfnXmit cope with disabled preemption for the 'wire'. (reported) */ 308 bool fWireNoPreempt; 309 /** Can pfnXmit cope with disabled preemption for the 'host'. (reported) */ 310 bool fHostNoPreempt; 311 /** Whether to supply physical addresses with the outbound SGs. (reported) */ 312 bool fPhysSG; 313 /** Set if a someone is waiting on INTNETNETWORK::hEvtBusyIf for cBusy to 314 * reach zero. */ 315 bool volatile fBusyZeroWakeup; 316 /** Busy count for tracking destination table references and active sends. 317 * Incremented while owning the switch table spinlock. */ 318 uint32_t volatile cBusy; 319 #endif /* WITH_NEW_STUFF */ 320 /** The GSO capabilities of the wire destination. (reported) */ 321 uint32_t fWireGsoCapabilites; 322 /** The GSO capabilities of the host destination. (reported) 193 323 * This is as bit map where each bit represents the GSO type with the same 194 324 * number. */ 195 uint32_t fGsoCapabilitesHost; 196 /** The GSO capabilities of the wire destination. */ 197 uint32_t fGsoCapabilitesWire; 325 uint32_t fHostGsoCapabilites; 198 326 /** Header buffer for when we're carving GSO frames. */ 199 327 uint8_t abGsoHdrs[256]; 328 #ifdef WITH_NEW_STUFF 329 /** @todo what exactly to do about the destination tables here? how many do 330 * we need / want? One? One per CPU? */ 331 #endif 200 332 } INTNETTRUNKIF; 201 333 /** Pointer to a trunk interface. */ … … 222 354 /** The network mutex. 223 355 * It protects everything dealing with this network. */ 356 #ifdef WITH_NEW_STUFF 357 /** @todo Make this a mutex so we can block on the event semaphore while holding 358 * it. Requires fixing the mutex code on linux... Or maybe add 359 * another mutex for creation / destruction serilization. */ 360 #endif 224 361 RTSEMFASTMUTEX FastMutex; 362 #ifdef WITH_NEW_STUFF 363 /** Wait for an interface to stop being busy so it can be removed or have its 364 * destination table replaced. We have to wait upon this while owning the 365 * network mutex. */ 366 RTSEMEVENT hEvtBusyIf; 367 #endif 225 368 /** Pointer to the instance data. */ 226 369 struct INTNET *pIntNet; … … 462 605 463 606 607 #ifdef WITH_NEW_STUFF 608 609 /** 610 * Compares two MAC addresses. 611 * 612 * @returns true if equal, false if not. 613 * @param pDstAddr1 Address 1. 614 * @param pDstAddr2 Address 2. 615 */ 616 DECL_FORCE_INLINE(bool) intnetR0AreMacAddrsEqual(PCRTMAC pDstAddr1, PCRTMAC pDstAddr2) 617 { 618 return pDstAddr1->au16[2] == pDstAddr2->au16[2] 619 && pDstAddr1->au16[1] == pDstAddr2->au16[1] 620 && pDstAddr1->au16[0] == pDstAddr2->au16[0]; 621 } 622 623 624 /** 625 * Switch a MAC address and return a destination table. 626 * 627 * @returns Destination table or NULL if *ppDstTab is NULL. 628 * @param pTab The MAC address table to work on. 629 * @param pDstAddr The destination address of the packet. 630 * @param ppDstTab Where to get the destination table from. 631 * @param pcBusy The busy counter to increment if *ppDstTab isn't 632 * NULL. 633 */ 634 static PINTNETDSTTAB intnetR0MacTabSwitch(PINTNETMACTAB pTab, PCRTMAC pDstAddr, 635 PINTNETDSTTAB volatile *ppDstTab, uint32_t volatile *pcBusy) 636 { 637 /* 638 * Grab the spinlock first, then get the destination table and increment 639 * the busy counter (to indicate that we're using the dst tab and it cannot 640 * be freed yet). 641 */ 642 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 643 RTSpinlockAcquire(pTab->hSpinlock, &Tmp); 644 PINTNETDSTTAB pDstTab = (PINTNETDSTTAB)ASMAtomicXchgPtr((void * volatile *)ppDstTab, NULL); 645 if (pDstTab) 646 { 647 ASMAtomicIncU32(pcBusy); 648 649 /* 650 * Do the switching. 651 */ 652 pDstTab->fTrunkDst = 0; 653 pDstTab->pTrunk = 0; 654 pDstTab->cIfs = 0; 655 656 uint32_t i = pTab->cEntries; 657 if (pDstAddr->au8[0] & 1) /* multicast or broadcast address */ 658 { 659 /* Broadcast/multicast - add all active interfaces. */ 660 while (i-- > 0) 661 { 662 if (pTab->paEntries[i].fActive) 663 { 664 PINTNETIF pIf = pTab->paEntries[i].pIf; 665 pDstTab->apIfs[i] = pIf; 666 ASMAtomicIncU32(&pIf->cBusy); 667 pDstTab->cIfs++; 668 } 669 } 670 671 if (pTab->fHostActive) 672 pDstTab->fTrunkDst |= INTNETTRUNKDIR_HOST; 673 if (pTab->fWireActive) 674 pDstTab->fTrunkDst |= INTNETTRUNKDIR_WIRE; 675 } 676 else 677 { 678 /* Find exactly matching or promiscuous interfaces. */ 679 uint32_t cExactHits = 0; 680 while (i-- > 0) 681 { 682 if (pTab->paEntries[i].fActive) 683 { 684 bool fExact = intnetR0AreMacAddrsEqual(&pTab->paEntries[i].MacAddr, pDstAddr); 685 if (fExact || pTab->paEntries[i].fPromiscuous) 686 { 687 cExactHits += fExact; 688 689 PINTNETIF pIf = pTab->paEntries[i].pIf; 690 pDstTab->apIfs[i] = pIf; 691 ASMAtomicIncU32(&pIf->cBusy); 692 pDstTab->cIfs++; 693 } 694 } 695 } 696 697 /* Does it match the host, or is the host promiscuous? */ 698 if (pTab->fHostActive) 699 { 700 bool fExact = intnetR0AreMacAddrsEqual(&pTab->HostMac, pDstAddr); 701 if (pTab->fHostPromiscuous) 702 { 703 cExactHits += fExact; 704 pDstTab->fTrunkDst |= INTNETTRUNKDIR_HOST; 705 } 706 } 707 708 /* Hit the wire if there are no exact matches or if it's in promiscuous mode. */ 709 if (pTab->fWireActive && (!cExactHits || pTab->fWirePromiscuous)) 710 pDstTab->fTrunkDst |= INTNETTRUNKDIR_WIRE; 711 } 712 713 /* Grab the trunk if we're sending to it. */ 714 if (pDstTab->fTrunkDst) 715 { 716 PINTNETTRUNKIF pTrunkIf = pTab->pTrunk; 717 pDstTab->pTrunk = pTrunkIf; 718 ASMAtomicIncU32(&pTrunkIf->cBusy); 719 } 720 } 721 722 RTSpinlockRelease(pTab->hSpinlock, &Tmp); 723 return pDstTab; 724 } 725 726 727 #endif /* WITH_NEW_STUFF */ 728 729 464 730 /** 465 731 * Retain an interface. … … 1638 1904 1639 1905 if (fDst == INTNETTRUNKDIR_HOST) 1640 return !!(pThis->f GsoCapabilitesHost& fMask);1906 return !!(pThis->fHostGsoCapabilites & fMask); 1641 1907 if (fDst == INTNETTRUNKDIR_WIRE) 1642 return !!(pThis->f GsoCapabilitesWire& fMask);1908 return !!(pThis->fWireGsoCapabilites & fMask); 1643 1909 Assert(fDst == (INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST)); 1644 return !!(pThis->f GsoCapabilitesHost & pThis->fGsoCapabilitesWire& fMask);1910 return !!(pThis->fHostGsoCapabilites & pThis->fWireGsoCapabilites & fMask); 1645 1911 } 1646 1912 … … 2227 2493 2228 2494 /* promiscuous checks first as they are cheaper than pfnIsHostMac. */ 2229 if ( pTrunkIf->f PromiscuousWire2495 if ( pTrunkIf->fWirePromiscuous 2230 2496 && !(pNetwork->fFlags & (INTNET_OPEN_FLAGS_IGNORE_PROMISC | INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC | INTNET_OPEN_FLAGS_IGNORE_PROMISC_TRUNK_WIRE | INTNET_OPEN_FLAGS_QUIETLY_IGNORE_PROMISC_TRUNK_WIRE)) ) 2231 2497 fDst |= INTNETTRUNKDIR_WIRE; … … 3322 3588 3323 3589 if (fDst & INTNETTRUNKDIR_HOST) 3324 pThis->f GsoCapabilitesHost= fGsoCapabilities;3590 pThis->fHostGsoCapabilites = fGsoCapabilities; 3325 3591 3326 3592 if (fDst & INTNETTRUNKDIR_WIRE) 3327 pThis->f GsoCapabilitesWire= fGsoCapabilities;3593 pThis->fWireGsoCapabilites = fGsoCapabilities; 3328 3594 } 3329 3595 … … 3648 3914 pTrunkIF->CachedMac.au8[5] = 0xff; 3649 3915 //pTrunkIF->fPhysSG = false; 3650 //pTrunkIF->f PromiscuousWire= false;3916 //pTrunkIF->fWirePromiscuous = false; 3651 3917 //pTrunkIF->fGroksGso = false; /** @todo query GSO support after connecting. */ 3652 3918 int rc = RTSemFastMutexCreate(&pTrunkIF->FastMutex);
Note:
See TracChangeset
for help on using the changeset viewer.