diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index 9d6fba53f..3645f3307 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -64,6 +64,7 @@ RoutingManager::RoutingManager(Instance &aInstance) , mIsRunning(false) , mIsEnabled(false) , mInfraIf(aInstance) + , mLocalOmrPrefix(aInstance) , mRouteInfoOptionPreference(NetworkData::kRoutePreferenceMedium) , mIsAdvertisingLocalOnLinkPrefix(false) , mOnLinkPrefixDeprecateTimer(aInstance, HandleOnLinkPrefixDeprecateTimer) @@ -82,8 +83,6 @@ RoutingManager::RoutingManager(Instance &aInstance) mBrUlaPrefix.Clear(); - mLocalOmrPrefix.Clear(); - mLocalOnLinkPrefix.Clear(); mLocalNat64Prefix.Clear(); @@ -96,7 +95,7 @@ Error RoutingManager::Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning) SuccessOrExit(error = mInfraIf.Init(aInfraIfIndex)); SuccessOrExit(error = LoadOrGenerateRandomBrUlaPrefix()); - GenerateOmrPrefix(); + mLocalOmrPrefix.GenerateFrom(mBrUlaPrefix); #if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE GenerateNat64Prefix(); #endif @@ -146,7 +145,7 @@ Error RoutingManager::GetOmrPrefix(Ip6::Prefix &aPrefix) Error error = kErrorNone; VerifyOrExit(IsInitialized(), error = kErrorInvalidState); - aPrefix = mLocalOmrPrefix; + aPrefix = mLocalOmrPrefix.GetPrefix(); exit: return error; @@ -209,15 +208,6 @@ exit: return error; } -void RoutingManager::GenerateOmrPrefix(void) -{ - mLocalOmrPrefix = mBrUlaPrefix; - mLocalOmrPrefix.SetSubnetId(kOmrPrefixSubnetId); - mLocalOmrPrefix.SetLength(kOmrPrefixLength); - - LogInfo("Generated OMR prefix: %s", mLocalOmrPrefix.ToString().AsCString()); -} - #if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE void RoutingManager::GenerateNat64Prefix(void) { @@ -272,7 +262,7 @@ void RoutingManager::Stop(void) { VerifyOrExit(mIsRunning); - UnpublishLocalOmrPrefix(); + mLocalOmrPrefix.RemoveFromNetData(); mFavoredDiscoveredOnLinkPrefix.Clear(); @@ -470,7 +460,7 @@ void RoutingManager::EvaluateOmrPrefix(OmrPrefixArray &aNewOmrPrefixes) } } - if (entry->GetPrefix() == mLocalOmrPrefix) + if (entry->GetPrefix() == mLocalOmrPrefix.GetPrefix()) { localOmrEntry = entry; } @@ -480,33 +470,34 @@ void RoutingManager::EvaluateOmrPrefix(OmrPrefixArray &aNewOmrPrefixes) if (favoredOmrEntry == nullptr) { - LogInfo("EvaluateOmrPrefix: No preferred OMR prefixes found in Thread network"); + LogInfo("EvaluateOmrPrefix: No preferred OMR prefix found in Thread network"); // The `aNewOmrPrefixes` remains empty if we fail to publish // the local OMR prefix. - SuccessOrExit(PublishLocalOmrPrefix()); + SuccessOrExit(mLocalOmrPrefix.AddToNetData()); - localOmrEntry = aNewOmrPrefixes.PushBack(); - VerifyOrExit(localOmrEntry != nullptr); + if (localOmrEntry == nullptr) + { + localOmrEntry = aNewOmrPrefixes.PushBack(); + VerifyOrExit(localOmrEntry != nullptr); - localOmrEntry->Init(mLocalOmrPrefix, NetworkData::kRoutePreferenceLow); + localOmrEntry->Init(mLocalOmrPrefix.GetPrefix(), NetworkData::kRoutePreferenceLow); + } } else if (favoredOmrEntry == localOmrEntry) { - IgnoreError(PublishLocalOmrPrefix()); + IgnoreError(mLocalOmrPrefix.AddToNetData()); } - else if (IsOmrPrefixAddedToLocalNetworkData()) + else if (mLocalOmrPrefix.IsAddedInNetData()) { LogInfo("EvaluateOmrPrefix: There is already a preferred OMR prefix %s in the Thread network", favoredOmrEntry->ToString().AsCString()); - UnpublishLocalOmrPrefix(); + mLocalOmrPrefix.RemoveFromNetData(); if (localOmrEntry != nullptr) { - // Remove the local OMR prefix from the list by overwriting it - // with popped last entry in the list. - *localOmrEntry = *aNewOmrPrefixes.PopBack(); + aNewOmrPrefixes.Remove(*localOmrEntry); } } @@ -514,66 +505,6 @@ exit: return; } -Error RoutingManager::PublishLocalOmrPrefix(void) -{ - Error error = kErrorNone; - NetworkData::OnMeshPrefixConfig omrPrefixConfig; - - OT_ASSERT(mIsRunning); - - VerifyOrExit(!IsOmrPrefixAddedToLocalNetworkData()); - - omrPrefixConfig.Clear(); - omrPrefixConfig.mPrefix = mLocalOmrPrefix; - omrPrefixConfig.mStable = true; - omrPrefixConfig.mSlaac = true; - omrPrefixConfig.mPreferred = true; - omrPrefixConfig.mOnMesh = true; - omrPrefixConfig.mDefaultRoute = false; - omrPrefixConfig.mPreference = NetworkData::kRoutePreferenceLow; - - error = Get().AddOnMeshPrefix(omrPrefixConfig); - if (error != kErrorNone) - { - LogWarn("Failed to publish local OMR prefix %s in Thread network: %s", mLocalOmrPrefix.ToString().AsCString(), - ErrorToString(error)); - } - else - { - Get().HandleServerDataUpdated(); - LogInfo("Publishing local OMR prefix %s in Thread network", mLocalOmrPrefix.ToString().AsCString()); - } - -exit: - return error; -} - -void RoutingManager::UnpublishLocalOmrPrefix(void) -{ - Error error = kErrorNone; - - VerifyOrExit(mIsRunning); - - VerifyOrExit(IsOmrPrefixAddedToLocalNetworkData()); - - SuccessOrExit(error = Get().RemoveOnMeshPrefix(mLocalOmrPrefix)); - - Get().HandleServerDataUpdated(); - LogInfo("Unpublishing local OMR prefix %s from Thread network", mLocalOmrPrefix.ToString().AsCString()); - -exit: - if (error != kErrorNone && error != kErrorNotFound) - { - LogWarn("Failed to unpublish local OMR prefix %s from Thread network: %s", - mLocalOmrPrefix.ToString().AsCString(), ErrorToString(error)); - } -} - -bool RoutingManager::IsOmrPrefixAddedToLocalNetworkData(void) const -{ - return Get().ContainsOnMeshPrefix(mLocalOmrPrefix); -} - Error RoutingManager::PublishExternalRoute(const Ip6::Prefix &aPrefix, RoutePreference aRoutePreference, bool aNat64) { Error error; @@ -1181,7 +1112,7 @@ bool RoutingManager::ShouldProcessRouteInfoOption(const Ip6::Nd::RouteInfoOption ExitNow(); } - VerifyOrExit(mLocalOmrPrefix != aPrefix); + VerifyOrExit(mLocalOmrPrefix.GetPrefix() != aPrefix); // Ignore OMR prefixes advertised by ourselves or in current Thread Network Data. // The `mAdvertisedOmrPrefixes` and the OMR prefix set in Network Data should eventually @@ -2038,6 +1969,80 @@ RoutingManager::OmrPrefix::InfoString RoutingManager::OmrPrefix::ToString(void) return string; } +//--------------------------------------------------------------------------------------------------------------------- +// LocalOmrPrefix + +RoutingManager::LocalOmrPrefix::LocalOmrPrefix(Instance &aInstance) + : InstanceLocator(aInstance) + , mIsAddedInNetData(false) +{ +} + +void RoutingManager::LocalOmrPrefix::GenerateFrom(const Ip6::Prefix &aBrUlaPrefix) +{ + mPrefix = aBrUlaPrefix; + mPrefix.SetSubnetId(kOmrPrefixSubnetId); + mPrefix.SetLength(kOmrPrefixLength); + + LogInfo("Generated OMR prefix: %s", mPrefix.ToString().AsCString()); +} + +Error RoutingManager::LocalOmrPrefix::AddToNetData(void) +{ + Error error = kErrorNone; + NetworkData::OnMeshPrefixConfig config; + + VerifyOrExit(!mIsAddedInNetData); + + config.Clear(); + config.mPrefix = mPrefix; + config.mStable = true; + config.mSlaac = true; + config.mPreferred = true; + config.mOnMesh = true; + config.mDefaultRoute = false; + config.mPreference = NetworkData::kRoutePreferenceLow; + + error = Get().AddOnMeshPrefix(config); + + if (error != kErrorNone) + { + LogWarn("Failed to add local OMR prefix %s in Thread Network Data: %s", mPrefix.ToString().AsCString(), + ErrorToString(error)); + ExitNow(); + } + + mIsAddedInNetData = true; + Get().HandleServerDataUpdated(); + LogInfo("Added local OMR prefix %s in Thread Network Data", mPrefix.ToString().AsCString()); + +exit: + return error; +} + +void RoutingManager::LocalOmrPrefix::RemoveFromNetData(void) +{ + Error error = kErrorNone; + + VerifyOrExit(mIsAddedInNetData); + + error = Get().RemoveOnMeshPrefix(mPrefix); + + if (error != kErrorNone) + { + LogWarn("Failed to remove local OMR prefix %s from Thread Network Data: %s", mPrefix.ToString().AsCString(), + ErrorToString(error)); + ExitNow(); + } + + mIsAddedInNetData = false; + Get().HandleServerDataUpdated(); + LogInfo("Removed local OMR prefix %s from Thread Network Data", mPrefix.ToString().AsCString()); + +exit: + return; +} + } // namespace BorderRouter } // namespace ot diff --git a/src/core/border_router/routing_manager.hpp b/src/core/border_router/routing_manager.hpp index e6650be31..a8f9dbb63 100644 --- a/src/core/border_router/routing_manager.hpp +++ b/src/core/border_router/routing_manager.hpp @@ -451,6 +451,21 @@ private: typedef Array OmrPrefixArray; + class LocalOmrPrefix : InstanceLocator + { + public: + explicit LocalOmrPrefix(Instance &aInstance); + void GenerateFrom(const Ip6::Prefix &aBrUlaPrefix); + const Ip6::Prefix &GetPrefix(void) const { return mPrefix; } + Error AddToNetData(void); + void RemoveFromNetData(void); + bool IsAddedInNetData(void) const { return mIsAddedInNetData; } + + private: + Ip6::Prefix mPrefix; + bool mIsAddedInNetData; + }; + void EvaluateState(void); void Start(void); void Stop(void); @@ -458,7 +473,6 @@ private: bool IsInitialized(void) const { return mInfraIf.IsInitialized(); } bool IsEnabled(void) const { return mIsEnabled; } Error LoadOrGenerateRandomBrUlaPrefix(void); - void GenerateOmrPrefix(void); void GenerateOnLinkPrefix(void); void EvaluateOnLinkPrefix(void); @@ -472,9 +486,6 @@ private: void StartRoutingPolicyEvaluationJitter(uint32_t aJitterMilli); void StartRoutingPolicyEvaluationDelay(uint32_t aDelayMilli); void EvaluateOmrPrefix(OmrPrefixArray &aNewOmrPrefixes); - Error PublishLocalOmrPrefix(void); - void UnpublishLocalOmrPrefix(void); - bool IsOmrPrefixAddedToLocalNetworkData(void) const; Error PublishExternalRoute(const Ip6::Prefix &aPrefix, RoutePreference aRoutePreference, bool aNat64 = false); void UnpublishExternalRoute(const Ip6::Prefix &aPrefix); void StartRouterSolicitationDelay(void); @@ -521,8 +532,7 @@ private: // randomly generated if none is found in persistent storage. Ip6::Prefix mBrUlaPrefix; - // The OMR prefix allocated from the /48 BR ULA prefix. - Ip6::Prefix mLocalOmrPrefix; + LocalOmrPrefix mLocalOmrPrefix; // The advertised OMR prefixes. For a stable Thread network without // manually configured OMR prefixes, there should be a single OMR