VirtualBox

Changeset 28025 in vbox for trunk/include/VBox


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

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

Location:
trunk/include/VBox
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/intnet.h

    r27840 r28025  
    44
    55/*
    6  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     6 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    197197
    198198/**
    199  * The packet header.
     199 * The frame header.
    200200 *
    201201 * The header is intentionally 8 bytes long. It will always
     
    208208{
    209209    /** Header type. This is currently serving as a magic, it
    210      * can be extended later to encode special command packets and stuff. */
     210     * can be extended later to encode special command frames and stuff. */
    211211    uint16_t        u16Type;
    212212    /** The size of the frame. */
     
    219219AssertCompileSize(INTNETHDR, 8);
    220220AssertCompileSizeAlignment(INTNETBUF, sizeof(INTNETHDR));
    221 /** Pointer to a packet header.*/
     221/** Pointer to a frame header.*/
    222222typedef INTNETHDR *PINTNETHDR;
    223 /** Pointer to a const packet header.*/
     223/** Pointer to a const frame header.*/
    224224typedef INTNETHDR const *PCINTNETHDR;
    225225
    226 /** The alignment of a packet header. */
     226/** The alignment of a frame header. */
    227227#define INTNETHDR_ALIGNMENT         sizeof(INTNETHDR)
    228228AssertCompile(sizeof(INTNETHDR) == INTNETHDR_ALIGNMENT);
    229229AssertCompile(INTNETHDR_ALIGNMENT <= INTNETRINGBUF_ALIGNMENT);
    230230
    231 /** INTNETHDR::u16Type value for normal frames. */
     231/** @name Frame types (INTNETHDR::u16Type).
     232 * @{ */
     233/** Normal frames. */
    232234#define INTNETHDR_TYPE_FRAME        0x2442
    233 /** INTNETHDR::u16Type value for padding frames. */
     235/** Padding frames. */
    234236#define INTNETHDR_TYPE_PADDING      0x3553
     237/** Generic segment offload frames.
     238 * The frame starts with a PDMNETWORKGSO structure which is followed by the
     239 * header template and data. */
     240#define INTNETHDR_TYPE_GSO          0x4664
     241AssertCompileSize(PDMNETWORKGSO, 8);
     242/** @}  */
    235243
    236244/**
     
    242250        AssertPtr(pHdr); \
    243251        Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr); \
    244         Assert((pHdr)->u16Type == INTNETHDR_TYPE_FRAME || (pHdr)->u16Type == INTNETHDR_TYPE_PADDING); \
     252        Assert(   (pHdr)->u16Type == INTNETHDR_TYPE_FRAME \
     253               || (pHdr)->u16Type == INTNETHDR_TYPE_GSO \
     254               || (pHdr)->u16Type == INTNETHDR_TYPE_PADDING); \
    245255        { \
    246256            uintptr_t const offHdr   = (uintptr_t)pHdr - (uintptr_t)pRingBuf; \
     
    269279    uint32_t        cb;
    270280} INTNETSEG;
    271 /** Pointer to a internal networking packet segment. */
     281/** Pointer to a internal networking frame segment. */
    272282typedef INTNETSEG *PINTNETSEG;
    273 /** Pointer to a internal networking packet segment. */
     283/** Pointer to a internal networking frame segment. */
    274284typedef INTNETSEG const *PCINTNETSEG;
    275285
     
    283293{
    284294    /** Owner data, don't touch! */
    285     void           *pvOwnerData;
     295    void               *pvOwnerData;
    286296    /** User data. */
    287     void           *pvUserData;
     297    void               *pvUserData;
    288298    /** User data 2 in case anyone needs it. */
    289     void           *pvUserData2;
     299    void               *pvUserData2;
     300    /** GSO context information, set the type to invalid if not relevant. */
     301    PDMNETWORKGSO       GsoCtx;
    290302    /** The total length of the scatter gather list. */
    291     uint32_t        cbTotal;
     303    uint32_t            cbTotal;
    292304    /** The number of users (references).
    293305     * This is used by the SGRelease code to decide when it can be freed. */
    294     uint16_t volatile cUsers;
     306    uint16_t volatile   cUsers;
    295307    /** Flags, see INTNETSG_FLAGS_* */
    296     uint16_t volatile fFlags;
     308    uint16_t volatile   fFlags;
     309#if ARCH_BITS == 64
     310    /** Alignment padding. */
     311    uint16_t            uPadding;
     312#endif
    297313    /** The number of segments allocated. */
    298     uint16_t        cSegsAlloc;
     314    uint16_t            cSegsAlloc;
    299315    /** The number of segments actually used. */
    300     uint16_t        cSegsUsed;
     316    uint16_t            cSegsUsed;
    301317    /** Variable sized list of segments. */
    302     INTNETSEG       aSegs[1];
     318    INTNETSEG           aSegs[1];
    303319} INTNETSG;
     320AssertCompileSizeAlignment(INTNETSG, 8);
    304321/** Pointer to a scatter / gather list. */
    305322typedef INTNETSG *PINTNETSG;
     
    326343
    327344
    328 /** @name Direction (packet source or destination)
     345/** @name Direction (frame source or destination)
    329346 * @{ */
    330347/** To/From the wire. */
     
    509526     *
    510527     * This method must be called before disconnecting and releasing the
    511      * object in order to prevent racing incoming/outgoing packets and
    512      * device enabling/disabling.
     528     * object in order to prevent racing incoming/outgoing frames and device
     529     * enabling/disabling.
    513530     *
    514531     * @returns IPRT status code (see RTSemEventWait).
     
    573590     * Transmit a frame.
    574591     *
    575      * @return  VBox status code. Error generally means we'll drop the packet.
     592     * @return  VBox status code. Error generally means we'll drop the frame.
    576593     * @param   pIfPort     Pointer to this structure.
    577594     * @param   pSG         Pointer to the (scatter /) gather structure for the frame.
     
    9971014 * @param   hIf         The interface handle.
    9981015 * @param   pSession    The caller's session.
    999  * @param   pvFrame     Pointer to the frame. Optional, please don't use.
    1000  * @param   cbFrame     Size of the frame. Optional, please don't use.
    1001  */
    1002 INTNETR0DECL(int) INTNETR0IfSend(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, const void *pvFrame, unsigned cbFrame);
     1016 */
     1017INTNETR0DECL(int) INTNETR0IfSend(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
    10031018
    10041019/**
  • trunk/include/VBox/intnetinline.h

    r27845 r28025  
    44 *
    55 * This is all inlined because it's too tedious to create 2-3 libraries to
    6  * contain it all.  Requires C++ since variables and code is mixed as usual.
     6 * contain it all.  Large parts of this header is only accessible from C++
     7 * sources because of mixed code and variables.
    78 */
    89
     
    3536#define ___VBox_intnetinline_h
    3637
    37 #ifndef __cplusplus
    38 # error "C++ only header."
    39 #endif
    40 
    4138#include <VBox/intnet.h>
    4239#include <iprt/string.h>
     
    4643
    4744
     45
     46/**
     47 * Valid internal networking frame type.
     48 *
     49 * @returns  true / false.
     50 * @param   u16Type             The frame type to check.
     51 */
     52DECLINLINE(bool) INETNETIsValidFrameType(uint16_t u16Type)
     53{
     54    if (RT_LIKELY(   u16Type == INTNETHDR_TYPE_FRAME
     55                  || u16Type == INTNETHDR_TYPE_GSO
     56                  || u16Type == INTNETHDR_TYPE_PADDING))
     57        return true;
     58    return false;
     59}
     60
     61
     62/**
     63 * Partly initializes a scatter / gather buffer, leaving the segments to the
     64 * caller.
     65 *
     66 * @returns Pointer to the start of the frame.
     67 * @param   pSG         Pointer to the scatter / gather structure.
     68 * @param   cbTotal     The total size.
     69 * @param   cSegs       The number of segments.
     70 * @param   cSegsUsed   The number of used segments.
     71 */
     72DECLINLINE(void) INTNETSgInitTempSegs(PINTNETSG pSG, uint32_t cbTotal, unsigned cSegs, unsigned cSegsUsed)
     73{
     74    pSG->pvOwnerData    = NULL;
     75    pSG->pvUserData     = NULL;
     76    pSG->pvUserData2    = NULL;
     77    pSG->cbTotal        = cbTotal;
     78    pSG->cUsers         = 1;
     79    pSG->fFlags         = INTNETSG_FLAGS_TEMP;
     80    pSG->GsoCtx.u8Type  = (uint8_t)PDMNETWORKGSOTYPE_INVALID;
     81    pSG->GsoCtx.cbHdrs  = 0;
     82    pSG->GsoCtx.cbMaxSeg= 0;
     83    pSG->GsoCtx.offHdr1 = 0;
     84    pSG->GsoCtx.cbHdr1  = 0;
     85    pSG->GsoCtx.offHdr2 = 0;
     86    pSG->GsoCtx.cbHdr2  = 0;
     87#if ARCH_BITS == 64
     88    pSG->uPadding       = 0;
     89#endif
     90    pSG->cSegsAlloc     = (uint16_t)cSegs;
     91    Assert(pSG->cSegsAlloc == cSegs);
     92    pSG->cSegsUsed      = (uint16_t)cSegsUsed;
     93    Assert(pSG->cSegsUsed == cSegsUsed);
     94    Assert(cSegs >= cSegsUsed);
     95}
     96
     97
     98/**
     99 * Partly initializes a scatter / gather buffer w/ GSO, leaving the segments to
     100 * the caller.
     101 *
     102 * @returns Pointer to the start of the frame.
     103 * @param   pSG         Pointer to the scatter / gather structure.
     104 * @param   cbTotal     The total size.
     105 * @param   cSegs       The number of segments.
     106 * @param   cSegsUsed   The number of used segments.
     107 * @param   pGso        The GSO context.
     108 */
     109DECLINLINE(void) INTNETSgInitTempSegsGso(PINTNETSG pSG, uint32_t cbTotal, unsigned cSegs,
     110                                         unsigned cSegsUsed, PCPDMNETWORKGSO pGso)
     111{
     112    pSG->pvOwnerData    = NULL;
     113    pSG->pvUserData     = NULL;
     114    pSG->pvUserData2    = NULL;
     115    pSG->cbTotal        = cbTotal;
     116    pSG->cUsers         = 1;
     117    pSG->fFlags         = INTNETSG_FLAGS_TEMP;
     118    pSG->GsoCtx.u8Type  = pGso->u8Type;
     119    pSG->GsoCtx.cbHdrs  = pGso->cbHdrs;
     120    pSG->GsoCtx.cbMaxSeg= pGso->cbMaxSeg;
     121    pSG->GsoCtx.offHdr1 = pGso->offHdr1;
     122    pSG->GsoCtx.cbHdr1  = pGso->cbHdr1;
     123    pSG->GsoCtx.offHdr2 = pGso->offHdr2;
     124    pSG->GsoCtx.cbHdr2  = pGso->cbHdr2;
     125#if ARCH_BITS == 64
     126    pSG->uPadding       = 0;
     127#endif
     128    pSG->cSegsAlloc     = (uint16_t)cSegs;
     129    Assert(pSG->cSegsAlloc == cSegs);
     130    pSG->cSegsUsed      = (uint16_t)cSegsUsed;
     131    Assert(pSG->cSegsUsed == cSegsUsed);
     132    Assert(cSegs >= cSegsUsed);
     133}
     134
     135
     136
     137/**
     138 * Initializes a scatter / gather buffer describing a simple linear buffer.
     139 *
     140 * @returns Pointer to the start of the frame.
     141 * @param   pSG         Pointer to the scatter / gather structure.
     142 * @param   pvFrame     Pointer to the frame
     143 * @param   cbFrame     The size of the frame.
     144 */
     145DECLINLINE(void) INTNETSgInitTemp(PINTNETSG pSG, void *pvFrame, uint32_t cbFrame)
     146{
     147    INTNETSgInitTempSegs(pSG, cbFrame, 1, 1);
     148    pSG->aSegs[0].Phys  = NIL_RTHCPHYS;
     149    pSG->aSegs[0].pv    = pvFrame;
     150    pSG->aSegs[0].cb    = cbFrame;
     151}
     152
     153/**
     154 * Initializes a scatter / gather buffer describing a simple linear buffer.
     155 *
     156 * @returns Pointer to the start of the frame.
     157 * @param   pSG         Pointer to the scatter / gather structure.
     158 * @param   pvFrame     Pointer to the frame
     159 * @param   cbFrame     The size of the frame.
     160 * @param   pGso        The GSO context.
     161 */
     162DECLINLINE(void) INTNETSgInitTempGso(PINTNETSG pSG, void *pvFrame, uint32_t cbFrame, PCPDMNETWORKGSO pGso)
     163{
     164    INTNETSgInitTempSegsGso(pSG, cbFrame, 1, 1, pGso);
     165    pSG->aSegs[0].Phys  = NIL_RTHCPHYS;
     166    pSG->aSegs[0].pv    = pvFrame;
     167    pSG->aSegs[0].cb    = cbFrame;
     168}
     169
     170#ifdef __cplusplus
     171
    48172/**
    49173 * Get the amount of space available for writing.
     
    120244#ifdef VBOX_STRICT
    121245    const uintptr_t off = (uintptr_t)pu8 - (uintptr_t)pBuf;
    122     Assert(pHdr->u16Type == INTNETHDR_TYPE_FRAME || pHdr->u16Type == INTNETHDR_TYPE_PADDING);
     246    Assert(INETNETIsValidFrameType(pHdr->u16Type));
    123247    Assert(off < pBuf->cbBuf);
    124248    Assert(off + pHdr->cbFrame <= pBuf->cbBuf);
     
    130254
    131255/**
     256 * Calculates the pointer to the GSO context.
     257 *
     258 * ASSUMES the frame is a GSO frame.
     259 *
     260 * The GSO context is immediately followed by the headers and payload.  The size
     261 * is INTNETBUF::cbFrame - sizeof(PDMNETWORKGSO).
     262 *
     263 * @returns Pointer to the GSO context.
     264 * @param   pHdr        Pointer to the packet header
     265 * @param   pBuf        The buffer the header is within. Only used in strict builds.
     266 */
     267DECLINLINE(PPDMNETWORKGSO) INTNETHdrGetGsoContext(PCINTNETHDR pHdr, PCINTNETBUF pBuf)
     268{
     269    PPDMNETWORKGSO pGso = (PPDMNETWORKGSO)((uint8_t *)pHdr + pHdr->offFrame);
     270#ifdef VBOX_STRICT
     271    const uintptr_t off = (uintptr_t)pGso - (uintptr_t)pBuf;
     272    Assert(pHdr->u16Type == INTNETHDR_TYPE_GSO);
     273    Assert(off < pBuf->cbBuf);
     274    Assert(off + pHdr->cbFrame <= pBuf->cbBuf);
     275#endif
     276    NOREF(pBuf);
     277    return pGso;
     278}
     279
     280
     281/**
    132282 * Skips to the next (read) frame in the buffer.
    133283 *
     
    141291    Assert(offReadOld <  pRingBuf->offEnd);
    142292    Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr);
    143     Assert(pHdr->u16Type == INTNETHDR_TYPE_FRAME || pHdr->u16Type == INTNETHDR_TYPE_PADDING);
     293    Assert(INETNETIsValidFrameType(pHdr->u16Type));
    144294
    145295    /* skip the frame */
     
    168318 * @param   ppvFrame            Where to return the frame pointer.
    169319 */
    170 DECLINLINE(int) INTNETRingAllocateFrame(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, PINTNETHDR *ppHdr, void **ppvFrame)
     320DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, uint16_t u16Type,
     321                                                PINTNETHDR *ppHdr, void **ppvFrame)
    171322{
    172323    /*
     
    194345
    195346            PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
    196             pHdr->u16Type  = INTNETHDR_TYPE_FRAME;
     347            pHdr->u16Type  = u16Type;
    197348            pHdr->cbFrame  = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
    198349            pHdr->offFrame = sizeof(INTNETHDR);
     
    215366
    216367            PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
    217             pHdr->u16Type  = INTNETHDR_TYPE_FRAME;
     368            pHdr->u16Type  = u16Type;
    218369            pHdr->cbFrame  = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
    219370            pHdr->offFrame = pRingBuf->offStart - offWriteInt;
     
    235386
    236387        PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
    237         pHdr->u16Type  = INTNETHDR_TYPE_FRAME;
     388        pHdr->u16Type  = u16Type;
    238389        pHdr->cbFrame  = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
    239390        pHdr->offFrame = sizeof(INTNETHDR);
     
    247398    STAM_REL_COUNTER_INC(&pRingBuf->cOverflows);
    248399    return VERR_BUFFER_OVERFLOW;
     400}
     401
     402
     403/**
     404 * Allocates a normal frame in the specified ring.
     405 *
     406 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
     407 * @param   pRingBuf            The ring buffer.
     408 * @param   cbFrame             The frame size.
     409 * @param   ppHdr               Where to return the frame header.
     410 *                              Don't touch this!
     411 * @param   ppvFrame            Where to return the frame pointer.
     412 */
     413DECLINLINE(int) INTNETRingAllocateFrame(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, PINTNETHDR *ppHdr, void **ppvFrame)
     414{
     415    return intnetRingAllocateFrameInternal(pRingBuf, cbFrame, INTNETHDR_TYPE_FRAME, ppHdr, ppvFrame);
     416}
     417
     418
     419/**
     420 * Allocates a GSO frame in the specified ring.
     421 *
     422 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
     423 * @param   pRingBuf            The ring buffer.
     424 * @param   cbFrame             The frame size.
     425 * @param   pGso                Pointer to the GSO context.
     426 * @param   ppHdr               Where to return the frame header.
     427 *                              Don't touch this!
     428 * @param   ppvFrame            Where to return the frame pointer.
     429 */
     430DECLINLINE(int) INTNETRingAllocateGsoFrame(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, PCPDMNETWORKGSO pGso,
     431                                           PINTNETHDR *ppHdr, void **ppvFrame)
     432{
     433    void *pvFrame;
     434    int rc = intnetRingAllocateFrameInternal(pRingBuf, cbFrame + sizeof(*pGso), INTNETHDR_TYPE_GSO, ppHdr, &pvFrame);
     435    if (RT_SUCCESS(rc))
     436    {
     437        PPDMNETWORKGSO pGsoCopy = (PPDMNETWORKGSO)pvFrame;
     438        *pGsoCopy = *pGso;
     439        *ppvFrame = pGsoCopy + 1;
     440    }
     441    return rc;
    249442}
    250443
     
    492685
    493686
    494 
    495687/**
    496688 * Initializes a buffer structure.
     
    535727}
    536728
     729#endif /* __cplusplus */
     730
    537731#endif
    538732
  • trunk/include/VBox/types.h

    r27973 r28025  
    746746    /** TCP/IPv4. */
    747747    PDMNETWORKGSOTYPE_IPV4_TCP,
    748 #if 0 /* later */
    749748    /** TCP/IPv6. */
    750749    PDMNETWORKGSOTYPE_IPV6_TCP,
     
    753752    /** UDP/IPv6. */
    754753    PDMNETWORKGSOTYPE_IPV6_UDP,
    755     /** IPv6 over IPv4 tunneling. */
    756     PDMNETWORKGSOTYPE_IPV4_TCPV6,
    757754    /** TCP/IPv6 over IPv4 tunneling.
    758755     * The header offsets and sizes relates to IPv4 and TCP, the IPv6 header is
    759756     * figured out as needed.
    760757     * @todo Needs checking against facts, this is just an outline of the idea. */
    761     PDMNETWORKGSOTYPE_IPV4_TCPV6_TCP,
     758    PDMNETWORKGSOTYPE_IPV4_IPV6_TCP,
    762759    /** UDP/IPv6 over IPv4 tunneling.
    763760     * The header offsets and sizes relates to IPv4 and UDP, the IPv6 header is
    764761     * figured out as needed.
    765762     * @todo Needs checking against facts, this is just an outline of the idea. */
    766     PDMNETWORKGSOTYPE_IPV4_TCPV6_UDP,
    767 #endif
     763    PDMNETWORKGSOTYPE_IPV4_IPV6_UDP,
    768764    /** The end of valid GSO types. */
    769765    PDMNETWORKGSOTYPE_END
     
    790786    uint16_t            cbMaxSeg;
    791787
    792     /** Offset of the first header (IPv4 / IPv6). */
     788    /** Offset of the first header (IPv4 / IPv6).  0 if not not needed. */
    793789    uint8_t             offHdr1;
    794     /** The size of the first header (IPv4 / IPv6). */
     790    /** The size of the first header (IPv4 / IPv6).  0 if not not needed. */
    795791    uint8_t             cbHdr1;
    796792
    797     /** Offset of the second header (TCP / UDP). */
     793    /** Offset of the second header (TCP / UDP).  0 if not not needed. */
    798794    uint8_t             offHdr2;
    799     /** The size of the second header (TCP / UDP). */
     795    /** The size of the second header (TCP / UDP).  0 if not not needed. */
    800796    uint8_t             cbHdr2;
    801797} PDMNETWORKGSO;
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