VirtualBox

Ignore:
Timestamp:
Apr 7, 2010 6:37:43 AM (15 years ago)
Author:
vboxsync
Message:

intnet, VBoxNet*, network device & drivers: GSO preps.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/NetworkServices/NAT/VBoxNetNAT.cpp

    r27976 r28025  
    268268        while ((pHdr = INTNETRingGetNextFrameToRead(pRingBuf)) != NULL)
    269269        {
    270             if (RT_LIKELY(pHdr->u16Type == INTNETHDR_TYPE_FRAME))
     270            uint16_t const u16Type = pHdr->u16Type;
     271            if (RT_LIKELY(   u16Type == INTNETHDR_TYPE_FRAME
     272                          || u16Type == INTNETHDR_TYPE_GSO))
    271273            {
    272                 size_t  cbFrame = pHdr->cbFrame;
    273                 size_t  cbIgnored;
    274                 void   *pvSlirpFrame;
    275                 struct mbuf *m = slirp_ext_m_get(g_pNAT->m_pNATState, cbFrame, &pvSlirpFrame, &cbIgnored);
    276                 if (!m)
     274                size_t       cbFrame = pHdr->cbFrame;
     275                size_t       cbIgnored;
     276                void        *pvSlirpFrame;
     277                struct mbuf *m;
     278                if (u16Type == INTNETHDR_TYPE_FRAME)
    277279                {
    278                     LogRel(("NAT: Can't allocate send buffer\n"));
    279                     break;
     280                    m = slirp_ext_m_get(g_pNAT->m_pNATState, cbFrame, &pvSlirpFrame, &cbIgnored);
     281                    if (!m)
     282                    {
     283                        LogRel(("NAT: Can't allocate send buffer cbFrame=%u\n", cbFrame));
     284                        break;
     285                    }
     286                    memcpy(pvSlirpFrame, INTNETHdrGetFramePtr(pHdr, m_pIfBuf), cbFrame);
     287                    INTNETRingSkipFrame(&m_pIfBuf->Recv);
     288
     289                    /* don't wait, we may have to wakeup the NAT thread first */
     290                    rc = RTReqCallEx(m_pReqQueue, NULL /*ppReq*/, 0 /*cMillies*/, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
     291                                     (PFNRT)SendWorker, 2, m, cbFrame);
     292                    AssertReleaseRC(rc);
    280293                }
    281                 memcpy(pvSlirpFrame, INTNETHdrGetFramePtr(pHdr, m_pIfBuf), cbFrame);
    282                 INTNETRingSkipFrame(&m_pIfBuf->Recv);
    283 
    284                 /* don't wait, we have to wakeup the NAT thread fist */
    285                 rc = RTReqCallEx(m_pReqQueue, NULL /*ppReq*/, 0 /*cMillies*/, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
    286                                  (PFNRT)SendWorker, 2, m, cbFrame);
    287                 AssertReleaseRC(rc);
     294                else
     295                {
     296                    /** @todo pass these unmodified. */
     297                    PCPDMNETWORKGSO pGso  = INTNETHdrGetGsoContext(pHdr, m_pIfBuf);
     298                    if (!PDMNetGsoIsValid(pGso, cbFrame, cbFrame - sizeof(*pGso)))
     299                    {
     300                        INTNETRingSkipFrame(&m_pIfBuf->Recv);
     301                        STAM_REL_COUNTER_INC(&m_pIfBuf->cStatBadFrames);
     302                        continue;
     303                    }
     304
     305                    uint32_t const cSegs = PDMNetGsoCalcSegmentCount(pGso, cbFrame - sizeof(*pGso));
     306                    for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
     307                    {
     308                        uint32_t cbSegFrame;
     309                        void  *pvSegFrame = PDMNetGsoCarveSegmentQD(pGso, (uint8_t *)(pGso + 1), cbFrame, abHdrScratch,
     310                                                                    &cbSegFrame);
     311                        m = slirp_ext_m_get(g_pNAT->m_pNATState, cbFrame, &pvSlirpFrame, &cbIgnored);
     312                        if (!m)
     313                        {
     314                            LogRel(("NAT: Can't allocate send buffer cbSegFrame=%u seg=%u/%u\n", cbSegFrame, iSeg, cSegs));
     315                            break;
     316                        }
     317                        memcpy(pvSlirpFrame, pvSegFrame, cbFrame);
     318
     319                        rc = RTReqCallEx(m_pReqQueue, NULL /*ppReq*/, 0 /*cMillies*/, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
     320                                         (PFNRT)SendWorker, 2, m, cbSubFrame);
     321                        AssertReleaseRC(rc);
     322                    }
     323                    INTNETRingSkipFrame(&m_pIfBuf->Recv);
     324                }
    288325
    289326#ifndef RT_OS_WINDOWS
     
    297334#endif
    298335            }
    299             else if (pHdr->u16Type == INTNETHDR_TYPE_PADDING)
     336            else if (u16Type == INTNETHDR_TYPE_PADDING)
    300337                INTNETRingSkipFrame(&m_pIfBuf->Recv);
    301338            else
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