diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index d42648192..eabf9f4ac 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -405,8 +405,9 @@ void RoutingManager::EvaluateOmrPrefix(OmrPrefixArray &aNewOmrPrefixes) { NetworkData::Iterator iterator = NetworkData::kIteratorInit; NetworkData::OnMeshPrefixConfig onMeshPrefixConfig; - Ip6::Prefix * smallestOmrPrefix = nullptr; - Ip6::Prefix * publishedLocalOmrPrefix = nullptr; + Ip6::Prefix * electedOmrPrefix = nullptr; + signed int electedOmrPrefixPreference = 0; + Ip6::Prefix * publishedLocalOmrPrefix = nullptr; OT_ASSERT(mIsRunning); @@ -431,9 +432,11 @@ void RoutingManager::EvaluateOmrPrefix(OmrPrefixArray &aNewOmrPrefixes) continue; } - if (smallestOmrPrefix == nullptr || (prefix < *smallestOmrPrefix)) + if (electedOmrPrefix == nullptr || onMeshPrefixConfig.mPreference > electedOmrPrefixPreference || + (onMeshPrefixConfig.mPreference == electedOmrPrefixPreference && prefix < *electedOmrPrefix)) { - smallestOmrPrefix = aNewOmrPrefixes.Back(); + electedOmrPrefix = aNewOmrPrefixes.Back(); + electedOmrPrefixPreference = onMeshPrefixConfig.mPreference; } if (prefix == mLocalOmrPrefix) @@ -458,16 +461,16 @@ void RoutingManager::EvaluateOmrPrefix(OmrPrefixArray &aNewOmrPrefixes) } else { - OT_ASSERT(smallestOmrPrefix != nullptr); + OT_ASSERT(electedOmrPrefix != nullptr); - if (*smallestOmrPrefix == mLocalOmrPrefix) + if (*electedOmrPrefix == mLocalOmrPrefix) { IgnoreError(PublishLocalOmrPrefix()); } else if (IsOmrPrefixAddedToLocalNetworkData()) { - LogInfo("EvaluateOmrPrefix: There is already a smaller OMR prefix %s in the Thread network", - smallestOmrPrefix->ToString().AsCString()); + LogInfo("EvaluateOmrPrefix: There is already a preferred OMR prefix %s (pref=%d) in the Thread network", + electedOmrPrefix->ToString().AsCString(), electedOmrPrefixPreference); UnpublishLocalOmrPrefix(); diff --git a/tests/scripts/thread-cert/border_router/test_manual_omr_prefix.py b/tests/scripts/thread-cert/border_router/test_manual_omr_prefix.py index 62b1fd1a9..66f4cf2dd 100644 --- a/tests/scripts/thread-cert/border_router/test_manual_omr_prefix.py +++ b/tests/scripts/thread-cert/border_router/test_manual_omr_prefix.py @@ -79,21 +79,29 @@ class ManualOmrsPrefix(thread_cert.TestCase): # Add a smaller OMR prefix. Verify BR_1 withdraws its OMR prefix. self._test_manual_omr_prefix('2001::/64', 'paros', expect_withdraw=True) + # Add a bigger OMR prefix. Verify BR_1 does not withdraw its OMR prefix. + self._test_manual_omr_prefix('fdff:ffff:1::/64', 'paros', expect_withdraw=False, prf='med') + # Add a high preference bigger OMR prefix. Verify BR_1 withdraws its OMR prefix. + self._test_manual_omr_prefix('fdff:ffff:2::/64', 'paros', expect_withdraw=True, prf='high') # Add a smaller but invalid OMR prefix (P_on_mesh = 0). Verify BR_1 does not withdraw its OMR prefix. self._test_manual_omr_prefix('2002::/64', 'pars', expect_withdraw=False) # Add a smaller but invalid OMR prefix (P_stable = 0). Verify BR_1 does not withdraw its OMR prefix. self._test_manual_omr_prefix('2003::/64', 'paro', expect_withdraw=False) - def _test_manual_omr_prefix(self, prefix, flags, expect_withdraw): + def _test_manual_omr_prefix(self, prefix, flags, expect_withdraw, prf='med'): br1 = self.nodes[BR_1] br2 = self.nodes[BR_2] - br2.add_prefix(prefix, flags) + br2.add_prefix(prefix, flags, prf=prf) br2.register_netdata() self.simulator.go(10) + is_omr_prefix = ('a' in flags and 'o' in flags and 's' in flags and 'D' not in flags) + if expect_withdraw: self._assert_prefixes_equal(br1.get_netdata_omr_prefixes(), [prefix]) + elif is_omr_prefix: + self._assert_prefixes_equal(br1.get_netdata_omr_prefixes(), [br1.get_br_omr_prefix(), prefix]) else: self._assert_prefixes_equal(br1.get_netdata_omr_prefixes(), [br1.get_br_omr_prefix()])