From be879f198d21ef7ca100c4efa2f6f0531e619009 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Thu, 8 May 2025 10:45:43 -0700 Subject: [PATCH] [nat64] remove support for `ipv4only.arpa` (#11481) Thread Specification is transitioning from RFC 7050 to RFC 8781 for discovering the NAT64 prefix. This commit removes RFC 7050 behavior. --- src/posix/platform/CMakeLists.txt | 9 +- src/posix/platform/infra_if.cpp | 144 +----------------- src/posix/platform/infra_if.hpp | 19 --- .../internet/test_multi_border_routers.py | 69 +-------- .../test_with_infrastructure_prefix.py | 3 + 5 files changed, 12 insertions(+), 232 deletions(-) diff --git a/src/posix/platform/CMakeLists.txt b/src/posix/platform/CMakeLists.txt index 923c4e284..766a15d52 100644 --- a/src/posix/platform/CMakeLists.txt +++ b/src/posix/platform/CMakeLists.txt @@ -174,16 +174,9 @@ target_link_libraries(openthread-posix ot-posix-config $<$>:util> $<$:rt> + $<$:anl> ) -option(OT_TARGET_OPENWRT "enable openthread posix for OpenWRT" OFF) -if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND NOT OT_TARGET_OPENWRT) - target_compile_definitions(ot-posix-config - INTERFACE "OPENTHREAD_POSIX_CONFIG_NAT64_AIL_PREFIX_ENABLE=1" - ) - target_link_libraries(openthread-posix PRIVATE anl) -endif() - target_compile_definitions(openthread-posix PUBLIC ${OT_PUBLIC_DEFINES} diff --git a/src/posix/platform/infra_if.cpp b/src/posix/platform/infra_if.cpp index 80438b19c..89b1f7bdf 100644 --- a/src/posix/platform/infra_if.cpp +++ b/src/posix/platform/infra_if.cpp @@ -102,10 +102,11 @@ otError otPlatInfraIfSendIcmp6Nd(uint32_t aInfraIfIndex, } #endif -#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE && OPENTHREAD_POSIX_CONFIG_NAT64_AIL_PREFIX_ENABLE +#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE otError otPlatInfraIfDiscoverNat64Prefix(uint32_t aInfraIfIndex) { - return ot::Posix::InfraNetif::Get().DiscoverNat64Prefix(aInfraIfIndex); + OT_UNUSED_VARIABLE(aInfraIfIndex); + return OT_ERROR_NOT_IMPLEMENTED; } #endif @@ -664,145 +665,6 @@ exit: } #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE -#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE && OPENTHREAD_POSIX_CONFIG_NAT64_AIL_PREFIX_ENABLE -const char InfraNetif::kWellKnownIpv4OnlyName[] = "ipv4only.arpa"; -const otIp4Address InfraNetif::kWellKnownIpv4OnlyAddress1 = {{{192, 0, 0, 170}}}; -const otIp4Address InfraNetif::kWellKnownIpv4OnlyAddress2 = {{{192, 0, 0, 171}}}; -const uint8_t InfraNetif::kValidNat64PrefixLength[] = {96, 64, 56, 48, 40, 32}; - -#ifdef __linux__ -void InfraNetif::DiscoverNat64PrefixDone(union sigval sv) -{ - struct gaicb *req = (struct gaicb *)sv.sival_ptr; - struct addrinfo *res = (struct addrinfo *)req->ar_result; - - otIp6Prefix prefix = {}; - - VerifyOrExit((char *)req->ar_name == kWellKnownIpv4OnlyName); - - LogInfo("Handling host address response for %s", kWellKnownIpv4OnlyName); - - // We extract the first valid NAT64 prefix from the address look-up response. - for (struct addrinfo *rp = res; rp != NULL && prefix.mLength == 0; rp = rp->ai_next) - { - struct sockaddr_in6 *ip6Addr; - otIp6Address ip6Address; - - if (rp->ai_family != AF_INET6) - { - continue; - } - - ip6Addr = reinterpret_cast(rp->ai_addr); - memcpy(&ip6Address.mFields.m8, &ip6Addr->sin6_addr.s6_addr, OT_IP6_ADDRESS_SIZE); - for (uint8_t length : kValidNat64PrefixLength) - { - otIp4Address ip4Address; - - otIp4ExtractFromIp6Address(length, &ip6Address, &ip4Address); - if (otIp4IsAddressEqual(&ip4Address, &kWellKnownIpv4OnlyAddress1) || - otIp4IsAddressEqual(&ip4Address, &kWellKnownIpv4OnlyAddress2)) - { - // We check that the well-known IPv4 address is present only once in the IPv6 address. - // In case another instance of the value is found for another prefix length, we ignore this address - // and search for the other well-known IPv4 address (per RFC 7050 section 3). - bool foundDuplicate = false; - - for (uint8_t dupLength : kValidNat64PrefixLength) - { - otIp4Address dupIp4Address; - - if (dupLength == length) - { - continue; - } - - otIp4ExtractFromIp6Address(dupLength, &ip6Address, &dupIp4Address); - if (otIp4IsAddressEqual(&dupIp4Address, &ip4Address)) - { - foundDuplicate = true; - break; - } - } - - if (!foundDuplicate) - { - otIp6GetPrefix(&ip6Address, length, &prefix); - break; - } - } - - if (prefix.mLength != 0) - { - break; - } - } - } - -#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE - otPlatInfraIfDiscoverNat64PrefixDone(gInstance, Get().mInfraIfIndex, &prefix); -#endif - -exit: - freeaddrinfo(res); - freeaddrinfo((struct addrinfo *)req->ar_request); - free(req); -} -#endif // #ifdef __linux__ - -otError InfraNetif::DiscoverNat64Prefix(uint32_t aInfraIfIndex) -{ -#ifdef __linux__ - otError error = OT_ERROR_NONE; - struct addrinfo *hints = nullptr; - struct gaicb *reqs[1] = {nullptr}; - struct sigevent sig; - int status; - - VerifyOrExit(aInfraIfIndex == mInfraIfIndex, error = OT_ERROR_DROP); - hints = (struct addrinfo *)malloc(sizeof(struct addrinfo)); - VerifyOrExit(hints != nullptr, error = OT_ERROR_NO_BUFS); - memset(hints, 0, sizeof(struct addrinfo)); - hints->ai_family = AF_INET6; - hints->ai_socktype = SOCK_STREAM; - - reqs[0] = (struct gaicb *)malloc(sizeof(struct gaicb)); - VerifyOrExit(reqs[0] != nullptr, error = OT_ERROR_NO_BUFS); - memset(reqs[0], 0, sizeof(struct gaicb)); - reqs[0]->ar_name = kWellKnownIpv4OnlyName; - reqs[0]->ar_request = hints; - - memset(&sig, 0, sizeof(struct sigevent)); - sig.sigev_notify = SIGEV_THREAD; - sig.sigev_value.sival_ptr = reqs[0]; - sig.sigev_notify_function = &InfraNetif::DiscoverNat64PrefixDone; - - status = getaddrinfo_a(GAI_NOWAIT, reqs, 1, &sig); - - if (status != 0) - { - LogNote("getaddrinfo_a failed: %s", gai_strerror(status)); - ExitNow(error = OT_ERROR_FAILED); - } - LogInfo("getaddrinfo_a requested for %s", kWellKnownIpv4OnlyName); -exit: - if (error != OT_ERROR_NONE) - { - if (hints) - { - freeaddrinfo(hints); - } - free(reqs[0]); - } - return error; -#else - OT_UNUSED_VARIABLE(aInfraIfIndex); - - return OT_ERROR_NOT_IMPLEMENTED; -#endif // #ifdef __linux__ -} -#endif // OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE && OPENTHREAD_POSIX_CONFIG_NAT64_AIL_PREFIX_ENABLE - #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE void InfraNetif::SetInfraNetifIcmp6SocketForBorderRouting(int aIcmp6Socket) { diff --git a/src/posix/platform/infra_if.hpp b/src/posix/platform/infra_if.hpp index 88771b964..c36ff1d9a 100644 --- a/src/posix/platform/infra_if.hpp +++ b/src/posix/platform/infra_if.hpp @@ -161,19 +161,6 @@ public: const uint8_t *aBuffer, uint16_t aBufferLength); -#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE && OPENTHREAD_POSIX_CONFIG_NAT64_AIL_PREFIX_ENABLE - /** - * Sends an asynchronous address lookup for the well-known host name "ipv4only.arpa" - * to discover the NAT64 prefix. - * - * @param[in] aInfraIfIndex The index of the infrastructure interface the address look-up is sent to. - * - * @retval OT_ERROR_NONE Successfully request address look-up. - * @retval OT_ERROR_FAILED Failed to request address look-up. - */ - otError DiscoverNat64Prefix(uint32_t aInfraIfIndex); -#endif - /** * Gets the infrastructure network interface name. * @@ -230,12 +217,6 @@ private: void ReceiveNetLinkMessage(void); #endif -#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE && OPENTHREAD_POSIX_CONFIG_NAT64_AIL_PREFIX_ENABLE -#ifdef __linux__ - static void DiscoverNat64PrefixDone(union sigval sv); -#endif // #ifdef __linux__ -#endif - #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE void SetInfraNetifIcmp6SocketForBorderRouting(int aIcmp6Socket); void ReceiveIcmp6Message(void); diff --git a/tests/scripts/thread-cert/border_router/internet/test_multi_border_routers.py b/tests/scripts/thread-cert/border_router/internet/test_multi_border_routers.py index 2e38ba55f..25a8e4d35 100755 --- a/tests/scripts/thread-cert/border_router/internet/test_multi_border_routers.py +++ b/tests/scripts/thread-cert/border_router/internet/test_multi_border_routers.py @@ -49,10 +49,6 @@ ROUTER = 2 BR2 = 3 HOST = 4 -OMR_PREFIX = "2000:0:1111:4444::/64" - -NAT64_PREFIX_REFRESH_DELAY = 305 - NAT64_STATE_DISABLED = 'disabled' NAT64_STATE_NOT_RUNNING = 'not_running' NAT64_STATE_IDLE = 'idle' @@ -100,8 +96,6 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): # ensure NAT64 is enabled here. br1.nat64_set_enabled(True) self.simulator.go(config.LEADER_STARTUP_DELAY) - br1.bash("service bind9 stop || true") - self.simulator.go(NAT64_PREFIX_REFRESH_DELAY) self.assertEqual('leader', br1.get_state()) router.start() @@ -109,9 +103,7 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): self.assertEqual('router', router.get_state()) # - # Case 1. BR2 with an infrastructure prefix joins the network later and - # it will add the infrastructure nat64 prefix to Network Data. - # Note: NAT64 translator will be bypassed. + # Case 1. BR2 joins the network and it will not add its local nat64 prefix to Network Data. # br2.start() # When feature flag is enabled, NAT64 might be disabled by default. So @@ -120,60 +112,9 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): self.simulator.go(config.BORDER_ROUTER_STARTUP_DELAY) self.assertEqual('router', br2.get_state()) - br2.add_prefix(OMR_PREFIX) - br2.register_netdata() self.simulator.go(10) - - self.simulator.go(10) - self.assertNotEqual(br1.get_br_favored_nat64_prefix(), br2.get_br_favored_nat64_prefix()) br1_local_nat64_prefix = br1.get_br_nat64_prefix() br2_local_nat64_prefix = br2.get_br_nat64_prefix() - self.assertNotEqual(br2_local_nat64_prefix, br2.get_br_favored_nat64_prefix()) - br2_infra_nat64_prefix = br2.get_br_favored_nat64_prefix() - - self.assertEqual(len(br1.get_netdata_nat64_routes()), 1) - nat64_prefix = br1.get_netdata_nat64_routes()[0] - self.assertEqual(nat64_prefix, br2_infra_nat64_prefix) - self.assertNotEqual(nat64_prefix, br1_local_nat64_prefix) - self.assertDictIncludes(br1.nat64_state, { - 'PrefixManager': NAT64_STATE_IDLE, - 'Translator': NAT64_STATE_NOT_RUNNING - }) - self.assertDictIncludes(br2.nat64_state, { - 'PrefixManager': NAT64_STATE_ACTIVE, - 'Translator': NAT64_STATE_NOT_RUNNING - }) - - # - # Case 2. Disable NAT64 on BR2. - # BR1 will add its local nat64 prefix. - # - br2.nat64_set_enabled(False) - self.simulator.go(10) - - self.assertEqual(len(br1.get_netdata_nat64_routes()), 1) - nat64_prefix = br1.get_netdata_nat64_routes()[0] - self.assertEqual(nat64_prefix, br1_local_nat64_prefix) - self.assertDictIncludes(br1.nat64_state, { - 'PrefixManager': NAT64_STATE_ACTIVE, - 'Translator': NAT64_STATE_ACTIVE - }) - self.assertDictIncludes(br2.nat64_state, { - 'PrefixManager': NAT64_STATE_DISABLED, - 'Translator': NAT64_STATE_DISABLED - }) - - # - # Case 3. Re-enables BR2 with a local prefix and it will not add - # its local nat64 prefix to Network Data. - # - br2.bash("service bind9 stop || true") - self.simulator.go(5) - br2.nat64_set_enabled(True) - - self.simulator.go(10) - self.assertEqual(br2_local_nat64_prefix, br2.get_br_favored_nat64_prefix()) - self.assertEqual(len(br1.get_netdata_nat64_routes()), 1) nat64_prefix = br1.get_netdata_nat64_routes()[0] self.assertEqual(nat64_prefix, br1_local_nat64_prefix) @@ -188,7 +129,7 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): }) # - # Case 4. Disable NAT64 on BR1. + # Case 2. Disable NAT64 on BR1. # BR1 withdraws its local prefix and BR2 advertises its local prefix. # br1.nat64_set_enabled(False) @@ -208,7 +149,7 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): }) # - # Case 5. Re-enable NAT64 on BR1. + # Case 3. Re-enable NAT64 on BR1. # NAT64 prefix in Network Data is still BR2's local prefix. # br1.nat64_set_enabled(True) @@ -228,7 +169,7 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): }) # - # Case 6. Disable the routing manager should stop NAT64 prefix manager. + # Case 4. Disable the routing manager should stop NAT64 prefix manager. # # br2.disable_br() @@ -247,7 +188,7 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): }) # - # Case 7. Enable the routing manager the BR should start NAT64 prefix manager if the prefix manager is enabled. + # Case 5. Enable the routing manager the BR should start NAT64 prefix manager if the prefix manager is enabled. # # br2.enable_br() diff --git a/tests/scripts/thread-cert/border_router/internet/test_with_infrastructure_prefix.py b/tests/scripts/thread-cert/border_router/internet/test_with_infrastructure_prefix.py index d05b4c374..7bb826c50 100755 --- a/tests/scripts/thread-cert/border_router/internet/test_with_infrastructure_prefix.py +++ b/tests/scripts/thread-cert/border_router/internet/test_with_infrastructure_prefix.py @@ -77,6 +77,9 @@ class Nat64SingleBorderRouter(thread_cert.TestCase): } def test(self): + # TODO: re-enable test when PREF64 capability is ready + return + br = self.nodes[BR] router = self.nodes[ROUTER]