VirtualBox

Ignore:
Timestamp:
Jan 14, 2011 8:46:18 AM (14 years ago)
Author:
vboxsync
Message:

netflt: hard_start_xmit override support for pre-2.6.29 kernels

File:
1 edited

Legend:

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

    r35382 r35554  
    828828#ifdef VBOXNETFLT_WITH_FILTER_HOST2GUEST_SKBS_EXPERIMENT
    829829
     830# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
     831
     832# include <linux/ethtool.h>
     833
     834typedef struct ethtool_ops OVR_OPSTYPE;
     835# define OVR_OPS  ethtool_ops
     836# define OVR_XMIT pfnStartXmit
     837
     838# else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) */
     839
     840typedef struct net_device_ops OVR_OPSTYPE;
     841# define OVR_OPS  netdev_ops
     842# define OVR_XMIT pOrgOps->ndo_start_xmit
     843
     844# endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) */
     845
    830846/**
    831847 * The overridden net_device_ops of the device we're attached to.
    832848 *
    833  * Requires Linux 2.6.29 or later.
     849 * As there is no net_device_ops structure in pre-2.6.29 kernels we override
     850 * ethtool_ops instead along with hard_start_xmit callback in net_device
     851 * structure.
    834852 *
    835  * This is a very dirty hack that was create to explore how much we can improve
    836  * the host to guest transfers by not CC'ing the NIC.
     853 * This is a very dirty hack that was created to explore how much we can improve
     854 * the host to guest transfers by not CC'ing the NIC. It turns out to be
     855 * the only way to filter outgoing packets for devices without TX queue.
    837856 */
    838857typedef struct VBoxNetDeviceOpsOverride
    839858{
    840859    /** Our overridden ops. */
    841     struct net_device_ops           Ops;
     860    OVR_OPSTYPE                     Ops;
    842861    /** Magic word. */
    843862    uint32_t                        u32Magic;
    844863    /** Pointer to the original ops. */
    845     struct net_device_ops const    *pOrgOps;
     864    OVR_OPSTYPE const              *pOrgOps;
     865# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
     866    /** Pointer to the original hard_start_xmit function. */
     867    int (*pfnStartXmit)(struct sk_buff *pSkb, struct net_device *pDev);
     868# endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) */
    846869    /** Pointer to the net filter instance. */
    847870    PVBOXNETFLTINS                  pVBoxNetFlt;
     
    864887static int vboxNetFltLinuxStartXmitFilter(struct sk_buff *pSkb, struct net_device *pDev)
    865888{
    866     PVBOXNETDEVICEOPSOVERRIDE   pOverride = (PVBOXNETDEVICEOPSOVERRIDE)pDev->netdev_ops;
     889    PVBOXNETDEVICEOPSOVERRIDE   pOverride = (PVBOXNETDEVICEOPSOVERRIDE)pDev->OVR_OPS;
    867890    uint8_t                     abHdrBuf[sizeof(RTNETETHERHDR) + sizeof(uint32_t) + RTNETIPV4_MIN_LEN];
    868891    PCRTNETETHERHDR             pEtherHdr;
     
    916939    }
    917940
    918     return pOverride->pOrgOps->ndo_start_xmit(pSkb, pDev);
     941    return pOverride->OVR_XMIT(pSkb, pDev);
    919942}
    920943
     
    933956    if (!pOverride)
    934957        return;
    935     pOverride->pOrgOps              = pDev->netdev_ops;
    936     pOverride->Ops                  = *pDev->netdev_ops;
     958    pOverride->pOrgOps              = pDev->OVR_OPS;
     959    pOverride->Ops                  = *pDev->OVR_OPS;
     960# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
     961    pOverride->pfnStartXmit         = pDev->hard_start_xmit;
     962# else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) */
    937963    pOverride->Ops.ndo_start_xmit   = vboxNetFltLinuxStartXmitFilter;
     964# endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) */
    938965    pOverride->u32Magic             = VBOXNETDEVICEOPSOVERRIDE_MAGIC;
    939966    pOverride->cTotal               = 0;
     
    942969
    943970    RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp); /* (this isn't necessary, but so what) */
    944     ASMAtomicWritePtr((void * volatile *)&pDev->netdev_ops, pOverride);
     971    ASMAtomicWritePtr((void * volatile *)&pDev->OVR_OPS, pOverride);
     972# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
     973    ASMAtomicXchgPtr((void * volatile *)&pDev->hard_start_xmit, vboxNetFltLinuxStartXmitFilter);
     974# endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) */
    945975    RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp);
    946976}
     
    963993    if (VALID_PTR(pDev))
    964994    {
    965         pOverride = (PVBOXNETDEVICEOPSOVERRIDE)pDev->netdev_ops;
     995        pOverride = (PVBOXNETDEVICEOPSOVERRIDE)pDev->OVR_OPS;
    966996        if (    VALID_PTR(pOverride)
    967997            &&  pOverride->u32Magic == VBOXNETDEVICEOPSOVERRIDE_MAGIC
     
    969999           )
    9701000        {
    971             ASMAtomicWritePtr((void * volatile *)&pDev->netdev_ops, pOverride->pOrgOps);
     1001# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
     1002            ASMAtomicWritePtr((void * volatile *)&pDev->hard_start_xmit, pOverride->pfnStartXmit);
     1003# endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) */
     1004            ASMAtomicWritePtr((void * volatile *)&pDev->OVR_OPS, pOverride->pOrgOps);
    9721005            ASMAtomicWriteU32(&pOverride->u32Magic, 0);
    9731006        }
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