[routing-manager] enhance mechanism to publish/unpublish route prefixes (#8187)

This commit updates and enhances the mechanism in `RoutingManager`
to publish/unpublish external route prefixes in Thread Network Data.

Instead of each sub-component (e.g., `DiscoveredPrefixTable`,
`LocalOnLinkPrefix`, `Nat64PrefixManager`, ...) directly trying to
publish/unpublish its entries which can lead to conflicting requests
that then needs to be checked and handled by each component, this
commit adds a new method `EvaluatePublishingPrefix()`. This method
makes a collective decision by checking with different sub-components
to see whether or not each wants this prefix published and if so at
what preference level and flags.

This change help simplify the code and handling of conflicting
situations and edge cases (e.g., while deprecating current/old local
on-link prefix, other routers adding/removing same prefix as PIO or
RIO in their emitted RAs).
This commit is contained in:
Abtin Keshavarzian
2022-10-12 15:13:16 -07:00
committed by GitHub
parent 23c01d7eaf
commit 16c927ea1c
3 changed files with 384 additions and 122 deletions
+228
View File
@@ -1760,6 +1760,232 @@ void TestExtPanIdChange(void)
testFreeInstance(sInstance);
}
void TestConflictingPrefix(void)
{
static const otExtendedPanId kExtPanId1 = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x08}};
Ip6::Prefix localOnLink;
Ip6::Prefix oldLocalOnLink;
Ip6::Prefix localOmr;
Ip6::Prefix onLinkPrefix = PrefixFromString("2000:abba:baba::", 64);
Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
Ip6::Address routerAddressB = AddressFromString("fd00::bbbb");
otOperationalDataset dataset;
Log("--------------------------------------------------------------------------------------------");
Log("TestConflictingPrefix");
InitTest();
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Start Routing Manager. Check emitted RS and RA messages.
sRsEmitted = false;
sRaValidated = false;
sExpectedPio = kPioAdvertisingLocalOnLink;
sExpectedRios.Clear();
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
sExpectedRios.Add(localOmr);
AdvanceTime(30000);
VerifyOrQuit(sRsEmitted);
VerifyOrQuit(sRaValidated);
VerifyOrQuit(sExpectedRios.SawAll());
Log("Received RA was validated");
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check Network Data to include the local OMR and on-link prefix.
VerifyOmrPrefixInNetData(localOmr);
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Send an RA from router A with our local on-link prefix as RIO.
Log("Send RA from router A with local on-link as RIO");
SendRouterAdvert(routerAddressA, {Rio(localOnLink, kValidLitime, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check that the local on-link prefix is still being advertised.
sRaValidated = false;
AdvanceTime(610000);
VerifyOrQuit(sRaValidated);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check Network Data to still include the local OMR and on-link prefix.
VerifyOmrPrefixInNetData(localOmr);
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Send an RA from router A removing local on-link prefix as RIO.
SendRouterAdvert(routerAddressA, {Rio(localOnLink, 0, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Verify that on-link prefix is still included in Network Data and
// the change by router A did not cause it to be unpublished.
AdvanceTime(10000);
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check that the local on-link prefix is still being advertised.
sRaValidated = false;
AdvanceTime(610000);
VerifyOrQuit(sRaValidated);
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Send RA from router B advertising an on-link prefix. This
// should cause local on-link prefix to be deprecated.
SendRouterAdvert(routerAddressB, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check that the local on-link prefix is now deprecating.
sRaValidated = false;
sExpectedPio = kPioDeprecatingLocalOnLink;
AdvanceTime(10000);
VerifyOrQuit(sRaValidated);
VerifyOrQuit(sExpectedRios.SawAll());
Log("On-link prefix is deprecating, remaining lifetime:%d", sOnLinkLifetime);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check Network Data to include the new on-link prefix from router B and
// the deprecating local on-link prefix.
VerifyOmrPrefixInNetData(localOmr);
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium),
ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Send an RA from router A again adding local on-link prefix as RIO.
Log("Send RA from router A with local on-link as RIO");
SendRouterAdvert(routerAddressA, {Rio(localOnLink, kValidLitime, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check that the local on-link prefix is still being deprecated.
sRaValidated = false;
AdvanceTime(610000);
VerifyOrQuit(sRaValidated);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check Network Data remains unchanged.
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium),
ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Send an RA from router A removing the previous RIO.
SendRouterAdvert(routerAddressA, {Rio(localOnLink, 0, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check Network Data remains unchanged and still contains
// the deprecating local on-link prefix.
AdvanceTime(60000);
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium),
ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Send RA from router B removing its on-link prefix.
SendRouterAdvert(routerAddressB, {Pio(onLinkPrefix, kValidLitime, 0)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check that the local on-link prefix is once again being advertised.
sRaValidated = false;
sExpectedPio = kPioAdvertisingLocalOnLink;
AdvanceTime(10000);
VerifyOrQuit(sRaValidated);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check Network Data still contains both prefixes.
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium),
ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Change the extended PAN ID.
Log("Changing ext PAN ID");
SuccessOrQuit(otDatasetGetActive(sInstance, &dataset));
VerifyOrQuit(dataset.mComponents.mIsExtendedPanIdPresent);
dataset.mExtendedPanId = kExtPanId1;
SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
AdvanceTime(10000);
oldLocalOnLink = localOnLink;
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
Log("Local on-link prefix is changed to %s from %s", localOnLink.ToString().AsCString(),
oldLocalOnLink.ToString().AsCString());
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check Network Data contains old and new local on-link prefix
// and deprecating prefix from router B.
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium),
ExternalRoute(oldLocalOnLink, NetworkData::kRoutePreferenceMedium),
ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Send an RA from router A again adding the old local on-link prefix
// as RIO.
SendRouterAdvert(routerAddressA, {Rio(oldLocalOnLink, kValidLitime, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check Network Data remains unchanged.
AdvanceTime(10000);
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium),
ExternalRoute(oldLocalOnLink, NetworkData::kRoutePreferenceMedium),
ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Send an RA from router A removing the previous RIO.
SendRouterAdvert(routerAddressA, {Rio(localOnLink, 0, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check Network Data remains unchanged.
AdvanceTime(10000);
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium),
ExternalRoute(oldLocalOnLink, NetworkData::kRoutePreferenceMedium),
ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Log("End of TestConflictingPrefix");
testFreeInstance(sInstance);
}
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
void TestAutoEnableOfSrpServer(void)
{
@@ -1980,9 +2206,11 @@ int main(void)
TestDomainPrefixAsOmr();
#endif
TestExtPanIdChange();
TestConflictingPrefix();
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
TestAutoEnableOfSrpServer();
#endif
printf("All tests passed\n");
#else
printf("BORDER_ROUTING feature is not enabled\n");