[routing-manager] derive on-link prefix from Extended PAN ID (#7695)

To align with latest Thread Specification.
This commit is contained in:
Jonathan Hui
2022-05-16 22:12:08 -07:00
committed by GitHub
parent 8330e708d1
commit 282b85fa9c
6 changed files with 63 additions and 36 deletions
+29 -29
View File
@@ -47,6 +47,7 @@
#include "common/log.hpp" #include "common/log.hpp"
#include "common/random.hpp" #include "common/random.hpp"
#include "common/settings.hpp" #include "common/settings.hpp"
#include "meshcop/extended_panid.hpp"
#include "net/ip6.hpp" #include "net/ip6.hpp"
#include "thread/network_data_leader.hpp" #include "thread/network_data_leader.hpp"
#include "thread/network_data_local.hpp" #include "thread/network_data_local.hpp"
@@ -101,7 +102,7 @@ Error RoutingManager::Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning)
#if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE #if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
GenerateNat64Prefix(); GenerateNat64Prefix();
#endif #endif
SuccessOrExit(error = LoadOrGenerateRandomOnLinkPrefix()); GenerateOnLinkPrefix();
mInfraIfIndex = aInfraIfIndex; mInfraIfIndex = aInfraIfIndex;
@@ -222,37 +223,18 @@ void RoutingManager::GenerateNat64Prefix(void)
} }
#endif #endif
Error RoutingManager::LoadOrGenerateRandomOnLinkPrefix(void) void RoutingManager::GenerateOnLinkPrefix(void)
{ {
Error error = kErrorNone; MeshCoP::ExtendedPanId extPanId = Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId();
bool generated = false;
if (Get<Settings>().Read<Settings::OnLinkPrefix>(mLocalOnLinkPrefix) != kErrorNone || mLocalOnLinkPrefix.mPrefix.mFields.m8[0] = 0xfd;
!mLocalOnLinkPrefix.IsUniqueLocal()) // Global ID: 40 most significant bits of Extended PAN ID
{ memcpy(mLocalOnLinkPrefix.mPrefix.mFields.m8 + 1, extPanId.m8, 5);
Ip6::NetworkPrefix randomOnLinkPrefix; // Subnet ID: 16 least significant bits of Extended PAN ID
memcpy(mLocalOnLinkPrefix.mPrefix.mFields.m8 + 6, extPanId.m8 + 6, 2);
mLocalOnLinkPrefix.SetLength(kOnLinkPrefixLength);
error = randomOnLinkPrefix.GenerateRandomUla(); LogNote("Local on-link prefix: %s", mLocalOnLinkPrefix.ToString().AsCString());
if (error != kErrorNone)
{
LogCrit("Failed to generate random on-link prefix");
ExitNow();
}
mLocalOnLinkPrefix.Set(randomOnLinkPrefix);
mLocalOnLinkPrefix.SetSubnetId(0);
IgnoreError(Get<Settings>().Save<Settings::OnLinkPrefix>(mLocalOnLinkPrefix));
generated = true;
}
OT_UNUSED_VARIABLE(generated);
LogNote("Local on-link prefix: %s (%s)", mLocalOnLinkPrefix.ToString().AsCString(),
generated ? "generated" : "loaded");
exit:
return error;
} }
void RoutingManager::EvaluateState(void) void RoutingManager::EvaluateState(void)
@@ -397,6 +379,24 @@ void RoutingManager::HandleNotifierEvents(Events aEvents)
StartRoutingPolicyEvaluationJitter(kRoutingPolicyEvaluationJitter); StartRoutingPolicyEvaluationJitter(kRoutingPolicyEvaluationJitter);
} }
if (aEvents.Contains(kEventThreadExtPanIdChanged))
{
if (mIsAdvertisingLocalOnLinkPrefix)
{
RemoveExternalRoute(mLocalOnLinkPrefix);
// TODO: consider deprecating/invalidating existing
// on-link prefix
mIsAdvertisingLocalOnLinkPrefix = false;
}
GenerateOnLinkPrefix();
if (mIsRunning)
{
StartRoutingPolicyEvaluationJitter(kRoutingPolicyEvaluationJitter);
}
}
exit: exit:
return; return;
} }
+1 -1
View File
@@ -317,7 +317,7 @@ private:
bool IsEnabled(void) const { return mIsEnabled; } bool IsEnabled(void) const { return mIsEnabled; }
Error LoadOrGenerateRandomBrUlaPrefix(void); Error LoadOrGenerateRandomBrUlaPrefix(void);
void GenerateOmrPrefix(void); void GenerateOmrPrefix(void);
Error LoadOrGenerateRandomOnLinkPrefix(void); void GenerateOnLinkPrefix(void);
const Ip6::Prefix *EvaluateOnLinkPrefix(void); const Ip6::Prefix *EvaluateOnLinkPrefix(void);
@@ -191,12 +191,13 @@ class MultiBorderRouters(thread_cert.TestCase):
br2_omr_prefix = br2.get_br_omr_prefix() br2_omr_prefix = br2.get_br_omr_prefix()
self.assertEqual(br2_omr_prefix, br2.get_netdata_omr_prefixes()[0]) self.assertEqual(br2_omr_prefix, br2.get_netdata_omr_prefixes()[0])
# Only BR2 will keep the route for BR1's on-link prefix # There should be no changes to the external route for the
# and add route for on-link prefix of its own. # on-link prefix, given that the on-link prefix is derived
self.assertEqual(len(br1.get_netdata_non_nat64_prefixes()), 2) # from the Extended PAN ID.
self.assertEqual(len(router1.get_netdata_non_nat64_prefixes()), 2) self.assertEqual(len(br1.get_netdata_non_nat64_prefixes()), 1)
self.assertEqual(len(br2.get_netdata_non_nat64_prefixes()), 2) self.assertEqual(len(router1.get_netdata_non_nat64_prefixes()), 1)
self.assertEqual(len(router2.get_netdata_non_nat64_prefixes()), 2) self.assertEqual(len(br2.get_netdata_non_nat64_prefixes()), 1)
self.assertEqual(len(router2.get_netdata_non_nat64_prefixes()), 1)
br2_on_link_prefix = br2.get_br_on_link_prefix() br2_on_link_prefix = br2.get_br_on_link_prefix()
self.assertEqual(set(map(IPv6Network, br2.get_netdata_non_nat64_prefixes())), self.assertEqual(set(map(IPv6Network, br2.get_netdata_non_nat64_prefixes())),
@@ -28,6 +28,7 @@
# #
import logging import logging
import unittest import unittest
from ipaddress import IPv6Network
import config import config
import thread_cert import thread_cert
@@ -326,6 +327,25 @@ class SingleBorderRouter(thread_cert.TestCase):
self.assertTrue(router.ping(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0])) self.assertTrue(router.ping(host.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0]))
self.assertTrue(host.ping(router.get_ip6_address(config.ADDRESS_TYPE.OMR)[0], backbone=True)) self.assertTrue(host.ping(router.get_ip6_address(config.ADDRESS_TYPE.OMR)[0], backbone=True))
#
# Case 7. Test if Border Router changes on-link prefix when
# Extended PAN ID changes.
#
prefixA = br.get_br_on_link_prefix()
router.commissioner_start()
self.simulator.go(5)
router.send_mgmt_active_set(
active_timestamp=100,
extended_panid='0001020304050607',
)
self.simulator.go(10)
prefixB = br.get_br_on_link_prefix()
self.assertNotEqual(IPv6Network(prefixA), IPv6Network(prefixB))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
@@ -67,6 +67,7 @@ class MultiThreadNetworks(thread_cert.TestCase):
'version': '1.2', 'version': '1.2',
'channel': CHANNEL1, 'channel': CHANNEL1,
'router_selection_jitter': 1, 'router_selection_jitter': 1,
'extended_panid': '0001020304050607'
}, },
ROUTER1: { ROUTER1: {
'name': 'Router_1', 'name': 'Router_1',
@@ -74,6 +75,7 @@ class MultiThreadNetworks(thread_cert.TestCase):
'version': '1.2', 'version': '1.2',
'channel': CHANNEL1, 'channel': CHANNEL1,
'router_selection_jitter': 1, 'router_selection_jitter': 1,
'extended_panid': '0001020304050607'
}, },
BR2: { BR2: {
'name': 'BR_2', 'name': 'BR_2',
@@ -82,6 +84,7 @@ class MultiThreadNetworks(thread_cert.TestCase):
'version': '1.2', 'version': '1.2',
'channel': CHANNEL2, 'channel': CHANNEL2,
'router_selection_jitter': 1, 'router_selection_jitter': 1,
'extended_panid': '08090a0b0c0d0e0f'
}, },
ROUTER2: { ROUTER2: {
'name': 'Router_2', 'name': 'Router_2',
@@ -89,6 +92,7 @@ class MultiThreadNetworks(thread_cert.TestCase):
'version': '1.2', 'version': '1.2',
'channel': CHANNEL2, 'channel': CHANNEL2,
'router_selection_jitter': 1, 'router_selection_jitter': 1,
'extended_panid': '08090a0b0c0d0e0f'
}, },
HOST: { HOST: {
'name': 'Host', 'name': 'Host',
+2
View File
@@ -183,6 +183,8 @@ class TestCase(NcpSupportMixin, unittest.TestCase):
self.nodes[i].set_panid(params['panid']) self.nodes[i].set_panid(params['panid'])
self.nodes[i].set_mode(params['mode']) self.nodes[i].set_mode(params['mode'])
if 'extended_panid' in params:
self.nodes[i].set_extpanid(params['extended_panid'])
if 'partition_id' in params: if 'partition_id' in params:
self.nodes[i].set_preferred_partition_id(params['partition_id']) self.nodes[i].set_preferred_partition_id(params['partition_id'])
if 'channel' in params: if 'channel' in params: