Skip to content

Commit

Permalink
[routing-manager] move tracking of local RA header to RxRaTracker (o…
Browse files Browse the repository at this point in the history
…penthread#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.
  • Loading branch information
abtink committed May 17, 2024
1 parent 63442f7 commit 67a2627
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 89 deletions.
131 changes: 67 additions & 64 deletions src/core/border_router/routing_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -696,12 +704,6 @@ void RoutingManager::HandleRsSenderFinished(TimeMilli aStartTime)
// Solicitation.

mRxRaTracker.RemoveOrDeprecateOldEntries(aStartTime);

if (mTxRaInfo.mHeaderUpdateTime <= aStartTime)
{
UpdateRouterAdvertHeader(/* aRouterAdvertMessage */ nullptr, kThisBrOtherEntity);
}

ScheduleRoutingPolicyEvaluation(kImmediately);
}

Expand Down Expand Up @@ -758,8 +760,6 @@ void RoutingManager::HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPack

mRxRaTracker.ProcessRouterAdvertMessage(raMsg, aSrcAddress, raOrigin);

UpdateRouterAdvertHeader(&raMsg, raOrigin);

exit:
return;
}
Expand Down Expand Up @@ -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();
Expand All @@ -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())
Expand Down Expand Up @@ -1113,6 +1063,7 @@ RoutingManager::RxRaTracker::RxRaTracker(Instance &aInstance)
, mRouterTimer(aInstance)
, mSignalTask(aInstance)
{
mLocalRaHeader.Clear();
}

void RoutingManager::RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaMessage,
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -1181,7 +1132,9 @@ void RoutingManager::RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert:
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();
Expand All @@ -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);

Expand Down Expand Up @@ -1496,6 +1479,8 @@ void RoutingManager::RxRaTracker::RemoveAllEntries(void)
mRouters.Free();
mEntryTimer.Stop();

mLocalRaHeader.Clear();

SignalTableChanged();
}

Expand Down Expand Up @@ -1525,6 +1510,12 @@ void RoutingManager::RxRaTracker::RemoveOrDeprecateOldEntries(TimeMilli aTimeThr
}
}

if (mLocalRaHeader.IsValid() && (mLocalRaHeaderUpdateTime <= aTimeThreshold))
{
mLocalRaHeader.Clear();
SignalTableChanged();
}

RemoveExpiredEntries();
}

Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down
39 changes: 15 additions & 24 deletions src/core/border_router/routing_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,8 @@ class RoutingManager : public InstanceLocator
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;
Expand Down Expand Up @@ -890,7 +892,7 @@ class RoutingManager : public InstanceLocator

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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);
Expand All @@ -912,10 +914,12 @@ class RoutingManager : public InstanceLocator
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;
Expand Down Expand Up @@ -1231,23 +1235,14 @@ class RoutingManager : public InstanceLocator
// - 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)
{
Expand All @@ -1257,13 +1252,10 @@ class RoutingManager : public InstanceLocator
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;
};

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand Down Expand Up @@ -1395,7 +1387,6 @@ class RoutingManager : public InstanceLocator
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);
Expand Down
11 changes: 10 additions & 1 deletion src/core/net/nd6.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ class RouterAdvert
*
*/
OT_TOOL_PACKED_BEGIN
class Header : public Equatable<Header>, private Clearable<Header>
class Header : public Equatable<Header>, public Clearable<Header>
{
friend class Clearable<Header>;

Expand All @@ -551,6 +551,15 @@ class RouterAdvert
*/
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.
*
Expand Down

0 comments on commit 67a2627

Please sign in to comment.