[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.
This commit is contained in:
Jonathan Hui
2025-05-08 10:45:43 -07:00
committed by GitHub
parent ec2b0d4873
commit be879f198d
5 changed files with 12 additions and 232 deletions
+1 -8
View File
@@ -174,16 +174,9 @@ target_link_libraries(openthread-posix
ot-posix-config
$<$<NOT:$<BOOL:${OT_ANDROID_NDK}>>:util>
$<$<STREQUAL:${CMAKE_SYSTEM_NAME},Linux>:rt>
$<$<STREQUAL:${CMAKE_SYSTEM_NAME},Linux>: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}
+3 -141
View File
@@ -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<sockaddr_in6 *>(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)
{
-19
View File
@@ -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);
@@ -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()
@@ -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]