[border-router] separate RxRaTracker into its own class (#12001)

This commit separates the `RxRaTracker` logic from `RoutingManager`
into its own class and source files.

Previously, `RxRaTracker` was a nested class within `RoutingManager`.
This change moves it to `src/core/border_router/rx_ra_tracker.hpp`
and `src/core/border_router/rx_ra_tracker.cpp`, making it a
standalone class within the `ot::BorderRouter` namespace.

This separation improves modularity and prepares for future changes
where `RxRaTracker` may operate independently of `RoutingManager`.
This commit is contained in:
Abtin Keshavarzian
2025-10-08 12:25:00 -07:00
committed by GitHub
parent c5971f7080
commit e18a5a9cd7
13 changed files with 2088 additions and 1917 deletions
+2
View File
@@ -388,6 +388,8 @@ openthread_core_files = [
"border_router/infra_if.hpp",
"border_router/routing_manager.cpp",
"border_router/routing_manager.hpp",
"border_router/rx_ra_tracker.cpp",
"border_router/rx_ra_tracker.hpp",
"coap/coap.cpp",
"coap/coap.hpp",
"coap/coap_message.cpp",
+1
View File
@@ -102,6 +102,7 @@ set(COMMON_SOURCES
border_router/dhcp6_pd_client.cpp
border_router/infra_if.cpp
border_router/routing_manager.cpp
border_router/rx_ra_tracker.cpp
coap/coap.cpp
coap/coap_message.cpp
coap/coap_secure.cpp
+6 -6
View File
@@ -208,7 +208,7 @@ void otBorderRoutingPrefixTableInitIterator(otInstance *aInstance, otBorderRouti
{
AssertPointerIsNotNull(aIterator);
AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().InitPrefixTableIterator(*aIterator);
AsCoreType(aInstance).Get<BorderRouter::RxRaTracker>().InitIterator(*aIterator);
}
otError otBorderRoutingGetNextPrefixTableEntry(otInstance *aInstance,
@@ -218,7 +218,7 @@ otError otBorderRoutingGetNextPrefixTableEntry(otInstance
AssertPointerIsNotNull(aIterator);
AssertPointerIsNotNull(aEntry);
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().GetNextPrefixTableEntry(*aIterator, *aEntry);
return AsCoreType(aInstance).Get<BorderRouter::RxRaTracker>().GetNextPrefixTableEntry(*aIterator, *aEntry);
}
otError otBorderRoutingGetNextRouterEntry(otInstance *aInstance,
@@ -228,7 +228,7 @@ otError otBorderRoutingGetNextRouterEntry(otInstance *aI
AssertPointerIsNotNull(aIterator);
AssertPointerIsNotNull(aEntry);
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().GetNextRouterEntry(*aIterator, *aEntry);
return AsCoreType(aInstance).Get<BorderRouter::RxRaTracker>().GetNextRouterEntry(*aIterator, *aEntry);
}
otError otBorderRoutingGetNextRdnssAddrEntry(otInstance *aInstance,
@@ -238,14 +238,14 @@ otError otBorderRoutingGetNextRdnssAddrEntry(otInstance
AssertPointerIsNotNull(aIterator);
AssertPointerIsNotNull(aEntry);
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().GetNextRdnssAddrEntry(*aIterator, *aEntry);
return AsCoreType(aInstance).Get<BorderRouter::RxRaTracker>().GetNextRdnssAddrEntry(*aIterator, *aEntry);
}
void otBorderRoutingSetRdnssAddrCallback(otInstance *aInstance,
otBorderRoutingRdnssAddrCallback aCallback,
void *aContext)
{
AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().SetRdnssAddrCallback(aCallback, aContext);
AsCoreType(aInstance).Get<BorderRouter::RxRaTracker>().SetRdnssAddrCallback(aCallback, aContext);
}
otError otBorderRoutingGetNextIfAddrEntry(otInstance *aInstance,
@@ -255,7 +255,7 @@ otError otBorderRoutingGetNextIfAddrEntry(otInstance *aI
AssertPointerIsNotNull(aIterator);
AssertPointerIsNotNull(aEntry);
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().GetNextIfAddrEntry(*aIterator, *aEntry);
return AsCoreType(aInstance).Get<BorderRouter::RxRaTracker>().GetNextIfAddrEntry(*aIterator, *aEntry);
}
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
+5 -4
View File
@@ -39,6 +39,7 @@
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
#include "border_router/br_types.hpp"
#include "common/log.hpp"
#include "net/ip6_address.hpp"
namespace ot {
@@ -85,10 +86,10 @@ void LogRecursiveDnsServerOption(const Ip6::Address &aAddress, uint32_t aLifetim
#else
void LogRaHeader(const RouterAdvert::Header &) {}
void LogPrefixInfoOption(const Ip6::Prefix &, uint32_t, uint32_t, PrefixInfoOption::Flags) {}
void LogRouteInfoOption(const Ip6::Prefix &, uint32_t, RoutePreference) {}
void LogRecursiveDnsServerOption(const Ip6::Address &, uint32_t) {}
inline void LogRaHeader(const RouterAdvert::Header &) {}
inline void LogPrefixInfoOption(const Ip6::Prefix &, uint32_t, uint32_t, PrefixInfoOption::Flags) {}
inline void LogRouteInfoOption(const Ip6::Prefix &, uint32_t, RoutePreference) {}
inline void LogRecursiveDnsServerOption(const Ip6::Address &, uint32_t) {}
#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
+1 -1
View File
@@ -88,7 +88,7 @@ uint16_t NetDataBrTracker::CountBrs(Filter aFilter, uint32_t &aMinAge) const
Error NetDataBrTracker::GetNext(Filter aFilter, TableIterator &aIterator, BorderRouterEntry &aEntry) const
{
using Iterator = RoutingManager::RxRaTracker::Iterator;
using Iterator = RxRaTracker::Iterator;
Iterator &iterator = static_cast<Iterator &>(aIterator);
Error error = kErrorNone;
File diff suppressed because it is too large Load Diff
+4 -459
View File
@@ -63,6 +63,7 @@
#include "border_router/br_tracker.hpp"
#include "border_router/br_types.hpp"
#include "border_router/infra_if.hpp"
#include "border_router/rx_ra_tracker.hpp"
#include "common/array.hpp"
#include "common/callback.hpp"
#include "common/equatable.hpp"
@@ -99,6 +100,7 @@ class RoutingManager : public InstanceLocator
friend class ot::Notifier;
friend class ot::Instance;
friend class NetDataBrTracker;
friend class RxRaTracker;
public:
/**
@@ -454,92 +456,6 @@ public:
*/
void HandleInfraIfStateChanged(void) { EvaluateState(); }
/**
* Initializes a `PrefixTableIterator`.
*
* An iterator can be initialized again to start from the beginning of the table.
*
* When iterating over entries in the table, to ensure the entry update times are consistent, they are given
* relative to the time the iterator was initialized.
*
* @param[out] aIterator The iterator to initialize.
*/
void InitPrefixTableIterator(PrefixTableIterator &aIterator) const { mRxRaTracker.InitIterator(aIterator); }
/**
* Iterates over entries in the discovered prefix table.
*
* @param[in,out] aIterator An iterator.
* @param[out] aEntry A reference to the entry to populate.
*
* @retval kErrorNone Got the next entry, @p aEntry is updated and @p aIterator is advanced.
* @retval kErrorNotFound No more entries in the table.
*/
Error GetNextPrefixTableEntry(PrefixTableIterator &aIterator, PrefixTableEntry &aEntry) const
{
return mRxRaTracker.GetNextEntry(aIterator, aEntry);
}
/**
* Iterates over discovered router entries on infrastructure link.
*
* @param[in,out] aIterator An iterator.
* @param[out] aEntry A reference to the entry to populate.
*
* @retval kErrorNone Got the next router info, @p aEntry is updated and @p aIterator is advanced.
* @retval kErrorNotFound No more routers.
*/
Error GetNextRouterEntry(PrefixTableIterator &aIterator, RouterEntry &aEntry) const
{
return mRxRaTracker.GetNextRouter(aIterator, aEntry);
}
/**
* Iterates over the discovered Recursive DNS Server (RDNSS) address entries.
*
* @param[in,out] aIterator An iterator.
* @param[out] aEntry A reference to the entry to populate.
*
* @retval kErrorNone Iterated to the next address entry, @p aEntry and @p aIterator are updated.
* @retval kErrorNotFound No more entries in the table.
* @retval kErrorInvalidArgs The @p aIterator is not valid (e.g. used to iterate over other entry types).
*/
Error GetNextRdnssAddrEntry(PrefixTableIterator &aIterator, RdnssAddrEntry &aEntry) const
{
return mRxRaTracker.GetNextRdnssAddr(aIterator, aEntry);
}
/**
* Sets the callback to be notified of changes to discovered Recursive DNS Server (RDNSS) address entries.
*
* A subsequent call to this method, replaces a previously set callback.
*
* @param[in] aCallback The callback function pointer. Can be `nullptr` if no callback is required.
* @param[in] aConext An arbitrary context information (used when invoking the callback).
*
*/
void SetRdnssAddrCallback(RdnssAddrCallback aCallback, void *aContext)
{
mRxRaTracker.SetRdnssCallback(aCallback, aContext);
}
/**
* Iterates over the infrastructure interface address entries.
*
* These are addresses used by the BR itself, for example, when sending Router Advertisements.
*
* @param[in,out] aIterator An iterator.
* @param[out] aEntry A reference to the entry to populate.
*
* @retval kErrorNone Iterated to the next address entry, @p aEntry and @p aIterator are updated.
* @retval kErrorNotFound No more entries in the table.
* @retval kErrorInvalidArgs The @p aIterator is not valid (e.g. used to iterate over other entry types).
*/
Error GetNextIfAddrEntry(PrefixTableIterator &aIterator, IfAddrEntry &aEntry) const
{
return mRxRaTracker.GetNextIfAddr(aIterator, aEntry);
}
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
/**
@@ -696,8 +612,6 @@ private:
static constexpr uint32_t kDefaultOnLinkPrefixLifetime = 1800;
static constexpr uint32_t kDefaultNat64PrefixLifetime = 300;
static constexpr uint32_t kStaleTime = 600; // 10 minutes.
// RA transmission constants (in milliseconds). Initially, three
// RAs are sent with a short interval of 16 seconds (± 2 seconds
// jitter). Subsequently, a longer, regular RA beacon interval of
@@ -728,13 +642,6 @@ private:
kAdvPrefixesFromNetData,
};
enum RouterAdvOrigin : uint8_t // Origin of a received Router Advert message.
{
kAnotherRouter, // From another router on infra-if.
kThisBrRoutingManager, // From this BR generated by `RoutingManager` itself.
kThisBrOtherEntity, // From this BR generated by another sw entity.
};
enum ScheduleMode : uint8_t // Used in `ScheduleRoutingPolicyEvaluation()`
{
kImmediately,
@@ -787,7 +694,7 @@ private:
bool mDetected;
uint16_t mNetDataPeerBrCount;
uint16_t mRxRaTrackerReachablePeerBrCount;
uint16_t mReachablePeerBrCount;
DetectTimer mTimer;
DetectCallback mCallback;
};
@@ -796,327 +703,6 @@ private:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void HandleRxRaTrackerSignalTask(void) { mRxRaTracker.HandleSignalTask(); }
void HandleRxRaTrackerRdnssAddrTask(void) { mRxRaTracker.HandleRdnssAddrTask(); }
void HandleRxRaTrackerExpirationTimer(void) { mRxRaTracker.HandleExpirationTimer(); }
void HandleRxRaTrackerStaleTimer(void) { mRxRaTracker.HandleStaleTimer(); }
void HandleRxRaTrackerRouterTimer(void) { mRxRaTracker.HandleRouterTimer(); }
void HandleRxRaTrackerRdnssAddrTimer(void) { mRxRaTracker.HandleRdnssAddrTimer(); }
class RxRaTracker : public InstanceLocator
{
// Processes received RA and NA messages tracking a table of active
// routers and their advertised on-link and route prefixes. Also
// manages prefix lifetimes and router reachability (sending NS probes
// as needed).
//
// When there is any change in the table (an entry is added, removed,
// or modified), it signals the change to `RoutingManager` by calling
// `HandleRaPrefixTableChanged()` callback. A `Tasklet` is used for
// signalling which ensures that if there are multiple changes within
// the same flow of execution, the callback is invoked after all the
// changes are processed.
friend class NetDataBrTracker;
public:
explicit RxRaTracker(Instance &aInstance);
void Start(void);
void Stop(void);
void SetRdnssCallback(RdnssAddrCallback aCallback, void *aContext) { mRdnssCallback.Set(aCallback, aContext); }
void ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaMessage,
const Ip6::Address &aSrcAddress,
RouterAdvOrigin aRaOrigin);
void ProcessNeighborAdvertMessage(const NeighborAdvertMessage &aNaMessage);
// Decision factors
bool ContainsDefaultOrNonUlaRoutePrefix(void) const { return mDecisionFactors.mHasNonUlaRoute; }
bool ContainsNonUlaOnLinkPrefix(void) const { return mDecisionFactors.mHasNonUlaOnLink; }
bool ContainsUlaOnLinkPrefix(void) const { return mDecisionFactors.mHasUlaOnLink; }
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
uint16_t GetReachablePeerBrCount(void) const { return mDecisionFactors.mReachablePeerBrCount; }
#endif
const Ip6::Prefix &GetFavoredOnLinkPrefix(void) const { return mDecisionFactors.mFavoredOnLinkPrefix; }
void SetHeaderFlagsOn(RouterAdvert::Header &aHeader) const;
const RouterAdvert::Header &GetLocalRaHeaderToMirror(void) const { return mLocalRaHeader; }
bool IsAddressOnLink(const Ip6::Address &aAddress) const;
bool IsAddressReachableThroughExplicitRoute(const Ip6::Address &aAddress) const;
// Iterating over discovered items
void InitIterator(PrefixTableIterator &aIterator) const;
Error GetNextEntry(PrefixTableIterator &aIterator, PrefixTableEntry &aEntry) const;
Error GetNextRouter(PrefixTableIterator &aIterator, RouterEntry &aEntry) const;
Error GetNextRdnssAddr(PrefixTableIterator &aIterator, RdnssAddrEntry &aEntry) const;
Error GetNextIfAddr(PrefixTableIterator &aIterator, IfAddrEntry &aEntry) const;
// Callbacks notifying of changes
void RemoveOrDeprecateOldEntries(TimeMilli aTimeThreshold);
void HandleLocalOnLinkPrefixChanged(void);
void HandleNetDataChange(void);
// Tasklet or timer callbacks
void HandleSignalTask(void);
void HandleRdnssAddrTask(void);
void HandleExpirationTimer(void);
void HandleStaleTimer(void);
void HandleRouterTimer(void);
void HandleRdnssAddrTimer(void);
private:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template <class Type>
struct Entry : public Type,
public LinkedListEntry<Entry<Type>>,
#if OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
public Heap::Allocatable<Entry<Type>>
#else
public InstanceLocatorInit
#endif
{
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
void Init(Instance &aInstance) { InstanceLocatorInit::Init(aInstance); }
void Free(void);
#endif
Entry<Type> *mNext;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
struct Router : public Clearable<Router>
{
// Reachability timeout intervals before starting Neighbor
// Solicitation (NS) probes. Generally 60 seconds (± 2
// seconds jitter) is used. For peer BRs a longer timeout
// of 200 seconds (3 min and 20 seconds) is used. This is
// selected to be longer than regular RA beacon interval
// of 3 minutes (± 15 seconds jitter).
static constexpr uint32_t kReachableInterval = OPENTHREAD_CONFIG_BORDER_ROUTING_ROUTER_ACTIVE_CHECK_TIMEOUT;
static constexpr uint32_t kPeerBrReachableInterval = Time::kOneSecondInMsec * 200;
static constexpr uint8_t kMaxNsProbes = 5; // Max number of NS probe attempts.
static constexpr uint32_t kNsProbeRetryInterval = 1000; // In msec. Time between NS probe attempts.
static constexpr uint32_t kNsProbeTimeout = 2000; // In msec. Max Wait time after last NS probe.
static constexpr uint32_t kJitter = 2000; // In msec. Jitter to randomize probe starts.
static_assert(kMaxNsProbes < 255, "kMaxNsProbes MUST not be 255");
struct EmptyChecker
{
};
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
struct HistoryInfo : public Equatable<HistoryInfo>, public Clearable<HistoryInfo>
{
void DetermineFrom(const Router &aRouter);
bool mHistoryRecorded : 1;
bool mManagedAddressConfigFlag : 1;
bool mOtherConfigFlag : 1;
bool mSnacRouterFlag : 1;
bool mIsLocalDevice : 1;
bool mIsReachable : 1;
bool mIsPeerBr : 1;
bool mProvidesDefaultRoute : 1;
RoutePreference mDefRoutePreference;
Ip6::Prefix mFavoredOnLinkPrefix;
};
#endif
bool IsReachable(void) const { return mNsProbeCount <= kMaxNsProbes; }
bool ShouldCheckReachability(void) const;
void ResetReachabilityState(void);
void DetermineReachabilityTimeout(void);
bool Matches(const Ip6::Address &aAddress) const { return aAddress == mAddress; }
bool Matches(const EmptyChecker &aChecker);
bool IsPeerBr(void) const;
void CopyInfoTo(RouterEntry &aEntry, TimeMilli aNow, uint32_t aUptime) const;
using OnLinkPrefixList = OwningList<Entry<OnLinkPrefix>>;
using RoutePrefixList = OwningList<Entry<RoutePrefix>>;
using RdnssAddressList = OwningList<Entry<RdnssAddress>>;
// `mDiscoverTime` tracks the initial discovery time of
// this router. To accommodate longer durations, the
// `Uptime` is used, as `TimeMilli` (which uses `uint32_t`
// intervals) would be limited to tracking ~ 49 days.
//
// `mLastUpdateTime` tracks the most recent time an RA or
// NA was received from this router. It is bounded due to
// the frequency of reachability checks, so we can safely
// use `TimeMilli` for it.
Ip6::Address mAddress;
OnLinkPrefixList mOnLinkPrefixes;
RoutePrefixList mRoutePrefixes;
RdnssAddressList mRdnssAddresses;
uint32_t mDiscoverTime;
TimeMilli mLastUpdateTime;
TimeMilli mTimeoutTime;
uint8_t mNsProbeCount;
bool mManagedAddressConfigFlag : 1;
bool mOtherConfigFlag : 1;
bool mSnacRouterFlag : 1;
bool mIsLocalDevice : 1;
bool mAllEntriesDisregarded : 1;
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
HistoryInfo mHistoryInfo;
#endif
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
struct Iterator : public PrefixTableIterator
{
enum Type : uint8_t
{
kUnspecified,
kRouterIterator,
kPrefixIterator,
kRdnssAddrIterator,
kIfAddrIterator,
kNetDataBrIterator, // Used by `NetDataPeerBrTracker`
};
enum PrefixType : uint8_t
{
kOnLinkPrefix,
kRoutePrefix,
};
void Init(const Entry<Router> *aRoutersHead, uint32_t aUptime);
Error AdvanceToNextRouter(Type aType);
Error AdvanceToNextPrefixEntry(void);
Error AdvanceToNextRdnssAddrEntry(void);
Error AdvanceToNextIfAddrEntry(const Entry<IfAddress> *aListHead);
uint32_t GetInitUptime(void) const { return mData0; }
void SetInitUptime(uint32_t aUptime) { mData0 = aUptime; }
TimeMilli GetInitTime(void) const { return TimeMilli(mData1); }
void SetInitTime(void) { mData1 = TimerMilli::GetNow().GetValue(); }
const Entry<Router> *GetRouter(void) const { return static_cast<const Entry<Router> *>(mPtr1); }
void SetRouter(const Entry<Router> *aRouter) { mPtr1 = aRouter; }
Type GetType(void) const { return static_cast<Type>(mData2); }
void SetType(Type aType) { mData2 = aType; }
const void *GetEntry(void) const { return mPtr2; }
void SetEntry(const void *aEntry) { mPtr2 = aEntry; }
bool HasEntry(void) const { return mPtr2 != nullptr; }
PrefixType GetPrefixType(void) const { return static_cast<PrefixType>(mData3); }
void SetPrefixType(PrefixType aType) { mData3 = aType; }
template <typename ObjectType> const Entry<ObjectType> *GetEntry(void) const
{
return static_cast<const Entry<ObjectType> *>(mPtr2);
}
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
static constexpr uint16_t kMaxRouters = OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_ROUTERS;
static constexpr uint16_t kMaxEntries = OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_PREFIXES;
union SharedEntry
{
SharedEntry(void) { mNext = nullptr; }
void SetNext(SharedEntry *aNext) { mNext = aNext; }
SharedEntry *GetNext(void) { return mNext; }
const SharedEntry *GetNext(void) const { return mNext; }
template <class Type> Entry<Type> &GetEntry(void);
SharedEntry *mNext;
Entry<OnLinkPrefix> mOnLinkEntry;
Entry<RoutePrefix> mRouteEntry;
Entry<RdnssAddress> mRdnssAddrEntry;
Entry<IfAddress> mIfAddrEntry;
};
#endif
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
struct DecisionFactors : public Clearable<DecisionFactors>, public Equatable<DecisionFactors>
{
DecisionFactors(void) { Clear(); }
bool HasFavoredOnLink(void) const { return (mFavoredOnLinkPrefix.GetLength() != 0); }
void UpdateFlagsFrom(const Router &aRouter);
void UpdateFrom(const OnLinkPrefix &aOnLinkPrefix);
void UpdateFrom(const RoutePrefix &aRoutePrefix);
Ip6::Prefix mFavoredOnLinkPrefix;
bool mHasNonUlaRoute : 1;
bool mHasNonUlaOnLink : 1;
bool mHasUlaOnLink : 1;
bool mHeaderManagedAddressConfigFlag : 1;
bool mHeaderOtherConfigFlag : 1;
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
uint16_t mReachablePeerBrCount;
#endif
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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 ProcessRecursiveDnsServerOption(const RecursiveDnsServerOption &aRdnss, Router &aRouter);
void UpdateIfAddresses(const Ip6::Address &aAddress);
void Evaluate(void);
void DetermineStaleTimeFor(const OnLinkPrefix &aPrefix, NextFireTime &aStaleTime);
void DetermineStaleTimeFor(const RoutePrefix &aPrefix, NextFireTime &aStaleTime);
void SendNeighborSolicitToRouter(const Router &aRouter);
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
uint16_t CountReachablePeerBrs(void) const;
#endif
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
void ReportChangesToHistoryTracker(Router &aRouter, bool aRemoved);
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
template <class Type> Entry<Type> *AllocateEntry(void) { return Entry<Type>::Allocate(); }
#else
template <class Type> Entry<Type> *AllocateEntry(void);
#endif
using SignalTask = TaskletIn<RoutingManager, &RoutingManager::HandleRxRaTrackerSignalTask>;
using RdnssAddrTask = TaskletIn<RoutingManager, &RoutingManager::HandleRxRaTrackerRdnssAddrTask>;
using ExpirationTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandleRxRaTrackerExpirationTimer>;
using StaleTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandleRxRaTrackerStaleTimer>;
using RouterTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandleRxRaTrackerRouterTimer>;
using RdnssAddrTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandleRxRaTrackerRdnssAddrTimer>;
using RouterList = OwningList<Entry<Router>>;
using IfAddressList = OwningList<Entry<IfAddress>>;
using RdnssCallback = Callback<RdnssAddrCallback>;
DecisionFactors mDecisionFactors;
RouterList mRouters;
IfAddressList mIfAddresses;
ExpirationTimer mExpirationTimer;
StaleTimer mStaleTimer;
RouterTimer mRouterTimer;
RdnssAddrTimer mRdnssAddrTimer;
SignalTask mSignalTask;
RdnssAddrTask mRdnssAddrTask;
RdnssCallback mRdnssCallback;
RouterAdvert::Header mLocalRaHeader;
TimeMilli mLocalRaHeaderUpdateTime;
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
Pool<SharedEntry, kMaxEntries> mEntryPool;
Pool<Entry<Router>, kMaxRouters> mRouterPool;
#endif
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class OmrPrefixManager : public InstanceLocator
{
public:
@@ -1576,7 +1162,7 @@ private:
static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix);
static const char *RouterAdvOriginToString(RouterAdvOrigin aRaOrigin);
static const char *RouterAdvOriginToString(RxRaTracker::RouterAdvOrigin aRaOrigin);
//------------------------------------------------------------------------------------------------------------------
// Variables
@@ -1608,8 +1194,6 @@ private:
MultiAilDetector mMultiAilDetector;
#endif
RxRaTracker mRxRaTracker;
RoutePublisher mRoutePublisher;
#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
@@ -1627,45 +1211,6 @@ private:
RoutingPolicyTimer mRoutingPolicyTimer;
};
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
//----------------------------------------------------------------------------------------------------------------------
// Template specializations and declarations
template <>
inline RoutingManager::RxRaTracker::Entry<OnLinkPrefix> &RoutingManager::RxRaTracker::SharedEntry::GetEntry(void)
{
return mOnLinkEntry;
}
template <>
inline RoutingManager::RxRaTracker::Entry<RoutePrefix> &RoutingManager::RxRaTracker::SharedEntry::GetEntry(void)
{
return mRouteEntry;
}
template <>
inline RoutingManager::RxRaTracker::Entry<RdnssAddress> &RoutingManager::RxRaTracker::SharedEntry::GetEntry(void)
{
return mRdnssAddrEntry;
}
template <>
inline RoutingManager::RxRaTracker::Entry<IfAddress> &RoutingManager::RxRaTracker::SharedEntry::GetEntry(void)
{
return mIfAddrEntry;
}
// Declare template (full) specializations for `Router` type.
template <>
RoutingManager::RxRaTracker::Entry<RoutingManager::RxRaTracker::Router> *RoutingManager::RxRaTracker::AllocateEntry(
void);
template <> void RoutingManager::RxRaTracker::Entry<RoutingManager::RxRaTracker::Router>::Free(void);
#endif // #if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
} // namespace BorderRouter
DefineMapEnum(otBorderRoutingState, BorderRouter::RoutingManager::State);
File diff suppressed because it is too large Load Diff
+572
View File
@@ -0,0 +1,572 @@
/*
* 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.
*/
/**
* @file
* This file includes definitions for the Received RA Tracker.
*/
#ifndef RX_RA_TRACKER_HPP_
#define RX_RA_TRACKER_HPP_
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
#include <openthread/border_routing.h>
#include "border_router/br_types.hpp"
#include "border_router/infra_if.hpp"
#include "common/callback.hpp"
#include "common/equatable.hpp"
#include "common/error.hpp"
#include "common/heap_allocatable.hpp"
#include "common/linked_list.hpp"
#include "common/locator.hpp"
#include "common/message.hpp"
#include "common/notifier.hpp"
#include "common/owning_list.hpp"
#include "common/pool.hpp"
#include "common/string.hpp"
#include "common/tasklet.hpp"
#include "common/timer.hpp"
#include "net/ip6.hpp"
#include "net/nd6.hpp"
namespace ot {
namespace BorderRouter {
class NetDataBrTracker;
/**
* Implements processing and tracking of received Router Advertisement (RA) and Neighbor Advertisement (NA) messages.
*
* This class processes received RA and NA messages, tracking a table of active routers on the infrastructure link and
* their advertised on-link and route prefixes and other information. It also manages prefix lifetimes and router
* reachability (sending Neighbor Solicitation probes as needed).
*/
class RxRaTracker : public InstanceLocator
{
friend class NetDataBrTracker;
public:
/**
* Represents the origin of a received Router Advertisement message.
*/
enum RouterAdvOrigin : uint8_t
{
kAnotherRouter, ///< From another router on the infrastructure interface.
kThisBrRoutingManager, ///< From this Border Router, generated by `RoutingManager` itself.
kThisBrOtherEntity, ///< From this Border Router, generated by another software entity.
};
/**
* Initializes the `RxRaTracker` object.
*
* @param[in] aInstance The OpenThread instance.
*/
explicit RxRaTracker(Instance &aInstance);
/**
* Starts the RA tracker.
*/
void Start(void);
/**
* Stops the RA tracker.
*/
void Stop(void);
/**
* Processes a received Router Advertisement (RA) message.
*
* @param[in] aRaMessage The received RA message.
* @param[in] aSrcAddress The source address of the RA message.
* @param[in] aRaOrigin The origin of the RA message.
*/
void ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaMessage,
const Ip6::Address &aSrcAddress,
RouterAdvOrigin aRaOrigin);
/**
* Processes a received Neighbor Advertisement (NA) message.
*
* @param[in] aNaMessage The received NA message.
*/
void ProcessNeighborAdvertMessage(const NeighborAdvertMessage &aNaMessage);
/**
* Initializes a `PrefixTableIterator`.
*
* An iterator can be initialized again to start from the beginning of the table.
*
* When iterating over entries in the table, to ensure the entry update times are consistent, they are given
* relative to the time the iterator was initialized.
*
* @param[out] aIterator The iterator to initialize.
*/
void InitIterator(PrefixTableIterator &aIterator) const;
/**
* Iterates over entries in the discovered prefix table.
*
* @param[in,out] aIterator An iterator.
* @param[out] aEntry A reference to the entry to populate.
*
* @retval kErrorNone Got the next entry, @p aEntry is updated and @p aIterator is advanced.
* @retval kErrorNotFound No more entries in the table.
*/
Error GetNextPrefixTableEntry(PrefixTableIterator &aIterator, PrefixTableEntry &aEntry) const;
/**
* Iterates over discovered router entries on infrastructure link.
*
* @param[in,out] aIterator An iterator.
* @param[out] aEntry A reference to the entry to populate.
*
* @retval kErrorNone Got the next router info, @p aEntry is updated and @p aIterator is advanced.
* @retval kErrorNotFound No more routers.
*/
Error GetNextRouterEntry(PrefixTableIterator &aIterator, RouterEntry &aEntry) const;
/**
* Iterates over the discovered Recursive DNS Server (RDNSS) address entries.
*
* @param[in,out] aIterator An iterator.
* @param[out] aEntry A reference to the entry to populate.
*
* @retval kErrorNone Iterated to the next address entry, @p aEntry and @p aIterator are updated.
* @retval kErrorNotFound No more entries in the table.
* @retval kErrorInvalidArgs The @p aIterator is not valid (e.g. used to iterate over other entry types).
*/
Error GetNextRdnssAddrEntry(PrefixTableIterator &aIterator, RdnssAddrEntry &aEntry) const;
/**
* Sets the callback to be notified of changes to discovered Recursive DNS Server (RDNSS) address entries.
*
* A subsequent call to this method, replaces a previously set callback.
*
* @param[in] aCallback The callback function pointer. Can be `nullptr` if no callback is required.
* @param[in] aConext An arbitrary context information (used when invoking the callback).
*
*/
void SetRdnssAddrCallback(RdnssAddrCallback aCallback, void *aContext) { mRdnssCallback.Set(aCallback, aContext); }
/**
* Iterates over the infrastructure interface address entries.
*
* These are addresses used by the BR itself, for example, when sending Router Advertisements.
*
* @param[in,out] aIterator An iterator.
* @param[out] aEntry A reference to the entry to populate.
*
* @retval kErrorNone Iterated to the next address entry, @p aEntry and @p aIterator are updated.
* @retval kErrorNotFound No more entries in the table.
* @retval kErrorInvalidArgs The @p aIterator is not valid (e.g. used to iterate over other entry types).
*/
Error GetNextIfAddrEntry(PrefixTableIterator &aIterator, IfAddrEntry &aEntry) const;
/**
* Indicates whether a discovered route prefix is a default route or a non-ULA prefix.
*
* @retval TRUE A default route or a non-ULA route prefix is discovered.
* @retval FALSE No default route or non-ULA route prefix is discovered.
*/
bool ContainsDefaultOrNonUlaRoutePrefix(void) const { return mDecisionFactors.mHasNonUlaRoute; }
/**
* Indicates whether a discovered on-link prefix is a non-ULA prefix.
*
* @retval TRUE A non-ULA on-link prefix is discovered.
* @retval FALSE No non-ULA on-link prefix is discovered.
*/
bool ContainsNonUlaOnLinkPrefix(void) const { return mDecisionFactors.mHasNonUlaOnLink; }
/**
* Indicates whether a discovered on-link prefix is a ULA prefix.
*
* @retval TRUE A ULA on-link prefix is discovered.
* @retval FALSE No ULA on-link prefix is discovered.
*/
bool ContainsUlaOnLinkPrefix(void) const { return mDecisionFactors.mHasUlaOnLink; }
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
/**
* Gets the number of reachable peer Border Routers.
*
* A peer BR is a BR on the same Thread mesh that is also connected to the same infrastructure link.
*
* @returns The number of reachable peer BRs.
*/
uint16_t GetReachablePeerBrCount(void) const { return mDecisionFactors.mReachablePeerBrCount; }
#endif
/**
* Gets the favored on-link prefix among all discovered on-link prefixes.
*
* @returns The favored on-link prefix.
*/
const Ip6::Prefix &GetFavoredOnLinkPrefix(void) const { return mDecisionFactors.mFavoredOnLinkPrefix; }
/**
* Sets the Managed Address Configuration (M) and Other Configuration (O) flags on a Router Advertisement header.
*
* The flags are set based on the currently discovered information from other routers on the infrastructure link.
*
* @param[out] aHeader The RA header to update.
*/
void SetHeaderFlagsOn(RouterAdvert::Header &aHeader) const;
/**
* Gets the last received Router Advertisement header from a local software entity.
*
* This can be used to mirror the RA flags in the RA messages sent by the Border Router.
*
* @returns The last received RA header from a local software entity.
*/
const RouterAdvert::Header &GetLocalRaHeaderToMirror(void) const { return mLocalRaHeader; }
/**
* Indicates whether an address is considered on-link on the infrastructure link.
*
* An address is considered on-link if it matches the local on-link prefix or any of the discovered on-link
* prefixes advertised by other routers.
*
* @param[in] aAddress The IPv6 address to check.
*
* @retval TRUE The address is on-link.
* @retval FALSE The address is not on-link.
*/
bool IsAddressOnLink(const Ip6::Address &aAddress) const;
/**
* Indicates whether an address is reachable through an explicit route on the infrastructure link.
*
* This method checks if the given address matches any discovered route prefix, excluding the default route.
*
* @param[in] aAddress The IPv6 address to check.
*
* @retval TRUE The address is reachable through an explicit route.
* @retval FALSE The address is not reachable through an explicit route.
*/
bool IsAddressReachableThroughExplicitRoute(const Ip6::Address &aAddress) const;
// Callbacks notifying of changes
void RemoveOrDeprecateOldEntries(TimeMilli aTimeThreshold);
void HandleLocalOnLinkPrefixChanged(void);
void HandleNetDataChange(void);
private:
static constexpr uint32_t kStaleTime = 600; // 10 minutes.
typedef Ip6::Nd::Option Option;
typedef Ip6::Nd::TxMessage TxMessage;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template <class Type>
struct Entry : public Type,
public LinkedListEntry<Entry<Type>>,
#if OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
public Heap::Allocatable<Entry<Type>>
#else
public InstanceLocatorInit
#endif
{
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
void Init(Instance &aInstance) { InstanceLocatorInit::Init(aInstance); }
void Free(void);
#endif
Entry<Type> *mNext;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
struct Router : public Clearable<Router>
{
// Reachability timeout intervals before starting Neighbor
// Solicitation (NS) probes. Generally 60 seconds (± 2
// seconds jitter) is used. For peer BRs a longer timeout
// of 200 seconds (3 min and 20 seconds) is used. This is
// selected to be longer than regular RA beacon interval
// of 3 minutes (± 15 seconds jitter).
static constexpr uint32_t kReachableInterval = OPENTHREAD_CONFIG_BORDER_ROUTING_ROUTER_ACTIVE_CHECK_TIMEOUT;
static constexpr uint32_t kPeerBrReachableInterval = Time::kOneSecondInMsec * 200;
static constexpr uint8_t kMaxNsProbes = 5; // Max number of NS probe attempts.
static constexpr uint32_t kNsProbeRetryInterval = 1000; // In msec. Time between NS probe attempts.
static constexpr uint32_t kNsProbeTimeout = 2000; // In msec. Max Wait time after last NS probe.
static constexpr uint32_t kJitter = 2000; // In msec. Jitter to randomize probe starts.
static_assert(kMaxNsProbes < 255, "kMaxNsProbes MUST not be 255");
struct EmptyChecker
{
};
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
struct HistoryInfo : public Equatable<HistoryInfo>, public Clearable<HistoryInfo>
{
void DetermineFrom(const Router &aRouter);
bool mHistoryRecorded : 1;
bool mManagedAddressConfigFlag : 1;
bool mOtherConfigFlag : 1;
bool mSnacRouterFlag : 1;
bool mIsLocalDevice : 1;
bool mIsReachable : 1;
bool mIsPeerBr : 1;
bool mProvidesDefaultRoute : 1;
RoutePreference mDefRoutePreference;
Ip6::Prefix mFavoredOnLinkPrefix;
};
#endif
bool IsReachable(void) const { return mNsProbeCount <= kMaxNsProbes; }
bool ShouldCheckReachability(void) const;
void ResetReachabilityState(void);
void DetermineReachabilityTimeout(void);
bool Matches(const Ip6::Address &aAddress) const { return aAddress == mAddress; }
bool Matches(const EmptyChecker &aChecker);
bool IsPeerBr(void) const;
void CopyInfoTo(RouterEntry &aEntry, TimeMilli aNow, uint32_t aUptime) const;
using OnLinkPrefixList = OwningList<Entry<OnLinkPrefix>>;
using RoutePrefixList = OwningList<Entry<RoutePrefix>>;
using RdnssAddressList = OwningList<Entry<RdnssAddress>>;
// `mDiscoverTime` tracks the initial discovery time of
// this router. To accommodate longer durations, the
// `Uptime` is used, as `TimeMilli` (which uses `uint32_t`
// intervals) would be limited to tracking ~ 49 days.
//
// `mLastUpdateTime` tracks the most recent time an RA or
// NA was received from this router. It is bounded due to
// the frequency of reachability checks, so we can safely
// use `TimeMilli` for it.
Ip6::Address mAddress;
OnLinkPrefixList mOnLinkPrefixes;
RoutePrefixList mRoutePrefixes;
RdnssAddressList mRdnssAddresses;
uint32_t mDiscoverTime;
TimeMilli mLastUpdateTime;
TimeMilli mTimeoutTime;
uint8_t mNsProbeCount;
bool mManagedAddressConfigFlag : 1;
bool mOtherConfigFlag : 1;
bool mSnacRouterFlag : 1;
bool mIsLocalDevice : 1;
bool mAllEntriesDisregarded : 1;
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
HistoryInfo mHistoryInfo;
#endif
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
struct Iterator : public PrefixTableIterator
{
enum Type : uint8_t
{
kUnspecified,
kRouterIterator,
kPrefixIterator,
kRdnssAddrIterator,
kIfAddrIterator,
kNetDataBrIterator, // Used by `NetDataPeerBrTracker`
};
enum PrefixType : uint8_t
{
kOnLinkPrefix,
kRoutePrefix,
};
void Init(const Entry<Router> *aRoutersHead, uint32_t aUptime);
Error AdvanceToNextRouter(Type aType);
Error AdvanceToNextPrefixEntry(void);
Error AdvanceToNextRdnssAddrEntry(void);
Error AdvanceToNextIfAddrEntry(const Entry<IfAddress> *aListHead);
uint32_t GetInitUptime(void) const { return mData0; }
void SetInitUptime(uint32_t aUptime) { mData0 = aUptime; }
TimeMilli GetInitTime(void) const { return TimeMilli(mData1); }
void SetInitTime(void) { mData1 = TimerMilli::GetNow().GetValue(); }
const Entry<Router> *GetRouter(void) const { return static_cast<const Entry<Router> *>(mPtr1); }
void SetRouter(const Entry<Router> *aRouter) { mPtr1 = aRouter; }
Type GetType(void) const { return static_cast<Type>(mData2); }
void SetType(Type aType) { mData2 = aType; }
const void *GetEntry(void) const { return mPtr2; }
void SetEntry(const void *aEntry) { mPtr2 = aEntry; }
bool HasEntry(void) const { return mPtr2 != nullptr; }
PrefixType GetPrefixType(void) const { return static_cast<PrefixType>(mData3); }
void SetPrefixType(PrefixType aType) { mData3 = aType; }
template <typename ObjectType> const Entry<ObjectType> *GetEntry(void) const
{
return static_cast<const Entry<ObjectType> *>(mPtr2);
}
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
static constexpr uint16_t kMaxRouters = OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_ROUTERS;
static constexpr uint16_t kMaxEntries = OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_PREFIXES;
union SharedEntry
{
SharedEntry(void) { mNext = nullptr; }
void SetNext(SharedEntry *aNext) { mNext = aNext; }
SharedEntry *GetNext(void) { return mNext; }
const SharedEntry *GetNext(void) const { return mNext; }
template <class Type> Entry<Type> &GetEntry(void);
SharedEntry *mNext;
Entry<OnLinkPrefix> mOnLinkEntry;
Entry<RoutePrefix> mRouteEntry;
Entry<RdnssAddress> mRdnssAddrEntry;
Entry<IfAddress> mIfAddrEntry;
};
#endif
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
struct DecisionFactors : public Clearable<DecisionFactors>, public Equatable<DecisionFactors>
{
DecisionFactors(void) { Clear(); }
bool HasFavoredOnLink(void) const { return (mFavoredOnLinkPrefix.GetLength() != 0); }
void UpdateFlagsFrom(const Router &aRouter);
void UpdateFrom(const OnLinkPrefix &aOnLinkPrefix);
void UpdateFrom(const RoutePrefix &aRoutePrefix);
Ip6::Prefix mFavoredOnLinkPrefix;
bool mHasNonUlaRoute : 1;
bool mHasNonUlaOnLink : 1;
bool mHasUlaOnLink : 1;
bool mHeaderManagedAddressConfigFlag : 1;
bool mHeaderOtherConfigFlag : 1;
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
uint16_t mReachablePeerBrCount;
#endif
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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 ProcessRecursiveDnsServerOption(const RecursiveDnsServerOption &aRdnss, Router &aRouter);
void UpdateIfAddresses(const Ip6::Address &aAddress);
void Evaluate(void);
void DetermineStaleTimeFor(const OnLinkPrefix &aPrefix, NextFireTime &aStaleTime);
void DetermineStaleTimeFor(const RoutePrefix &aPrefix, NextFireTime &aStaleTime);
void SendNeighborSolicitToRouter(const Router &aRouter);
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
uint16_t CountReachablePeerBrs(void) const;
#endif
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
void ReportChangesToHistoryTracker(Router &aRouter, bool aRemoved);
#endif
// Tasklet or timer callbacks
void HandleSignalTask(void);
void HandleRdnssAddrTask(void);
void HandleExpirationTimer(void);
void HandleStaleTimer(void);
void HandleRouterTimer(void);
void HandleRdnssAddrTimer(void);
#if OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
template <class Type> Entry<Type> *AllocateEntry(void) { return Entry<Type>::Allocate(); }
#else
template <class Type> Entry<Type> *AllocateEntry(void);
#endif
using SignalTask = TaskletIn<RxRaTracker, &RxRaTracker::HandleSignalTask>;
using RdnssAddrTask = TaskletIn<RxRaTracker, &RxRaTracker::HandleRdnssAddrTask>;
using ExpirationTimer = TimerMilliIn<RxRaTracker, &RxRaTracker::HandleExpirationTimer>;
using StaleTimer = TimerMilliIn<RxRaTracker, &RxRaTracker::HandleStaleTimer>;
using RouterTimer = TimerMilliIn<RxRaTracker, &RxRaTracker::HandleRouterTimer>;
using RdnssAddrTimer = TimerMilliIn<RxRaTracker, &RxRaTracker::HandleRdnssAddrTimer>;
using RouterList = OwningList<Entry<Router>>;
using IfAddressList = OwningList<Entry<IfAddress>>;
using RdnssCallback = Callback<RdnssAddrCallback>;
DecisionFactors mDecisionFactors;
RouterList mRouters;
IfAddressList mIfAddresses;
ExpirationTimer mExpirationTimer;
StaleTimer mStaleTimer;
RouterTimer mRouterTimer;
RdnssAddrTimer mRdnssAddrTimer;
SignalTask mSignalTask;
RdnssAddrTask mRdnssAddrTask;
RdnssCallback mRdnssCallback;
RouterAdvert::Header mLocalRaHeader;
TimeMilli mLocalRaHeaderUpdateTime;
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
Pool<SharedEntry, kMaxEntries> mEntryPool;
Pool<Entry<Router>, kMaxRouters> mRouterPool;
#endif
};
#if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
//----------------------------------------------------------------------------------------------------------------------
// Template specializations and declarations
template <> inline RxRaTracker::Entry<OnLinkPrefix> &RxRaTracker::SharedEntry::GetEntry(void) { return mOnLinkEntry; }
template <> inline RxRaTracker::Entry<RoutePrefix> &RxRaTracker::SharedEntry::GetEntry(void) { return mRouteEntry; }
template <> inline RxRaTracker::Entry<RdnssAddress> &RxRaTracker::SharedEntry::GetEntry(void)
{
return mRdnssAddrEntry;
}
template <> inline RxRaTracker::Entry<IfAddress> &RxRaTracker::SharedEntry::GetEntry(void) { return mIfAddrEntry; }
// Declare template (full) specializations for `Router` type.
template <> RxRaTracker::Entry<RxRaTracker::Router> *RxRaTracker::AllocateEntry(void);
template <> void RxRaTracker::Entry<RxRaTracker::Router>::Free(void);
#endif // #if !OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
} // namespace BorderRouter
} // namespace ot
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
#endif // RX_RA_TRACKER_HPP_
+1
View File
@@ -267,6 +267,7 @@ Instance::Instance(void)
, mAnnounceSender(*this)
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
, mRxRaTracker(*this)
, mRoutingManager(*this)
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
, mNetDataBrTracker(*this)
+3
View File
@@ -75,6 +75,7 @@
#include "backbone_router/bbr_manager.hpp"
#include "border_router/dhcp6_pd_client.hpp"
#include "border_router/routing_manager.hpp"
#include "border_router/rx_ra_tracker.hpp"
#include "coap/coap_secure.hpp"
#include "common/code_utils.hpp"
#include "common/notifier.hpp"
@@ -710,6 +711,7 @@ private:
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
BorderRouter::RxRaTracker mRxRaTracker;
BorderRouter::RoutingManager mRoutingManager;
#if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
BorderRouter::NetDataBrTracker mNetDataBrTracker;
@@ -1093,6 +1095,7 @@ template <> inline LinkMetrics::Subject &Instance::Get(void) { return mSubject;
#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
template <> inline BorderRouter::RxRaTracker &Instance::Get(void) { return mRxRaTracker; }
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
+2
View File
@@ -42,6 +42,7 @@
#include <openthread/platform/radio.h>
#include "border_router/routing_manager.hpp"
#include "border_router/rx_ra_tracker.hpp"
#include "common/as_core_type.hpp"
#include "common/clearable.hpp"
#include "common/locator.hpp"
@@ -158,6 +159,7 @@ class Local : public InstanceLocator, private NonCopyable
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
friend class ot::BorderRouter::RoutingManager;
friend class ot::BorderRouter::RxRaTracker;
#endif
public:
+7 -7
View File
@@ -1080,9 +1080,9 @@ void VerifyPrefixTable(const OnLinkPrefix *aOnLinkPrefixes,
Log("VerifyPrefixTable()");
sInstance->Get<BorderRouter::RoutingManager>().InitPrefixTableIterator(iter);
sInstance->Get<BorderRouter::RxRaTracker>().InitIterator(iter);
while (sInstance->Get<BorderRouter::RoutingManager>().GetNextPrefixTableEntry(iter, entry) == kErrorNone)
while (sInstance->Get<BorderRouter::RxRaTracker>().GetNextPrefixTableEntry(iter, entry) == kErrorNone)
{
bool didFind = false;
@@ -1168,9 +1168,9 @@ void VerifyRdnssAddressTable(const RdnssAddress *aRdnssAddresses, uint16_t aNumA
Log("VerifyRdnssAddressTable()");
sInstance->Get<BorderRouter::RoutingManager>().InitPrefixTableIterator(iter);
sInstance->Get<BorderRouter::RxRaTracker>().InitIterator(iter);
while (sInstance->Get<BorderRouter::RoutingManager>().GetNextRdnssAddrEntry(iter, entry) == kErrorNone)
while (sInstance->Get<BorderRouter::RxRaTracker>().GetNextRdnssAddrEntry(iter, entry) == kErrorNone)
{
bool didFind = false;
@@ -1235,9 +1235,9 @@ void VerifyDiscoveredRouters(const InfraRouter *aRouters, uint16_t aNumRouters)
Log("VerifyDiscoveredRouters()");
sInstance->Get<BorderRouter::RoutingManager>().InitPrefixTableIterator(iter);
sInstance->Get<BorderRouter::RxRaTracker>().InitIterator(iter);
while (sInstance->Get<BorderRouter::RoutingManager>().GetNextRouterEntry(iter, entry) == kErrorNone)
while (sInstance->Get<BorderRouter::RxRaTracker>().GetNextRouterEntry(iter, entry) == kErrorNone)
{
bool didFind = false;
@@ -4977,7 +4977,7 @@ void TestRdnss(void)
// Set the RDNSS callback on Routing Manager
rdnssCallbackCalled = false;
sInstance->Get<BorderRouter::RoutingManager>().SetRdnssAddrCallback(HandleRdnssChanged, &rdnssCallbackCalled);
sInstance->Get<BorderRouter::RxRaTracker>().SetRdnssAddrCallback(HandleRdnssChanged, &rdnssCallbackCalled);
VerifyOrQuit(!rdnssCallbackCalled);