From 4fdd08111eb67c44e45b988aa407a6ff857c2cd1 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 27 Oct 2025 16:54:47 -0700 Subject: [PATCH] [border-router] manage `RxRaTracker` state via multiple requesters (#12050) This change introduces a mechanism to control the `RxRaTracker` from multiple sources. A new method `RxRaTracker::SetEnabled()` is added, which accepts a `Requester` enum. The tracker now maintains separate enable flags for each requester (e.g., `RoutingManager`). The `RxRaTracker` will start only when at least one requester has enabled it AND the infrastructure interface is initialized and running. It stops when all requesters have disabled it or when the interface goes down. The `Start()` and `Stop()` methods are now private, managed by a new `UpdateState()` method to centralize the state logic. `InfraIf` is updated to notify `RxRaTracker` of state changes. --- src/core/border_router/infra_if.cpp | 1 + src/core/border_router/routing_manager.cpp | 4 +-- src/core/border_router/rx_ra_tracker.cpp | 42 ++++++++++++++++++++++ src/core/border_router/rx_ra_tracker.hpp | 34 ++++++++++++++---- 4 files changed, 72 insertions(+), 9 deletions(-) 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;