mirror of
https://github.com/espressif/openthread.git
synced 2026-08-13 14:17:47 +00:00
[routing-manager] adding LocalOmrPrefix class (#7871)
This commit contain smaller enhancements related to managing the local OMR prefix: - It adds a new class to encapsulate all the related data and methods. - We directly track whether or not the prefix is added to the local Network Data (using a boolean) - The methods are renamed to use the terms "add/remove" instead of "publish/unpublish" since the Network data publisher is not used for OMR prefix and it is directly added or removed.
This commit is contained in:
@@ -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<NetworkData::Local>().AddOnMeshPrefix(omrPrefixConfig);
|
||||
if (error != kErrorNone)
|
||||
{
|
||||
LogWarn("Failed to publish local OMR prefix %s in Thread network: %s", mLocalOmrPrefix.ToString().AsCString(),
|
||||
ErrorToString(error));
|
||||
}
|
||||
else
|
||||
{
|
||||
Get<NetworkData::Notifier>().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<NetworkData::Local>().RemoveOnMeshPrefix(mLocalOmrPrefix));
|
||||
|
||||
Get<NetworkData::Notifier>().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<NetworkData::Local>().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<NetworkData::Local>().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<NetworkData::Notifier>().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<NetworkData::Local>().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<NetworkData::Notifier>().HandleServerDataUpdated();
|
||||
LogInfo("Removed local OMR prefix %s from Thread Network Data", mPrefix.ToString().AsCString());
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace BorderRouter
|
||||
|
||||
} // namespace ot
|
||||
|
||||
@@ -451,6 +451,21 @@ private:
|
||||
|
||||
typedef Array<OmrPrefix, kMaxOmrPrefixNum> 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
|
||||
|
||||
Reference in New Issue
Block a user