[routing-manager] move tracking of local RA header to RxRaTracker (#10257)

This commit moves the tracking of the RA header of locally generated
RA messages from `TxRaInfo` to the `RxRaTracker` class. The tracked
RA header is used when `RoutingManager` sends an RA, ensuring
consistent RA headers across all RAs emitted from the device.

This aligns the logic by having `RxRaTracker` track all information
from received RAs and simplifies stale time calculations.
This commit is contained in:
Abtin Keshavarzian
2024-05-17 15:57:47 -07:00
committed by GitHub
parent 63442f7302
commit 67a262713c
3 changed files with 92 additions and 89 deletions
+67 -64
View File
@@ -597,7 +597,15 @@ void RoutingManager::SendRouterAdvertisement(RouterAdvTxMode aRaTxMode)
LogInfo("Preparing RA");
header = mTxRaInfo.mHeader;
if (mRxRaTracker.GetLocalRaHeaderToMirror().IsValid())
{
header = mRxRaTracker.GetLocalRaHeaderToMirror();
}
else
{
header.SetToDefault();
}
mRxRaTracker.DetermineAndSetFlags(header);
SuccessOrExit(error = raMsg.AppendHeader(header));
@@ -696,12 +704,6 @@ void RoutingManager::HandleRsSenderFinished(TimeMilli aStartTime)
// Solicitation.
mRxRaTracker.RemoveOrDeprecateOldEntries(aStartTime);
if (mTxRaInfo.mHeaderUpdateTime <= aStartTime)
{
UpdateRouterAdvertHeader(/* aRouterAdvertMessage */ nullptr, kThisBrOtherEntity);
}
ScheduleRoutingPolicyEvaluation(kImmediately);
}
@@ -758,8 +760,6 @@ void RoutingManager::HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPack
mRxRaTracker.ProcessRouterAdvertMessage(raMsg, aSrcAddress, raOrigin);
UpdateRouterAdvertHeader(&raMsg, raOrigin);
exit:
return;
}
@@ -870,48 +870,6 @@ bool RoutingManager::NetworkDataContainsUlaRoute(void) const
return contains;
}
void RoutingManager::UpdateRouterAdvertHeader(const RouterAdvert::RxMessage *aRaMsg, RouterAdvOrigin aRaOrigin)
{
// Updates the `mTxRaInfo` from the given RA message.
RouterAdvert::Header oldHeader;
VerifyOrExit(aRaOrigin == kThisBrOtherEntity);
oldHeader = mTxRaInfo.mHeader;
mTxRaInfo.mHeaderUpdateTime = TimerMilli::GetNow();
if (aRaMsg == nullptr || aRaMsg->GetHeader().GetRouterLifetime() == 0)
{
mTxRaInfo.mHeader.SetToDefault();
mTxRaInfo.mIsHeaderFromHost = false;
}
else
{
// The checksum is set to zero in `mTxRaInfo.mHeader`
// which indicates to platform that it needs to do the
// calculation and update it.
mTxRaInfo.mHeader = aRaMsg->GetHeader();
mTxRaInfo.mHeader.SetChecksum(0);
mTxRaInfo.mIsHeaderFromHost = true;
}
ResetDiscoveredPrefixStaleTimer();
if (mTxRaInfo.mHeader != oldHeader)
{
// If there was a change to the header, start timer to
// reevaluate routing policy and send RA message with new
// header.
ScheduleRoutingPolicyEvaluation(kAfterRandomDelay);
}
exit:
return;
}
void RoutingManager::ResetDiscoveredPrefixStaleTimer(void)
{
TimeMilli now = TimerMilli::GetNow();
@@ -924,14 +882,6 @@ void RoutingManager::ResetDiscoveredPrefixStaleTimer(void)
nextStaleTime = mRxRaTracker.CalculateNextStaleTime(now);
// Check for stale Router Advertisement Message if learnt from Host.
if (mTxRaInfo.mIsHeaderFromHost)
{
TimeMilli raStaleTime = Max(now, mTxRaInfo.mHeaderUpdateTime + Time::SecToMsec(kRtrAdvStaleTime));
nextStaleTime = Min(nextStaleTime, raStaleTime);
}
if (nextStaleTime == now.GetDistantFuture())
{
if (mDiscoveredPrefixStaleTimer.IsRunning())
@@ -1113,6 +1063,7 @@ RoutingManager::RxRaTracker::RxRaTracker(Instance &aInstance)
, mRouterTimer(aInstance)
, mSignalTask(aInstance)
{
mLocalRaHeader.Clear();
}
void RoutingManager::RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaMessage,
@@ -1150,7 +1101,7 @@ void RoutingManager::RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert:
// in a `::/0` RIO override the preference and lifetime values in
// the RA header (per RFC 4191 section 3.1).
ProcessRaHeader(aRaMessage.GetHeader(), *router);
ProcessRaHeader(aRaMessage.GetHeader(), *router, aRaOrigin);
for (const Option &option : aRaMessage)
{
@@ -1181,7 +1132,9 @@ exit:
return;
}
void RoutingManager::RxRaTracker::ProcessRaHeader(const RouterAdvert::Header &aRaHeader, Router &aRouter)
void RoutingManager::RxRaTracker::ProcessRaHeader(const RouterAdvert::Header &aRaHeader,
Router &aRouter,
RouterAdvOrigin aRaOrigin)
{
bool managedFlag = aRaHeader.IsManagedAddressConfigFlagSet();
bool otherFlag = aRaHeader.IsOtherConfigFlagSet();
@@ -1202,6 +1155,36 @@ void RoutingManager::RxRaTracker::ProcessRaHeader(const RouterAdvert::Header &aR
SignalTableChanged();
}
if (aRaOrigin == kThisBrOtherEntity)
{
// Update `mLocalRaHeader`, which tracks the RA header of
// locally generated RA by another sw entity running on this
// device.
RouterAdvert::Header oldHeader = mLocalRaHeader;
if (aRaHeader.GetRouterLifetime() == 0)
{
mLocalRaHeader.Clear();
}
else
{
mLocalRaHeader = aRaHeader;
mLocalRaHeaderUpdateTime = TimerMilli::GetNow();
// The checksum is set to zero which indicates to platform
// that it needs to do the calculation and update it.
mLocalRaHeader.SetChecksum(0);
}
if (mLocalRaHeader != oldHeader)
{
SignalTableChanged();
Get<RoutingManager>().ScheduleRoutingPolicyEvaluation(kAfterRandomDelay);
}
}
prefix.Clear();
entry = aRouter.mRoutePrefixes.FindMatching(prefix);
@@ -1496,6 +1479,8 @@ void RoutingManager::RxRaTracker::RemoveAllEntries(void)
mRouters.Free();
mEntryTimer.Stop();
mLocalRaHeader.Clear();
SignalTableChanged();
}
@@ -1525,6 +1510,12 @@ void RoutingManager::RxRaTracker::RemoveOrDeprecateOldEntries(TimeMilli aTimeThr
}
}
if (mLocalRaHeader.IsValid() && (mLocalRaHeaderUpdateTime <= aTimeThreshold))
{
mLocalRaHeader.Clear();
SignalTableChanged();
}
RemoveExpiredEntries();
}
@@ -1562,7 +1553,7 @@ void RoutingManager::RxRaTracker::RemoveOrDeprecateEntriesFromInactiveRouters(vo
TimeMilli RoutingManager::RxRaTracker::CalculateNextStaleTime(TimeMilli aNow) const
{
TimeMilli onLinkStaleTime = aNow;
TimeMilli routeStaleTime = aNow.GetDistantFuture();
TimeMilli staleTime = aNow.GetDistantFuture();
bool foundOnLink = false;
// For on-link prefixes, we consider stale time as when all on-link
@@ -1586,11 +1577,23 @@ TimeMilli RoutingManager::RxRaTracker::CalculateNextStaleTime(TimeMilli aNow) co
{
TimeMilli entryStaleTime = Max(aNow, entry.GetStaleTime());
routeStaleTime = Min(routeStaleTime, entryStaleTime);
staleTime = Min(staleTime, entryStaleTime);
}
}
return foundOnLink ? Min(onLinkStaleTime, routeStaleTime) : routeStaleTime;
if (foundOnLink)
{
staleTime = Min(staleTime, onLinkStaleTime);
}
if (mLocalRaHeader.IsValid())
{
TimeMilli raHeaderStaleTime = Max(aNow, mLocalRaHeaderUpdateTime + Time::SecToMsec(kRtrAdvStaleTime));
staleTime = Min(staleTime, raHeaderStaleTime);
}
return staleTime;
}
void RoutingManager::RxRaTracker::RemoveRoutersWithNoEntriesOrFlags(void)
+15 -24
View File
@@ -757,6 +757,8 @@ private:
void RemoveAllEntries(void);
void RemoveOrDeprecateOldEntries(TimeMilli aTimeThreshold);
const RouterAdvert::Header &GetLocalRaHeaderToMirror(void) const { return mLocalRaHeader; }
TimeMilli CalculateNextStaleTime(TimeMilli aNow) const;
void DetermineAndSetFlags(RouterAdvert::Header &aHeader) const;
@@ -890,7 +892,7 @@ private:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ProcessRaHeader(const RouterAdvert::Header &aRaHeader, Router &aRouter);
void ProcessRaHeader(const RouterAdvert::Header &aRaHeader, Router &aRouter, RouterAdvOrigin aRaOrigin);
void ProcessPrefixInfoOption(const PrefixInfoOption &aPio, Router &aRouter);
void ProcessRouteInfoOption(const RouteInfoOption &aRio, Router &aRouter);
void ProcessRaFlagsExtOption(const RaFlagsExtOption &aFlagsOption, Router &aRouter);
@@ -912,10 +914,12 @@ private:
using RouterTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandleRxRaTrackerRouterTimer>;
using RouterList = OwningList<Entry<Router>>;
RouterList mRouters;
EntryTimer mEntryTimer;
RouterTimer mRouterTimer;
SignalTask mSignalTask;
RouterList mRouters;
EntryTimer mEntryTimer;
RouterTimer mRouterTimer;
SignalTask mSignalTask;
RouterAdvert::Header mLocalRaHeader;
TimeMilli mLocalRaHeaderUpdateTime;
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
Pool<SharedEntry, kMaxEntries> mEntryPool;
Pool<Entry<Router>, kMaxRouters> mRouterPool;
@@ -1231,23 +1235,14 @@ private:
// - Number of RAs sent
// - Last RA TX time
// - Hashes of last TX RAs (to tell if a received RA is from
// `RoutingManager` itself)
// - RA header to use, and
// - Whether the RA header is discovered from receiving RAs
// from the host itself.
//
// This ensures that if an entity on host is advertising certain
// info in its RA header (e.g., a default route), the RAs we
// emit from `RoutingManager` also include the same header.
// `RoutingManager` itself).
typedef Crypto::Sha256::Hash Hash;
static constexpr uint16_t kNumHashEntries = 5;
TxRaInfo(void)
: mHeaderUpdateTime(TimerMilli::GetNow())
, mIsHeaderFromHost(false)
, mTxCount(0)
: mTxCount(0)
, mLastTxTime(TimerMilli::GetNow() - kMinDelayBetweenRtrAdvs)
, mLastHashIndex(0)
{
@@ -1257,13 +1252,10 @@ private:
bool IsRaFromManager(const RouterAdvert::RxMessage &aRaMessage) const;
static void CalculateHash(const RouterAdvert::RxMessage &aRaMessage, Hash &aHash);
RouterAdvert::Header mHeader;
TimeMilli mHeaderUpdateTime;
bool mIsHeaderFromHost;
uint32_t mTxCount;
TimeMilli mLastTxTime;
Hash mHashes[kNumHashEntries];
uint16_t mLastHashIndex;
uint32_t mTxCount;
TimeMilli mLastTxTime;
Hash mHashes[kNumHashEntries];
uint16_t mLastHashIndex;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1395,7 +1387,6 @@ private:
bool ShouldProcessRouteInfoOption(const RouteInfoOption &aRio, const Ip6::Prefix &aPrefix);
void UpdateRxRaTrackerOnNetDataChange(void);
bool NetworkDataContainsUlaRoute(void) const;
void UpdateRouterAdvertHeader(const RouterAdvert::RxMessage *aRaMsg, RouterAdvOrigin aRaOrigin);
void ResetDiscoveredPrefixStaleTimer(void);
static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix);
+10 -1
View File
@@ -539,7 +539,7 @@ public:
*
*/
OT_TOOL_PACKED_BEGIN
class Header : public Equatable<Header>, private Clearable<Header>
class Header : public Equatable<Header>, public Clearable<Header>
{
friend class Clearable<Header>;
@@ -551,6 +551,15 @@ public:
*/
Header(void) { SetToDefault(); }
/**
* Indicates whether the header is valid by checking the type field to match Router Advertisement ICMPv6 type.
*
* @retval TRUE The header is valid.
* @retval FALSE The header is not valid.
*
*/
bool IsValid(void) const { return GetType() == Icmp::Header::kTypeRouterAdvert; }
/**
* Sets the RA message to default values.
*