VirtualBox

Changeset 46904 in vbox for trunk


Ignore:
Timestamp:
Jul 2, 2013 12:59:56 PM (12 years ago)
Author:
vboxsync
Message:

IntNet, VirtioNet, NetFilter: Large frame support + drop oversized + UFO fix (#6821)

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/intnet.h

    r39034 r46904  
    214214typedef struct INTNETHDR
    215215{
     216    /** The size of the frame. */
     217    uint32_t        cbFrame : 24;
    216218    /** Header type. This is currently serving as a magic, it
    217219     * can be extended later to encode special command frames and stuff. */
    218     uint16_t        u16Type;
    219     /** The size of the frame. */
    220     uint16_t        cbFrame;
     220    uint32_t        u8Type  : 8;
    221221    /** The offset from the start of this header to where the actual frame starts.
    222222     * This is used to keep the frame it self contiguous in virtual memory and
     
    236236AssertCompile(INTNETHDR_ALIGNMENT <= INTNETRINGBUF_ALIGNMENT);
    237237
    238 /** @name Frame types (INTNETHDR::u16Type).
     238/** @name Frame types (INTNETHDR::u8Type).
    239239 * @{ */
    240240/** Normal frames. */
    241 #define INTNETHDR_TYPE_FRAME        0x2442
     241#define INTNETHDR_TYPE_FRAME        0x42
    242242/** Padding frames. */
    243 #define INTNETHDR_TYPE_PADDING      0x3553
     243#define INTNETHDR_TYPE_PADDING      0x53
    244244/** Generic segment offload frames.
    245245 * The frame starts with a PDMNETWORKGSO structure which is followed by the
    246246 * header template and data. */
    247 #define INTNETHDR_TYPE_GSO          0x4664
     247#define INTNETHDR_TYPE_GSO          0x64
    248248AssertCompileSize(PDMNETWORKGSO, 8);
    249249/** @}  */
     
    258258        AssertPtr(pHdr); \
    259259        Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr); \
    260         Assert(   (pHdr)->u16Type == INTNETHDR_TYPE_FRAME \
    261                || (pHdr)->u16Type == INTNETHDR_TYPE_GSO \
    262                || (pHdr)->u16Type == INTNETHDR_TYPE_PADDING); \
     260        Assert(   (pHdr)->u8Type == INTNETHDR_TYPE_FRAME \
     261               || (pHdr)->u8Type == INTNETHDR_TYPE_GSO \
     262               || (pHdr)->u8Type == INTNETHDR_TYPE_PADDING); \
    263263        { \
    264264            uintptr_t const offHdr   = (uintptr_t)pHdr - (uintptr_t)pRingBuf; \
  • trunk/include/VBox/intnetinline.h

    r44528 r46904  
    4444 *
    4545 * @returns  true / false.
    46  * @param   u16Type             The frame type to check.
    47  */
    48 DECLINLINE(bool) IntNetIsValidFrameType(uint16_t u16Type)
    49 {
    50     if (RT_LIKELY(   u16Type == INTNETHDR_TYPE_FRAME
    51                   || u16Type == INTNETHDR_TYPE_GSO
    52                   || u16Type == INTNETHDR_TYPE_PADDING))
     46 * @param    u8Type             The frame type to check.
     47 */
     48DECLINLINE(bool) IntNetIsValidFrameType(uint8_t u8Type)
     49{
     50    if (RT_LIKELY(   u8Type == INTNETHDR_TYPE_FRAME
     51                  || u8Type == INTNETHDR_TYPE_GSO
     52                  || u8Type == INTNETHDR_TYPE_PADDING))
    5353        return true;
    5454    return false;
     
    328328#ifdef VBOX_STRICT
    329329    const uintptr_t off = (uintptr_t)pu8 - (uintptr_t)pBuf;
    330     Assert(IntNetIsValidFrameType(pHdr->u16Type));
     330    Assert(IntNetIsValidFrameType(pHdr->u8Type));
    331331    Assert(off < pBuf->cbBuf);
    332332    Assert(off + pHdr->cbFrame <= pBuf->cbBuf);
     
    354354#ifdef VBOX_STRICT
    355355    const uintptr_t off = (uintptr_t)pGso - (uintptr_t)pBuf;
    356     Assert(pHdr->u16Type == INTNETHDR_TYPE_GSO);
     356    Assert(pHdr->u8Type == INTNETHDR_TYPE_GSO);
    357357    Assert(off < pBuf->cbBuf);
    358358    Assert(off + pHdr->cbFrame <= pBuf->cbBuf);
     
    375375    Assert(offReadOld <  pRingBuf->offEnd);
    376376    Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr);
    377     Assert(IntNetIsValidFrameType(pHdr->u16Type));
     377    Assert(IntNetIsValidFrameType(pHdr->u8Type));
    378378
    379379    /* skip the frame */
     
    402402 * @param   ppvFrame            Where to return the frame pointer.
    403403 */
    404 DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, uint16_t u16Type,
     404DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, uint8_t u8Type,
    405405                                                PINTNETHDR *ppHdr, void **ppvFrame)
    406406{
     
    426426            if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt)))
    427427                return VERR_WRONG_ORDER; /* race */
    428             Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (1) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame));
     428            Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (1) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u8Type, cbFrame));
    429429
    430430            PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
    431             pHdr->u16Type  = u16Type;
    432             pHdr->cbFrame  = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
     431            pHdr->u8Type   = u8Type;
     432            pHdr->cbFrame  = cbFrame; Assert(pHdr->cbFrame == cbFrame);
    433433            pHdr->offFrame = sizeof(INTNETHDR);
    434434
     
    447447            if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt)))
    448448                return VERR_WRONG_ORDER; /* race */
    449             Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (2) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame));
     449            Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (2) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u8Type, cbFrame));
    450450
    451451            PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
    452             pHdr->u16Type  = u16Type;
    453             pHdr->cbFrame  = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
     452            pHdr->u8Type   = u8Type;
     453            pHdr->cbFrame  = cbFrame; Assert(pHdr->cbFrame == cbFrame);
    454454            pHdr->offFrame = pRingBuf->offStart - offWriteInt;
    455455
     
    467467        if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt)))
    468468            return VERR_WRONG_ORDER; /* race */
    469         Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (3) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame));
     469        Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (3) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u8Type, cbFrame));
    470470
    471471        PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
    472         pHdr->u16Type  = u16Type;
    473         pHdr->cbFrame  = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
     472        pHdr->u8Type   = u8Type;
     473        pHdr->cbFrame  = cbFrame; Assert(pHdr->cbFrame == cbFrame);
    474474        pHdr->offFrame = sizeof(INTNETHDR);
    475475
     
    561561        offWriteCom = pRingBuf->offStart;
    562562    }
    563     Log2(("IntNetRingCommitFrame:   offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u16Type, cbFrame));
     563    Log2(("IntNetRingCommitFrame:   offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u8Type, cbFrame));
    564564    ASMAtomicWriteU32(&pRingBuf->offWriteCom, offWriteCom);
    565565    STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbFrame);
     
    589589    Assert(pRingBuf->offWriteCom == ((uintptr_t)pHdr - (uintptr_t)pRingBuf));
    590590
    591     if (pHdr->u16Type == INTNETHDR_TYPE_GSO)
     591    if (pHdr->u8Type == INTNETHDR_TYPE_GSO)
    592592        cbUsed += sizeof(PDMNETWORKGSO);
    593593
     
    613613        /** @todo Later: Try unallocate the extra memory.  */
    614614        PINTNETHDR pHdrPadding = (PINTNETHDR)((uint8_t *)pHdr + pHdr->offFrame + cbAlignedUsed);
    615         pHdrPadding->u16Type  = INTNETHDR_TYPE_PADDING;
    616         pHdrPadding->cbFrame  = (uint16_t)(cbAlignedFrame - cbAlignedUsed - sizeof(INTNETHDR));
     615        pHdrPadding->u8Type   = INTNETHDR_TYPE_PADDING;
     616        pHdrPadding->cbFrame  = cbAlignedFrame - cbAlignedUsed - sizeof(INTNETHDR);
     617        Assert(pHdrPadding->cbFrame == cbAlignedFrame - cbAlignedUsed - sizeof(INTNETHDR));
    617618        pHdrPadding->offFrame = sizeof(INTNETHDR);
    618         pHdr->cbFrame = (uint16_t)cbUsed;
    619     }
    620 
    621     Log2(("IntNetRingCommitFrameEx:   offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x P=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u16Type, pHdr->cbFrame, cbAlignedFrame - cbAlignedUsed));
     619        pHdr->cbFrame = cbUsed; Assert(pHdr->cbFrame == cbUsed);
     620    }
     621
     622    Log2(("IntNetRingCommitFrameEx:   offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x P=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u8Type, pHdr->cbFrame, cbAlignedFrame - cbAlignedUsed));
    622623    ASMAtomicWriteU32(&pRingBuf->offWriteCom, offWriteCom);
    623624    STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbUsed);
     
    665666
    666667            PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
    667             pHdr->u16Type  = INTNETHDR_TYPE_FRAME;
    668             pHdr->cbFrame  = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
     668            pHdr->u8Type   = INTNETHDR_TYPE_FRAME;
     669            pHdr->cbFrame  = cbFrame; Assert(pHdr->cbFrame == cbFrame);
    669670            pHdr->offFrame = sizeof(INTNETHDR);
    670671
     
    690691
    691692            PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
    692             pHdr->u16Type  = INTNETHDR_TYPE_FRAME;
    693             pHdr->cbFrame  = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
     693            pHdr->u8Type   = INTNETHDR_TYPE_FRAME;
     694            pHdr->cbFrame  = cbFrame; Assert(pHdr->cbFrame == cbFrame);
    694695            pHdr->offFrame = pRingBuf->offStart - offWriteInt;
    695696
     
    714715
    715716        PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
    716         pHdr->u16Type  = INTNETHDR_TYPE_FRAME;
    717         pHdr->cbFrame  = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
     717        pHdr->u8Type   = INTNETHDR_TYPE_FRAME;
     718        pHdr->cbFrame  = cbFrame; Assert(pHdr->cbFrame == cbFrame);
    718719        pHdr->offFrame = sizeof(INTNETHDR);
    719720
  • trunk/src/VBox/Devices/Network/DevVirtioNet.cpp

    r46576 r46904  
    6767
    6868#define VNET_TX_DELAY           150   /**< 150 microseconds */
    69 #define VNET_MAX_FRAME_SIZE     65536  ///< @todo Is it the right limit?
     69#define VNET_MAX_FRAME_SIZE     65535 + 18  /**< Max IP packet size + Ethernet header with VLAN tag */
    7070#define VNET_MAC_FILTER_LEN     32
    7171#define VNET_MAX_VID            (1 << 12)
     
    386386        | VNET_F_HOST_TSO4
    387387        | VNET_F_HOST_TSO6
    388 /*        | VNET_F_HOST_UFO   -- Disabled temporarely (see @bugref{6821}) */
     388        | VNET_F_HOST_UFO
    389389        | VNET_F_GUEST_CSUM   /* We expect the guest to accept partial TCP checksums (see @bugref{4796}) */
    390390        | VNET_F_GUEST_TSO4
     
    11551155            for (unsigned int i = 1; i < elem.nOut; i++)
    11561156                uSize += elem.aSegsOut[i].cb;
     1157            Log5(("%s vnetTransmitPendingPackets: complete frame is %u bytes.\n",
     1158                  INSTANCE(pThis), uSize));
    11571159            Assert(uSize <= VNET_MAX_FRAME_SIZE);
    11581160            if (pThis->pDrv)
     
    12111213                            /* Update GSO structure embedded into the frame */
    12121214                            ((PPDMNETWORKGSO)pSgBuf->pvUser)->cbHdrsTotal = pGso->cbHdrsTotal;
    1213                             ((PPDMNETWORKGSO)pSgBuf->pvUser)->cbHdrsSeg   = pGso->cbHdrsTotal;
     1215                            ((PPDMNETWORKGSO)pSgBuf->pvUser)->cbHdrsSeg   = pGso->cbHdrsSeg;
    12141216                            Log4(("%s vnetTransmitPendingPackets: adjusted HdrLen to %d.\n",
    12151217                                  INSTANCE(pThis), pGso->cbHdrsTotal));
  • trunk/src/VBox/Devices/Network/DrvIntNet.cpp

    r46326 r46904  
    463463    Assert(pSgBuf->fFlags == (PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1));
    464464    Assert(pSgBuf->cbUsed <= pSgBuf->cbAvailable);
    465     Assert(   pHdr->u16Type == INTNETHDR_TYPE_FRAME
    466            || pHdr->u16Type == INTNETHDR_TYPE_GSO);
     465    Assert(   pHdr->u8Type == INTNETHDR_TYPE_FRAME
     466           || pHdr->u8Type == INTNETHDR_TYPE_GSO);
    467467    Assert(PDMCritSectIsOwner(&pThis->XmitLock));
    468468
    469469    /** @todo LATER: try unalloc the frame. */
    470     pHdr->u16Type = INTNETHDR_TYPE_PADDING;
     470    pHdr->u8Type = INTNETHDR_TYPE_PADDING;
    471471    IntNetRingCommitFrame(&pThis->CTX_SUFF(pBuf)->Send, pHdr);
    472472
     
    703703
    704704            Log2(("pHdr=%p offRead=%#x: %.8Rhxs\n", pHdr, pRingBuf->offReadX, pHdr));
    705             uint16_t u16Type = pHdr->u16Type;
    706             if (    (   u16Type == INTNETHDR_TYPE_FRAME
    707                      || u16Type == INTNETHDR_TYPE_GSO)
     705            uint8_t u8Type = pHdr->u8Type;
     706            if (    (   u8Type == INTNETHDR_TYPE_FRAME
     707                     || u8Type == INTNETHDR_TYPE_GSO)
    708708                &&  !pThis->fLinkDown)
    709709            {
     
    715715                if (rc == VINF_SUCCESS)
    716716                {
    717                     if (u16Type == INTNETHDR_TYPE_FRAME)
     717                    if (u8Type == INTNETHDR_TYPE_FRAME)
    718718                    {
    719719                        /*
     
    814814                             * NIC is going down, likely because the VM is being reset. Skip the frame.
    815815                             */
    816                             AssertMsg(IntNetIsValidFrameType(pHdr->u16Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u16Type, pRingBuf->offReadX));
     816                            AssertMsg(IntNetIsValidFrameType(pHdr->u8Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u8Type, pRingBuf->offReadX));
    817817                            IntNetRingSkipFrame(pRingBuf);
    818818                        }
     
    831831                 * Link down or unknown frame - skip to the next frame.
    832832                 */
    833                 AssertMsg(IntNetIsValidFrameType(pHdr->u16Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u16Type, pRingBuf->offReadX));
     833                AssertMsg(IntNetIsValidFrameType(pHdr->u8Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u8Type, pRingBuf->offReadX));
    834834                IntNetRingSkipFrame(pRingBuf);
    835835                STAM_REL_COUNTER_INC(&pBuf->cStatBadFrames);
  • trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp

    r45717 r46904  
    26882688
    26892689    /*
     2690     * @todo: We have to adjust MSS so it does not exceed the value configured
     2691     * for the host's interface.
     2692     */
     2693
     2694    /*
    26902695     * Carve out the frame segments with the header and frame in different
    26912696     * scatter / gather segments.
     
    37443749            while ((pHdr = IntNetRingGetNextFrameToRead(&pIf->pIntBuf->Send)) != NULL)
    37453750            {
    3746                 uint16_t const      u16Type = pHdr->u16Type;
    3747                 if (u16Type == INTNETHDR_TYPE_FRAME)
     3751                uint8_t const      u8Type = pHdr->u8Type;
     3752                if (u8Type == INTNETHDR_TYPE_FRAME)
    37483753                {
    37493754                    /* Send regular frame. */
     
    37543759                    enmSwDecision = intnetR0NetworkSend(pNetwork, pIf,  0 /*fSrc*/, &Sg, pDstTab);
    37553760                }
    3756                 else if (u16Type == INTNETHDR_TYPE_GSO)
     3761                else if (u8Type == INTNETHDR_TYPE_GSO)
    37573762                {
    37583763                    /* Send GSO frame if sane. */
     
    37763781                else
    37773782                {
    3778                     if (u16Type != INTNETHDR_TYPE_PADDING)
     3783                    if (u8Type != INTNETHDR_TYPE_PADDING)
    37793784                        STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatBadFrames); /* ignore */
    37803785                    enmSwDecision = INTNETSWDECISION_DROP;
  • trunk/src/VBox/Devices/Network/testcase/tstIntNet-1.cpp

    r44528 r46904  
    463463        while ((pHdr = IntNetRingGetNextFrameToRead(pRingBuf)))
    464464        {
    465             if (pHdr->u16Type == INTNETHDR_TYPE_FRAME)
     465            if (pHdr->u8Type == INTNETHDR_TYPE_FRAME)
    466466            {
    467467                size_t      cbFrame = pHdr->cbFrame;
     
    540540                }
    541541            }
    542             else if (pHdr->u16Type == INTNETHDR_TYPE_GSO)
     542            else if (pHdr->u8Type == INTNETHDR_TYPE_GSO)
    543543            {
    544544                PCPDMNETWORKGSO pGso    = IntNetHdrGetGsoContext(pHdr, pBuf);
     
    568568                }
    569569            }
    570             else if (pHdr->u16Type != INTNETHDR_TYPE_PADDING)
     570            else if (pHdr->u8Type != INTNETHDR_TYPE_PADDING)
    571571            {
    572                 RTPrintf("tstIntNet-1: Unknown frame type %d\n", pHdr->u16Type);
     572                RTPrintf("tstIntNet-1: Unknown frame type %d\n", pHdr->u8Type);
    573573                STAM_REL_COUNTER_INC(&pBuf->cStatBadFrames);
    574574                g_cErrors++;
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h

    r44529 r46904  
    160160            /** Pointer to the device. */
    161161            struct net_device * volatile pDev;
     162            /** MTU of host's interface. */
     163            uint32_t cbMtu;
    162164            /** Whether we've successfully put the interface into to promiscuous mode.
    163165             * This is for dealing with the ENETDOWN case. */
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c

    r44528 r46904  
    542542
    543543/**
     544 * Checks whether this SG list contains a GSO packet.
     545 *
     546 * @returns true / false accordingly.
     547 * @param   pSG             The (scatter/)gather list.
     548 */
     549DECLINLINE(bool) vboxNetFltLinuxIsGso(PINTNETSG pSG)
     550{
     551#if defined(VBOXNETFLT_WITH_GSO_XMIT_WIRE) || defined(VBOXNETFLT_WITH_GSO_XMIT_HOST)
     552    return !((PDMNETWORKGSOTYPE)pSG->GsoCtx.u8Type == PDMNETWORKGSOTYPE_INVALID);
     553#else /* !VBOXNETFLT_WITH_GSO_XMIT_WIRE && !VBOXNETFLT_WITH_GSO_XMIT_HOST */
     554    return false;
     555#endif /* !VBOXNETFLT_WITH_GSO_XMIT_WIRE && !VBOXNETFLT_WITH_GSO_XMIT_HOST */
     556}
     557
     558
     559/**
     560 * Find out the frame size (of a single segment in case of GSO frames).
     561 *
     562 * @returns the frame size.
     563 * @param   pSG             The (scatter/)gather list.
     564 */
     565DECLINLINE(uint32_t) vboxNetFltLinuxFrameSize(PINTNETSG pSG)
     566{
     567    RTNETETHERHDR EthHdr;
     568    uint16_t      u16Type = 0;
     569    uint32_t      cbVlanTag = 0;
     570    if (pSG->aSegs[0].cb >= sizeof(EthHdr))
     571        u16Type = RT_BE2H_U16(((PCRTNETETHERHDR)pSG->aSegs[0].pv)->EtherType);
     572    else if (pSG->cbTotal >= sizeof(EthHdr))
     573    {
     574        uint32_t i, uOffset = RT_OFFSETOF(RTNETETHERHDR, EtherType);
     575        for (i = 0; i < pSG->cSegsUsed; ++i)
     576        {
     577            if (uOffset > pSG->aSegs[i].cb)
     578            {
     579                uOffset -= pSG->aSegs[i].cb;
     580                continue;
     581            }
     582            if (uOffset + sizeof(uint16_t) > pSG->aSegs[i].cb)
     583            {
     584                if (i + 1 < pSG->cSegsUsed)
     585                    u16Type = RT_BE2H_U16(  ((uint16_t)( ((uint8_t*)pSG->aSegs[i].pv)[uOffset] ) << 8)
     586                                          + *(uint8_t*)pSG->aSegs[i + 1].pv);
     587            }
     588            else
     589                u16Type = RT_BE2H_U16(*(uint16_t*)((uint8_t*)pSG->aSegs[i].pv + uOffset));
     590        }
     591    }
     592    if (u16Type == RTNET_ETHERTYPE_VLAN)
     593        cbVlanTag = 4;
     594    return (vboxNetFltLinuxIsGso(pSG) ? (uint32_t)pSG->GsoCtx.cbMaxSeg + pSG->GsoCtx.cbHdrsTotal : pSG->cbTotal) - cbVlanTag;
     595}
     596
     597
     598/**
    544599 * Internal worker that create a linux sk_buff for a
    545600 * (scatter/)gather list.
     
    559614    {
    560615        LogRel(("VBoxNetFlt: Dropped empty packet coming from internal network.\n"));
     616        return NULL;
     617    }
     618    Log5(("VBoxNetFlt: Packet to %s of %d bytes (frame=%d).\n", fDstWire?"wire":"host", pSG->cbTotal, vboxNetFltLinuxFrameSize(pSG)));
     619    if (fDstWire && (vboxNetFltLinuxFrameSize(pSG) > ASMAtomicReadU32(&pThis->u.s.cbMtu) + 14))
     620    {
     621        static bool fOnce = true;
     622        if (fOnce)
     623        {
     624            fOnce = false;
     625            printk("VBoxNetFlt: Dropped over-sized packet (%d bytes) coming from internal network.\n", vboxNetFltLinuxFrameSize(pSG));
     626        }
    561627        return NULL;
    562628    }
     
    15301596    /* Get the mac address while we still have a valid net_device reference. */
    15311597    memcpy(&pThis->u.s.MacAddr, pDev->dev_addr, sizeof(pThis->u.s.MacAddr));
     1598    /* Initialize MTU */
     1599    pThis->u.s.cbMtu = pDev->mtu;
    15321600
    15331601    /*
     
    16771745    else
    16781746        Log(("vboxNetFltLinuxDeviceGoingDown: no need to disable promiscuous mode on %s (%d)\n", pThis->szName, pDev->promiscuity));
     1747    return NOTIFY_OK;
     1748}
     1749
     1750/**
     1751 * Callback for listening to MTU change event.
     1752 *
     1753 * We need to track changes of host's inteface MTU to discard over-sized frames
     1754 * coming from the internal network as they may hang the TX queue of host's
     1755 * adapter.
     1756 *
     1757 * @returns NOTIFY_OK
     1758 * @param   pThis               The netfilter instance.
     1759 * @param   pDev                Pointer to device structure of host's interface.
     1760 */
     1761static int vboxNetFltLinuxDeviceMtuChange(PVBOXNETFLTINS pThis, struct net_device *pDev)
     1762{
     1763    ASMAtomicWriteU32(&pThis->u.s.cbMtu, pDev->mtu);
     1764    Log(("vboxNetFltLinuxDeviceMtuChange: set MTU for %s to %d\n", pThis->szName, pDev->mtu));
    16791765    return NOTIFY_OK;
    16801766}
     
    17471833                    rc = vboxNetFltLinuxDeviceGoingDown(pThis, pDev);
    17481834                    break;
     1835                case NETDEV_CHANGEMTU:
     1836                    rc = vboxNetFltLinuxDeviceMtuChange(pThis, pDev);
     1837                    break;
    17491838                case NETDEV_CHANGENAME:
    17501839                    break;
  • trunk/src/VBox/NetworkServices/NetLib/VBoxNetARP.cpp

    r44529 r46904  
    4444    PCINTNETHDR pHdr = IntNetRingGetNextFrameToRead(&pBuf->Recv);
    4545    if (   !pHdr
    46         || pHdr->u16Type != INTNETHDR_TYPE_FRAME)
     46        || pHdr->u8Type != INTNETHDR_TYPE_FRAME)
    4747        return false;
    4848
  • trunk/src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp

    r44529 r46904  
    6262    PCINTNETHDR pHdr = IntNetRingGetNextFrameToRead(&pBuf->Recv);
    6363    if (    !pHdr
    64         ||  (   pHdr->u16Type != INTNETHDR_TYPE_FRAME
    65              && pHdr->u16Type != INTNETHDR_TYPE_GSO))
     64        ||  (   pHdr->u8Type != INTNETHDR_TYPE_FRAME
     65             && pHdr->u8Type != INTNETHDR_TYPE_GSO))
    6666        return NULL;
    6767
     
    6969    const void     *pvFrame = IntNetHdrGetFramePtr(pHdr, pBuf);
    7070    PCPDMNETWORKGSO pGso    = NULL;
    71     if (pHdr->u16Type == INTNETHDR_TYPE_GSO)
     71    if (pHdr->u8Type == INTNETHDR_TYPE_GSO)
    7272    {
    7373        pGso = (PCPDMNETWORKGSO)pvFrame;
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