diff --git a/src/core/border_router/infra_if.cpp b/src/core/border_router/infra_if.cpp index 02d5e48e4..e5edcc3a0 100644 --- a/src/core/border_router/infra_if.cpp +++ b/src/core/border_router/infra_if.cpp @@ -167,6 +167,7 @@ Error InfraIf::HandleStateChanged(uint32_t aIfIndex, bool aIsRunning) mIsRunning = aIsRunning; + Get().HandleInfraIfStateChanged(); Get().HandleInfraIfStateChanged(); #if OPENTHREAD_CONFIG_SRP_SERVER_ADVERTISING_PROXY_ENABLE diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index 0bda7cad1..d6c56bd3d 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -260,7 +260,7 @@ void RoutingManager::Start(void) LogInfo("Starting"); mIsRunning = true; - Get().Start(); + Get().SetEnabled(true, RxRaTracker::kRequesterRoutingManager); mOnLinkPrefixManager.Start(); mOmrPrefixManager.Start(); mRoutePublisher.Start(); @@ -294,7 +294,7 @@ void RoutingManager::Stop(void) SendRouterAdvertisement(kInvalidateAllPrevPrefixes); - Get().Stop(); + Get().SetEnabled(false, RxRaTracker::kRequesterRoutingManager); mTxRaInfo.mTxCount = 0; diff --git a/src/core/border_router/rx_ra_tracker.cpp b/src/core/border_router/rx_ra_tracker.cpp index 245a2af07..ebf2fde24 100644 --- a/src/core/border_router/rx_ra_tracker.cpp +++ b/src/core/border_router/rx_ra_tracker.cpp @@ -48,6 +48,9 @@ RegisterLogModule("BorderRouting"); RxRaTracker::RxRaTracker(Instance &aInstance) : InstanceLocator(aInstance) + , mRoutingManagerEnabled(false) + , mMultiAilDetectorEnabled(false) + , mIsRunning(false) , mRsSender(aInstance) , mExpirationTimer(aInstance) , mStaleTimer(aInstance) @@ -59,14 +62,50 @@ RxRaTracker::RxRaTracker(Instance &aInstance) mLocalRaHeader.Clear(); } +void RxRaTracker::SetEnabled(bool aEnable, Requester aRequester) +{ + switch (aRequester) + { + case kRequesterRoutingManager: + mRoutingManagerEnabled = aEnable; + break; + case kRequesterMultiAilDetector: + mMultiAilDetectorEnabled = aEnable; + break; + } + + UpdateState(); +} + +void RxRaTracker::UpdateState(void) +{ + if ((mRoutingManagerEnabled || mMultiAilDetectorEnabled) && Get().IsRunning()) + { + Start(); + } + else + { + Stop(); + } +} + void RxRaTracker::Start(void) { + VerifyOrExit(!mIsRunning); + mIsRunning = true; + mRsSender.Start(); HandleNetDataChange(); + +exit: + return; } void RxRaTracker::Stop(void) { + VerifyOrExit(mIsRunning); + mIsRunning = false; + mRouters.Free(); mIfAddresses.Free(); mLocalRaHeader.Clear(); @@ -78,6 +117,9 @@ void RxRaTracker::Stop(void) mRdnssAddrTimer.Stop(); mRsSender.Stop(); + +exit: + return; } void RxRaTracker::HandleRsSenderFinished(TimeMilli aStartTime) diff --git a/src/core/border_router/rx_ra_tracker.hpp b/src/core/border_router/rx_ra_tracker.hpp index 344ea7969..d42098607 100644 --- a/src/core/border_router/rx_ra_tracker.hpp +++ b/src/core/border_router/rx_ra_tracker.hpp @@ -74,6 +74,7 @@ class RxRaTracker : public InstanceLocator { friend class NetDataBrTracker; friend class ot::Notifier; + friend class InfraIf; public: /** @@ -86,6 +87,15 @@ public: kThisBrOtherEntity, ///< From this Border Router, generated by another software entity. }; + /** + * Represents an entity requesting to enable/disable the `RxRaTracker`. + */ + enum Requester : uint8_t + { + kRequesterRoutingManager, ///< Requested by `RoutingManager`. + kRequesterMultiAilDetector, ///< Requested by `MultiAilDetector`. + }; + /** * Initializes the `RxRaTracker` object. * @@ -94,14 +104,15 @@ public: explicit RxRaTracker(Instance &aInstance); /** - * Starts the RA tracker. + * Enables or disables the `RxRaTracker`. + * + * The `RxRaTracker` can be enabled by multiple requesters (see `Requester`). It remains enabled as long as + * at least one requester has it enabled. It is disabled only when all requesters have disabled it. + * + * @param[in] aEnable A boolean to enable/disable the Tracker. + * @param[in] aRequester The entity requesting to enable/disable. */ - void Start(void); - - /** - * Stops the RA tracker. - */ - void Stop(void); + void SetEnabled(bool aEnable, Requester aRequester); /** * Indicates whether the Router Solicitation (RS) transmission process is in progress. @@ -532,6 +543,9 @@ private: //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + void UpdateState(void); + void Start(void); + void Stop(void); void HandleRsSenderFinished(TimeMilli aStartTime); void ProcessRaHeader(const RouterAdvert::Header &aRaHeader, Router &aRouter, RouterAdvOrigin aRaOrigin); void ProcessPrefixInfoOption(const PrefixInfoOption &aPio, Router &aRouter); @@ -552,6 +566,9 @@ private: void HandleNotifierEvents(Events aEvents); void HandleNetDataChange(void); + // Callback from `InfraIf` + void HandleInfraIfStateChanged(void) { UpdateState(); } + // Tasklet or timer callbacks void HandleSignalTask(void); void HandleRdnssAddrTask(void); @@ -576,6 +593,9 @@ private: using IfAddressList = OwningList>; using RdnssCallback = Callback; + bool mRoutingManagerEnabled : 1; + bool mMultiAilDetectorEnabled : 1; + bool mIsRunning : 1; RsSender mRsSender; DecisionFactors mDecisionFactors; RouterList mRouters;