mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 21:57:47 +00:00
[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:
@@ -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}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user