[border-router] centralize infra-if management in InfraIf (#12046)

This change moves the management of the infrastructure interface state
out of the `RoutingManager` and centralizes it within the `InfraIf`
class. This makes `InfraIf` a more self-contained component and
simplifies the logic in `RoutingManager`.

The `RoutingManager` now depends on an initialized `InfraIf`. Its
`Init()` method is simplified and is now called from
`InfraIf::Init()`.

The public API `otBorderRoutingInit()` now directly initializes the
`InfraIf`. The `InfraIf::Init()` method is updated to support
re-initialization, allowing to switch to a new interface. When
switching, it ensures that components on the previous interface are
stopped before restarting on the new one.
This commit is contained in:
Abtin Keshavarzian
2025-10-24 06:55:11 +08:00
committed by GitHub
parent 36b14d3ef7
commit b492922a9c
13 changed files with 86 additions and 127 deletions
+6 -7
View File
@@ -211,19 +211,18 @@ typedef enum
/**
* Initializes the Border Routing Manager on given infrastructure interface.
*
* @note This method MUST be called before any other otBorderRouting* APIs.
* @note This method can be re-called to change the infrastructure interface, but the Border Routing Manager should be
* disabled first, and re-enabled after.
* This function MUST be called before any other otBorderRouting* APIs.
*
* This function can also be used to re-initialize and switch the infrastructure interface index to a new one.
* Switching the interface index will trigger all components running on the previous interface (Border Routing,
* mDNS, etc) to be stopped (as if the previous if-index is no longer running) before restarting operations on the
* new interface.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aInfraIfIndex The infrastructure interface index.
* @param[in] aInfraIfIsRunning A boolean that indicates whether the infrastructure
* interface is running.
*
* @retval OT_ERROR_NONE Successfully started the Border Routing Manager on given infrastructure.
* @retval OT_ERROR_INVALID_STATE The Border Routing Manager is in a state other than disabled or uninitialized.
* @retval OT_ERROR_INVALID_ARGS The index of the infrastructure interface is not valid.
* @retval OT_ERROR_FAILED Internal failure. Usually due to failure in generating random prefixes.
*
* @sa otPlatInfraIfStateChanged.
* @sa otBorderRoutingSetEnabled.
+1 -1
View File
@@ -52,7 +52,7 @@ extern "C" {
*
* @note This number versions both OpenThread platform and user APIs.
*/
#define OPENTHREAD_API_VERSION (544)
#define OPENTHREAD_API_VERSION (545)
/**
* @addtogroup api-instance
+12 -5
View File
@@ -41,21 +41,28 @@ using namespace ot;
otError otBorderRoutingInit(otInstance *aInstance, uint32_t aInfraIfIndex, bool aInfraIfIsRunning)
{
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().Init(aInfraIfIndex, aInfraIfIsRunning);
AsCoreType(aInstance).Get<BorderRouter::InfraIf>().Init(aInfraIfIndex, aInfraIfIsRunning);
return kErrorNone;
}
otError otBorderRoutingGetInfraIfInfo(otInstance *aInstance, uint32_t *aInfraIfIndex, bool *aInfraIfIsRunning)
{
bool isRunning;
Error error = kErrorNone;
AssertPointerIsNotNull(aInfraIfIndex);
if (aInfraIfIsRunning == nullptr)
VerifyOrExit(AsCoreType(aInstance).Get<BorderRouter::InfraIf>().IsInitialized(), error = kErrorInvalidState);
*aInfraIfIndex = AsCoreType(aInstance).Get<BorderRouter::InfraIf>().GetIfIndex();
if (aInfraIfIsRunning != nullptr)
{
aInfraIfIsRunning = &isRunning;
*aInfraIfIsRunning = AsCoreType(aInstance).Get<BorderRouter::InfraIf>().IsRunning();
}
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().GetInfraIfInfo(*aInfraIfIndex, *aInfraIfIsRunning);
exit:
return error;
}
otError otBorderRoutingSetEnabled(otInstance *aInstance, bool aEnabled)
+26 -9
View File
@@ -50,28 +50,45 @@ InfraIf::InfraIf(Instance &aInstance)
{
}
Error InfraIf::Init(uint32_t aIfIndex)
void InfraIf::Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning)
{
Error error = kErrorNone;
if (mInitialized)
{
VerifyOrExit(aInfraIfIndex != mIfIndex);
VerifyOrExit(!mInitialized, error = kErrorInvalidState);
LogInfo("Switching previously configured %s to %lu", ToString().AsCString(), ToUlong(aInfraIfIndex));
mIfIndex = aIfIndex;
// When switching interface index, we `Deinit()` to signal
// that the previous `mIfIndex` is down so that all modules
// operating on this interface are stopped before restarting
// operation on the new interface.
Deinit();
}
mIfIndex = aInfraIfIndex;
mInitialized = true;
LogInfo("Init %s", ToString().AsCString());
Get<RoutingManager>().Init();
exit:
return error;
IgnoreError(HandleStateChanged(mIfIndex, aInfraIfIsRunning));
}
void InfraIf::Deinit(void)
{
mInitialized = false;
mIsRunning = false;
mIfIndex = 0;
VerifyOrExit(mInitialized);
LogInfo("Deinit");
LogInfo("Deinit %s", ToString().AsCString());
IgnoreError(HandleStateChanged(mIfIndex, /* aIsRunning */ false));
mInitialized = false;
exit:
return;
}
bool InfraIf::HasAddress(const Ip6::Address &aAddress) const
+7 -5
View File
@@ -101,13 +101,15 @@ public:
/**
* Initializes the `InfraIf`.
*
* @param[in] aIfIndex The infrastructure interface index.
* This method can also be used to re-initialize and switch the infrastructure interface index to a new one.
* Switching the interface index will trigger all components running on the previous interface (Border Routing,
* mDNS, etc) to be stopped (as if the previous if-index is no longer running) before restarting operations on the
* new interface.
*
* @retval kErrorNone Successfully initialized the `InfraIf`.
* @retval kErrorInvalidArgs The index of the infra interface is not valid.
* @retval kErrorInvalidState The `InfraIf` is already initialized.
* @param[in] aInfraIfIndex The infrastructure network interface index.
* @param[in] aInfraIfIsRunning A boolean that indicates whether the infrastructure interface is running.
*/
Error Init(uint32_t aIfIndex);
void Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning);
/**
* Deinitilaizes the `InfraIf`.
+20 -67
View File
@@ -73,65 +73,26 @@ RoutingManager::RoutingManager(Instance &aInstance)
mBrUlaPrefix.Clear();
}
Error RoutingManager::Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning)
void RoutingManager::Init(void)
{
Error error;
VerifyOrExit(Get<InfraIf>().IsInitialized());
VerifyOrExit(GetState() == kStateUninitialized || GetState() == kStateDisabled, error = kErrorInvalidState);
if (!Get<InfraIf>().IsInitialized())
{
LogInfo("Initializing - InfraIfIndex:%lu", ToUlong(aInfraIfIndex));
SuccessOrExit(error = Get<InfraIf>().Init(aInfraIfIndex));
SuccessOrExit(error = LoadOrGenerateRandomBrUlaPrefix());
mOmrPrefixManager.Init(mBrUlaPrefix);
LoadOrGenerateRandomBrUlaPrefix();
mOmrPrefixManager.Init(mBrUlaPrefix);
#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
mNat64PrefixManager.GenerateLocalPrefix(mBrUlaPrefix);
mNat64PrefixManager.GenerateLocalPrefix(mBrUlaPrefix);
#endif
mOnLinkPrefixManager.Init();
}
else if (aInfraIfIndex != Get<InfraIf>().GetIfIndex())
{
LogInfo("Reinitializing - InfraIfIndex:%lu -> %lu", ToUlong(Get<InfraIf>().GetIfIndex()),
ToUlong(aInfraIfIndex));
#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE && OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF
IgnoreError(Get<Dns::Multicast::Core>().SetEnabled(false, Get<InfraIf>().GetIfIndex()));
#endif
Get<InfraIf>().SetIfIndex(aInfraIfIndex);
}
error = Get<InfraIf>().HandleStateChanged(Get<InfraIf>().GetIfIndex(), aInfraIfIsRunning);
mOnLinkPrefixManager.Init();
exit:
if (error != kErrorNone)
{
Get<InfraIf>().Deinit();
}
return error;
}
bool RoutingManager::IsInitialized(void) const { return Get<InfraIf>().IsInitialized(); }
Error RoutingManager::GetInfraIfInfo(uint32_t &aInfraIfIndex, bool &aInfraIfIsRunning) const
{
Error error = kErrorNone;
VerifyOrExit(IsInitialized(), error = kErrorInvalidState);
aInfraIfIndex = Get<InfraIf>().GetIfIndex();
aInfraIfIsRunning = Get<InfraIf>().IsRunning();
exit:
return error;
return;
}
Error RoutingManager::SetEnabled(bool aEnabled)
{
Error error = kErrorNone;
VerifyOrExit(IsInitialized(), error = kErrorInvalidState);
VerifyOrExit(Get<InfraIf>().IsInitialized(), error = kErrorInvalidState);
VerifyOrExit(aEnabled != mIsEnabled);
@@ -147,7 +108,7 @@ RoutingManager::State RoutingManager::GetState(void) const
{
State state = kStateUninitialized;
VerifyOrExit(IsInitialized());
VerifyOrExit(Get<InfraIf>().IsInitialized());
VerifyOrExit(IsEnabled(), state = kStateDisabled);
state = IsRunning() ? kStateRunning : kStateStopped;
@@ -160,7 +121,7 @@ Error RoutingManager::GetOmrPrefix(Ip6::Prefix &aPrefix) const
{
Error error = kErrorNone;
VerifyOrExit(IsInitialized(), error = kErrorInvalidState);
VerifyOrExit(Get<InfraIf>().IsInitialized(), error = kErrorInvalidState);
aPrefix = mOmrPrefixManager.GetGeneratedPrefix();
exit:
@@ -172,7 +133,7 @@ Error RoutingManager::GetDhcp6PdOmrPrefix(Dhcp6PdPrefix &aPrefix) const
{
Error error = kErrorNone;
VerifyOrExit(IsInitialized(), error = kErrorInvalidState);
VerifyOrExit(Get<InfraIf>().IsInitialized(), error = kErrorInvalidState);
error = mPdPrefixManager.GetPrefix(aPrefix);
exit:
@@ -183,7 +144,7 @@ Error RoutingManager::GetDhcp6PdCounters(Dhcp6PdCounters &aCounters)
{
Error error = kErrorNone;
VerifyOrExit(IsInitialized(), error = kErrorInvalidState);
VerifyOrExit(Get<InfraIf>().IsInitialized(), error = kErrorInvalidState);
error = mPdPrefixManager.GetCounters(aCounters);
exit:
@@ -207,7 +168,7 @@ Error RoutingManager::GetOnLinkPrefix(Ip6::Prefix &aPrefix) const
{
Error error = kErrorNone;
VerifyOrExit(IsInitialized(), error = kErrorInvalidState);
VerifyOrExit(Get<InfraIf>().IsInitialized(), error = kErrorInvalidState);
aPrefix = mOnLinkPrefixManager.GetLocalPrefix();
exit:
@@ -218,7 +179,7 @@ Error RoutingManager::GetFavoredOnLinkPrefix(Ip6::Prefix &aPrefix) const
{
Error error = kErrorNone;
VerifyOrExit(IsInitialized(), error = kErrorInvalidState);
VerifyOrExit(Get<InfraIf>().IsInitialized(), error = kErrorInvalidState);
aPrefix = mOnLinkPrefixManager.GetFavoredPrefix();
exit:
@@ -236,7 +197,7 @@ Error RoutingManager::GetNat64Prefix(Ip6::Prefix &aPrefix)
{
Error error = kErrorNone;
VerifyOrExit(IsInitialized(), error = kErrorInvalidState);
VerifyOrExit(Get<InfraIf>().IsInitialized(), error = kErrorInvalidState);
aPrefix = mNat64PrefixManager.GetLocalPrefix();
exit:
@@ -247,7 +208,7 @@ Error RoutingManager::GetFavoredNat64Prefix(Ip6::Prefix &aPrefix, RoutePreferenc
{
Error error = kErrorNone;
VerifyOrExit(IsInitialized(), error = kErrorInvalidState);
VerifyOrExit(Get<InfraIf>().IsInitialized(), error = kErrorInvalidState);
aPrefix = mNat64PrefixManager.GetFavoredPrefix(aRoutePreference);
exit:
@@ -255,10 +216,9 @@ exit:
}
#endif
Error RoutingManager::LoadOrGenerateRandomBrUlaPrefix(void)
void RoutingManager::LoadOrGenerateRandomBrUlaPrefix(void)
{
Error error = kErrorNone;
bool generated = false;
bool generated = false;
if (Get<Settings>().Read<Settings::BrUlaPrefix>(mBrUlaPrefix) != kErrorNone || !IsValidBrUlaPrefix(mBrUlaPrefix))
{
@@ -266,7 +226,7 @@ Error RoutingManager::LoadOrGenerateRandomBrUlaPrefix(void)
LogNote("No valid /48 BR ULA prefix found in settings, generating new one");
SuccessOrExit(error = randomUlaPrefix.GenerateRandomUla());
SuccessOrAssert(randomUlaPrefix.GenerateRandomUla());
mBrUlaPrefix.Set(randomUlaPrefix);
mBrUlaPrefix.SetSubnetId(0);
@@ -279,13 +239,6 @@ Error RoutingManager::LoadOrGenerateRandomBrUlaPrefix(void)
OT_UNUSED_VARIABLE(generated);
LogNote("BR ULA prefix: %s (%s)", mBrUlaPrefix.ToString().AsCString(), generated ? "generated" : "loaded");
exit:
if (error != kErrorNone)
{
LogCrit("Failed to generate random /48 BR ULA prefix");
}
return error;
}
void RoutingManager::EvaluateState(void)
@@ -435,7 +388,7 @@ void RoutingManager::HandleNotifierEvents(Events aEvents)
mRoutePublisher.HandleNotifierEvents(aEvents);
VerifyOrExit(IsInitialized() && IsEnabled());
VerifyOrExit(Get<InfraIf>().IsInitialized() && IsEnabled());
if (aEvents.Contains(kEventThreadRoleChanged))
{
+8 -27
View File
@@ -156,27 +156,9 @@ public:
explicit RoutingManager(Instance &aInstance);
/**
* Initializes the routing manager on given infrastructure interface.
*
* @param[in] aInfraIfIndex An infrastructure network interface index.
* @param[in] aInfraIfIsRunning A boolean that indicates whether the infrastructure
* interface is running.
*
* @retval kErrorNone Successfully started the routing manager.
* @retval kErrorInvalidArgs The index of the infra interface is not valid.
* Initializes the routing manager.
*/
Error Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning);
/**
* Gets the interface index of the currently configured infrastructure interface.
*
* @param[out] aInfraIfIndex A reference to output the interface index.
* @param[out] aInfraIfIsRunning A reference to output whether the interface is running.
*
* @retval kErrorNone Successfully retrieved the interface information.
* @retval kErrorInvalidState The Border Routing Manager is not initialized.
*/
Error GetInfraIfInfo(uint32_t &aInfraIfIndex, bool &aInfraIfIsRunning) const;
void Init(void);
/**
* Enables/disables the Border Routing Manager.
@@ -1103,13 +1085,12 @@ private:
//------------------------------------------------------------------------------------------------------------------
// Methods
void EvaluateState(void);
void Start(void);
void Stop(void);
void HandleNotifierEvents(Events aEvents);
bool IsInitialized(void) const;
bool IsEnabled(void) const { return mIsEnabled; }
Error LoadOrGenerateRandomBrUlaPrefix(void);
void EvaluateState(void);
void Start(void);
void Stop(void);
void HandleNotifierEvents(Events aEvents);
bool IsEnabled(void) const { return mIsEnabled; }
void LoadOrGenerateRandomBrUlaPrefix(void);
void EvaluateRoutingPolicy(void);
bool IsInitialPolicyEvaluationDone(void) const;
+1 -1
View File
@@ -111,7 +111,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
otCliInit(&node.GetInstance(), CliOutput, nullptr);
node.GetInstance().Get<BorderRouter::RoutingManager>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
node.GetInstance().Get<BorderRouter::InfraIf>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
node.GetInstance().Get<BorderRouter::RoutingManager>().SetEnabled(true);
node.GetInstance().Get<Srp::Server>().SetAutoEnableMode(true);
node.GetInstance().Get<BorderRouter::RoutingManager>().SetDhcp6PdEnabled(true);
+1 -1
View File
@@ -100,7 +100,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
node.GetInstance().SetLogLevel(kLogLevelInfo);
node.GetInstance().Get<BorderRouter::RoutingManager>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
node.GetInstance().Get<BorderRouter::InfraIf>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
node.GetInstance().Get<BorderRouter::RoutingManager>().SetEnabled(true);
node.GetInstance().Get<Srp::Server>().SetAutoEnableMode(true);
node.GetInstance().Get<BorderRouter::RoutingManager>().SetDhcp6PdEnabled(true);
+1 -1
View File
@@ -112,7 +112,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
node.GetInstance().SetLogLevel(kLogLevelInfo);
node.GetInstance().Get<BorderRouter::RoutingManager>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
node.GetInstance().Get<BorderRouter::InfraIf>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
node.GetInstance().Get<BorderRouter::RoutingManager>().SetEnabled(true);
node.GetInstance().Get<Srp::Server>().SetAutoEnableMode(true);
node.GetInstance().Get<BorderRouter::RoutingManager>().SetDhcp6PdEnabled(true);
+1 -1
View File
@@ -111,7 +111,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
node.GetInstance().SetLogLevel(kLogLevelInfo);
node.GetInstance().Get<BorderRouter::RoutingManager>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
node.GetInstance().Get<BorderRouter::InfraIf>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
node.GetInstance().Get<BorderRouter::RoutingManager>().SetEnabled(true);
node.GetInstance().Get<Srp::Server>().SetAutoEnableMode(true);
node.GetInstance().Get<BorderRouter::RoutingManager>().SetDhcp6PdEnabled(true);
+1 -1
View File
@@ -110,7 +110,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
node.GetInstance().SetLogLevel(kLogLevelInfo);
node.GetInstance().Get<BorderRouter::RoutingManager>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
node.GetInstance().Get<BorderRouter::InfraIf>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
node.GetInstance().Get<BorderRouter::RoutingManager>().SetEnabled(true);
node.GetInstance().Get<Srp::Server>().SetAutoEnableMode(true);
node.GetInstance().Get<BorderRouter::RoutingManager>().SetDhcp6PdEnabled(true);
+1 -1
View File
@@ -101,7 +101,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
node.GetInstance().SetLogLevel(kLogLevelInfo);
node.GetInstance().Get<BorderRouter::RoutingManager>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
node.GetInstance().Get<BorderRouter::InfraIf>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
node.GetInstance().Get<BorderRouter::RoutingManager>().SetEnabled(true);
node.GetInstance().Get<Srp::Server>().SetAutoEnableMode(true);
node.GetInstance().Get<BorderRouter::RoutingManager>().SetDhcp6PdEnabled(true);