VirtualBox

Changeset 52543 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Aug 31, 2014 11:48:41 PM (10 years ago)
Author:
vboxsync
Message:

IntNet: follow up to r85262 - refactor rewriting of link-level address
option in IPv6 Neighbor Discovery datagrams when bridging to wireless.

Ok bird@

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp

    r52518 r52543  
    28092809}
    28102810
     2811
     2812/**
     2813 * Rewrite VM MAC address with shared host MAC address inside IPv6
     2814 * Neighbor Discovery datagrams.
     2815 */
     2816static void intnetR0TrunkSharedMacEditIPv6FromIntNet(PINTNETTRUNKIF pThis, PINTNETIF pIfSender,
     2817                                                     PRTNETETHERHDR pEthHdr, uint32_t cb)
     2818{
     2819    if (RT_UNLIKELY(cb < sizeof(*pEthHdr)))
     2820        return;
     2821
     2822    /* have IPv6 header */
     2823    PRTNETIPV6 pIPv6 = (PRTNETIPV6)(pEthHdr + 1);
     2824    cb -= sizeof(*pEthHdr);
     2825    if (RT_UNLIKELY(cb < sizeof(*pIPv6)))
     2826        return;
     2827
     2828    if (   pIPv6->ip6_nxt  != RTNETIPV6_PROT_ICMPV6
     2829        || pIPv6->ip6_hlim != 0xff)
     2830        return;
     2831
     2832    PRTNETICMPV6HDR pICMPv6 = (PRTNETICMPV6HDR)(pIPv6 + 1);
     2833    cb -= sizeof(*pIPv6);
     2834    if (RT_UNLIKELY(cb < sizeof(*pICMPv6)))
     2835        return;
     2836
     2837    size_t hdrlen = 0;
     2838    uint8_t llaopt = RTNETIPV6_ICMP_ND_SLLA_OPT;
     2839
     2840    uint8_t type = pICMPv6->icmp6_type;
     2841    switch (type)
     2842    {
     2843        case RTNETIPV6_ICMP_TYPE_RS:
     2844            hdrlen = 8;
     2845            break;
     2846
     2847        case RTNETIPV6_ICMP_TYPE_RA:
     2848            hdrlen = 16;
     2849            break;
     2850
     2851        case RTNETIPV6_ICMP_TYPE_NS:
     2852            hdrlen = 24;
     2853            break;
     2854
     2855        case RTNETIPV6_ICMP_TYPE_NA:
     2856            hdrlen = 24;
     2857            llaopt = RTNETIPV6_ICMP_ND_TLLA_OPT;
     2858            break;
     2859
     2860        default:
     2861            return;
     2862    }
     2863
     2864    AssertReturnVoid(hdrlen > 0);
     2865    if (RT_UNLIKELY(cb < hdrlen))
     2866        return;
     2867
     2868    if (RT_UNLIKELY(pICMPv6->icmp6_code != 0))
     2869        return;
     2870
     2871    PRTNETNDP_LLA_OPT pLLAOpt = NULL;
     2872    char *pOpt = (char *)pICMPv6 + hdrlen;
     2873    cb -= hdrlen;
     2874
     2875    while (cb >= 8)
     2876    {
     2877        uint8_t opt = ((uint8_t *)pOpt)[0];
     2878        size_t optlen = (size_t)((uint8_t *)pOpt)[1] * 8;
     2879        if (RT_UNLIKELY(cb < optlen))
     2880            return;
     2881
     2882        if (opt == llaopt)
     2883        {
     2884            if (RT_UNLIKELY(optlen != 8))
     2885                return;
     2886            pLLAOpt = (PRTNETNDP_LLA_OPT)pOpt;
     2887            break;
     2888        }
     2889
     2890        pOpt += optlen;
     2891        cb -= optlen;
     2892    }
     2893
     2894    if (pLLAOpt == NULL)
     2895        return;
     2896
     2897    if (memcmp(&pLLAOpt->lla, &pIfSender->MacAddr, sizeof(RTMAC)) != 0)
     2898        return;
     2899
     2900    /* overwrite VM's MAC with host's MAC */
     2901    pLLAOpt->lla = pThis->MacAddr;
     2902
     2903    /* recompute the checksum */
     2904    pICMPv6->icmp6_cksum = 0;
     2905    pICMPv6->icmp6_cksum = computeIPv6FullChecksum(pIPv6);
     2906}
     2907
     2908
    28112909/**
    28122910 * Sends a frame down the trunk.
     
    28882986            }
    28892987        }
    2890         else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6))
     2988        else if (pEthHdr->EtherType == RT_H2N_U16_C(RTNET_ETHERTYPE_IPV6))
    28912989        {
    2892             /*
    2893              * IPV6 ICMP Neighbor Discovery : replace
    2894              * 1) the advertised source mac address in outgoing neighbor sollicitations
    2895              *    with the HW MAC address of the trunk interface,
    2896              * 2) the advertised target mac address in outgoing neighbor advertisements
    2897              *    with the HW mac address of the trunk interface.
    2898              *
    2899              * Note that this only applies to traffic going out on the trunk. Incoming
    2900              * NS/NA will never advertise any VM mac address, so we do not need to touch
    2901              * them. Other VMs on this bridge as well as the host will see and use the VM's
    2902              * actual mac addresses.
    2903              *
    2904              */
    2905 
    2906             PRTNETIPV6 pIPv6            = (PRTNETIPV6)(pEthHdr + 1);
    2907             PRTNETNDP pNd               = (PRTNETNDP)(pIPv6 + 1);
    2908             PRTNETNDP_SLLA_OPT pLLAOpt  = (PRTNETNDP_SLLA_OPT)(pNd + 1);
    2909 
    2910             /* make sure we have enough bytes to work with */
    2911             if(pSG->cbTotal >= (RTNETIPV6_MIN_LEN + RTNETIPV6_ICMPV6_ND_WITH_LLA_OPT_MIN_LEN) &&
    2912                /* ensure the packet came from our LAN (not gone through any router) */
    2913                pIPv6->ip6_hlim == 0xff &&
    2914                /* protocol has to be icmpv6 */
    2915                 pIPv6->ip6_nxt == RTNETIPV6_PROT_ICMPV6 &&
    2916                /* we either have a sollicitation with source link layer addr. opt, or */
    2917                 ((pNd->icmp6_type == RTNETIPV6_ICMP_NS_TYPE &&
    2918                             pNd->icmp6_code == RTNETIPV6_ICMPV6_CODE_0 &&
    2919                             pLLAOpt->type == RTNETIPV6_ICMP_ND_SLLA_OPT) ||
    2920                  /* an advertisement with target link layer addr. option */
    2921                 ((pNd->icmp6_type == RTNETIPV6_ICMP_NA_TYPE &&
    2922                             pNd->icmp6_code == RTNETIPV6_ICMPV6_CODE_0 &&
    2923                             pLLAOpt->type == RTNETIPV6_ICMP_ND_TLLA_OPT)) ) &&
    2924                 pLLAOpt->len == RTNETIPV6_ICMP_ND_LLA_LEN)
    2925             {
    2926                 /* swap the advertised VM MAC address with the trunk's */
    2927                 pLLAOpt->slla   = pThis->MacAddr;
    2928 
    2929                 /* recompute the checksum since we changed the packet */
    2930                 pNd->icmp6_cksum = 0;
    2931                 pNd->icmp6_cksum = computeIPv6FullChecksum(pIPv6);
    2932             }
    2933 
     2990            intnetR0TrunkSharedMacEditIPv6FromIntNet(pThis, pIfSender, pEthHdr, pSG->cbTotal);
    29342991        }
    29352992    }
    29362993
    29372994    /*
    2938      * Send the frame, handling the GSO fallback                                                                                           .
    2939      *                                                                                                                                     .
    2940      * Note! The trunk implementation will re-check that the trunk is active                                                               .
     2995     * Send the frame, handling the GSO fallback.
     2996     *
     2997     * Note! The trunk implementation will re-check that the trunk is active
    29412998     *       before sending, so we don't have to duplicate that effort here.
    29422999     */
     
    30993156    if (    pIPv6->ip6_hlim == 0xff
    31003157        &&  pIPv6->ip6_nxt  == RTNETIPV6_PROT_ICMPV6
    3101         &&  pNd->icmp6_type == RTNETIPV6_ICMP_NS_TYPE
    3102         &&  pNd->icmp6_code == RTNETIPV6_ICMPV6_CODE_0
     3158        &&  pNd->Hdr.icmp6_type == RTNETIPV6_ICMP_TYPE_NS
     3159        &&  pNd->Hdr.icmp6_code == 0
    31033160        &&  pIPv6->ip6_src.QWords.qw0 == 0
    31043161        &&  pIPv6->ip6_src.QWords.qw1 == 0)
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