[border-router] decouple NetDataPeerBrTracker from RoutingManager (#11960)

Moves the nested `RoutingManager::NetDataPeerBrTracker` class into its
own standalone class `BorderRouter::NetDataPeerBrTracker` in new
files `br_tracker.cpp` and `br_tracker.hpp`.

`NetDataPeerBrTracker` is now instantiated as a member of `Instance`
and is no longer owned by `RoutingManager`.

There is no logical/behavioral change in the `NetDataPeerBrTracker`
functionality.

Public C APIs `otBorderRoutingGetNextPeerBrEntry()` and
`otBorderRoutingCountPeerBrs()` are updated to get and use the
`NetDataPeerBrTracker` component.
This commit is contained in:
Abtin Keshavarzian
2025-09-24 08:33:15 -07:00
committed by GitHub
parent 27932f2006
commit 38781d43c9
10 changed files with 287 additions and 178 deletions
+2
View File
@@ -375,6 +375,8 @@ openthread_core_files = [
"backbone_router/multicast_listeners_table.hpp",
"backbone_router/ndproxy_table.cpp",
"backbone_router/ndproxy_table.hpp",
"border_router/br_tracker.cpp",
"border_router/br_tracker.hpp",
"border_router/dhcp6_pd_client.cpp",
"border_router/dhcp6_pd_client.hpp",
"border_router/infra_if.cpp",
+1
View File
@@ -95,6 +95,7 @@ set(COMMON_SOURCES
backbone_router/bbr_manager.cpp
backbone_router/multicast_listeners_table.cpp
backbone_router/ndproxy_table.cpp
border_router/br_tracker.cpp
border_router/dhcp6_pd_client.cpp
border_router/infra_if.cpp
border_router/routing_manager.cpp
+3 -3
View File
@@ -268,15 +268,15 @@ otError otBorderRoutingGetNextPeerBrEntry(otInstance *
AssertPointerIsNotNull(aIterator);
AssertPointerIsNotNull(aEntry);
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().GetNextPeerBrEntry(*aIterator, *aEntry);
return AsCoreType(aInstance).Get<BorderRouter::NetDataPeerBrTracker>().GetNext(*aIterator, *aEntry);
}
uint16_t otBorderRoutingCountPeerBrs(otInstance *aInstance, uint32_t *aMinAge)
{
uint32_t minAge;
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().CountPeerBrs((aMinAge != nullptr) ? *aMinAge
: minAge);
return AsCoreType(aInstance).Get<BorderRouter::NetDataPeerBrTracker>().CountPeerBrs((aMinAge != nullptr) ? *aMinAge
: minAge);
}
#endif
+130
View File
@@ -0,0 +1,130 @@
/*
* Copyright (c) 2025, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "border_router/br_tracker.hpp"
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
#include "instance/instance.hpp"
namespace ot {
namespace BorderRouter {
RegisterLogModule("BorderRouting");
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
NetDataPeerBrTracker::NetDataPeerBrTracker(Instance &aInstance)
: InstanceLocator(aInstance)
{
}
uint16_t NetDataPeerBrTracker::CountPeerBrs(uint32_t &aMinAge) const
{
uint32_t uptime = Get<Uptime>().GetUptimeInSeconds();
uint16_t count = 0;
aMinAge = NumericLimits<uint16_t>::kMax;
for (const PeerBr &peerBr : mPeerBrs)
{
count++;
aMinAge = Min(aMinAge, peerBr.GetAge(uptime));
}
if (count == 0)
{
aMinAge = 0;
}
return count;
}
Error NetDataPeerBrTracker::GetNext(TableIterator &aIterator, PeerBrEntry &aEntry) const
{
using Iterator = RoutingManager::RxRaTracker::Iterator;
Iterator &iterator = static_cast<Iterator &>(aIterator);
Error error;
SuccessOrExit(error = iterator.AdvanceToNextPeerBr(mPeerBrs.GetHead()));
aEntry.mRloc16 = iterator.GetPeerBrEntry()->mRloc16;
aEntry.mAge = iterator.GetPeerBrEntry()->GetAge(iterator.GetInitUptime());
exit:
return error;
}
void NetDataPeerBrTracker::HandleNotifierEvents(Events aEvents)
{
NetworkData::Rlocs rlocs;
VerifyOrExit(aEvents.ContainsAny(kEventThreadNetdataChanged | kEventThreadRoleChanged));
Get<NetworkData::Leader>().FindRlocs(NetworkData::kBrProvidingExternalIpConn, NetworkData::kAnyRole, rlocs);
// Remove `PeerBr` entries no longer found in Network Data,
// or they match the device RLOC16. Then allocate and add
// entries for newly discovered peers.
mPeerBrs.RemoveAndFreeAllMatching(PeerBr::Filter(rlocs));
mPeerBrs.RemoveAndFreeAllMatching(Get<Mle::Mle>().GetRloc16());
for (uint16_t rloc16 : rlocs)
{
PeerBr *newEntry;
if (Get<Mle::Mle>().HasRloc16(rloc16) || mPeerBrs.ContainsMatching(rloc16))
{
continue;
}
newEntry = PeerBr::Allocate();
VerifyOrExit(newEntry != nullptr, LogWarn("Failed to allocate `PeerBr` entry"));
newEntry->mRloc16 = rloc16;
newEntry->mDiscoverTime = Get<Uptime>().GetUptimeInSeconds();
mPeerBrs.Push(*newEntry);
}
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
Get<RoutingManager>().mMultiAilDetector.Evaluate();
#endif
exit:
return;
}
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
} // namespace BorderRouter
} // namespace ot
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
+135
View File
@@ -0,0 +1,135 @@
/*
* Copyright (c) 2025, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BR_TRACKER_HPP_
#define BR_TRACKER_HPP_
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
#include <openthread/border_routing.h>
#include "common/heap_allocatable.hpp"
#include "common/linked_list.hpp"
#include "common/locator.hpp"
#include "common/notifier.hpp"
#include "common/owning_list.hpp"
#include "thread/network_data.hpp"
namespace ot {
namespace BorderRouter {
class RoutingManager;
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
/**
* Represents a Network Data BR tracker which discovers and tracks BRs in the Thread Network Data.
*/
class NetDataPeerBrTracker : public InstanceLocator
{
friend class RoutingManager;
friend class ot::Notifier;
public:
/**
* Represents an iterator to iterate through the tracked BR entries.
*/
using TableIterator = otBorderRoutingPrefixTableIterator;
/**
* Represents information about a peer Border Router found in the Network Data.
*/
using PeerBrEntry = otBorderRoutingPeerBorderRouterEntry;
/**
* Initializes a `NetDataPeerBrTracker`.
*
* @param[in] aInstance The OpenThread instance.
*/
explicit NetDataPeerBrTracker(Instance &aInstance);
/**
* Counts the number of peer BRs found in the Network Data.
*
* The count does not include this device itself (when it itself is acting as a BR).
*
* @param[out] aMinAge Reference to an `uint32_t` to return the minimum age among all peer BRs.
* Age is represented as seconds since appearance of the BR entry in the Network Data.
*
* @returns The number of peer BRs.
*/
uint16_t CountPeerBrs(uint32_t &aMinAge) const;
/**
* Iterates over the peer BRs found in the Network Data.
*
* @param[in,out] aIterator An iterator.
* @param[out] aEntry A reference to the entry to populate.
*
* @retval kErrorNone Got the next peer BR info, @p aEntry is updated and @p aIterator is advanced.
* @retval kErrorNotFound No more peer BRs in the list.
*/
Error GetNext(TableIterator &aIterator, PeerBrEntry &aEntry) const;
private:
struct PeerBr : LinkedListEntry<PeerBr>, Heap::Allocatable<PeerBr>
{
struct Filter
{
Filter(const NetworkData::Rlocs &aRlocs)
: mExcludeRlocs(aRlocs)
{
}
const NetworkData::Rlocs &mExcludeRlocs;
};
uint32_t GetAge(uint32_t aUptime) const { return aUptime - mDiscoverTime; }
bool Matches(uint16_t aRloc16) const { return mRloc16 == aRloc16; }
bool Matches(const Filter &aFilter) const { return !aFilter.mExcludeRlocs.Contains(mRloc16); }
PeerBr *mNext;
uint16_t mRloc16;
uint32_t mDiscoverTime;
};
void HandleNotifierEvents(Events aEvents);
OwningList<PeerBr> mPeerBrs;
};
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
} // namespace BorderRouter
} // namespace ot
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
#endif // BR_TRACKER_HPP_
+2 -98
View File
@@ -57,9 +57,7 @@ RoutingManager::RoutingManager(Instance &aInstance)
, mOmrPrefixManager(aInstance)
, mRioAdvertiser(aInstance)
, mOnLinkPrefixManager(aInstance)
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
, mNetDataPeerBrTracker(aInstance)
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
, mMultiAilDetector(aInstance)
#endif
@@ -439,10 +437,6 @@ void RoutingManager::HandleNotifierEvents(Events aEvents)
mRoutePublisher.HandleNotifierEvents(aEvents);
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
mNetDataPeerBrTracker.HandleNotifierEvents(aEvents);
#endif
VerifyOrExit(IsInitialized() && IsEnabled());
if (aEvents.Contains(kEventThreadRoleChanged))
@@ -1108,96 +1102,6 @@ void RoutingManager::IfAddress::CopyInfoTo(IfAddrEntry &aEntry, uint32_t aUptime
aEntry.mSecSinceLastUse = aUptimeNow - mLastUseUptime;
}
//---------------------------------------------------------------------------------------------------------------------
// NetDataPeerBrTracker
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
RoutingManager::NetDataPeerBrTracker::NetDataPeerBrTracker(Instance &aInstance)
: InstanceLocator(aInstance)
{
}
uint16_t RoutingManager::NetDataPeerBrTracker::CountPeerBrs(uint32_t &aMinAge) const
{
uint32_t uptime = Get<Uptime>().GetUptimeInSeconds();
uint16_t count = 0;
aMinAge = NumericLimits<uint16_t>::kMax;
for (const PeerBr &peerBr : mPeerBrs)
{
count++;
aMinAge = Min(aMinAge, peerBr.GetAge(uptime));
}
if (count == 0)
{
aMinAge = 0;
}
return count;
}
Error RoutingManager::NetDataPeerBrTracker::GetNext(PrefixTableIterator &aIterator, PeerBrEntry &aEntry) const
{
using Iterator = RxRaTracker::Iterator;
Iterator &iterator = static_cast<Iterator &>(aIterator);
Error error;
SuccessOrExit(error = iterator.AdvanceToNextPeerBr(mPeerBrs.GetHead()));
aEntry.mRloc16 = iterator.GetPeerBrEntry()->mRloc16;
aEntry.mAge = iterator.GetPeerBrEntry()->GetAge(iterator.GetInitUptime());
exit:
return error;
}
void RoutingManager::NetDataPeerBrTracker::HandleNotifierEvents(Events aEvents)
{
NetworkData::Rlocs rlocs;
VerifyOrExit(aEvents.ContainsAny(kEventThreadNetdataChanged | kEventThreadRoleChanged));
Get<NetworkData::Leader>().FindRlocs(NetworkData::kBrProvidingExternalIpConn, NetworkData::kAnyRole, rlocs);
// Remove `PeerBr` entries no longer found in Network Data,
// or they match the device RLOC16. Then allocate and add
// entries for newly discovered peers.
mPeerBrs.RemoveAndFreeAllMatching(PeerBr::Filter(rlocs));
mPeerBrs.RemoveAndFreeAllMatching(Get<Mle::Mle>().GetRloc16());
for (uint16_t rloc16 : rlocs)
{
PeerBr *newEntry;
if (Get<Mle::Mle>().HasRloc16(rloc16) || mPeerBrs.ContainsMatching(rloc16))
{
continue;
}
newEntry = PeerBr::Allocate();
VerifyOrExit(newEntry != nullptr, LogWarn("Failed to allocate `PeerBr` entry"));
newEntry->mRloc16 = rloc16;
newEntry->mDiscoverTime = Get<Uptime>().GetUptimeInSeconds();
mPeerBrs.Push(*newEntry);
}
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
Get<RoutingManager>().mMultiAilDetector.Evaluate();
#endif
exit:
return;
}
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
//---------------------------------------------------------------------------------------------------------------------
// MultiAilDetector
@@ -1228,7 +1132,7 @@ void RoutingManager::MultiAilDetector::Evaluate(void)
VerifyOrExit(Get<RoutingManager>().IsRunning());
count = Get<RoutingManager>().mNetDataPeerBrTracker.CountPeerBrs(minAge);
count = Get<NetDataPeerBrTracker>().CountPeerBrs(minAge);
if (count != mNetDataPeerBrCount)
{
+2 -77
View File
@@ -60,6 +60,7 @@
#include <openthread/netdata.h>
#include <openthread/platform/border_routing.h>
#include "border_router/br_tracker.hpp"
#include "border_router/infra_if.hpp"
#include "common/array.hpp"
#include "common/callback.hpp"
@@ -96,6 +97,7 @@ class RoutingManager : public InstanceLocator
{
friend class ot::Notifier;
friend class ot::Instance;
friend class NetDataPeerBrTracker;
public:
typedef NetworkData::RoutePreference RoutePreference; ///< Route preference (high, medium, low).
@@ -570,36 +572,6 @@ public:
return mRxRaTracker.GetNextIfAddr(aIterator, aEntry);
}
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
/**
* Iterates over the peer BRs found in the Network Data.
*
* @param[in,out] aIterator An iterator.
* @param[out] aEntry A reference to the entry to populate.
*
* @retval kErrorNone Got the next peer BR info, @p aEntry is updated and @p aIterator is advanced.
* @retval kErrorNotFound No more PR beers in the list.
*/
Error GetNextPeerBrEntry(PrefixTableIterator &aIterator, PeerBrEntry &aEntry) const
{
return mNetDataPeerBrTracker.GetNext(aIterator, aEntry);
}
/**
* Returns the number of peer BRs found in the Network Data.
*
* The count does not include this device itself (when it itself is acting as a BR).
*
* @param[out] aMinAge Reference to an `uint32_t` to return the minimum age among all peer BRs.
* Age is represented as seconds since appearance of the BR entry in the Network Data.
*
* @returns The number of peer BRs.
*/
uint16_t CountPeerBrs(uint32_t &aMinAge) const { return mNetDataPeerBrTracker.CountPeerBrs(aMinAge); }
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
/**
@@ -952,49 +924,6 @@ private:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
class RxRaTracker;
class NetDataPeerBrTracker : public InstanceLocator
{
friend class RxRaTracker;
public:
explicit NetDataPeerBrTracker(Instance &aInstance);
uint16_t CountPeerBrs(uint32_t &aMinAge) const;
Error GetNext(PrefixTableIterator &aIterator, PeerBrEntry &aEntry) const;
void HandleNotifierEvents(Events aEvents);
private:
struct PeerBr : LinkedListEntry<PeerBr>, Heap::Allocatable<PeerBr>
{
struct Filter
{
Filter(const NetworkData::Rlocs &aRlocs)
: mExcludeRlocs(aRlocs)
{
}
const NetworkData::Rlocs &mExcludeRlocs;
};
uint32_t GetAge(uint32_t aUptime) const { return aUptime - mDiscoverTime; }
bool Matches(uint16_t aRloc16) const { return mRloc16 == aRloc16; }
bool Matches(const Filter &aFilter) const { return !aFilter.mExcludeRlocs.Contains(mRloc16); }
PeerBr *mNext;
uint16_t mRloc16;
uint32_t mDiscoverTime;
};
OwningList<PeerBr> mPeerBrs;
};
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
@@ -1909,10 +1838,6 @@ private:
OnLinkPrefixManager mOnLinkPrefixManager;
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
NetDataPeerBrTracker mNetDataPeerBrTracker;
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
MultiAilDetector mMultiAilDetector;
#endif
+3
View File
@@ -162,6 +162,9 @@ void Notifier::EmitEvents(void)
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
Get<BorderRouter::RoutingManager>().HandleNotifierEvents(events);
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
Get<BorderRouter::NetDataPeerBrTracker>().HandleNotifierEvents(events);
#endif
#endif
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
Get<Srp::Client>().HandleNotifierEvents(events);
+3
View File
@@ -264,6 +264,9 @@ Instance::Instance(void)
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
, mRoutingManager(*this)
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
, mNetDataPeerBrTracker(*this)
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE && OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_CLIENT_ENABLE
, mDhcp6PdClient(*this)
#endif
+6
View File
@@ -705,6 +705,9 @@ private:
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
BorderRouter::RoutingManager mRoutingManager;
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
BorderRouter::NetDataPeerBrTracker mNetDataPeerBrTracker;
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE && OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_CLIENT_ENABLE
BorderRouter::Dhcp6PdClient mDhcp6PdClient;
#endif
@@ -1082,6 +1085,9 @@ template <> inline Utils::Otns &Instance::Get(void) { return mOtns; }
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
template <> inline BorderRouter::RoutingManager &Instance::Get(void) { return mRoutingManager; }
template <> inline BorderRouter::InfraIf &Instance::Get(void) { return mRoutingManager.mInfraIf; }
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
template <> inline BorderRouter::NetDataPeerBrTracker &Instance::Get(void) { return mNetDataPeerBrTracker; }
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE && OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_CLIENT_ENABLE
template <> inline BorderRouter::Dhcp6PdClient &Instance::Get(void) { return mDhcp6PdClient; }
#endif