[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:
Abtin Keshavarzian
2022-05-23 14:52:16 -07:00
committed by GitHub
parent 58f56bbec2
commit 5f2437939d
2 changed files with 138 additions and 119 deletions
+110 -83
View File
@@ -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
+28 -36
View File
@@ -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;