mirror of
https://github.com/espressif/openthread.git
synced 2026-07-30 15:47:46 +00:00
[history-tracker] record AIL router history (#11827)
This commit enhances the `HistoryTracker` to record information about routers discovered on the Adjacent Infrastructure Link (AIL). This feature is applicable when the device operates as a Border Router, providing a mechanism to monitor the history of changes to the discovered AIL routers for debugging and network analysis. The history tracker records events when an AIL router is added, removed, or when its tracked information changes. The recorded information includes: - The IPv6 address of the router - Default router status and its preference - RA flags: 'M' (Managed Addr), 'O' (Other), 'S' (SNAC Router) - Operational information: - Whether the router is a local entity (on same device) - Reachability status - Whether it is a peer Border Router on the same Thread mesh - The favored advertised on-link prefix by this router (if any) A new public API, `otHistoryTrackerIterateAilRoutersHistory()`, is added to iterate over the recorded AIL router history. A corresponding CLI command, `history ailrouters`, is also included to display this information.
This commit is contained in:
@@ -314,6 +314,49 @@ typedef struct otHistoryTrackerFavoredOnLinkPrefix
|
||||
bool mIsLocal : 1; ///< `true` if the prefix is the local on-link prefix; `false` otherwise.
|
||||
} otHistoryTrackerFavoredOnLinkPrefix;
|
||||
|
||||
/**
|
||||
* Defines events for discovered routers on an Adjacent Infrastructure Link (AIL).
|
||||
*
|
||||
* This applies when a device is acting as a Border Router, processing received Router Advertisements and tracking
|
||||
* AIL routers.
|
||||
*
|
||||
* `OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_CHANGED` is used if any of the properties in the `otHistoryTrackerAilRouter`
|
||||
* structure associated with a specific router changes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_ADDED = 0, ///< A new AIL router is discovered.
|
||||
OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_CHANGED = 1, ///< A property in the router's information has changed.
|
||||
OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_REMOVED = 2, ///< The AIL router is removed and no longer tracked.
|
||||
} otHistoryTrackerAilRouterEvent;
|
||||
|
||||
/**
|
||||
* Represents information about a discovered router on an Adjacent Infrastructure Link (AIL).
|
||||
*
|
||||
* This applies when a device is acting as a Border Router, processing received Router Advertisements and tracking
|
||||
* information about discovered AIL routers.
|
||||
*
|
||||
* `mProvidesDefaultRoute` indicates whether the router provides a default route. If it does, `mDefRoutePreference`
|
||||
* specifies the route preference.
|
||||
*
|
||||
* `mFavoredOnLinkPrefix` indicates the favored on-link prefix advertised by the router. If there is no on-link prefix,
|
||||
* this will be an empty prefix (i.e., its length will be zero).
|
||||
*/
|
||||
typedef struct otHistoryTrackerAilRouter
|
||||
{
|
||||
otHistoryTrackerAilRouterEvent mEvent; ///< The event type (e.g., added, changed, removed).
|
||||
int8_t mDefRoutePreference; ///< Def route preference.
|
||||
otIp6Address mAddress; ///< The IPv6 address of the AIL router.
|
||||
otIp6Prefix mFavoredOnLinkPrefix; ///< The favored on-link prefix, if any.
|
||||
bool mProvidesDefaultRoute : 1; ///< Whether the router provides a default route.
|
||||
bool mManagedAddressConfigFlag : 1; ///< The Managed Address Config flag (`M` flag).
|
||||
bool mOtherConfigFlag : 1; ///< The Other Config flag (`O` flag).
|
||||
bool mSnacRouterFlag : 1; ///< The SNAC Router flag (`S` flag).
|
||||
bool mIsLocalDevice : 1; ///< This router is the local device (this BR).
|
||||
bool mIsReachable : 1; ///< This router is reachable.
|
||||
bool mIsPeerBr : 1; ///< This router is (likely) a peer BR.
|
||||
} otHistoryTrackerAilRouter;
|
||||
|
||||
/**
|
||||
* Initializes an `otHistoryTrackerIterator`.
|
||||
*
|
||||
@@ -547,6 +590,24 @@ const otHistoryTrackerFavoredOnLinkPrefix *otHistoryTrackerIterateFavoredOnLinkP
|
||||
otHistoryTrackerIterator *aIterator,
|
||||
uint32_t *aEntryAge);
|
||||
|
||||
/**
|
||||
* Iterates over the entries in the BR AIL routers history list.
|
||||
*
|
||||
* Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE` (device acting as Border Router).
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in,out] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined.
|
||||
* @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL.
|
||||
* Age is provided as the duration (in milliseconds) from when the entry was recorded to
|
||||
* @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
|
||||
* older than the max age.
|
||||
*
|
||||
* @returns The `otHistoryTrackerAilRouter` entry or `NULL` if no more entries in the list.
|
||||
*/
|
||||
const otHistoryTrackerAilRouter *otHistoryTrackerIterateAilRoutersHistory(otInstance *aInstance,
|
||||
otHistoryTrackerIterator *aIterator,
|
||||
uint32_t *aEntryAge);
|
||||
|
||||
/**
|
||||
* Converts a given entry age to a human-readable string.
|
||||
*
|
||||
|
||||
@@ -52,7 +52,7 @@ extern "C" {
|
||||
*
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (527)
|
||||
#define OPENTHREAD_API_VERSION (528)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -11,6 +11,7 @@ The number of entries recorded for each history list is configurable through a s
|
||||
Usage : `history [command] ...`
|
||||
|
||||
- [help](#help)
|
||||
- [ailrouters](#ailrouters)
|
||||
- [dnssrpaddr](#dnssrpaddr)
|
||||
- [ipaddr](#ipaddr)
|
||||
- [ipmaddr](#ipmaddr)
|
||||
@@ -68,6 +69,55 @@ Done
|
||||
>
|
||||
```
|
||||
|
||||
### ailrouters
|
||||
|
||||
Usage `history ailrouters [list] [<num-entries>]`
|
||||
|
||||
Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE`.
|
||||
|
||||
Print the AIL routers history. Each entry provides:
|
||||
|
||||
- The event, possible values are `Added`, `Changed`, `Removed`.
|
||||
- The IPv6 address of the AIL router.
|
||||
- Flags
|
||||
- `R`: Indicates whether or not this router is reachable.
|
||||
- `M`: The Managed Address Config flag (from the received Router Advertisement (RA) header).
|
||||
- `O`: The Other Config flag (from the RA header).
|
||||
- `S`: The SNAC Router flag (from the RA header).
|
||||
- `L`: Indicates whether or not this router is the local device (this BR).
|
||||
- `P`: Indicates whether or not this router is a peer BR connected to same Thread mesh.
|
||||
- `D`: Indicates whether or not this router provides a default route.
|
||||
- The default route preference (`high`, `med`, `low`) if this router provides a default route. Otherwise `-`.
|
||||
- The favored on-link prefix advertised by this router if any. If none, `-` is shown.
|
||||
|
||||
```bash
|
||||
> history ailrouters
|
||||
| Age | Event | IPv6 Address |R|M|O|S|L|P|D|RtPrf |
|
||||
+----------------------+---------+------------------------------------------+-+-+-+-+-+-+-+------+
|
||||
| | Favored on-link prefix | | | | | | | | |
|
||||
+----------------------+----------------------------------------------------+-+-+-+-+-+-+-+------+
|
||||
| 00:01:35.107 | Changed | fe80:0:0:0:0:0:0:2 |N|N|N|Y|N|Y|N| |
|
||||
| | - | | | | | | | | |
|
||||
| 00:05:01.115 | Changed | fe80:0:0:0:0:0:0:2 |Y|N|N|Y|N|Y|N| |
|
||||
| | - | | | | | | | | |
|
||||
| 00:08:01.804 | Added | fe80:0:0:0:0:0:0:2 |Y|N|N|Y|N|Y|N| |
|
||||
| | fd99:4cdc:3b3d:56ef::/64 | | | | | | | | |
|
||||
Done
|
||||
```
|
||||
|
||||
Print the history as a list.
|
||||
|
||||
```bash
|
||||
>history ailrouters list
|
||||
00:01:35.161 -> event:Changed address:fe80:0:0:0:0:0:0:2 reachable:N M:N O:N S:Y local:N peer:Y def-route:N prf:
|
||||
favored-on-link-prefix:-
|
||||
00:05:01.169 -> event:Changed address:fe80:0:0:0:0:0:0:2 reachable:Y M:N O:N S:Y local:N peer:Y def-route:N prf:
|
||||
favored-on-link-prefix:-
|
||||
00:08:01.858 -> event:Added address:fe80:0:0:0:0:0:0:2 reachable:Y M:N O:N S:Y local:N peer:Y def-route:N prf:
|
||||
favored-on-link-prefix:fd99:4cdc:3b3d:56ef::/64
|
||||
Done
|
||||
```
|
||||
|
||||
### dnssrpaddr
|
||||
|
||||
Usage `history dnssrpaddr [list] [<num-entries>]`
|
||||
|
||||
@@ -1684,6 +1684,126 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @cli history ailrouters
|
||||
* @code
|
||||
* history ailrouters
|
||||
* | Age | Event | IPv6 Address |R|M|O|S|L|P|D|RtPrf |
|
||||
* +----------------------+---------+------------------------------------------+-+-+-+-+-+-+-+------+
|
||||
* | | Favored on-link prefix | | | | | | | | |
|
||||
* +----------------------+----------------------------------------------------+-+-+-+-+-+-+-+------+
|
||||
* | 00:01:35.107 | Changed | fe80:0:0:0:0:0:0:2 |N|N|N|Y|N|Y|N| |
|
||||
* | | - | | | | | | | | |
|
||||
* | 00:05:01.115 | Changed | fe80:0:0:0:0:0:0:2 |Y|N|N|Y|N|Y|N| |
|
||||
* | | - | | | | | | | | |
|
||||
* | 00:08:01.804 | Added | fe80:0:0:0:0:0:0:2 |Y|N|N|Y|N|Y|N| |
|
||||
* | | fd99:4cdc:3b3d:56ef::/64 | | | | | | | | |
|
||||
* Done
|
||||
* @endcode
|
||||
* @code
|
||||
* history ailrouters list
|
||||
* 00:01:35.161 -> event:Changed address:fe80:0:0:0:0:0:0:2 reachable:N M:N O:N S:Y local:N peer:Y def-route:N prf:
|
||||
* favored-on-link-prefix:-
|
||||
* 00:05:01.169 -> event:Changed address:fe80:0:0:0:0:0:0:2 reachable:Y M:N O:N S:Y local:N peer:Y def-route:N prf:
|
||||
* favored-on-link-prefix:-
|
||||
* 00:08:01.858 -> event:Added address:fe80:0:0:0:0:0:0:2 reachable:Y M:N O:N S:Y local:N peer:Y def-route:N prf:
|
||||
* favored-on-link-prefix:fd99:4cdc:3b3d:56ef::/64
|
||||
* Done
|
||||
* @endcode
|
||||
* @cparam history ailrouters [@ca{list}] [@ca{num-entries}]
|
||||
* * Use the `list` option to display the output in list format. Otherwise, the output is shown in table format.
|
||||
* * Use the `num-entries` option to limit the output to the number of most-recent entries specified. If this option
|
||||
* is not used, all stored entries are shown in the output.
|
||||
* @par
|
||||
* Displays the AIL routers history in table or list format.
|
||||
* @par
|
||||
* Each table or list entry provides:
|
||||
* * Age: Time elapsed since the command was issued, and given in the format:
|
||||
* `hours`:`minutes`:`seconds`.`milliseconds`
|
||||
* * The event, possible values are `Added`, `Changed`, `Removed`.
|
||||
* * The IPv6 address of the AIL router.
|
||||
* * Flags
|
||||
* * `R`: Indicates whether or not this router is reachable.
|
||||
* * `M`: The Managed Address Config flag (from the Router Advertisement (RA) header).
|
||||
* * `O`: The Other Config flag (from the RA header).
|
||||
* * `S`: The SNAC Router flag (from the RA header).
|
||||
* * `L`: Indicates whether or not this router is the local device (this BR).
|
||||
* * `P`: Indicates whether or not this router is a peer BR connected to same Thread mesh.
|
||||
* * `D`: Indicates whether or not this router provides a default route.
|
||||
* * The default route preference (`high`, `med`, `low`) if this router provides a default route, otherwise `-`.
|
||||
* * The favored on-link prefix advertised by this router if any. If none, `-` is shown.
|
||||
* @sa otHistoryTrackerIterateAilRoutersHistory
|
||||
*/
|
||||
template <> otError History::Process<Cmd("ailrouters")>(Arg aArgs[])
|
||||
{
|
||||
otError error;
|
||||
bool isList;
|
||||
uint16_t numEntries;
|
||||
otHistoryTrackerIterator iterator;
|
||||
const otHistoryTrackerAilRouter *info;
|
||||
uint32_t entryAge;
|
||||
char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
|
||||
char addrString[OT_IP6_ADDRESS_STRING_SIZE];
|
||||
char prefixString[OT_IP6_PREFIX_STRING_SIZE];
|
||||
|
||||
SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));
|
||||
|
||||
if (!isList)
|
||||
{
|
||||
static const char *const kTitles1[] = {"Age", "Event", "IPv6 Address", "R", "M", "O", "S", "L",
|
||||
"P", "D", "RtPrf"};
|
||||
static const uint8_t kColWidths1[] = {22, 9, 42, 1, 1, 1, 1, 1, 1, 1, 6};
|
||||
|
||||
static const char *const kTitles2[] = {"", "Favored on-link prefix", "", "", "", "", "", "", "", ""};
|
||||
static const uint8_t kColWidths2[] = {22, 52, 1, 1, 1, 1, 1, 1, 1, 6};
|
||||
|
||||
OutputTableHeader(kTitles1, kColWidths1);
|
||||
OutputTableHeader(kTitles2, kColWidths2);
|
||||
}
|
||||
|
||||
otHistoryTrackerInitIterator(&iterator);
|
||||
|
||||
for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
|
||||
{
|
||||
info = otHistoryTrackerIterateAilRoutersHistory(GetInstancePtr(), &iterator, &entryAge);
|
||||
VerifyOrExit(info != nullptr);
|
||||
|
||||
otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));
|
||||
|
||||
otIp6AddressToString(&info->mAddress, addrString, sizeof(addrString));
|
||||
otIp6PrefixToString(&info->mFavoredOnLinkPrefix, prefixString, sizeof(prefixString));
|
||||
|
||||
OutputLine(isList ? "%s -> event:%s address:%s reachable:%c M:%c O:%c S:%c local:%c peer:%c def-route:%c prf:%s"
|
||||
: "| %20s | %-7s | %-40s |%c|%c|%c|%c|%c|%c|%c| %4s |",
|
||||
ageString, AilRouterEventToString(info->mEvent), addrString, info->mIsReachable ? 'Y' : 'N',
|
||||
info->mManagedAddressConfigFlag ? 'Y' : 'N', info->mOtherConfigFlag ? 'Y' : 'N',
|
||||
info->mSnacRouterFlag ? 'Y' : 'N', info->mIsLocalDevice ? 'Y' : 'N', info->mIsPeerBr ? 'Y' : 'N',
|
||||
info->mProvidesDefaultRoute ? 'Y' : 'N',
|
||||
info->mProvidesDefaultRoute ? PreferenceToString(info->mDefRoutePreference) : "-");
|
||||
|
||||
OutputLine(isList ? " %sfavored-on-link-prefix:%s" : "| %20s | %-50s | | | | | | | | |", "",
|
||||
info->mFavoredOnLinkPrefix.mLength == 0 ? "-" : prefixString);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
const char *History::AilRouterEventToString(otHistoryTrackerAilRouterEvent aEvent)
|
||||
{
|
||||
static const char *const kAilRouterEventStrings[] = {
|
||||
"Added", /* (0) OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_ADDED */
|
||||
"Changed", /* (1) OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_CHANGED */
|
||||
"Removed", /* (2) OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_REMOVED */
|
||||
};
|
||||
|
||||
static_assert(OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_ADDED == 0, "AIL_ROUTER_EVENT_ADDED is incorrect");
|
||||
static_assert(OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_CHANGED == 1, "AIL_ROUTER_EVENT_CHANGED is incorrect");
|
||||
static_assert(OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_REMOVED == 2, "AIL_ROUTER_EVENT_REMOVED is incorrect");
|
||||
|
||||
return Stringify(aEvent, kAilRouterEventStrings, "--");
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
const char *History::DnsSrpAddrTypeToString(otHistoryTrackerDnsSrpAddrType aType)
|
||||
@@ -1706,6 +1826,9 @@ otError History::Process(Arg aArgs[])
|
||||
#define CmdEntry(aCommandString) {aCommandString, &History::Process<Cmd(aCommandString)>}
|
||||
|
||||
static constexpr Command kCommands[] = {
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
CmdEntry("ailrouters"),
|
||||
#endif
|
||||
CmdEntry("dnssrpaddr"), CmdEntry("ipaddr"), CmdEntry("ipmaddr"),
|
||||
CmdEntry("neighbor"), CmdEntry("netinfo"),
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
@@ -101,6 +101,7 @@ private:
|
||||
static const char *RadioTypeToString(const otHistoryTrackerMessageInfo &aInfo);
|
||||
static const char *MessageTypeToString(const otHistoryTrackerMessageInfo &aInfo);
|
||||
static const char *DnsSrpAddrTypeToString(otHistoryTrackerDnsSrpAddrType aType);
|
||||
static const char *AilRouterEventToString(otHistoryTrackerAilRouterEvent aEvent);
|
||||
};
|
||||
|
||||
} // namespace Cli
|
||||
|
||||
@@ -176,7 +176,17 @@ const otHistoryTrackerFavoredOnLinkPrefix *otHistoryTrackerIterateFavoredOnLinkP
|
||||
*aEntryAge);
|
||||
}
|
||||
|
||||
#endif
|
||||
const otHistoryTrackerAilRouter *otHistoryTrackerIterateAilRoutersHistory(otInstance *aInstance,
|
||||
otHistoryTrackerIterator *aIterator,
|
||||
uint32_t *aEntryAge)
|
||||
{
|
||||
AssertPointerIsNotNull(aEntryAge);
|
||||
|
||||
return AsCoreType(aInstance).Get<HistoryTracker::Local>().IterateAilRoutersHistory(AsCoreType(aIterator),
|
||||
*aEntryAge);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
void otHistoryTrackerEntryAgeToString(uint32_t aEntryAge, char *aBuffer, uint16_t aSize)
|
||||
{
|
||||
|
||||
@@ -1767,6 +1767,7 @@ void RoutingManager::RxRaTracker::Evaluate(void)
|
||||
NextFireTime entryExpireTime(now);
|
||||
NextFireTime staleTime(now);
|
||||
NextFireTime rdnsssAddrExpireTime(now);
|
||||
RouterList removedRouters;
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Remove expired entries associated with each router
|
||||
@@ -1788,7 +1789,16 @@ void RoutingManager::RxRaTracker::Evaluate(void)
|
||||
// Remove any router entry that no longer has any valid on-link
|
||||
// or route prefixes, RDNSS addresses, or other relevant flags set.
|
||||
|
||||
mRouters.RemoveAndFreeAllMatching(Router::EmptyChecker());
|
||||
mRouters.RemoveAllMatching(removedRouters, Router::EmptyChecker());
|
||||
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
for (Router &router : removedRouters)
|
||||
{
|
||||
ReportChangesToHistoryTracker(router, /* aRemoved */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
removedRouters.Free();
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Determine decision factors (favored on-link prefix, has any
|
||||
@@ -1891,6 +1901,17 @@ void RoutingManager::RxRaTracker::Evaluate(void)
|
||||
mExpirationTimer.FireAt(entryExpireTime);
|
||||
mStaleTimer.FireAt(staleTime);
|
||||
mRdnssAddrTimer.FireAt(rdnsssAddrExpireTime);
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Report any changes to history tracker.
|
||||
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
for (Router &router : mRouters)
|
||||
{
|
||||
ReportChangesToHistoryTracker(router, /* aRemoved */ false);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void RoutingManager::RxRaTracker::DetermineStaleTimeFor(const OnLinkPrefix &aPrefix, NextFireTime &aStaleTime)
|
||||
@@ -2202,6 +2223,62 @@ uint16_t RoutingManager::RxRaTracker::CountReachablePeerBrs(void) const
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
|
||||
void RoutingManager::RxRaTracker::ReportChangesToHistoryTracker(Router &aRouter, bool aRemoved)
|
||||
{
|
||||
// Report any changes in the `aRouter` to `HistoryTracker` only if
|
||||
// something has changed since the last recorded event.
|
||||
|
||||
Router::HistoryInfo oldInfo;
|
||||
HistoryTracker::AilRouter *entry;
|
||||
|
||||
if (aRemoved)
|
||||
{
|
||||
// If we have never recorded this router entry in the
|
||||
// `HistoryTracker`, there is no point in reporting its
|
||||
// removal. This can happen if we receive an RA from a router
|
||||
// with no useful information that we want to track. In this
|
||||
// case, the router entry is removed immediately during
|
||||
// `Evaluate()`.
|
||||
|
||||
VerifyOrExit(aRouter.mHistoryInfo.mHistoryRecorded);
|
||||
}
|
||||
else
|
||||
{
|
||||
oldInfo = aRouter.mHistoryInfo;
|
||||
}
|
||||
|
||||
aRouter.mHistoryInfo.DetermineFrom(aRouter);
|
||||
|
||||
VerifyOrExit(aRemoved || (aRouter.mHistoryInfo != oldInfo));
|
||||
|
||||
// Allocate and populate the new `HistoryTracker::AilRouter` entry.
|
||||
|
||||
entry = Get<HistoryTracker::Local>().RecordAilRouterEvent();
|
||||
VerifyOrExit(entry != nullptr);
|
||||
|
||||
entry->mEvent = aRemoved ? HistoryTracker::Local::kAilRouterRemoved
|
||||
: (oldInfo.mHistoryRecorded ? HistoryTracker::Local::kAilRouterChanged
|
||||
: HistoryTracker::Local::kAilRouterAdded);
|
||||
|
||||
entry->mAddress = aRouter.mAddress;
|
||||
entry->mDefRoutePreference = static_cast<int8_t>(aRouter.mHistoryInfo.mDefRoutePreference);
|
||||
entry->mFavoredOnLinkPrefix = aRouter.mHistoryInfo.mFavoredOnLinkPrefix;
|
||||
entry->mProvidesDefaultRoute = aRouter.mHistoryInfo.mProvidesDefaultRoute;
|
||||
entry->mManagedAddressConfigFlag = aRouter.mHistoryInfo.mManagedAddressConfigFlag;
|
||||
entry->mOtherConfigFlag = aRouter.mHistoryInfo.mOtherConfigFlag;
|
||||
entry->mSnacRouterFlag = aRouter.mHistoryInfo.mSnacRouterFlag;
|
||||
entry->mIsLocalDevice = aRouter.mHistoryInfo.mIsLocalDevice;
|
||||
entry->mIsReachable = aRouter.mHistoryInfo.mIsReachable;
|
||||
entry->mIsPeerBr = aRouter.mHistoryInfo.mIsPeerBr;
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// RxRaTracker::Iterator
|
||||
|
||||
@@ -2430,6 +2507,46 @@ void RoutingManager::RxRaTracker::Router::CopyInfoTo(RouterEntry &aEntry, TimeMi
|
||||
aEntry.mIsPeerBr = IsPeerBr();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// RxRaTracker::Router::HistoryInfo
|
||||
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
|
||||
void RoutingManager::RxRaTracker::Router::HistoryInfo::DetermineFrom(const Router &aRouter)
|
||||
{
|
||||
Ip6::Prefix emptyPrefix;
|
||||
const RoutePrefix *defRoute;
|
||||
|
||||
Clear();
|
||||
|
||||
mHistoryRecorded = true;
|
||||
mManagedAddressConfigFlag = aRouter.mManagedAddressConfigFlag;
|
||||
mOtherConfigFlag = aRouter.mOtherConfigFlag;
|
||||
mSnacRouterFlag = aRouter.mSnacRouterFlag;
|
||||
mIsLocalDevice = aRouter.mIsLocalDevice;
|
||||
mIsReachable = aRouter.IsReachable();
|
||||
mIsPeerBr = aRouter.IsPeerBr();
|
||||
|
||||
emptyPrefix.Clear();
|
||||
defRoute = aRouter.mRoutePrefixes.FindMatching(emptyPrefix);
|
||||
|
||||
if ((defRoute != nullptr) && (defRoute->GetValidLifetime() > 0))
|
||||
{
|
||||
mProvidesDefaultRoute = true;
|
||||
mDefRoutePreference = defRoute->GetRoutePreference();
|
||||
}
|
||||
|
||||
for (const OnLinkPrefix &onLinkPrefix : aRouter.mOnLinkPrefixes)
|
||||
{
|
||||
if (onLinkPrefix.IsFavoredOver(mFavoredOnLinkPrefix))
|
||||
{
|
||||
mFavoredOnLinkPrefix = onLinkPrefix.GetPrefix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// RxRaTracker::DecisionFactors
|
||||
|
||||
|
||||
@@ -1123,6 +1123,24 @@ private:
|
||||
{
|
||||
};
|
||||
|
||||
#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);
|
||||
@@ -1159,6 +1177,9 @@ private:
|
||||
bool mSnacRouterFlag : 1;
|
||||
bool mIsLocalDevice : 1;
|
||||
bool mAllEntriesDisregarded : 1;
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
HistoryInfo mHistoryInfo;
|
||||
#endif
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@@ -1270,6 +1291,10 @@ private:
|
||||
#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
|
||||
|
||||
@@ -204,6 +204,17 @@
|
||||
#define OPENTHREAD_CONFIG_HISTORY_TRACKER_ON_LINK_PREFIX_LIST_SIZE 16
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_HISTORY_TRACKER_AIL_ROUTER_LIST_SIZE
|
||||
*
|
||||
* Specifies the maximum number of entries in BR AIL Router history.
|
||||
*
|
||||
* Can be set to zero to configure History Tracker module not to collect any BR AIL Router info.
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_HISTORY_TRACKER_AIL_ROUTER_LIST_SIZE
|
||||
#define OPENTHREAD_CONFIG_HISTORY_TRACKER_AIL_ROUTER_LIST_SIZE 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -608,6 +608,8 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
AilRouter *Local::RecordAilRouterEvent(void) { return mAilRoutersHistory.AddNewEntry(); }
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
void Local::HandleNotifierEvents(Events aEvents)
|
||||
@@ -643,6 +645,7 @@ void Local::HandleTimer(void)
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
mFavoredOmrPrefixHistory.UpdateAgedEntries();
|
||||
mFavoredOnLinkPrefixHistory.UpdateAgedEntries();
|
||||
mAilRoutersHistory.UpdateAgedEntries();
|
||||
#endif
|
||||
mTimer.Start(kAgeCheckPeriod);
|
||||
}
|
||||
|
||||
@@ -113,6 +113,7 @@ typedef otHistoryTrackerBorderAgentEpskcEvent EpskcEvent; ///< Border Agent ePSK
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
typedef otHistoryTrackerFavoredOmrPrefix FavoredOmrPrefix; ///< Favored OMR Prefix
|
||||
typedef otHistoryTrackerFavoredOnLinkPrefix FavoredOnLinkPrefix; ///< Favored On-link Prefix
|
||||
typedef otHistoryTrackerAilRouter AilRouter; ///< An AIL router tracked when acting as BR
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -285,6 +286,11 @@ public:
|
||||
{
|
||||
return mFavoredOnLinkPrefixHistory.Iterate(aIterator, aEntryAge);
|
||||
}
|
||||
|
||||
const AilRouter *IterateAilRoutersHistory(Iterator &aIterator, uint32_t &aEntryAge) const
|
||||
{
|
||||
return mAilRoutersHistory.Iterate(aIterator, aEntryAge);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -322,6 +328,7 @@ private:
|
||||
static constexpr uint16_t kEpskcEventListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_EPSKC_EVENT_SIZE;
|
||||
static constexpr uint16_t kOmrPrefixListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_OMR_PREFIX_LIST_SIZE;
|
||||
static constexpr uint16_t kOnLinkPrefixListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_ON_LINK_PREFIX_LIST_SIZE;
|
||||
static constexpr uint16_t kAilRouterListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_AIL_ROUTER_LIST_SIZE;
|
||||
|
||||
typedef otHistoryTrackerAddressEvent AddressEvent;
|
||||
|
||||
@@ -357,6 +364,14 @@ private:
|
||||
|
||||
static constexpr uint16_t kAnycastServerPort = 53;
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
typedef otHistoryTrackerAilRouterEvent AilRouterEvent;
|
||||
|
||||
static constexpr AilRouterEvent kAilRouterAdded = OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_ADDED;
|
||||
static constexpr AilRouterEvent kAilRouterChanged = OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_CHANGED;
|
||||
static constexpr AilRouterEvent kAilRouterRemoved = OT_HISTORY_TRACKER_AIL_ROUTER_EVENT_REMOVED;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
#define DefineEpskcEvent(aName, aPublicEnumName) \
|
||||
static constexpr EpskcEvent kEpskc##aName = OT_HISTORY_TRACKER_BORDER_AGENT_EPSKC_EVENT_##aPublicEnumName
|
||||
@@ -500,10 +515,11 @@ private:
|
||||
void RecordEpskcEvent(EpskcEvent aEvent);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
void RecordFavoredOmrPrefix(const Ip6::Prefix &aPrefix,
|
||||
BorderRouter::RoutingManager::RoutePreference aPreference,
|
||||
bool aIsLocal);
|
||||
void RecordFavoredOnLinkPrefix(const Ip6::Prefix &aPrefix, bool aIsLocal);
|
||||
void RecordFavoredOmrPrefix(const Ip6::Prefix &aPrefix,
|
||||
BorderRouter::RoutingManager::RoutePreference aPreference,
|
||||
bool aIsLocal);
|
||||
void RecordFavoredOnLinkPrefix(const Ip6::Prefix &aPrefix, bool aIsLocal);
|
||||
AilRouter *RecordAilRouterEvent(void);
|
||||
#endif
|
||||
|
||||
using TrackerTimer = TimerMilliIn<Local, &Local::HandleTimer>;
|
||||
@@ -524,6 +540,7 @@ private:
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
EntryList<FavoredOmrPrefix, kOmrPrefixListSize> mFavoredOmrPrefixHistory;
|
||||
EntryList<FavoredOnLinkPrefix, kOnLinkPrefixListSize> mFavoredOnLinkPrefixHistory;
|
||||
EntryList<AilRouter, kAilRouterListSize> mAilRoutersHistory;
|
||||
#endif
|
||||
|
||||
TrackerTimer mTimer;
|
||||
|
||||
@@ -203,6 +203,18 @@ verify(len(services) == len(nodes_non_br))
|
||||
for host in hosts:
|
||||
verify(host['addresses'][0].startswith(br2_local_omr[:-4]))
|
||||
|
||||
# Check the history tracker `ailrouters` command
|
||||
|
||||
hist_table = br2.cli('history ailrouters')
|
||||
verify(len(hist_table) == 10)
|
||||
|
||||
hist_list = br2.cli('history ailrouters list')
|
||||
verify(len(hist_list) == 6)
|
||||
|
||||
verify(hist_list[0].strip().split(' -> ')[1].startswith('event:Changed '))
|
||||
verify(hist_list[2].strip().split(' -> ')[1].startswith('event:Changed '))
|
||||
verify(hist_list[4].strip().split(' -> ')[1].startswith('event:Added '))
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
# Test finished
|
||||
|
||||
|
||||
Reference in New Issue
Block a user