mirror of
https://github.com/espressif/openthread.git
synced 2026-06-06 05:24:51 +00:00
[routing-manager] track router age (#10453)
This commit adds a new mechanism in `RoutingManager` to track the duration since a router is first discovered. This information is now provided in `otBorderRoutingRouterEntry`, and the CLI `br routers` command is updated to include this information for each router. To enable tracking of longer durations, `Uptime` is used, which tracks milliseconds since the start of `ot::Instance` as a `uint64_t` value. `TimerMilli::GetNow()` is not suitable for this purpose because it utilizes `uint32_t` intervals, which would limit the maximum trackable time to roughly 49 days due to potential overflow.
This commit is contained in:
committed by
GitHub
parent
821f2415e0
commit
8d4119c914
@@ -85,6 +85,7 @@ typedef struct otBorderRoutingPrefixTableIterator
|
||||
{
|
||||
const void *mPtr1;
|
||||
const void *mPtr2;
|
||||
uint32_t mData0;
|
||||
uint32_t mData1;
|
||||
uint8_t mData2;
|
||||
uint8_t mData3;
|
||||
@@ -98,6 +99,7 @@ typedef struct otBorderRoutingRouterEntry
|
||||
{
|
||||
otIp6Address mAddress; ///< IPv6 address of the router.
|
||||
uint32_t mMsecSinceLastUpdate; ///< Milliseconds since last update (any message rx) from this router.
|
||||
uint32_t mAge; ///< The router's age in seconds (duration since its first discovery).
|
||||
bool mManagedAddressConfigFlag : 1; ///< The router's Managed Address Config flag (`M` flag).
|
||||
bool mOtherConfigFlag : 1; ///< The router's Other Config flag (`O` flag).
|
||||
bool mStubRouterFlag : 1; ///< The router's Stub Router flag.
|
||||
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (424)
|
||||
#define OPENTHREAD_API_VERSION (425)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -80,6 +80,7 @@ OT_BUILD_OPTIONS=(
|
||||
"-DOT_SRP_ADV_PROXY=ON"
|
||||
"-DOT_SRP_CLIENT=ON"
|
||||
"-DOT_SRP_SERVER=ON"
|
||||
"-DOT_UPTIME=ON"
|
||||
"-DOT_VENDOR_NAME=OpenThread"
|
||||
"-DOT_VENDOR_MODEL=Scan-build"
|
||||
"-DOT_VENDOR_SW_VERSION=OT"
|
||||
|
||||
@@ -353,10 +353,11 @@ Info per router:
|
||||
- Stub: Stub Router flag (indicates whether the router is a stub router)
|
||||
- Milliseconds since last received message from this router
|
||||
- Reachability flag: A router is marked as unreachable if it fails to respond to multiple Neighbor Solicitation probes.
|
||||
- Age: Duration interval since this router was first discovered. It is formatted as `{hh}:{mm}:{ss}` for hours, minutes, seconds, if the duration is less than 24 hours. If the duration is 24 hours or more, the format is `{dd}d.{hh}:{mm}:{ss}` for days, hours, minutes, seconds.
|
||||
- `(this BR)` is appended when the router is the local device itself.
|
||||
|
||||
```bash
|
||||
> br routers
|
||||
ff02:0:0:0:0:0:0:1 (M:0 O:0 Stub:1) ms-since-rx:1505 reachable:yes
|
||||
ff02:0:0:0:0:0:0:1 (M:0 O:0 Stub:1) ms-since-rx:1505 reachable:yes age:00:18:13
|
||||
Done
|
||||
```
|
||||
|
||||
+10
-3
@@ -518,7 +518,7 @@ exit:
|
||||
* @cli br routers
|
||||
* @code
|
||||
* br routers
|
||||
* ff02:0:0:0:0:0:0:1 (M:0 O:0 Stub:1) ms-since-rx:1505 reachable:yes
|
||||
* ff02:0:0:0:0:0:0:1 (M:0 O:0 Stub:1) ms-since-rx:1505 reachable:yes age:00:18:13
|
||||
* Done
|
||||
* @endcode
|
||||
* @par
|
||||
@@ -532,6 +532,9 @@ exit:
|
||||
* - Milliseconds since last received message from this router
|
||||
* - Reachability flag: A router is marked as unreachable if it fails to respond to multiple Neighbor Solicitation
|
||||
* probes.
|
||||
* - Age: Duration interval since this router was first discovered. It is formatted as `{hh}:{mm}:{ss}` for hours,
|
||||
* minutes, seconds, if the duration is less than 24 hours. If the duration is 24 hours or more, the format is
|
||||
* `{dd}d.{hh}:{mm}:{ss}` for days, hours, minutes, seconds.
|
||||
* - `(this BR)` is appended when the router is the local device itself.
|
||||
* @sa otBorderRoutingGetNextRouterEntry
|
||||
*/
|
||||
@@ -562,8 +565,12 @@ void Br::OutputRouterInfo(const otBorderRoutingRouterEntry &aEntry, RouterOutput
|
||||
|
||||
if (aMode == kLongVersion)
|
||||
{
|
||||
OutputFormat(" ms-since-rx:%lu reachable:%s", ToUlong(aEntry.mMsecSinceLastUpdate),
|
||||
aEntry.mIsReachable ? "yes" : "no");
|
||||
char ageString[OT_DURATION_STRING_SIZE];
|
||||
|
||||
otConvertDurationInSecondsToString(aEntry.mAge, ageString, sizeof(ageString));
|
||||
|
||||
OutputFormat(" ms-since-rx:%lu reachable:%s age:%s", ToUlong(aEntry.mMsecSinceLastUpdate),
|
||||
aEntry.mIsReachable ? "yes" : "no", ageString);
|
||||
|
||||
if (aEntry.mIsLocalDevice)
|
||||
{
|
||||
|
||||
@@ -1032,7 +1032,8 @@ void RoutingManager::RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert:
|
||||
|
||||
router = newEntry;
|
||||
router->Clear();
|
||||
router->mAddress = aSrcAddress;
|
||||
router->mDiscoverTime = Uptime::MsecToSec(Get<Uptime>().GetUptime());
|
||||
router->mAddress = aSrcAddress;
|
||||
|
||||
mRouters.Push(*newEntry);
|
||||
}
|
||||
@@ -1713,7 +1714,7 @@ void RoutingManager::RxRaTracker::SetHeaderFlagsOn(RouterAdvert::Header &aHeader
|
||||
|
||||
void RoutingManager::RxRaTracker::InitIterator(PrefixTableIterator &aIterator) const
|
||||
{
|
||||
static_cast<Iterator &>(aIterator).Init(mRouters.GetHead());
|
||||
static_cast<Iterator &>(aIterator).Init(mRouters.GetHead(), Uptime::MsecToSec(Get<Uptime>().GetUptime()));
|
||||
}
|
||||
|
||||
Error RoutingManager::RxRaTracker::GetNextEntry(PrefixTableIterator &aIterator, PrefixTableEntry &aEntry) const
|
||||
@@ -1725,7 +1726,7 @@ Error RoutingManager::RxRaTracker::GetNextEntry(PrefixTableIterator &aIterator,
|
||||
|
||||
SuccessOrExit(error = iterator.AdvanceToNextEntry());
|
||||
|
||||
iterator.GetRouter()->CopyInfoTo(aEntry.mRouter, iterator.GetInitTime());
|
||||
iterator.GetRouter()->CopyInfoTo(aEntry.mRouter, iterator.GetInitTime(), iterator.GetInitUptime());
|
||||
|
||||
switch (iterator.GetEntryType())
|
||||
{
|
||||
@@ -1749,7 +1750,7 @@ Error RoutingManager::RxRaTracker::GetNextRouter(PrefixTableIterator &aIterator,
|
||||
ClearAllBytes(aEntry);
|
||||
|
||||
SuccessOrExit(error = iterator.AdvanceToNextRouter(Iterator::kRouterIterator));
|
||||
iterator.GetRouter()->CopyInfoTo(aEntry, iterator.GetInitTime());
|
||||
iterator.GetRouter()->CopyInfoTo(aEntry, iterator.GetInitTime(), iterator.GetInitUptime());
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -1758,8 +1759,9 @@ exit:
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// RxRaTracker::Iterator
|
||||
|
||||
void RoutingManager::RxRaTracker::Iterator::Init(const Entry<Router> *aRoutersHead)
|
||||
void RoutingManager::RxRaTracker::Iterator::Init(const Entry<Router> *aRoutersHead, uint32_t aUptime)
|
||||
{
|
||||
SetInitUptime(aUptime);
|
||||
SetInitTime();
|
||||
SetType(kUnspecified);
|
||||
SetRouter(aRoutersHead);
|
||||
@@ -1914,10 +1916,11 @@ bool RoutingManager::RxRaTracker::Router::Matches(const EmptyChecker &aChecker)
|
||||
return !hasFlags && mOnLinkPrefixes.IsEmpty() && mRoutePrefixes.IsEmpty();
|
||||
}
|
||||
|
||||
void RoutingManager::RxRaTracker::Router::CopyInfoTo(RouterEntry &aEntry, TimeMilli aNow) const
|
||||
void RoutingManager::RxRaTracker::Router::CopyInfoTo(RouterEntry &aEntry, TimeMilli aNow, uint32_t aUptime) const
|
||||
{
|
||||
aEntry.mAddress = mAddress;
|
||||
aEntry.mMsecSinceLastUpdate = aNow - mLastUpdateTime;
|
||||
aEntry.mAge = aUptime - mDiscoverTime;
|
||||
aEntry.mManagedAddressConfigFlag = mManagedAddressConfigFlag;
|
||||
aEntry.mOtherConfigFlag = mOtherConfigFlag;
|
||||
aEntry.mStubRouterFlag = mStubRouterFlag;
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
#error "OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE is required for OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE."
|
||||
#endif
|
||||
|
||||
#if !OPENTHREAD_CONFIG_UPTIME_ENABLE
|
||||
#error "OPENTHREAD_CONFIG_UPTIME_ENABLE is required for OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE"
|
||||
#endif
|
||||
|
||||
#include <openthread/border_routing.h>
|
||||
#include <openthread/nat64.h>
|
||||
#include <openthread/netdata.h>
|
||||
@@ -837,14 +841,25 @@ private:
|
||||
void DetermineReachabilityTimeout(void);
|
||||
bool Matches(const Ip6::Address &aAddress) const { return aAddress == mAddress; }
|
||||
bool Matches(const EmptyChecker &aChecker);
|
||||
void CopyInfoTo(RouterEntry &aEntry, TimeMilli aNow) const;
|
||||
void CopyInfoTo(RouterEntry &aEntry, TimeMilli aNow, uint32_t aUptime) const;
|
||||
|
||||
using OnLinkPrefixList = OwningList<Entry<OnLinkPrefix>>;
|
||||
using RoutePrefixList = OwningList<Entry<RoutePrefix>>;
|
||||
|
||||
// `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;
|
||||
uint32_t mDiscoverTime;
|
||||
TimeMilli mLastUpdateTime;
|
||||
TimeMilli mTimeoutTime;
|
||||
uint8_t mNsProbeCount;
|
||||
@@ -873,9 +888,10 @@ private:
|
||||
kRoutePrefix,
|
||||
};
|
||||
|
||||
void Init(const Entry<Router> *aRoutersHead);
|
||||
void Init(const Entry<Router> *aRoutersHead, uint32_t aUptime);
|
||||
Error AdvanceToNextRouter(Type aType);
|
||||
Error AdvanceToNextEntry(void);
|
||||
uint32_t GetInitUptime(void) const { return mData0; }
|
||||
TimeMilli GetInitTime(void) const { return TimeMilli(mData1); }
|
||||
Type GetType(void) const { return static_cast<Type>(mData2); }
|
||||
const Entry<Router> *GetRouter(void) const { return static_cast<const Entry<Router> *>(mPtr1); }
|
||||
@@ -888,6 +904,7 @@ private:
|
||||
|
||||
private:
|
||||
void SetRouter(const Entry<Router> *aRouter) { mPtr1 = aRouter; }
|
||||
void SetInitUptime(uint32_t aUptime) { mData0 = aUptime; }
|
||||
void SetInitTime(void) { mData1 = TimerMilli::GetNow().GetValue(); }
|
||||
void SetEntry(const void *aEntry) { mPtr2 = aEntry; }
|
||||
bool HasEntry(void) const { return mPtr2 != nullptr; }
|
||||
|
||||
Reference in New Issue
Block a user