VirtualBox

Changeset 87637 in vbox


Ignore:
Timestamp:
Feb 8, 2021 1:18:11 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142674
Message:

NAT/Net: Get IPv6 address from the API instead of always constructing
one based on IPV4. bugref:8124, bugref:9929.

Location:
trunk/src/VBox/NetworkServices/NAT
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp

    r87620 r87637  
    178178    int logInit();
    179179    int ipv4Init();
     180    int ipv6Init();
    180181    int eventsInit();
    181182
     
    242243    RT_ZERO(m_ProxyOptions.ipv4_addr);
    243244    RT_ZERO(m_ProxyOptions.ipv4_mask);
     245    RT_ZERO(m_ProxyOptions.ipv6_addr);
    244246    m_ProxyOptions.ipv6_enabled = 0;
    245247    m_ProxyOptions.ipv6_defroute = 0;
     
    365367    AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
    366368
    367     /*
    368      * Get the settings related to IPv4.
    369      */
     369
     370    /* Get the settings related to IPv4. */
    370371    rc = ipv4Init();
    371372    if (RT_FAILURE(rc))
    372373        return rc;
    373374
    374 
    375     BOOL fIPv6Enabled = FALSE;
    376     hrc = m_net->COMGETTER(IPv6Enabled)(&fIPv6Enabled);
    377     AssertComRCReturn(hrc, VERR_NOT_FOUND);
    378 
    379     BOOL fIPv6DefaultRoute = FALSE;
    380     if (fIPv6Enabled)
    381     {
    382         hrc = m_net->COMGETTER(AdvertiseDefaultIPv6RouteEnabled)(&fIPv6DefaultRoute);
    383         AssertComRCReturn(hrc, VERR_NOT_FOUND);
    384     }
    385 
    386     m_ProxyOptions.ipv6_enabled = fIPv6Enabled;
    387     m_ProxyOptions.ipv6_defroute = fIPv6DefaultRoute;
    388 
    389 
    390     /*
    391      * IPv6 source address, if configured.
    392      */
    393     if (fIPv6Enabled)
    394     {
    395         com::Utf8Str strSourceIp6;
    396         rc = getExtraData(strSourceIp6, "SourceIp6");
    397         if (RT_SUCCESS(rc) && strSourceIp6.isNotEmpty())
    398         {
    399             RTNETADDRIPV6 addr;
    400             char *pszZone = NULL;
    401             rc = RTNetStrToIPv6Addr(strSourceIp6.c_str(), &addr, &pszZone);
    402             if (RT_SUCCESS(rc))
    403             {
    404                 memcpy(&m_src6.sin6_addr, &addr, sizeof(addr));
    405                 m_ProxyOptions.src6 = &m_src6;
    406 
    407                 LogRel(("Will use %RTnaipv6 as IPv6 source address\n",
    408                         &m_src6.sin6_addr));
    409             }
    410             else
    411             {
    412                 LogRel(("Failed to parse \"%s\" IPv6 source address specification\n",
    413                         strSourceIp6.c_str()));
    414             }
    415         }
    416     }
    417 
    418 
    419     if (fIPv6Enabled)
    420         createRawSock6();
     375    /* Get the settings related to IPv6. */
     376    rc = ipv6Init();
     377    if (RT_FAILURE(rc))
     378        return rc;
     379
    421380
    422381
    423382    fetchNatPortForwardRules(m_vecPortForwardRule4, /* :fIsIPv6 */ false);
    424     if (fIPv6Enabled)
     383    if (m_ProxyOptions.ipv6_enabled)
    425384        fetchNatPortForwardRules(m_vecPortForwardRule6, /* :fIsIPv6 */ true);
    426385
     
    575534    AssertReturn(m_net.isNotNull(), VERR_GENERAL_FAILURE);
    576535
     536
    577537    /*
    578538     * IPv4 address and mask.
     
    622582
    623583
    624     /*
    625      * Raw socket for ICMP.
    626      */
     584    /* Raw socket for ICMP. */
    627585    createRawSock4();
    628586
    629587
    630     /*
    631      * IPv4 source address (host), if configured.
    632      */
     588    /* IPv4 source address (host), if configured. */
    633589    com::Utf8Str strSourceIp4;
    634590    rc = getExtraData(strSourceIp4, "SourceIp4");
     
    655611}
    656612
     613
     614/*
     615 * Read IPv6 related settings and do necessary initialization.  These
     616 * settings will be picked up by the proxy on the lwIP thread.  See
     617 * onLwipTcpIpInit().
     618 */
     619int VBoxNetLwipNAT::ipv6Init()
     620{
     621    HRESULT hrc;
     622    int rc;
     623
     624    AssertReturn(m_net.isNotNull(), VERR_GENERAL_FAILURE);
     625
     626
     627    /* Is IPv6 enabled for this network at all? */
     628    BOOL fIPv6Enabled = FALSE;
     629    hrc = m_net->COMGETTER(IPv6Enabled)(&fIPv6Enabled);
     630    if (FAILED(hrc))
     631    {
     632        reportComError(m_net, "IPv6Enabled", hrc);
     633        return VERR_GENERAL_FAILURE;
     634    }
     635
     636    m_ProxyOptions.ipv6_enabled = !!fIPv6Enabled;
     637    if (!fIPv6Enabled)
     638        return VINF_SUCCESS;
     639
     640
     641    /*
     642     * IPv6 address.
     643     */
     644    com::Bstr bstrIPv6Prefix;
     645    hrc = m_net->COMGETTER(IPv6Prefix)(bstrIPv6Prefix.asOutParam());
     646    if (FAILED(hrc))
     647    {
     648        reportComError(m_net, "IPv6Prefix", hrc);
     649        return VERR_GENERAL_FAILURE;
     650    }
     651
     652    RTNETADDRIPV6 Net6;
     653    int iPrefixLength;
     654    rc = RTNetStrToIPv6Cidr(com::Utf8Str(bstrIPv6Prefix).c_str(),
     655                            &Net6, &iPrefixLength);
     656    if (RT_FAILURE(rc))
     657    {
     658        reportError("Failed to parse IPv6 prefix %ls\n", bstrIPv6Prefix.raw());
     659        return rc;
     660    }
     661
     662    /* Allow both addr:: and addr::/64 */
     663    if (iPrefixLength == 128)   /* no length was specified after the address? */
     664        iPrefixLength = 64;     /*   take it to mean /64 which we require anyway */
     665    else if (iPrefixLength != 64)
     666    {
     667        reportError("Invalid IPv6 prefix length %d,"
     668                    " must be 64.\n", iPrefixLength);
     669        return rc;
     670    }
     671
     672    /* Verify the address is unicast. */
     673    if (   ((Net6.au8[0] & 0xe0) != 0x20)  /* global 2000::/3 */
     674        && ((Net6.au8[0] & 0xfe) != 0xfc)) /* local  fc00::/7 */
     675    {
     676        reportError("IPv6 prefix %RTnaipv6 is not unicast.\n", &Net6);
     677        return VERR_INVALID_PARAMETER;
     678    }
     679
     680    /* Verify the interfaces ID part is zero */
     681    if (Net6.au64[1] != 0)
     682    {
     683        reportError("Non-zero bits in the interface ID part"
     684                    " of the IPv6 prefix %RTnaipv6/64.\n", &Net6);
     685        return VERR_INVALID_PARAMETER;
     686    }
     687
     688    /* Use ...::1 as our address */
     689    RTNETADDRIPV6 Addr6 = Net6;
     690    Addr6.au8[15] = 0x01;
     691    memcpy(&m_ProxyOptions.ipv6_addr, &Addr6, sizeof(ip6_addr_t));
     692
     693
     694    /*
     695     * Should we advertise ourselves as default IPv6 route?  If the
     696     * host doesn't have IPv6 connectivity, it's probably better not
     697     * to, to prevent the guest from IPv6 connection attempts doomed
     698     * to fail.
     699     *
     700     * We might want to make this modifiable while the natnet is
     701     * running.
     702     */
     703    BOOL fIPv6DefaultRoute = FALSE;
     704    hrc = m_net->COMGETTER(AdvertiseDefaultIPv6RouteEnabled)(&fIPv6DefaultRoute);
     705    if (FAILED(hrc))
     706    {
     707        reportComError(m_net, "AdvertiseDefaultIPv6RouteEnabled", hrc);
     708        return VERR_GENERAL_FAILURE;
     709    }
     710
     711    m_ProxyOptions.ipv6_defroute = fIPv6DefaultRoute;
     712
     713
     714    /* Raw socket for ICMP. */
     715    createRawSock6();
     716
     717
     718    /* IPv6 source address, if configured. */
     719    com::Utf8Str strSourceIp6;
     720    rc = getExtraData(strSourceIp6, "SourceIp6");
     721    if (RT_SUCCESS(rc) && strSourceIp6.isNotEmpty())
     722    {
     723        RTNETADDRIPV6 addr;
     724        char *pszZone = NULL;
     725        rc = RTNetStrToIPv6Addr(strSourceIp6.c_str(), &addr, &pszZone);
     726        if (RT_SUCCESS(rc))
     727        {
     728            memcpy(&m_src6.sin6_addr, &addr, sizeof(addr));
     729            m_ProxyOptions.src6 = &m_src6;
     730
     731            LogRel(("Will use %RTnaipv6 as IPv6 source address\n",
     732                    &m_src6.sin6_addr));
     733        }
     734        else
     735        {
     736            LogRel(("Failed to parse \"%s\" IPv6 source address specification\n",
     737                    strSourceIp6.c_str()));
     738        }
     739    }
     740
     741    return VINF_SUCCESS;
     742}
    657743
    658744
     
    9261012        netif_ip6_addr_set_state(pNetif, 0, IP6_ADDR_PREFERRED); // skip DAD
    9271013
    928         /*
    929          * RFC 4193 Locally Assigned Global ID (ULA) in slot 1
    930          * [fd17:625c:f037:XXXX::1] where XXXX, 16 bit Subnet ID, are two
    931          * bytes from the middle of the IPv4 address, e.g. :dead: for
    932          * 10.222.173.1
    933          */
    934         u8_t nethi = ip4_addr2(&pNetif->ip_addr);
    935         u8_t netlo = ip4_addr3(&pNetif->ip_addr);
    936 
    937         ip6_addr_t *paddr = netif_ip6_addr(pNetif, 1);
    938         IP6_ADDR(paddr, 0,   0xFD, 0x17,   0x62, 0x5C);
    939         IP6_ADDR(paddr, 1,   0xF0, 0x37,  nethi, netlo);
    940         IP6_ADDR(paddr, 2,   0x00, 0x00,   0x00, 0x00);
    941         IP6_ADDR(paddr, 3,   0x00, 0x00,   0x00, 0x01);
     1014        /* INATNetwork::IPv6Prefix in slot 1 */
     1015        memcpy(netif_ip6_addr(pNetif, 1),
     1016               &self->m_ProxyOptions.ipv6_addr, sizeof(ip6_addr_t));
    9421017        netif_ip6_addr_set_state(pNetif, 1, IP6_ADDR_PREFERRED);
    9431018
  • trunk/src/VBox/NetworkServices/NAT/proxy.h

    r87620 r87637  
    5353    ip_addr_t ipv4_addr;
    5454    ip_addr_t ipv4_mask;
     55    ip6_addr_t ipv6_addr;
    5556    int ipv6_enabled;
    5657    int ipv6_defroute;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette