diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index 498700d5d7d..eb9e6907e75 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -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 @@ 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(); @@ -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().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) diff --git a/src/core/border_router/routing_manager.hpp b/src/core/border_router/routing_manager.hpp index a28141ef28b..824a3766ca9 100644 --- a/src/core/border_router/routing_manager.hpp +++ b/src/core/border_router/routing_manager.hpp @@ -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; @@ -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); @@ -912,10 +914,12 @@ class RoutingManager : public InstanceLocator using RouterTimer = TimerMilliIn; using RouterList = OwningList>; - 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 mEntryPool; Pool, kMaxRouters> mRouterPool; @@ -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) { @@ -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; }; //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -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); diff --git a/src/core/net/nd6.hpp b/src/core/net/nd6.hpp index c4753b660f8..8c6f3bd2ad5 100644 --- a/src/core/net/nd6.hpp +++ b/src/core/net/nd6.hpp @@ -539,7 +539,7 @@ class RouterAdvert * */ OT_TOOL_PACKED_BEGIN - class Header : public Equatable
, private Clearable
+ class Header : public Equatable
, public Clearable
{ friend class Clearable
; @@ -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. *