VirtualBox

Changeset 94274 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Mar 16, 2022 5:36:35 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
150533
Message:

Dev/E1000: bugref:10197 Improved handling of mixed descriptor types, VLAN tag additional check

File:
1 edited

Legend:

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

    r93115 r94274  
    776776#define E1K_DTYP_CONTEXT 0
    777777#define E1K_DTYP_DATA    1
     778#define E1K_DTYP_INVALID 2
    778779
    779780struct E1kTDLegacy
     
    17101711    uint32_t tdh;
    17111712    uint32_t tdt;
     1713    uint8_t  nextPacket;
    17121714};
    17131715typedef struct E1kTxDContext E1KTXDC, *PE1KTXDC;
     
    37193721 * @param   pCtx                The context descriptor.
    37203722 */
    3721 DECLINLINE(void) e1kSetupGsoCtx(PPDMNETWORKGSO pGso, E1KTXCTX const *pCtx)
     3723DECLINLINE(bool) e1kSetupGsoCtx(PPDMNETWORKGSO pGso, E1KTXCTX const *pCtx)
    37223724{
    37233725    pGso->u8Type = PDMNETWORKGSOTYPE_INVALID;
     
    37313733    {
    37323734        E1kLog(("e1kSetupGsoCtx: IPCSS=%#x\n", pCtx->ip.u8CSS));
    3733         return;
     3735        return false;
    37343736    }
    37353737    if (RT_UNLIKELY( pCtx->tu.u8CSS     < (size_t)pCtx->ip.u8CSS + (pCtx->dw2.fIP  ? RTNETIPV4_MIN_LEN : RTNETIPV6_MIN_LEN) ))
    37363738    {
    37373739        E1kLog(("e1kSetupGsoCtx: TUCSS=%#x\n", pCtx->tu.u8CSS));
    3738         return;
     3740        return false;
    37393741    }
    37403742    if (RT_UNLIKELY(   pCtx->dw2.fTCP
     
    37433745    {
    37443746        E1kLog(("e1kSetupGsoCtx: HDRLEN=%#x TCP=%d\n", pCtx->dw3.u8HDRLEN, pCtx->dw2.fTCP));
    3745         return;
     3747        return false;
    37463748    }
    37473749
     
    37503752    {
    37513753        E1kLog(("e1kSetupGsoCtx: TUCSE=%#x HDRLEN=%#x\n", pCtx->tu.u16CSE, pCtx->dw3.u8HDRLEN));
    3752         return;
     3754        return false;
    37533755    }
    37543756
     
    37573759    {
    37583760        E1kLog(("e1kSetupGsoCtx: IPCSO=%#x IPCSS=%#x\n", pCtx->ip.u8CSO, pCtx->ip.u8CSS));
    3759         return;
     3761        return false;
    37603762    }
    37613763
     
    37673769    {
    37683770        E1kLog(("e1kSetupGsoCtx: TUCSO=%#x TUCSS=%#x TCP=%d\n", pCtx->ip.u8CSO, pCtx->ip.u8CSS, pCtx->dw2.fTCP));
    3769         return;
     3771        return false;
    37703772    }
    37713773
     
    37783780        E1kLog(("e1kSetupGsoCtx: HDRLEN(=%#x) + PAYLEN(=%#x) = %#x, max is %#x\n",
    37793781                pCtx->dw3.u8HDRLEN, pCtx->dw2.u20PAYLEN, pCtx->dw3.u8HDRLEN + pCtx->dw2.u20PAYLEN, VBOX_MAX_GSO_SIZE));
    3780         return;
     3782        return false;
    37813783    }
    37823784
     
    38153817    E1kLog2(("e1kSetupGsoCtx: mss=%#x hdr=%#x hdrseg=%#x hdr1=%#x hdr2=%#x %s\n",
    38163818             pGso->cbMaxSeg, pGso->cbHdrsTotal, pGso->cbHdrsSeg, pGso->offHdr1, pGso->offHdr2, PDMNetGsoTypeName((PDMNETWORKGSOTYPE)pGso->u8Type) ));
     3819    return PDMNetGsoIsValid(pGso, sizeof(*pGso), pGso->cbMaxSeg * 5);
    38173820}
    38183821
     
    41784181    Assert(!pSg || pSg->cSegs == 1);
    41794182
     4183    if (cbFrame < 14)
     4184    {
     4185        Log(("%s Ignoring invalid frame (%u bytes)\n", pThis->szPrf, cbFrame));
     4186        return;
     4187    }
    41804188    if (cbFrame > 70) /* unqualified guess */
    41814189        pThis->led.Asserted.s.fWriting = pThis->led.Actual.s.fWriting = 1;
     
    42034211
    42044212    /* Add VLAN tag */
    4205     if (cbFrame > 12 && pThis->fVTag)
     4213    if (cbFrame > 12 && pThis->fVTag && pSg->cbUsed + 4 <= pSg->cbAvailable)
    42064214    {
    42074215        E1kLog3(("%s Inserting VLAN tag %08x\n",
     
    52775285            {
    52785286                E1kLog(("%s Empty legacy descriptor, skipped.\n", pThis->szPrf));
     5287                if (pDesc->data.cmd.fEOP)
     5288                {
     5289                    e1kTransmitFrame(pDevIns, pThis, pThisCC, fOnWorkerThread);
     5290                    pThis->u16TxPktLen = 0;
     5291                }
    52795292            }
    52805293            else
     
    53255338    if (pDesc->context.dw2.fTSE)
    53265339    {
     5340        if (!e1kSetupGsoCtx(&pThis->GsoCtx, &pDesc->context))
     5341        {
     5342            pThis->contextTSE.dw2.u4DTYP = E1K_DTYP_INVALID;
     5343            return false;
     5344        }
    53275345        pThis->contextTSE = pDesc->context;
    53285346        uint32_t cbMaxSegmentSize = pThis->contextTSE.dw3.u16MSS + pThis->contextTSE.dw3.u8HDRLEN + 4; /*VTAG*/
     
    53555373}
    53565374
    5357 static bool e1kLocateTxPacket(PE1KSTATE pThis)
     5375enum E1kPacketType
     5376{
     5377    E1K_PACKET_NONE = 0,
     5378    E1K_PACKET_LEGACY,
     5379    E1K_PACKET_NORMAL,
     5380    E1K_PACKET_TSE
     5381};
     5382
     5383static int e1kLocateTxPacket(PE1KSTATE pThis, PE1KTXDC pTxdc)
    53585384{
    53595385    LogFlow(("%s e1kLocateTxPacket: ENTER cbTxAlloc=%d\n",
     
    53675393    }
    53685394
     5395    pThis->fGSO = false;
     5396    pThis->fVTag = false;
     5397    pThis->fIPcsum  = false;
     5398    pThis->fTCPcsum = false;
     5399    pThis->u16TxPktLen = 0;
     5400
     5401    enum E1kPacketType packetType = E1K_PACKET_NONE;
     5402    enum E1kPacketType expectedPacketType = E1K_PACKET_NONE;
     5403    /*
     5404     * Valid packets start with 1 or 0 context descriptors, followed by 1 or
     5405     * more data descriptors of the same type: legacy, normal or TSE. Note
     5406     * that legacy descriptors do not belong to neither normal nor segmentation
     5407     * contexts rendering the sequence (context_descriptor, legacy_descriptor)
     5408     * invalid, but the context descriptor will still be applied and the legacy
     5409     * descriptor will be treated as the beginning of next packet.
     5410     */
     5411    bool fInvalidPacket = false;
    53695412    bool fTSE = false;
    53705413    uint32_t cbPacket = 0;
     
    53755418    {
    53765419        E1KTXDESC *pDesc = &pThis->aTxDescriptors[i];
    5377         /* Assume the descriptor valid until proven otherwise. */
    5378         pThis->afTxDValid[i] = true;
     5420
    53795421        switch (e1kGetDescType(pDesc))
    53805422        {
    53815423            case E1K_DTYP_CONTEXT:
     5424                /* There can be only one context per packet. Each context descriptor starts a new packet. */
     5425                if (packetType != E1K_PACKET_NONE)
     5426                {
     5427                    fInvalidPacket = true;
     5428                    break;
     5429                }
     5430                packetType = (pDesc->context.dw2.fTSE) ? E1K_PACKET_TSE : E1K_PACKET_NORMAL;
    53825431                if (cbPacket == 0)
    53835432                    pThis->afTxDValid[i] = e1kUpdateTxContext(pThis, pDesc);
     
    53875436                continue;
    53885437            case E1K_DTYP_LEGACY:
     5438                if (packetType != E1K_PACKET_NONE && packetType != E1K_PACKET_LEGACY)
     5439                {
     5440                    fInvalidPacket = true;
     5441                    break;
     5442                }
     5443                packetType = E1K_PACKET_LEGACY;
    53895444                /* Skip invalid descriptors. */
    53905445                if (cbPacket > 0 && (pThis->fGSO || fTSE))
     
    53925447                    E1kLog(("%s e1kLocateTxPacket: ignoring a legacy descriptor in the segmentation context, cbPacket=%d\n",
    53935448                            pThis->szPrf, cbPacket));
    5394                     pThis->afTxDValid[i] = false; /* Make sure it is skipped by processing */
    53955449                    continue;
    53965450                }
     5451                pThis->afTxDValid[i] = true; /* Passed all checks, process it */
     5452
    53975453                /* Skip empty descriptors. */
    53985454                if (!pDesc->legacy.u64BufAddr || !pDesc->legacy.cmd.u16Length)
     
    54025458                break;
    54035459            case E1K_DTYP_DATA:
     5460                expectedPacketType = pDesc->data.cmd.fTSE ? E1K_PACKET_TSE : E1K_PACKET_NORMAL;
     5461                if (packetType != E1K_PACKET_NONE && packetType != expectedPacketType)
     5462                {
     5463                    fInvalidPacket = true;
     5464                    break;
     5465                }
    54045466                /* Skip invalid descriptors. */
     5467                if (pDesc->data.cmd.fTSE)
     5468                {
     5469                    if (pThis->contextTSE.dw2.u4DTYP == E1K_DTYP_INVALID)
     5470                    {
     5471                        E1kLog(("%s e1kLocateTxPacket: ignoring TSE descriptor in invalid segmentation context, cbPacket=%d\n",
     5472                                pThis->szPrf, cbPacket));
     5473                        continue;
     5474                    }
     5475                }
     5476                else /* !TSE */
     5477                {
     5478                    if (pThis->contextNormal.dw2.u4DTYP == E1K_DTYP_INVALID)
     5479                    {
     5480                        E1kLog(("%s e1kLocateTxPacket: ignoring non-TSE descriptor in invalid normal context, cbPacket=%d\n",
     5481                                pThis->szPrf, cbPacket));
     5482                        continue;
     5483                    }
     5484                }
    54055485                if (cbPacket > 0 && (bool)pDesc->data.cmd.fTSE != fTSE)
    54065486                {
    54075487                    E1kLog(("%s e1kLocateTxPacket: ignoring %sTSE descriptor in the %ssegmentation context, cbPacket=%d\n",
    54085488                            pThis->szPrf, pDesc->data.cmd.fTSE ? "" : "non-", fTSE ? "" : "non-", cbPacket));
    5409                     pThis->afTxDValid[i] = false; /* Make sure it is skipped by processing */
    54105489                    continue;
    54115490                }
     5491                pThis->afTxDValid[i] = true; /* Passed all checks, process it */
     5492
    54125493                /* Skip empty descriptors. */
    54135494                if (!pDesc->data.u64BufAddr || !pDesc->data.cmd.u20DTALEN)
     
    54395520                continue;
    54405521        }
     5522        if (fInvalidPacket)
     5523        {
     5524            for (int index = pThis->iTxDCurrent; index < i; ++index)
     5525                pThis->afTxDValid[index] = false; /* Make sure all descriptors for this packet are skipped by processing */
     5526            LogFlow(("%s e1kLocateTxPacket: marked %d descriptors as invalid\n", pThis->szPrf, i - pThis->iTxDCurrent));
     5527            LogFlow(("%s e1kLocateTxPacket: RET true cbTxAlloc=%d cbPacket=%d%s%s\n",
     5528                     pThis->szPrf, pThis->cbTxAlloc, cbPacket,
     5529                     pThis->fGSO ? " GSO" : "", fTSE ? " TSE" : ""));
     5530            pTxdc->nextPacket = i;
     5531            return true;
     5532        }
    54415533        if (pDesc->legacy.cmd.fEOP)
    54425534        {
     
    54635555                     pThis->szPrf, pThis->cbTxAlloc, cbPacket,
    54645556                     pThis->fGSO ? " GSO" : "", fTSE ? " TSE" : ""));
     5557            pTxdc->nextPacket = i + 1;
    54655558            return true;
    54665559        }
     
    54725565        LogFlow(("%s e1kLocateTxPacket: RET true cbTxAlloc=%d, zero packet!\n",
    54735566                 pThis->szPrf, pThis->cbTxAlloc));
     5567        pTxdc->nextPacket = pThis->nTxDFetched;
    54745568        return true;
    54755569    }
     
    54875581             pThis->szPrf, pThis->iTxDCurrent, pThis->nTxDFetched));
    54885582
    5489     while (pThis->iTxDCurrent < pThis->nTxDFetched)
     5583    while (pThis->iTxDCurrent < pTxdc->nextPacket && pThis->iTxDCurrent < pThis->nTxDFetched)
    54905584    {
    54915585        E1KTXDESC *pDesc = &pThis->aTxDescriptors[pThis->iTxDCurrent];
     
    56795773        while (fTxContextValid && !pThis->fLocked && e1kTxDLazyLoad(pDevIns, pThis, &txdc))
    56805774        {
    5681             while (e1kLocateTxPacket(pThis))
     5775            while (e1kLocateTxPacket(pThis, &txdc))
    56825776            {
     5777                Log4(("%s e1kXmitPending: Located packet at %d. Next packet at %d\n",
     5778                      pThis->szPrf, pThis->iTxDCurrent, txdc.nextPacket));
    56835779                fIncomplete = false;
    56845780                /* Found a complete packet, allocate it. */
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