VirtualBox

Changeset 28868 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Apr 28, 2010 2:01:56 PM (15 years ago)
Author:
vboxsync
Message:

Solaris/VBoxNetFlt: fix priority tagged VLAN packets.

Location:
trunk/src/VBox/HostDrivers/VBoxNetFlt
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h

    r28832 r28868  
    203203            /** Whether we are attaching to IPv6 stream dynamically now. */
    204204            bool volatile fAttaching;
     205            /** Whether this is a VLAN interface or not. */
     206            bool volatile fVLAN;
    205207            /** Layered device handle to the interface. */
    206208            ldi_handle_t hIface;
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c

    r28830 r28868  
    110110#define VBOXNETFLT_LOOPBACK_SIZE        32
    111111
     112/** VLAN tag masking, should probably be in IPRT? */
     113#define VLAN_ID(vlan)          (((vlan) >>  0) & 0x0fffu)
     114#define VLAN_CFI(vlan)         (((vlan) >> 12) & 0x0001u)
     115#define VLAN_PRI(vlan)         (((vlan) >> 13) & 0x0007u)
     116
     117typedef struct VLANHEADER
     118{
     119    uint16_t Type;
     120    uint16_t Data;
     121} VLANHEADER;
     122typedef struct VLANHEADER *PVLANHEADER;
     123
    112124/*******************************************************************************
    113125*   Global Functions                                                           *
     
    18141826
    18151827    char *pszEnd = strchr(pszDev, '\0');
    1816     int PPALen = 0;
    18171828    while (--pszEnd > pszDev)
    1818     {
    18191829        if (!RT_C_IS_DIGIT(*pszEnd))
    18201830            break;
    1821         PPALen++;
    1822     }
    18231831    pszEnd++;
    18241832
     
    18751883    DevId = ldi_ident_from_anon();
    18761884    int ret;
     1885
     1886    /*
     1887     * Figure out if this is a VLAN interface or not based on the interface name.
     1888     * Only works for the VLAN PPA-hack based names. See #4854 for details.
     1889     */
     1890    char *pszEnd = strchr(pThis->szName, '\0');
     1891    while (--pszEnd > pThis->szName)
     1892        if (!RT_C_IS_DIGIT(*pszEnd))
     1893            break;
     1894    pszEnd++;
     1895    uint32_t PPA = RTStrToUInt32(pszEnd);
     1896    if (PPA > 1000)
     1897    {
     1898        pThis->u.s.fVLAN = true;
     1899        LogRel((DEVICE_NAME ": %s detected as VLAN interface with VID=%u.\n", pThis->szName, PPA / 1000U));
     1900    }
    18771901
    18781902    /*
     
    25712595    LogFlowFunc((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface pThis=%p\n", pThis));
    25722596
     2597    /*
     2598     * Since this is asynchronous streams injection, let the attach succeed before we can start
     2599     * processing the stream.
     2600     */
     2601    ASMAtomicWriteBool(&pThis->fDisconnectedFromHost, true);
    25732602    int rc = vboxNetFltSolarisOpenStream(pThis);
    25742603    if (RT_SUCCESS(rc))
     
    32333262
    32343263    /*
     3264     * Solaris raw mode streams for priority-tagged VLAN does not strip the VLAN tag.
     3265     * It zero's the VLAN-Id but keeps the tag intact as part of the Ethernet header.
     3266     * We need to manually strip these tags out or the guests might get confused.
     3267     */
     3268    bool fCopied = false;
     3269    if (   pThis->u.s.fVLAN
     3270        && pPromiscStream->fRawMode)
     3271    {
     3272        if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_VLAN))
     3273        {
     3274            if (msgdsize(pMsg) > sizeof(RTNETETHERHDR) + sizeof(VLANHEADER))
     3275            {
     3276                if (pMsg->b_cont)
     3277                {
     3278                    mblk_t *pFullMsg = msgpullup(pMsg, -1 /* all data blocks */);
     3279                    if (pFullMsg)
     3280                    {
     3281                        /* Original pMsg will be freed by the caller */
     3282                        pMsg = pFullMsg;
     3283                        fCopied = true;
     3284                    }
     3285                    else
     3286                    {
     3287                        LogRel((DEVICE_NAME ":vboxNetFltSolarisRecv msgpullup failed.\n"));
     3288                        return VERR_NO_MEMORY;
     3289                    }
     3290                }
     3291
     3292                PVLANHEADER pVlanHdr = (PVLANHEADER)(pMsg->b_rptr + sizeof(RTNETETHERHDR) - sizeof(pEthHdr->EtherType));
     3293                LogFlow((DEVICE_NAME ":Recv VLAN Pcp=%u Cfi=%u Id=%u\n", VLAN_PRI(RT_BE2H_U16(pVlanHdr->Data)),
     3294                            VLAN_CFI(RT_BE2H_U16(pVlanHdr->Data)), VLAN_ID(RT_BE2H_U16(pVlanHdr->Data))));
     3295                if (   VLAN_PRI(RT_BE2H_U16(pVlanHdr->Data)) > 0
     3296                    && VLAN_ID(RT_BE2H_U16(pVlanHdr->Data) == 0)
     3297                {
     3298                    /*
     3299                     * Create new Ethernet header with stripped VLAN tag.
     3300                     */
     3301                    size_t cbEthPrefix = sizeof(RTNETETHERHDR) - sizeof(pEthHdr->EtherType);
     3302                    mblk_t *pStrippedMsg = allocb(cbEthPrefix, BPRI_MED);
     3303                    if (RT_LIKELY(pStrippedMsg))
     3304                    {
     3305                        /*
     3306                         * Copy ethernet header excluding the ethertype.
     3307                         */
     3308                        bcopy(pMsg->b_rptr, pStrippedMsg->b_wptr, cbEthPrefix);
     3309                        pStrippedMsg->b_wptr += cbEthPrefix;
     3310
     3311                        /*
     3312                         * Link the rest of the message (ethertype + data, skipping VLAN header).
     3313                         */
     3314                        pMsg->b_rptr += cbEthPrefix + sizeof(VLANHEADER);
     3315                        pStrippedMsg->b_cont = pMsg;
     3316                        pMsg = pStrippedMsg;
     3317                        LogFlow((DEVICE_NAME ":Stripped VLAN tag.\n"));
     3318                    }
     3319                    else
     3320                    {
     3321                        LogRel((DEVICE_NAME ":vboxNetFltSolarisRecv insufficient memory for creating VLAN stripped packet cbMsg=%u.\n",
     3322                                    cbEthPrefix));
     3323                        if (fCopied)
     3324                            freemsg(pMsg);
     3325                        return VERR_NO_MEMORY;
     3326                    }
     3327                }
     3328            }
     3329        }
     3330    }
     3331
     3332    /*
    32353333     * Route all received packets into the internal network.
    32363334     */
     
    32423340    else
    32433341        LogRel((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG failed. rc=%d\n", rc));
     3342
     3343    /*
     3344     * If we made an extra copy for VLAN stripping, we need to free that ourselves.
     3345     */
     3346    if (fCopied)
     3347        freemsg(pMsg);
    32443348
    32453349    return VINF_SUCCESS;
     
    33993503        {
    34003504            if (pIpHdr->ip_p == RTNETIPV4_PROT_ICMP)
    3401                 LogFlow((DEVICE_NAME ":ICMP D=%.6Rhxs  S=%.6Rhxs  T=%04x\n", pb, pb + 6, RT_BE2H_U16(*(uint16_t *)(pb + 12))));
     3505                LogRel((DEVICE_NAME ":ICMP D=%.6Rhxs  S=%.6Rhxs  T=%04x\n", pb, pb + 6, RT_BE2H_U16(*(uint16_t *)(pb + 12))));
    34023506            else if (pIpHdr->ip_p == RTNETIPV4_PROT_TCP)
    3403                 LogFlow((DEVICE_NAME ":TCP D=%.6Rhxs  S=%.6Rhxs\n", pb, pb + 6));
     3507                LogRel((DEVICE_NAME ":TCP D=%.6Rhxs  S=%.6Rhxs\n", pb, pb + 6));
    34043508            else if (pIpHdr->ip_p == RTNETIPV4_PROT_UDP)
    34053509            {
     
    34203524    else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_VLAN))
    34213525    {
    3422         typedef struct VLANHEADER
    3423         {
    3424             int Pcp:3;
    3425             int Cfi:1;
    3426             int Vid:12;
    3427         } VLANHEADER;
    3428 
    3429         VLANHEADER *pVlanHdr = (VLANHEADER *)(pMsg->b_rptr + sizeof(RTNETETHERHDR));
    3430         LogFlow((DEVICE_NAME ":VLAN Pcp=%d Cfi=%d Id=%d\n", pVlanHdr->Pcp, pVlanHdr->Cfi, pVlanHdr->Vid >> 4));
    3431         LogFlow((DEVICE_NAME "%.*Rhxd\n", MBLKL(pMsg), pMsg->b_rptr));
     3526        PVLANHEADER pVlanHdr = (PVLANHEADER)(pMsg->b_rptr + sizeof(RTNETETHERHDR) - sizeof(pEthHdr->EtherType));
     3527        LogRel((DEVICE_NAME ":VLAN Pcp=%u Cfi=%u Id=%u\n", VLAN_PRI(RT_BE2H_U16(pVlanHdr->Data)), VLAN_CFI(RT_BE2H_U16(pVlanHdr->Data)), VLAN_ID(RT_BE2H_U16(pVlanHdr->Data))));
     3528        LogRel((DEVICE_NAME "%.*Rhxd\n", sizeof(VLANHEADER), pVlanHdr));
    34323529    }
    34333530    else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_ARP))
    34343531    {
    34353532        PRTNETARPHDR pArpHdr = (PRTNETARPHDR)(pEthHdr + 1);
    3436         LogFlow((DEVICE_NAME ":ARP Op=%d\n", pArpHdr->ar_oper));
     3533        LogRel((DEVICE_NAME ":ARP Op=%d\n", pArpHdr->ar_oper));
    34373534    }
    34383535    else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6))
    34393536    {
    3440         LogFlow((DEVICE_NAME ":IPv6 D=%.6Rhxs S=%.6Rhxs\n", pb, pb + 6));
     3537        LogRel((DEVICE_NAME ":IPv6 D=%.6Rhxs S=%.6Rhxs\n", pb, pb + 6));
    34413538    }
    34423539    else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPX_1)
     
    34443541             || pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPX_3))
    34453542    {
    3446         LogFlow((DEVICE_NAME ":IPX packet.\n"));
     3543        LogRel((DEVICE_NAME ":IPX packet.\n"));
    34473544    }
    34483545    else
    34493546    {
    3450         LogFlow((DEVICE_NAME ":Unknown EtherType=%x D=%.6Rhxs S=%.6Rhxs\n", RT_H2BE_U16(pEthHdr->EtherType), &pEthHdr->DstMac,
     3547        LogRel((DEVICE_NAME ":Unknown EtherType=%x D=%.6Rhxs S=%.6Rhxs\n", RT_H2BE_U16(pEthHdr->EtherType), &pEthHdr->DstMac,
    34513548                    &pEthHdr->SrcMac));
    34523549        /* LogFlow((DEVICE_NAME ":%.*Rhxd\n", MBLKL(pMsg), pMsg->b_rptr)); */
     
    35723669    pThis->u.s.pvArpStream = NULL;
    35733670    pThis->u.s.pvPromiscStream = NULL;
     3671    pThis->u.s.fAttaching = false;
     3672    pThis->u.s.fVLAN = false;
    35743673    pThis->u.s.hFastMtx = NIL_RTSEMFASTMUTEX;
    35753674#ifdef VBOXNETFLT_SOLARIS_IPV6_POLLING
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