VirtualBox

Changeset 50082 in vbox for trunk


Ignore:
Timestamp:
Jan 16, 2014 12:18:24 AM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
91603
Message:

Deal with ETH_PAD_SIZE != 0. Express processGSO() in terms of
processFrame() to avoid code duplication.

File:
1 edited

Legend:

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

    r50075 r50082  
    526526    AssertPtrReturn(pNetif, ERR_ARG);
    527527    AssertPtrReturn(pPBuf, ERR_ARG);
    528     AssertReturn((void *)g_pLwipNat == pNetif->state, ERR_ARG);
     528
     529    VBoxNetLwipNAT *self = static_cast<VBoxNetLwipNAT *>(pNetif->state);
     530    AssertPtrReturn(self, ERR_IF);
     531    AssertReturn(self == g_pLwipNat, ERR_ARG);
    529532
    530533    LogFlowFunc(("ENTER: pNetif[%c%c%d], pPbuf:%p\n",
     
    535538
    536539    RT_ZERO(VBoxNetLwipNAT::aXmitSeg);
    537    
    538     unsigned idx = 0;
    539     for( struct pbuf *pPBufPtr = pPBuf;
    540          pPBufPtr;
    541          pPBufPtr = pPBufPtr->next, ++idx)
     540
     541    size_t idx = 0;
     542    for (struct pbuf *q = pPBuf; q != NULL; q = q->next, ++idx)
    542543    {
    543544        AssertReturn(idx < RT_ELEMENTS(VBoxNetLwipNAT::aXmitSeg), ERR_MEM);
    544         VBoxNetLwipNAT::aXmitSeg[idx].pv = pPBufPtr->payload;
    545         VBoxNetLwipNAT::aXmitSeg[idx].cb = pPBufPtr->len;
    546     }
    547 
    548     int rc = g_pLwipNat->sendBufferOnWire(VBoxNetLwipNAT::aXmitSeg, idx, pPBuf->tot_len);
     545
     546#if ETH_PAD_SIZE
     547        if (q == pPBuf)
     548        {
     549            VBoxNetLwipNAT::aXmitSeg[idx].pv = (uint8_t *)q->payload + ETH_PAD_SIZE;
     550            VBoxNetLwipNAT::aXmitSeg[idx].cb = q->len - ETH_PAD_SIZE;
     551        }
     552        else
     553#endif
     554        {
     555            VBoxNetLwipNAT::aXmitSeg[idx].pv = q->payload;
     556            VBoxNetLwipNAT::aXmitSeg[idx].cb = q->len;
     557        }
     558    }
     559
     560    int rc = self->sendBufferOnWire(VBoxNetLwipNAT::aXmitSeg, idx,
     561                                    pPBuf->tot_len - ETH_PAD_SIZE);
    549562    AssertRCReturn(rc, ERR_IF);
    550563
    551     g_pLwipNat->flushWire();
     564    self->flushWire();
    552565
    553566    LogFlowFunc(("LEAVE: %d\n", ERR_OK));
     
    885898int VBoxNetLwipNAT::processFrame(void *pvFrame, size_t cbFrame)
    886899{
    887     AssertReturn(pvFrame && cbFrame, VERR_INVALID_PARAMETER);
    888 
    889     struct  pbuf *pPbufHdr, *pPbuf;
    890     pPbufHdr = pPbuf = pbuf_alloc(PBUF_RAW, cbFrame, PBUF_POOL);
    891 
    892     AssertMsgReturn(pPbuf, ("NAT: Can't allocate send buffer cbFrame=%u\n", cbFrame), VERR_INTERNAL_ERROR);
    893     AssertReturn(pPbufHdr->tot_len == cbFrame, VERR_INTERNAL_ERROR);
    894                    
    895     uint8_t *pu8Frame = (uint8_t *)pvFrame;
    896     while(pPbuf)
    897     {
    898         memcpy(pPbuf->payload, pu8Frame, pPbuf->len);
    899         pu8Frame += pPbuf->len;
    900         pPbuf = pPbuf->next;
    901     }
    902 
    903     m_LwipNetIf.input(pPbufHdr, &m_LwipNetIf);
    904    
     900    AssertPtrReturn(pvFrame, VERR_INVALID_PARAMETER);
     901    AssertReturn(cbFrame != 0, VERR_INVALID_PARAMETER);
     902
     903    struct pbuf *p = pbuf_alloc(PBUF_RAW, cbFrame + ETH_PAD_SIZE, PBUF_POOL);
     904    if (RT_UNLIKELY(p == NULL))
     905    {
     906        return VERR_NO_MEMORY;
     907    }
     908
     909    /*
     910     * The code below is inlined version of:
     911     *
     912     *   pbuf_header(p, -ETH_PAD_SIZE); // hide padding
     913     *   pbuf_take(p, pvFrame, cbFrame);
     914     *   pbuf_header(p, ETH_PAD_SIZE);  // reveal padding
     915     */
     916    struct pbuf *q = p;
     917    uint8_t *pu8Chunk = (uint8_t *)pvFrame;
     918    do {
     919        uint8_t *payload = (uint8_t *)q->payload;
     920        size_t len = q->len;
     921
     922#if ETH_PAD_SIZE
     923        if (RT_LIKELY(q == p))  // single pbuf is large enough
     924        {
     925            payload += ETH_PAD_SIZE;
     926            len -= ETH_PAD_SIZE;
     927        }
     928#endif
     929        memcpy(payload, pu8Chunk, len);
     930        pu8Chunk += len;
     931        q = q->next;
     932    } while (RT_UNLIKELY(q != NULL));
     933
     934    m_LwipNetIf.input(p, &m_LwipNetIf);
    905935    return VINF_SUCCESS;
    906936}
     
    929959                                  &cbSegFrame);
    930960
    931         struct pbuf *pPbuf = pbuf_alloc(PBUF_RAW, cbSegFrame, PBUF_POOL);
    932 
    933         AssertMsgReturn(pPbuf, ("NAT: Can't allocate send buffer cbFrame=%u\n", cbSegFrame), VERR_INTERNAL_ERROR);
    934         AssertReturn(!pPbuf->next && pPbuf->len == cbSegFrame, VERR_INTERNAL_ERROR);
    935 
    936         memcpy(pPbuf->payload, pvSegFrame, cbSegFrame);
    937         m_LwipNetIf.input(pPbuf, &g_pLwipNat->m_LwipNetIf);
     961        int rc = processFrame(pvSegFrame, cbSegFrame);
     962        if (RT_FAILURE(rc))
     963        {
     964            return rc;
     965        }
    938966    }
    939967
Note: See TracChangeset for help on using the changeset viewer.

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