mirror of
https://github.com/espressif/openthread.git
synced 2026-08-08 11:47:46 +00:00
[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:
@@ -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)
|
||||
|
||||
@@ -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
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user