VirtualBox

Ignore:
Timestamp:
Nov 24, 2008 8:46:58 AM (16 years ago)
Author:
vboxsync
Message:

Linux hostif: Added packet segmentation for host-to-guest transfer.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c

    r14435 r14506  
    326326    }
    327327    pSG->cbTotal = pBuf->len;
     328#ifdef VBOXNETFLT_SG_SUPPORT
    328329    pSG->aSegs[0].cb = skb_headlen(pBuf);
    329330    pSG->aSegs[0].pv = pBuf->data;
     
    335336        pSG->aSegs[i+1].cb = pFrag->size;
    336337        pSG->aSegs[i+1].pv = kmap(pFrag->page);
     338        printk("%p = kmap()\n", pSG->aSegs[i+1].pv);
    337339        pSG->aSegs[i+1].Phys = NIL_RTHCPHYS;
    338340    }
    339341    pSG->cSegsUsed = ++i;
     342#else
     343    pSG->aSegs[0].cb = pBuf->len;
     344    pSG->aSegs[0].pv = pBuf->data;
     345    pSG->aSegs[0].Phys = NIL_RTHCPHYS;
     346    pSG->cSegsUsed = i = 1;
     347#endif
     348
    340349
    341350#ifdef PADD_RUNT_FRAMES_FROM_HOST
     
    360369    }
    361370#endif
     371    Log2(("vboxNetFltLinuxSkBufToSG: allocated=%d, segments=%d frags=%d next=%p frag_list=%p pkt_type=%x fSrc=%x\n",
     372          pSG->cSegsAlloc, pSG->cSegsUsed, skb_shinfo(pBuf)->nr_frags, pBuf->next, skb_shinfo(pBuf)->frag_list, pBuf->pkt_type, fSrc));
     373    for (i = 0; i < pSG->cSegsUsed; i++)
     374        Log2(("vboxNetFltLinuxSkBufToSG:   #%d: cb=%d pv=%p\n",
     375              i, pSG->aSegs[i].cb, pSG->aSegs[i].pv));
    362376}
    363377
     
    411425static unsigned vboxNetFltLinuxSGSegments(PVBOXNETFLTINS pThis, struct sk_buff *pBuf)
    412426{
     427#ifdef VBOXNETFLT_SG_SUPPORT
    413428    unsigned cSegs = 1 + skb_shinfo(pBuf)->nr_frags;
     429#else
     430    unsigned cSegs = 1;
     431#endif
    414432#ifdef PADD_RUNT_FRAMES_FROM_HOST
    415433    /*
     
    422440}
    423441
    424 
    425442/* WARNING! This function should only be called after vboxNetFltLinuxSkBufToSG()! */
    426443static void  vboxNetFltLinuxFreeSkBuff(struct sk_buff *pBuf, PINTNETSG pSG)
    427444{
     445#ifdef VBOXNETFLT_SG_SUPPORT
    428446    int i;
    429447
    430448    for (i = 0; i < skb_shinfo(pBuf)->nr_frags; i++)
     449    {
     450        printk("kunmap(%p)\n", pSG->aSegs[i+1].pv);
    431451        kunmap(pSG->aSegs[i+1].pv);
     452    }
     453#endif
    432454           
    433455    dev_kfree_skb(pBuf);
    434456}
    435457
    436 static void vboxNetFltLinuxForwardToIntNet(PVBOXNETFLTINS pThis, struct sk_buff *pBuf)
    437 {
    438     bool fDropIt;
    439     unsigned cSegs;
    440     uint32_t fSrc = pBuf->pkt_type == PACKET_OUTGOING ? INTNETTRUNKDIR_HOST : INTNETTRUNKDIR_WIRE;
    441     /*
    442      * Finalize out-bound packets since the stack puts off finalizing
    443      * TCP/IP checksums as long as possible.
    444      * ASSUMES this only applies to outbound IP packets.
    445      *
    446     if (    (fSrc & INTNETTRUNKDIR_HOST)
    447         &&  eProtocol == PF_INET)
    448     {
    449         Assert(!pvFrame);
    450         mbuf_outbound_finalize(pMBuf, eProtocol, sizeof(RTNETETHERHDR));
    451     }*/
    452 
    453     /*
    454      * Create a (scatter/)gather list for the mbuf and feed it to the internal network.
    455      */
    456     fDropIt = false;
    457     cSegs = vboxNetFltLinuxSGSegments(pThis, pBuf);
     458static int vboxNetFltLinuxForwardSegment(PVBOXNETFLTINS pThis, struct sk_buff *pBuf, uint32_t fSrc)
     459{
     460    unsigned cSegs = vboxNetFltLinuxSGSegments(pThis, pBuf);
    458461    if (cSegs < MAX_SKB_FRAGS)
    459462    {
     
    463466        {
    464467            Log(("VBoxNetFlt: Failed to allocate SG buffer.\n"));
    465             return;
     468            return VERR_NO_MEMORY;
    466469        }
    467470        vboxNetFltLinuxSkBufToSG(pThis, pBuf, pSG, cSegs, fSrc);
     
    479482    }
    480483
     484    return VINF_SUCCESS;
     485}
     486
     487static void vboxNetFltLinuxForwardToIntNet(PVBOXNETFLTINS pThis, struct sk_buff *pBuf)
     488{
     489    struct sk_buff *pNext, *pSegment = NULL;
     490    uint32_t fSrc = pBuf->pkt_type == PACKET_OUTGOING ? INTNETTRUNKDIR_HOST : INTNETTRUNKDIR_WIRE;
     491
     492#ifndef VBOXNETFLT_SG_SUPPORT
     493    /*
     494     * Get rid of fragmented packets, they cause too much trouble.
     495     */
     496    struct sk_buff *pCopy = skb_copy(pBuf, GFP_KERNEL);
     497    kfree_skb(pBuf);
     498    if (!pCopy)
     499    {
     500        LogRel(("VBoxNetFlt: Failed to allocate packet buffer, dropping the packet.\n"));
     501        return;
     502    }
     503    pBuf = pCopy;
     504#endif
     505
     506    Log2(("vboxNetFltLinuxForwardToIntNet: cb=%u gso_size=%u gso_segs=%u gso_type=%u\n",
     507          pBuf->len, skb_shinfo(pBuf)->gso_size, skb_shinfo(pBuf)->gso_segs, skb_shinfo(pBuf)->gso_type));
     508
     509    if (skb_is_gso(pBuf))
     510    {
     511        /* Need to segment the packet */
     512        struct sk_buff *pSegments = skb_gso_segment(pBuf, 0); /* No features, very dumb device */
     513        pBuf->next = pSegments;
     514    }
     515    /*
     516     * Create a (scatter/)gather list for the sk_buff and feed it to the internal network.
     517     */
     518    for (pSegment = pBuf; pSegment; pSegment = pNext)
     519    {
     520        pNext = pSegment->next;
     521        pSegment->next = 0;
     522        vboxNetFltLinuxForwardSegment(pThis, pSegment, fSrc);
     523    }
    481524}
    482525
     
    698741    {
    699742        /*
    700          * Create a mbuf for the gather list and push it onto the wire.
     743         * Create a sk_buff for the gather list and push it onto the wire.
    701744         */
    702745        if (fDst & INTNETTRUNKDIR_WIRE)
     
    719762
    720763        /*
    721          * Create a mbuf for the gather list and push it onto the host stack.
     764         * Create a sk_buff for the gather list and push it onto the host stack.
    722765         */
    723766        if (fDst & INTNETTRUNKDIR_HOST)
     
    797840            Assert(!pThis->u.s.fPromiscuousSet);
    798841
     842#if 0
    799843            /*
    800844             * Try bring the interface up and running if it's down.
     
    803847            if ((fIf & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING))
    804848            {
     849                rtnl_lock();
    805850                err = dev_change_flags(pDev, fIf | IFF_UP);
     851                rtnl_unlock();
    806852                fIf = dev_get_flags(pDev);
    807853            }
     
    814860                && !ASMAtomicReadBool(&pThis->u.s.fPromiscuousSet))
    815861            {
     862#endif
    816863                rtnl_lock();
    817864                dev_set_promiscuity(pDev, 1);
     
    831878                }
    832879#endif
     880#if 0
    833881            }
    834882            else if (!err)
     
    836884            if (err)
    837885                LogRel(("VBoxNetFlt: Failed to put '%s' into promiscuous mode, err=%d (%d->%d)\n", pThis->szName, err, cPromiscBefore, VBOX_GET_PCOUNT(pDev)));
     886#endif
    838887        }
    839888        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