VirtualBox

Changeset 28430 in vbox


Ignore:
Timestamp:
Apr 17, 2010 2:30:31 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
60201
Message:

SrcIntNetR0.cpp: started on the rewrie, all changes disabled as they are very incomplete.

File:
1 edited

Legend:

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

    r28208 r28430  
    5050#define INTNET_WITH_DHCP_SNOOPING
    5151
     52#if 0
     53/** Enables the new code - temporarily while doing the rewrite. */
     54# define WITH_NEW_STUFF
     55#endif
     56
     57
    5258
    5359/*******************************************************************************
    5460*   Structures and Typedefs                                                    *
    5561*******************************************************************************/
     62#ifdef WITH_NEW_STUFF
     63/**
     64 * MAC address lookup table entry.
     65 */
     66typedef 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. */
     81typedef INTNETMACTABENTRY *PINTNETMACTABENTRY;
     82/** Pointer to a const MAC address lookup table entry. */
     83typedef INTNETMACTABENTRY const *PCINTNETMACTABENTRY;
     84
     85/**
     86 * MAC address lookup table.
     87 */
     88typedef 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 .  */
     115typedef INTNETMACTAB *PINTNETMACTAB;
     116
     117/**
     118 * Destination table.
     119 */
     120typedef 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. */
     132typedef INTNETDSTTAB *PINTNETDSTTAB;
     133#endif /* WITH_NEW_STUFF */
     134
     135
     136/** Network layer address type. */
    56137typedef enum INTNETADDRTYPE
    57138{
     
    79160{
    80161    /** The address type. */
    81     INTNETADDRTYPE enmType;
     162    INTNETADDRTYPE          enmType;
    82163    /** The address. */
    83     RTNETADDRU Addr;
     164    RTNETADDRU              Addr;
    84165} INTNETADDR;
    85166/** Pointer to an address. */
     
    95176{
    96177    /** Pointer to the table of addresses. */
    97     uint8_t *pbEntries;
     178    uint8_t                *pbEntries;
    98179    /** The number of valid address entries. */
    99     uint8_t cEntries;
     180    uint8_t                 cEntries;
    100181    /** The number of allocated address entries. */
    101     uint8_t cEntriesAlloc;
     182    uint8_t                 cEntriesAlloc;
    102183    /** The address size. */
    103     uint8_t cbAddress;
     184    uint8_t                 cbAddress;
    104185    /** The size of an entry. */
    105     uint8_t cbEntry;
     186    uint8_t                 cbEntry;
    106187} INTNETADDRCACHE;
    107188/** Pointer to an address cache. */
     
    121202     * This is protected by the INTNET::FastMutex. */
    122203    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.  */
    124206    RTMAC                   Mac;
    125207    /** Set if the INTNET::Mac member is valid. */
     
    133215    bool volatile           fDestroying;
    134216    /** Number of yields done to try make the interface read pending data.
    135      * We will stop yeilding when this reaches a threshold assuming that the VM is paused or
    136      * 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. */
    138220    uint32_t                cYields;
    139221    /** Pointer to the current exchange buffer (ring-0). */
     
    162244    /** The network layer address cache. (Indexed by type, 0 entry isn't used.) */
    163245    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 */
    164260} INTNETIF;
    165261/** Pointer to an internal network interface. */
     
    176272    /** The port interface we get from the component. */
    177273    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
    178279    /** The trunk mutex that serializes all calls <b>to</b> the component. */
    179280    RTSEMFASTMUTEX          FastMutex;
     281#endif
    180282    /** Pointer to the network we're connect to.
    181283     * This may be NULL if we're orphaned? */
    182284    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
    183291    /** The cached MAC address of the interface the trunk is attached to.
    184292     * This is for the situations where we cannot take the out-bound
    185293     * semaphore (the recv case) but need to make frame edits (ARP). */
    186294    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) */
    188298    bool volatile           fPhysSG;
    189299    /** Set if the 'wire' is in promiscuous mode.
    190300     * 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)
    193323     * This is as bit map where each bit represents the GSO type with the same
    194324     * number. */
    195     uint32_t                fGsoCapabilitesHost;
    196     /** The GSO capabilities of the wire destination. */
    197     uint32_t                fGsoCapabilitesWire;
     325    uint32_t                fHostGsoCapabilites;
    198326    /** Header buffer for when we're carving GSO frames. */
    199327    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
    200332} INTNETTRUNKIF;
    201333/** Pointer to a trunk interface. */
     
    222354    /** The network mutex.
    223355     * 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
    224361    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
    225368    /** Pointer to the instance data. */
    226369    struct INTNET          *pIntNet;
     
    462605
    463606
     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 */
     616DECL_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 */
     634static 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
    464730/**
    465731 * Retain an interface.
     
    16381904
    16391905    if (fDst == INTNETTRUNKDIR_HOST)
    1640         return !!(pThis->fGsoCapabilitesHost & fMask);
     1906        return !!(pThis->fHostGsoCapabilites & fMask);
    16411907    if (fDst == INTNETTRUNKDIR_WIRE)
    1642         return !!(pThis->fGsoCapabilitesWire & fMask);
     1908        return !!(pThis->fWireGsoCapabilites & fMask);
    16431909    Assert(fDst == (INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST));
    1644     return !!(pThis->fGsoCapabilitesHost & pThis->fGsoCapabilitesWire & fMask);
     1910    return !!(pThis->fHostGsoCapabilites & pThis->fWireGsoCapabilites & fMask);
    16451911}
    16461912
     
    22272493
    22282494        /* promiscuous checks first as they are cheaper than pfnIsHostMac. */
    2229         if (    pTrunkIf->fPromiscuousWire
     2495        if (    pTrunkIf->fWirePromiscuous
    22302496            &&  !(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)) )
    22312497            fDst |= INTNETTRUNKDIR_WIRE;
     
    33223588
    33233589    if (fDst & INTNETTRUNKDIR_HOST)
    3324         pThis->fGsoCapabilitesHost = fGsoCapabilities;
     3590        pThis->fHostGsoCapabilites = fGsoCapabilities;
    33253591
    33263592    if (fDst & INTNETTRUNKDIR_WIRE)
    3327         pThis->fGsoCapabilitesWire = fGsoCapabilities;
     3593        pThis->fWireGsoCapabilites = fGsoCapabilities;
    33283594}
    33293595
     
    36483914    pTrunkIF->CachedMac.au8[5] = 0xff;
    36493915    //pTrunkIF->fPhysSG = false;
    3650     //pTrunkIF->fPromiscuousWire = false;
     3916    //pTrunkIF->fWirePromiscuous = false;
    36513917    //pTrunkIF->fGroksGso = false;  /** @todo query GSO support after connecting. */
    36523918    int rc = RTSemFastMutexCreate(&pTrunkIF->FastMutex);
Note: See TracChangeset for help on using the changeset viewer.

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