mirror of
https://github.com/espressif/openthread.git
synced 2026-09-17 14:40:07 +00:00
[routing-manager] simplify ExternalPrefix (#7723)
This commit contains smaller enhancement in `RoutingManager` related to `ExternalPrefix` class (which represents a prefix discovered from processing Router Advertisements from infrastructure netif). This commit also uses `Array::Find()` methods when searching in the `mDiscoveredPrefixes` array.
This commit is contained in:
@@ -560,14 +560,14 @@ const Ip6::Prefix *RoutingManager::EvaluateOnLinkPrefix(void)
|
||||
|
||||
for (const ExternalPrefix &prefix : mDiscoveredPrefixes)
|
||||
{
|
||||
if (!prefix.mIsOnLinkPrefix || prefix.IsDeprecated())
|
||||
if (!prefix.IsOnLinkPrefix() || prefix.IsDeprecated())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (smallestOnLinkPrefix == nullptr || (prefix.mPrefix < *smallestOnLinkPrefix))
|
||||
if (smallestOnLinkPrefix == nullptr || (prefix.GetPrefix() < *smallestOnLinkPrefix))
|
||||
{
|
||||
smallestOnLinkPrefix = &prefix.mPrefix;
|
||||
smallestOnLinkPrefix = &prefix.GetPrefix();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,7 +619,7 @@ void RoutingManager::HandleOnLinkPrefixDeprecateTimer(void)
|
||||
|
||||
for (const ExternalPrefix &prefix : mDiscoveredPrefixes)
|
||||
{
|
||||
if (prefix.mIsOnLinkPrefix && prefix.mPrefix == mLocalOnLinkPrefix)
|
||||
if (prefix.IsOnLinkPrefix() && prefix.GetPrefix() == mLocalOnLinkPrefix)
|
||||
{
|
||||
discoveredLocalOnLinkPrefix = true;
|
||||
break;
|
||||
@@ -1024,15 +1024,15 @@ void RoutingManager::HandleRouterSolicitTimer(void)
|
||||
// Invalidate/deprecate all OMR/on-link prefixes that are not refreshed during Router Solicitation.
|
||||
for (ExternalPrefix &prefix : mDiscoveredPrefixes)
|
||||
{
|
||||
if (prefix.mTimeLastUpdate <= mTimeRouterSolicitStart)
|
||||
if (prefix.GetLastUpdateTime() <= mTimeRouterSolicitStart)
|
||||
{
|
||||
if (prefix.mIsOnLinkPrefix)
|
||||
if (prefix.IsOnLinkPrefix())
|
||||
{
|
||||
prefix.mPreferredLifetime = 0;
|
||||
prefix.ClearPreferredLifetime();
|
||||
}
|
||||
else
|
||||
{
|
||||
InvalidateDiscoveredPrefixes(&prefix.mPrefix, prefix.mIsOnLinkPrefix);
|
||||
InvalidateDiscoveredPrefixes(&prefix.GetPrefix(), prefix.IsOnLinkPrefix());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1091,22 +1091,6 @@ void RoutingManager::HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, co
|
||||
StartRoutingPolicyEvaluationJitter(kRaReplyJitter);
|
||||
}
|
||||
|
||||
uint32_t RoutingManager::ExternalPrefix::GetPrefixExpireDelay(uint32_t aValidLifetime)
|
||||
{
|
||||
uint32_t delay;
|
||||
|
||||
if (aValidLifetime * static_cast<uint64_t>(1000) > Timer::kMaxDelay)
|
||||
{
|
||||
delay = Timer::kMaxDelay;
|
||||
}
|
||||
else
|
||||
{
|
||||
delay = aValidLifetime * 1000;
|
||||
}
|
||||
|
||||
return delay;
|
||||
}
|
||||
|
||||
void RoutingManager::HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress)
|
||||
{
|
||||
OT_ASSERT(mIsRunning);
|
||||
@@ -1204,23 +1188,13 @@ bool RoutingManager::UpdateDiscoveredOnLinkPrefix(const RouterAdv::PrefixInfoOpt
|
||||
LogInfo("Discovered on-link prefix (%s, %u seconds) from %s", prefix.ToString().AsCString(),
|
||||
aPio.GetValidLifetime(), mInfraIf.ToString().AsCString());
|
||||
|
||||
onLinkPrefix.mIsOnLinkPrefix = true;
|
||||
onLinkPrefix.mPrefix = prefix;
|
||||
onLinkPrefix.mValidLifetime = aPio.GetValidLifetime();
|
||||
onLinkPrefix.mPreferredLifetime = aPio.GetPreferredLifetime();
|
||||
onLinkPrefix.mTimeLastUpdate = TimerMilli::GetNow();
|
||||
onLinkPrefix.InitFrom(aPio);
|
||||
|
||||
for (ExternalPrefix &externalPrefix : mDiscoveredPrefixes)
|
||||
{
|
||||
if (externalPrefix == onLinkPrefix)
|
||||
{
|
||||
existingPrefix = &externalPrefix;
|
||||
}
|
||||
}
|
||||
existingPrefix = mDiscoveredPrefixes.Find(onLinkPrefix);
|
||||
|
||||
if (existingPrefix == nullptr)
|
||||
{
|
||||
if (onLinkPrefix.mValidLifetime == 0)
|
||||
if (onLinkPrefix.GetValidLifetime() == 0)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
@@ -1240,34 +1214,11 @@ bool RoutingManager::UpdateDiscoveredOnLinkPrefix(const RouterAdv::PrefixInfoOpt
|
||||
}
|
||||
else
|
||||
{
|
||||
constexpr uint32_t kTwoHoursInSeconds = 2 * 3600;
|
||||
|
||||
// Per RFC 4862 section 5.5.3.e:
|
||||
// 1. If the received Valid Lifetime is greater than 2 hours or
|
||||
// greater than RemainingLifetime, set the valid lifetime of the
|
||||
// corresponding address to the advertised Valid Lifetime.
|
||||
// 2. If RemainingLifetime is less than or equal to 2 hours, ignore
|
||||
// the Prefix Information option with regards to the valid
|
||||
// lifetime, unless ...
|
||||
// 3. Otherwise, reset the valid lifetime of the corresponding
|
||||
// address to 2 hours.
|
||||
|
||||
if (onLinkPrefix.mValidLifetime > kTwoHoursInSeconds ||
|
||||
onLinkPrefix.GetExpireTime() > existingPrefix->GetExpireTime())
|
||||
{
|
||||
existingPrefix->mValidLifetime = onLinkPrefix.mValidLifetime;
|
||||
}
|
||||
else if (existingPrefix->GetExpireTime() > TimerMilli::GetNow() + TimeMilli::SecToMsec(kTwoHoursInSeconds))
|
||||
{
|
||||
existingPrefix->mValidLifetime = kTwoHoursInSeconds;
|
||||
}
|
||||
|
||||
// The on-link prefix routing policy may be affected when a
|
||||
// discovered on-link prefix becomes deprecated or preferred.
|
||||
needReevaluate = (onLinkPrefix.IsDeprecated() != existingPrefix->IsDeprecated());
|
||||
|
||||
existingPrefix->mPreferredLifetime = onLinkPrefix.mPreferredLifetime;
|
||||
existingPrefix->mTimeLastUpdate = onLinkPrefix.mTimeLastUpdate;
|
||||
existingPrefix->AdoptValidAndPreferredLiftimesFrom(onLinkPrefix);
|
||||
}
|
||||
|
||||
mDiscoveredPrefixInvalidTimer.FireAtIfEarlier(existingPrefix->GetExpireTime());
|
||||
@@ -1318,30 +1269,20 @@ void RoutingManager::UpdateDiscoveredOmrPrefix(const RouterAdv::RouteInfoOption
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
omrPrefix.mIsOnLinkPrefix = false;
|
||||
omrPrefix.mPrefix = prefix;
|
||||
omrPrefix.mValidLifetime = aRio.GetRouteLifetime();
|
||||
omrPrefix.mRoutePreference = aRio.GetPreference();
|
||||
omrPrefix.mTimeLastUpdate = TimerMilli::GetNow();
|
||||
omrPrefix.InitFrom(aRio);
|
||||
|
||||
for (ExternalPrefix &externalPrefix : mDiscoveredPrefixes)
|
||||
{
|
||||
if (externalPrefix == omrPrefix)
|
||||
{
|
||||
existingPrefix = &externalPrefix;
|
||||
}
|
||||
}
|
||||
existingPrefix = mDiscoveredPrefixes.Find(omrPrefix);
|
||||
|
||||
if (existingPrefix == nullptr)
|
||||
{
|
||||
if (omrPrefix.mValidLifetime == 0)
|
||||
if (omrPrefix.GetValidLifetime() == 0)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
if (!mDiscoveredPrefixes.IsFull())
|
||||
{
|
||||
SuccessOrExit(PublishExternalRoute(prefix, omrPrefix.mRoutePreference));
|
||||
SuccessOrExit(PublishExternalRoute(prefix, omrPrefix.GetRoutePreference()));
|
||||
existingPrefix = mDiscoveredPrefixes.PushBack();
|
||||
}
|
||||
else
|
||||
@@ -1371,22 +1312,22 @@ void RoutingManager::InvalidateDiscoveredPrefixes(const Ip6::Prefix *aPrefix, bo
|
||||
for (const ExternalPrefix &prefix : mDiscoveredPrefixes)
|
||||
{
|
||||
bool isAdvertisedLocalOnLinkPrefix =
|
||||
mIsAdvertisingLocalOnLinkPrefix && prefix.mIsOnLinkPrefix && mLocalOnLinkPrefix == prefix.mPrefix;
|
||||
mIsAdvertisingLocalOnLinkPrefix && prefix.IsOnLinkPrefix() && mLocalOnLinkPrefix == prefix.GetPrefix();
|
||||
|
||||
if (
|
||||
// Invalidate specified prefix
|
||||
(aPrefix != nullptr && prefix.mPrefix == *aPrefix && prefix.mIsOnLinkPrefix == aIsOnLinkPrefix) ||
|
||||
(aPrefix != nullptr && prefix.GetPrefix() == *aPrefix && prefix.IsOnLinkPrefix() == aIsOnLinkPrefix) ||
|
||||
// Invalidate expired prefix
|
||||
(prefix.GetExpireTime() <= now) ||
|
||||
// Invalidate Local OMR prefixes
|
||||
(!prefix.mIsOnLinkPrefix &&
|
||||
(mAdvertisedOmrPrefixes.Contains(prefix.mPrefix) || NetworkDataContainsOmrPrefix(prefix.mPrefix))) ||
|
||||
(!prefix.IsOnLinkPrefix() && (mAdvertisedOmrPrefixes.Contains(prefix.GetPrefix()) ||
|
||||
NetworkDataContainsOmrPrefix(prefix.GetPrefix()))) ||
|
||||
// Remove local on-link prefix if the BR is advertising on-link prefix
|
||||
isAdvertisedLocalOnLinkPrefix)
|
||||
{
|
||||
if (!isAdvertisedLocalOnLinkPrefix)
|
||||
{
|
||||
UnpublishExternalRoute(prefix.mPrefix);
|
||||
UnpublishExternalRoute(prefix.GetPrefix());
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1395,7 +1336,7 @@ void RoutingManager::InvalidateDiscoveredPrefixes(const Ip6::Prefix *aPrefix, bo
|
||||
|
||||
IgnoreError(remainingPrefixes.PushBack(prefix));
|
||||
|
||||
if (prefix.mIsOnLinkPrefix)
|
||||
if (prefix.IsOnLinkPrefix())
|
||||
{
|
||||
++remainingOnLinkPrefixNum;
|
||||
}
|
||||
@@ -1416,7 +1357,7 @@ void RoutingManager::InvalidateAllDiscoveredPrefixes(void)
|
||||
{
|
||||
for (ExternalPrefix &prefix : mDiscoveredPrefixes)
|
||||
{
|
||||
prefix.mValidLifetime = 0;
|
||||
prefix.ClearValidLifetime();
|
||||
}
|
||||
|
||||
InvalidateDiscoveredPrefixes();
|
||||
@@ -1500,7 +1441,7 @@ void RoutingManager::ResetDiscoveredPrefixStaleTimer(void)
|
||||
{
|
||||
TimeMilli prefixStaleTime = externalPrefix.GetStaleTime();
|
||||
|
||||
if (externalPrefix.mIsOnLinkPrefix)
|
||||
if (externalPrefix.IsOnLinkPrefix())
|
||||
{
|
||||
if (!externalPrefix.IsDeprecated())
|
||||
{
|
||||
@@ -1536,6 +1477,92 @@ void RoutingManager::ResetDiscoveredPrefixStaleTimer(void)
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// ExtneralPrefix
|
||||
|
||||
void RoutingManager::ExternalPrefix::InitFrom(const RouterAdv::PrefixInfoOption &aPio)
|
||||
{
|
||||
Clear();
|
||||
aPio.GetPrefix(mPrefix);
|
||||
mIsOnLinkPrefix = true;
|
||||
mValidLifetime = aPio.GetValidLifetime();
|
||||
mPreferredLifetime = aPio.GetPreferredLifetime();
|
||||
mLastUpdateTime = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
void RoutingManager::ExternalPrefix::InitFrom(const RouterAdv::RouteInfoOption &aRio)
|
||||
{
|
||||
Clear();
|
||||
aRio.GetPrefix(mPrefix);
|
||||
mIsOnLinkPrefix = false;
|
||||
mValidLifetime = aRio.GetRouteLifetime();
|
||||
mRoutePreference = aRio.GetPreference();
|
||||
mLastUpdateTime = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
bool RoutingManager::ExternalPrefix::operator==(const ExternalPrefix &aPrefix) const
|
||||
{
|
||||
return mIsOnLinkPrefix == aPrefix.mIsOnLinkPrefix && (mPrefix == aPrefix.mPrefix);
|
||||
}
|
||||
|
||||
TimeMilli RoutingManager::ExternalPrefix::GetStaleTime(void) const
|
||||
{
|
||||
uint32_t delay = OT_MIN(kRtrAdvStaleTime, mIsOnLinkPrefix ? mPreferredLifetime : mValidLifetime);
|
||||
|
||||
return mLastUpdateTime + TimeMilli::SecToMsec(delay);
|
||||
}
|
||||
|
||||
bool RoutingManager::ExternalPrefix::IsDeprecated(void) const
|
||||
{
|
||||
OT_ASSERT(mIsOnLinkPrefix);
|
||||
|
||||
return mLastUpdateTime + TimeMilli::SecToMsec(mPreferredLifetime) <= TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
void RoutingManager::ExternalPrefix::AdoptValidAndPreferredLiftimesFrom(const ExternalPrefix &aPrefix)
|
||||
{
|
||||
constexpr uint32_t kTwoHoursInSeconds = 2 * 3600;
|
||||
|
||||
// Per RFC 4862 section 5.5.3.e:
|
||||
//
|
||||
// 1. If the received Valid Lifetime is greater than 2 hours or
|
||||
// greater than RemainingLifetime, set the valid lifetime of the
|
||||
// corresponding address to the advertised Valid Lifetime.
|
||||
// 2. If RemainingLifetime is less than or equal to 2 hours, ignore
|
||||
// the Prefix Information option with regards to the valid
|
||||
// lifetime, unless ...
|
||||
// 3. Otherwise, reset the valid lifetime of the corresponding
|
||||
// address to 2 hours.
|
||||
|
||||
if (aPrefix.mValidLifetime > kTwoHoursInSeconds || aPrefix.GetExpireTime() > GetExpireTime())
|
||||
{
|
||||
mValidLifetime = aPrefix.mValidLifetime;
|
||||
}
|
||||
else if (GetExpireTime() > TimerMilli::GetNow() + TimeMilli::SecToMsec(kTwoHoursInSeconds))
|
||||
{
|
||||
mValidLifetime = kTwoHoursInSeconds;
|
||||
}
|
||||
|
||||
mPreferredLifetime = aPrefix.GetPreferredLifetime();
|
||||
mLastUpdateTime = aPrefix.GetLastUpdateTime();
|
||||
}
|
||||
|
||||
uint32_t RoutingManager::ExternalPrefix::GetPrefixExpireDelay(uint32_t aValidLifetime)
|
||||
{
|
||||
uint32_t delay;
|
||||
|
||||
if (aValidLifetime * static_cast<uint64_t>(1000) > Timer::kMaxDelay)
|
||||
{
|
||||
delay = Timer::kMaxDelay;
|
||||
}
|
||||
else
|
||||
{
|
||||
delay = aValidLifetime * 1000;
|
||||
}
|
||||
|
||||
return delay;
|
||||
}
|
||||
|
||||
} // namespace BorderRouter
|
||||
|
||||
} // namespace ot
|
||||
|
||||
@@ -243,47 +243,39 @@ private:
|
||||
static_assert(kRtrAdvStaleTime >= 1800 && kRtrAdvStaleTime <= kDefaultOnLinkPrefixLifetime,
|
||||
"invalid RA STALE time");
|
||||
|
||||
// This struct represents an external prefix which is
|
||||
// discovered on the infrastructure interface.
|
||||
struct ExternalPrefix : public Clearable<ExternalPrefix>, public Unequatable<ExternalPrefix>
|
||||
// A prefix discovered from Router Advert msg from infra netif
|
||||
class ExternalPrefix : private Clearable<ExternalPrefix>, public Unequatable<ExternalPrefix>
|
||||
{
|
||||
Ip6::Prefix mPrefix;
|
||||
uint32_t mValidLifetime;
|
||||
public:
|
||||
void InitFrom(const RouterAdv::PrefixInfoOption &aPio);
|
||||
void InitFrom(const RouterAdv::RouteInfoOption &aRio);
|
||||
bool IsOnLinkPrefix(void) const { return mIsOnLinkPrefix; }
|
||||
const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
|
||||
const TimeMilli & GetLastUpdateTime(void) const { return mLastUpdateTime; }
|
||||
uint32_t GetValidLifetime(void) const { return mValidLifetime; }
|
||||
void ClearValidLifetime(void) { mValidLifetime = 0; }
|
||||
TimeMilli GetExpireTime(void) const { return mLastUpdateTime + GetPrefixExpireDelay(mValidLifetime); }
|
||||
TimeMilli GetStaleTime(void) const;
|
||||
bool operator==(const ExternalPrefix &aPrefix) const;
|
||||
|
||||
union
|
||||
{
|
||||
// Preferred Lifetime of on-link prefix, available
|
||||
// only when `mIsOnLinkPrefix` is TRUE.
|
||||
uint32_t mPreferredLifetime;
|
||||
// Methods to use when `IsOnLinkPrefix()`
|
||||
uint32_t GetPreferredLifetime(void) const { return mPreferredLifetime; }
|
||||
void ClearPreferredLifetime(void) { mPreferredLifetime = 0; }
|
||||
bool IsDeprecated(void) const;
|
||||
void AdoptValidAndPreferredLiftimesFrom(const ExternalPrefix &Prefix);
|
||||
|
||||
// The preference of this route, available
|
||||
// only when `mIsOnLinkPrefix` is FALSE.
|
||||
RoutePreference mRoutePreference;
|
||||
};
|
||||
TimeMilli mTimeLastUpdate;
|
||||
bool mIsOnLinkPrefix;
|
||||
|
||||
bool operator==(const ExternalPrefix &aPrefix) const
|
||||
{
|
||||
return mPrefix == aPrefix.mPrefix && mIsOnLinkPrefix == aPrefix.mIsOnLinkPrefix;
|
||||
}
|
||||
|
||||
bool IsDeprecated(void) const
|
||||
{
|
||||
OT_ASSERT(mIsOnLinkPrefix);
|
||||
|
||||
return mTimeLastUpdate + TimeMilli::SecToMsec(mPreferredLifetime) <= TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
TimeMilli GetExpireTime(void) const { return mTimeLastUpdate + GetPrefixExpireDelay(mValidLifetime); }
|
||||
TimeMilli GetStaleTime(void) const
|
||||
{
|
||||
uint32_t delay = OT_MIN(kRtrAdvStaleTime, mIsOnLinkPrefix ? mPreferredLifetime : mValidLifetime);
|
||||
|
||||
return mTimeLastUpdate + TimeMilli::SecToMsec(delay);
|
||||
}
|
||||
// Method to use when `!IsOnlinkPrefix()`
|
||||
RoutePreference GetRoutePreference(void) const { return mRoutePreference; }
|
||||
|
||||
private:
|
||||
static uint32_t GetPrefixExpireDelay(uint32_t aValidLifetime);
|
||||
|
||||
Ip6::Prefix mPrefix;
|
||||
TimeMilli mLastUpdateTime;
|
||||
uint32_t mValidLifetime;
|
||||
uint32_t mPreferredLifetime; // Applicable when prefix is on-link.
|
||||
RoutePreference mRoutePreference; // Applicable when prefix is not on-link
|
||||
bool mIsOnLinkPrefix;
|
||||
};
|
||||
|
||||
typedef Array<Ip6::Prefix, kMaxOmrPrefixNum> OmrPrefixArray;
|
||||
|
||||
Reference in New Issue
Block a user