VirtualBox

Ticket #3056: VBoxNetFlt-linux.c.patch

File VBoxNetFlt-linux.c.patch, 12.4 KB (added by Jeremy Visser, 16 years ago)

Here's the same patch, but in .diff form to make it easier to scruitinise.

  • VBoxNetFlt-linux.c

    old new  
    1 /* $Id: VBoxNetFlt-linux.c 41144 2008-12-17 09:20:11Z frank $ */
     1/* $Id: VBoxNetFlt-linux.c 41779 2009-01-20 11:13:08Z aleksey $ */
    22/** @file
    33 * VBoxNetFlt - Network Filter Driver (Host), Linux Specific Code.
    44 */
     
    7070# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
    7171#  define VBOX_SKB_CHECKSUM_HELP(skb) skb_checksum_help(skb, 0)
    7272# else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) */
    73 #  define VBOX_SKB_CHECKSUM_HELP(skb) skb_checksum_help(&skb, 0)
     73#  if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 7)
     74#   define VBOX_SKB_CHECKSUM_HELP(skb) skb_checksum_help(&skb, 0)
     75#  else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 7) */
     76#   define VBOX_SKB_CHECKSUM_HELP(skb) (!skb_checksum_help(skb))
     77#  endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 7) */
    7478# endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) */
    7579#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) */
    7680
     
    8387# define VBOX_SKB_GSO_SEGMENT(skb) NULL
    8488#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) */
    8589
     90#ifndef NET_IP_ALIGN
     91# define NET_IP_ALIGN 2
     92#endif
     93
    8694#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12)
    8795unsigned dev_get_flags(const struct net_device *dev)
    8896{
     
    114122/**
    115123 * The (common) global data.
    116124 */
     125#ifdef RT_ARCH_AMD64
     126/**
     127 * Memory for the executable memory heap (in IPRT).
     128 */
     129extern uint8_t g_abExecMemory[1572864]; /* 1.5 MB */
     130__asm__(".section execmemory, \"awx\", @progbits\n\t"
     131        ".align 32\n\t"
     132        ".globl g_abExecMemory\n"
     133        "g_abExecMemory:\n\t"
     134        ".zero 1572864\n\t"
     135        ".type g_abExecMemory, @object\n\t"
     136        ".size g_abExecMemory, 1572864\n\t"
     137        ".text\n\t");
     138#endif
     139
    117140static VBOXNETFLTGLOBALS g_VBoxNetFltGlobals;
    118141
    119142module_init(VBoxNetFltLinuxInit);
     
    142165static int __init VBoxNetFltLinuxInit(void)
    143166{
    144167    int rc;
    145     Log(("VBoxNetFltLinuxInit\n"));
    146 
    147168    /*
    148169     * Initialize IPRT.
    149170     */
    150171    rc = RTR0Init(0);
    151172    if (RT_SUCCESS(rc))
    152173    {
     174#ifdef RT_ARCH_AMD64
     175        rc = RTR0MemExecDonate(&g_abExecMemory[0], sizeof(g_abExecMemory));
     176        printk("VBoxNetFlt: dbg - g_abExecMemory=%p\n", (void *)&g_abExecMemory[0]);
     177        if (RT_FAILURE(rc))
     178        {
     179            printk("VBoxNetFlt: failed to donate exec memory, no logging will be available.\n");
     180        }
     181#endif
     182        Log(("VBoxNetFltLinuxInit\n"));
     183
    153184        /*
    154185         * Initialize the globals and connect to the support driver.
    155186         *
     
    259290}
    260291
    261292#define VBOXNETFLT_CB_TAG 0xA1C9D7C3
    262 #define VBOXNETFLT_SKB_CB(skb) (*(uint32_t*)&((skb)->cb[0]))
     293#define VBOXNETFLT_SKB_TAG(skb) (*(uint32_t*)&((skb)->cb[sizeof((skb)->cb)-sizeof(uint32_t)]))
    263294
    264295/**
    265296 * Checks whether this is an mbuf created by vboxNetFltLinuxMBufFromSG,
     
    270301 */
    271302DECLINLINE(bool) vboxNetFltLinuxSkBufIsOur(struct sk_buff *pBuf)
    272303{
    273     return VBOXNETFLT_SKB_CB(pBuf) == VBOXNETFLT_CB_TAG ;
     304    return VBOXNETFLT_SKB_TAG(pBuf) == VBOXNETFLT_CB_TAG ;
    274305}
    275306
    276307
     
    322353            VBOX_SKB_RESET_NETWORK_HDR(pPkt);
    323354            /* Restore ethernet header back. */
    324355            skb_push(pPkt, ETH_HLEN);
     356            VBOX_SKB_RESET_MAC_HDR(pPkt);
    325357        }
    326         VBOX_SKB_RESET_MAC_HDR(pPkt);
    327         VBOXNETFLT_SKB_CB(pPkt) = VBOXNETFLT_CB_TAG;
     358        VBOXNETFLT_SKB_TAG(pPkt) = VBOXNETFLT_CB_TAG;
    328359
    329360        return pPkt;
    330361    }
     
    413444        pSG->cSegsUsed++;
    414445    }
    415446#endif
    416     Log2(("vboxNetFltLinuxSkBufToSG: allocated=%d, segments=%d frags=%d next=%p frag_list=%p pkt_type=%x fSrc=%x\n",
     447    Log4(("vboxNetFltLinuxSkBufToSG: allocated=%d, segments=%d frags=%d next=%p frag_list=%p pkt_type=%x fSrc=%x\n",
    417448          pSG->cSegsAlloc, pSG->cSegsUsed, skb_shinfo(pBuf)->nr_frags, pBuf->next, skb_shinfo(pBuf)->frag_list, pBuf->pkt_type, fSrc));
    418449    for (i = 0; i < pSG->cSegsUsed; i++)
    419         Log2(("vboxNetFltLinuxSkBufToSG:   #%d: cb=%d pv=%p\n",
     450        Log4(("vboxNetFltLinuxSkBufToSG:   #%d: cb=%d pv=%p\n",
    420451              i, pSG->aSegs[i].cb, pSG->aSegs[i].pv));
    421452}
    422453
     
    430461 * @param   fSrc            Where the packet (allegedly) comes from, one INTNETTRUNKDIR_* value.
    431462 * @param   eProtocol       The protocol.
    432463 */
     464#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
    433465static int vboxNetFltLinuxPacketHandler(struct sk_buff *pBuf,
    434466                                        struct net_device *pSkbDev,
    435467                                        struct packet_type *pPacketType,
    436468                                        struct net_device *pOrigDev)
     469#else
     470static int vboxNetFltLinuxPacketHandler(struct sk_buff *pBuf,
     471                                        struct net_device *pSkbDev,
     472                                        struct packet_type *pPacketType)
     473#endif
    437474{
    438475    PVBOXNETFLTINS pThis;
    439476    struct net_device *pDev;
     477    LogFlow(("vboxNetFltLinuxPacketHandler: pBuf=%p pSkbDev=%p pPacketType=%p\n",
     478             pBuf, pSkbDev, pPacketType));
    440479    /*
    441480     * Drop it immediately?
    442481     */
    443     Log2(("vboxNetFltLinuxPacketHandler: pBuf=%p pSkbDev=%p pPacketType=%p pOrigDev=%p\n",
    444           pBuf, pSkbDev, pPacketType, pOrigDev));
    445482    if (!pBuf)
    446483        return 0;
     484   
    447485    pThis = VBOX_FLT_PT_TO_INST(pPacketType);
    448486    pDev = (struct net_device *)ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pDev);
    449487    if (pThis->u.s.pDev != pSkbDev)
     
    452490        return 0;
    453491    }
    454492
     493    Log4(("vboxNetFltLinuxPacketHandler: pBuf->cb dump:\n%.*Rhxd\n", sizeof(pBuf->cb), pBuf->cb));
    455494    if (vboxNetFltLinuxSkBufIsOur(pBuf))
    456495    {
     496        Log2(("vboxNetFltLinuxPacketHandler: got our own sk_buff, drop it.\n"));
    457497        dev_kfree_skb(pBuf);
    458498        return 0;
    459499    }
    460500
     501#ifndef VBOXNETFLT_SG_SUPPORT
     502    {
     503        /*
     504         * Get rid of fragmented packets, they cause too much trouble.
     505         */
     506        struct sk_buff *pCopy = skb_copy(pBuf, GFP_ATOMIC);
     507        kfree_skb(pBuf);
     508        if (!pCopy)
     509        {
     510            LogRel(("VBoxNetFlt: Failed to allocate packet buffer, dropping the packet.\n"));
     511            return 0;
     512        }
     513        pBuf = pCopy;
     514    }
     515#endif
     516
    461517    /* Add the packet to transmit queue and schedule the bottom half. */
    462518    skb_queue_tail(&pThis->u.s.XmitQueue, pBuf);
    463519    schedule_work(&pThis->u.s.XmitTask);
    464     Log2(("vboxNetFltLinuxPacketHandler: scheduled work %p for sk_buff %p\n",
     520    Log4(("vboxNetFltLinuxPacketHandler: scheduled work %p for sk_buff %p\n",
    465521          &pThis->u.s.XmitTask, pBuf));
    466522    /* It does not really matter what we return, it is ignored by the kernel. */
    467523    return 0;
     
    500556    dev_kfree_skb(pBuf);
    501557}
    502558
     559#ifndef LOG_ENABLED
     560#define vboxNetFltDumpPacket(a, b, c, d)
     561#else
     562static void vboxNetFltDumpPacket(PINTNETSG pSG, bool fEgress, const char *pszWhere, int iIncrement)
     563{
     564    uint8_t *pInt, *pExt;
     565    static int iPacketNo = 1;
     566    iPacketNo += iIncrement;
     567    if (fEgress)
     568    {
     569        pExt = pSG->aSegs[0].pv;
     570        pInt = pExt + 6;
     571    }
     572    else
     573    {
     574        pInt = pSG->aSegs[0].pv;
     575        pExt = pInt + 6;
     576    }
     577    Log(("VBoxNetFlt: (int)%02x:%02x:%02x:%02x:%02x:%02x"
     578         " %s (%s)%02x:%02x:%02x:%02x:%02x:%02x (%u bytes) packet #%u\n",
     579         pInt[0], pInt[1], pInt[2], pInt[3], pInt[4], pInt[5],
     580         fEgress ? "-->" : "<--", pszWhere,
     581         pExt[0], pExt[1], pExt[2], pExt[3], pExt[4], pExt[5],
     582         pSG->cbTotal, iPacketNo));
     583    Log3(("%.*Rhxd\n", pSG->aSegs[0].cb, pSG->aSegs[0].pv));
     584}
     585#endif
     586
    503587static int vboxNetFltLinuxForwardSegment(PVBOXNETFLTINS pThis, struct sk_buff *pBuf, uint32_t fSrc)
    504588{
    505589    unsigned cSegs = vboxNetFltLinuxSGSegments(pThis, pBuf);
     
    515599        vboxNetFltLinuxSkBufToSG(pThis, pBuf, pSG, cSegs, fSrc);
    516600
    517601        pTmp = pSG->aSegs[0].pv;
    518         Log(("VBoxNetFlt: (int)%02x:%02x:%02x:%02x:%02x:%02x"
    519              " <-- (%s)%02x:%02x:%02x:%02x:%02x:%02x (%u bytes)\n",
    520              pTmp[0], pTmp[1], pTmp[2], pTmp[3], pTmp[4], pTmp[5],
    521              (fSrc & INTNETTRUNKDIR_HOST) ? "host" : "wire",
    522              pTmp[6], pTmp[7], pTmp[8], pTmp[9], pTmp[10], pTmp[11],
    523              pSG->cbTotal));
     602        vboxNetFltDumpPacket(pSG, false, (fSrc & INTNETTRUNKDIR_HOST) ? "host" : "wire", 1);
    524603        pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, fSrc);
    525         Log2(("VBoxNetFlt: Dropping the sk_buff.\n"));
     604        Log4(("VBoxNetFlt: Dropping the sk_buff.\n"));
    526605        vboxNetFltLinuxFreeSkBuff(pBuf, pSG);
    527606    }
    528607
     
    533612{
    534613    uint32_t fSrc = pBuf->pkt_type == PACKET_OUTGOING ? INTNETTRUNKDIR_HOST : INTNETTRUNKDIR_WIRE;
    535614
    536 #ifndef VBOXNETFLT_SG_SUPPORT
    537     /*
    538      * Get rid of fragmented packets, they cause too much trouble.
    539      */
    540     struct sk_buff *pCopy = skb_copy(pBuf, GFP_KERNEL);
    541     kfree_skb(pBuf);
    542     if (!pCopy)
    543     {
    544         LogRel(("VBoxNetFlt: Failed to allocate packet buffer, dropping the packet.\n"));
    545         return;
    546     }
    547     pBuf = pCopy;
    548 #endif
    549 
    550615    if (VBOX_SKB_IS_GSO(pBuf))
    551616    {
    552617        /* Need to segment the packet */
     
    578643     */
    579644}
    580645
     646#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
    581647static void vboxNetFltLinuxXmitTask(struct work_struct *pWork)
     648#else
     649static void vboxNetFltLinuxXmitTask(void *pWork)
     650#endif
    582651{
    583652    struct sk_buff *pBuf;
    584653    bool fActive;
    585654    PVBOXNETFLTINS pThis;
    586655    RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
    587656
    588     Log2(("vboxNetFltLinuxXmitTask: Got work %p.\n", pWork));
     657    Log4(("vboxNetFltLinuxXmitTask: Got work %p.\n", pWork));
    589658    pThis = VBOX_FLT_XT_TO_INST(pWork);
    590659    /*
    591660     * Active? Retain the instance and increment the busy counter.
     
    779848    return !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost);
    780849}
    781850
    782 
    783851int  vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
    784852{
    785     uint8_t *pTmp;
    786853    struct net_device * pDev;
    787854    int err;
    788855    int rc = VINF_SUCCESS;
    789856
    790857    LogFlow(("vboxNetFltPortOsXmit: pThis=%p (%s)\n", pThis, pThis->szName));
    791858
    792     pTmp = pSG->aSegs[0].pv;
    793 
    794859    pDev = vboxNetFltLinuxRetainNetDev(pThis);
    795860    if (pDev)
    796861    {
     
    802867            struct sk_buff *pBuf = vboxNetFltLinuxSkBufFromSG(pThis, pSG, true);
    803868            if (pBuf)
    804869            {
    805                 Log(("VBoxNetFlt: (int)%02x:%02x:%02x:%02x:%02x:%02x"
    806                      " --> (wire)%02x:%02x:%02x:%02x:%02x:%02x (%u bytes)\n",
    807                      pTmp[6], pTmp[7], pTmp[8], pTmp[9], pTmp[10], pTmp[11],
    808                      pTmp[0], pTmp[1], pTmp[2], pTmp[3], pTmp[4], pTmp[5],
    809                      pSG->cbTotal));
     870                vboxNetFltDumpPacket(pSG, true, "wire", 1);
     871                Log4(("vboxNetFltPortOsXmit: pBuf->cb dump:\n%.*Rhxd\n", sizeof(pBuf->cb), pBuf->cb));
     872                Log4(("vboxNetFltPortOsXmit: dev_queue_xmit(%p)\n", pBuf));
    810873                err = dev_queue_xmit(pBuf);
    811874                if (err)
    812875                    rc = RTErrConvertFromErrno(err);
     
    823886            struct sk_buff *pBuf = vboxNetFltLinuxSkBufFromSG(pThis, pSG, false);
    824887            if (pBuf)
    825888            {
    826                 Log(("VBoxNetFlt: (int)%02x:%02x:%02x:%02x:%02x:%02x"
    827                      " --> (host)%02x:%02x:%02x:%02x:%02x:%02x (%u bytes)\n",
    828                      pTmp[6], pTmp[7], pTmp[8], pTmp[9], pTmp[10], pTmp[11],
    829                      pTmp[0], pTmp[1], pTmp[2], pTmp[3], pTmp[4], pTmp[5],
    830                      pSG->cbTotal));
     889                vboxNetFltDumpPacket(pSG, true, "host", (fDst & INTNETTRUNKDIR_WIRE) ? 0 : 1);
     890                Log4(("vboxNetFltPortOsXmit: pBuf->cb dump:\n%.*Rhxd\n", sizeof(pBuf->cb), pBuf->cb));
     891                Log4(("vboxNetFltPortOsXmit: netif_rx_ni(%p)\n", pBuf));
    831892                err = netif_rx_ni(pBuf);
    832893                if (err)
    833894                    rc = RTErrConvertFromErrno(err);
     
    850911    if (pDev)
    851912    {
    852913        fRc = !!(pDev->promiscuity - (ASMAtomicUoReadBool(&pThis->u.s.fPromiscuousSet) & 1));
     914        LogFlow(("vboxNetFltPortOsIsPromiscuous: returns %d, pDev->promiscuity=%d, fPromiscuousSet=%d\n",
     915                 fRc, pDev->promiscuity, pThis->u.s.fPromiscuousSet));
    853916        vboxNetFltLinuxReleaseNetDev(pThis, pDev);
    854917    }
    855918    return fRc;
     
    10281091#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
    10291092    INIT_WORK(&pThis->u.s.XmitTask, vboxNetFltLinuxXmitTask);
    10301093#else
    1031     INIT_WORK(&pThis->u.s.XmitTask, vboxNetFltLinuxXmitTask, NULL);
     1094    INIT_WORK(&pThis->u.s.XmitTask, vboxNetFltLinuxXmitTask, &pThis->u.s.XmitTask);
    10321095#endif
    10331096
    10341097    return VINF_SUCCESS;

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy