Skip to content

Commit 283edc0

Browse files
authored
[routing-manager] introduce MultiAilDetector (openthread#11400)
This commit introduces the `MultiAilDetector` feature within the `RoutingManager`. This feature detects whether Border Routers(BRs) on the Thread mesh might be connected to different Adjacent Infrastructure Links (AILs). The feature can be enabled using the configuration option `OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE`. The detection mechanism operates as follows: The Routing Manager monitors the number of peer BRs listed in the Thread Network Data and compares this with the number of peer BRs discovered by processing received Router Advertisements (RAs) on its local AIL. If the count derived from Network Data consistently exceeds the count derived from RAs for a detection period of 5 minutes, the detector concludes that BRs are likely connected to different AILs. This triggers a detection state change, and a registered callback is invoked. To clear this state, a shorter window of 1 minute is used. Public APIs and corresponding CLI commands have been added to allow checking the current detection state and registering a callback for state change notifications. This commit also includes test coverage for the newly added feature.
1 parent 16bafad commit 283edc0

12 files changed

Lines changed: 565 additions & 1 deletion

File tree

include/openthread/border_routing.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,68 @@ otError otBorderRoutingGetNextPeerBrEntry(otInstance *
596596
*/
597597
uint16_t otBorderRoutingCountPeerBrs(otInstance *aInstance, uint32_t *aMinAge);
598598

599+
/**
600+
* A callback function pointer called when the multi-AIL detection state changes.
601+
*
602+
* This callback function is invoked by the OpenThread stack whenever the Routing Manager determines a change in
603+
* whether Border Routers on the Thread mesh might be connected to different Adjacent Infrastructure Links (AILs).
604+
*
605+
* See `otBorderRoutingIsMultiAilDetected()` for more details.
606+
*
607+
* @param[in] aDetected `TRUE` if multiple AILs are now detected, `FALSE` otherwise.
608+
* @param[in] aContext A pointer to arbitrary context information provided when the callback was registered
609+
* using `otBorderRoutingSetMultiAilCallback()`.
610+
*/
611+
typedef void (*otBorderRoutingMultiAilCallback)(bool aDetected, void *aContext);
612+
613+
/**
614+
* Gets the current detected state regarding multiple Adjacent Infrastructure Links (AILs).
615+
*
616+
* Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE`.
617+
*
618+
* It returns whether the Routing Manager currently believes that Border Routers (BRs) on the Thread mesh may be
619+
* connected to different AILs.
620+
*
621+
* The detection mechanism operates as follows: The Routing Manager monitors the number of peer BRs listed in the
622+
* Thread Network Data (see `otBorderRoutingCountPeerBrs()`) and compares this count with the number of peer BRs
623+
* discovered by processing received Router Advertisement (RA) messages on its connected AIL. If the count derived from
624+
* Network Data consistently exceeds the count derived from RAs for a detection duration of 10 minutes, it concludes
625+
* that BRs are likely connected to different AILs. To clear state a shorter window of 1 minute is used.
626+
*
627+
* The detection window of 10 minutes helps to avoid false positives due to transient changes. The Routing Manager uses
628+
* 200 seconds for reachability checks of peer BRs (sending Neighbor Solicitation). Stale Network Data entries are
629+
* also expected to age out within a few minutes. So a 10-minute detection time accommodates both cases.
630+
*
631+
* While generally effective, this detection mechanism may get less reliable in scenarios with a large number of
632+
* BRs, particularly exceeding ten. This is related to the "Network Data Publisher" mechanism, where BRs might refrain
633+
* from publishing their external route information in the Network Data to conserve its limited size, potentially
634+
* skewing the Network Data BR count.
635+
*
636+
* @param[in] aInstance A pointer to the OpenThread instance.
637+
*
638+
* @retval TRUE Has detected that BRs are likely connected to multiple AILs.
639+
* @retval FALSE Has not detected (or no longer detects) that BRs are connected to multiple AILs.
640+
*/
641+
bool otBorderRoutingIsMultiAilDetected(otInstance *aInstance);
642+
643+
/**
644+
* Sets a callback function to be notified of changes in the multi-AIL detection state.
645+
*
646+
* Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE`.
647+
*
648+
* Subsequent calls to this function will overwrite the previous callback setting. Using `NULL` for @p aCallback will
649+
* disable the callback.
650+
*
651+
* @param[in] aInstance A pointer to the OpenThread instance.
652+
* @param[in] aCallback A pointer to the function (`otBorderRoutingMultiAilCallback`) to be called
653+
* upon state changes, or `NULL` to unregister a previously set callback.
654+
* @param[in] aContext A pointer to application-specific context that will be passed back
655+
* in the `aCallback` function. This can be `NULL` if no context is needed.
656+
*/
657+
void otBorderRoutingSetMultiAilCallback(otInstance *aInstance,
658+
otBorderRoutingMultiAilCallback aCallback,
659+
void *aContext);
660+
599661
/**
600662
* Iterates over the Recursive DNS Server (RDNSS) address entries.
601663
*

include/openthread/instance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ extern "C" {
5252
*
5353
* @note This number versions both OpenThread platform and user APIs.
5454
*/
55-
#define OPENTHREAD_API_VERSION (498)
55+
#define OPENTHREAD_API_VERSION (499)
5656

5757
/**
5858
* @addtogroup api-instance

src/cli/README_BR.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Print BR command help menu.
3333
counters
3434
disable
3535
enable
36+
multiail
3637
omrconfig
3738
omrprefix
3839
onlinkprefix
@@ -118,6 +119,47 @@ RS TxFailed: 0
118119
Done
119120
```
120121

122+
### multiail
123+
124+
Usage : `br multiail`
125+
126+
Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE`.
127+
128+
Get the current detected state regarding multiple Adjacent Infrastructure Links (AILs) indicating whether the Routing Manager currently believes that Border Routers (BRs) on the Thread mesh may be connected to different AILs.
129+
130+
The detection mechanism operates as follows: The Routing Manager monitors the number of peer BRs listed in the Thread Network Data (see `br peers`) and compares this count with the number of peer BRs discovered by processing received Router Advertisement (RA) messages on its connected AIL. If the count derived from Network Data consistently exceeds the count derived from RAs for a detection duration of 10 minutes, it concludes that BRs are likely connected to different AILs. To clear the state a shorter window of 1 minute is used.
131+
132+
The detection window of 10 minutes helps to avoid false positives due to transient changes. The Routing Manager uses 200 seconds for reachability checks of peer BRs (sending Neighbor Solicitation). Stale Network Data entries are also expected to age out within a few minutes. So a 10-minute detection time accommodates both cases.
133+
134+
While generally effective, this detection mechanism may get less reliable in scenarios with a large number of BRs, particularly exceeding ten. This is related to the "Network Data Publisher" mechanism, where BRs might refrain from publishing their external route information in the Network Data to conserve its limited size, potentially skewing the Network Data BR count.
135+
136+
```bash
137+
> br multiail
138+
not detected
139+
Done
140+
141+
> br multiail
142+
detected
143+
Done
144+
```
145+
146+
Usage: `br multiail callback enable|disable`
147+
148+
Enable or disable callback to be notified of changes in the multi-AIL detection state.
149+
150+
```bash
151+
> br multiail callback enable
152+
Done
153+
154+
BR multi AIL callback: detected
155+
156+
> br multiail
157+
detected
158+
Done
159+
160+
BR multi AIL callback: cleared
161+
```
162+
121163
### omrconfig
122164

123165
Usage: `br omrconfig`

src/cli/cli_br.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,70 @@ template <> otError Br::Process<Cmd("state")>(Arg aArgs[])
143143
return error;
144144
}
145145

146+
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
147+
148+
template <> otError Br::Process<Cmd("multiail")>(Arg aArgs[])
149+
{
150+
otError error = OT_ERROR_NONE;
151+
152+
/**
153+
* @cli br multiail
154+
* @code
155+
* br multiail
156+
* not detected
157+
* @endcode
158+
* @par api_copy
159+
* #otBorderRoutingIsMultiAilDetected
160+
*/
161+
if (aArgs[0].IsEmpty())
162+
{
163+
OutputLine("%sdetected", otBorderRoutingIsMultiAilDetected(GetInstancePtr()) ? "" : "not ");
164+
}
165+
/**
166+
* @cli br multiail callback
167+
* @code
168+
* br multiail callback enable
169+
* Done
170+
* @endcode
171+
* @cparam br multiail callback @ca{enable|disable}
172+
* @par api_copy
173+
* #otBorderRoutingSetMultiAilCallback
174+
*/
175+
else if (aArgs[0] == "callback")
176+
{
177+
bool enable;
178+
otBorderRoutingMultiAilCallback callback = nullptr;
179+
180+
SuccessOrExit(error = ParseEnableOrDisable(aArgs[1], enable));
181+
182+
if (enable)
183+
{
184+
callback = &HandleMultiAilDetected;
185+
}
186+
187+
otBorderRoutingSetMultiAilCallback(GetInstancePtr(), callback, this);
188+
}
189+
else
190+
{
191+
error = OT_ERROR_INVALID_ARGS;
192+
}
193+
194+
exit:
195+
return error;
196+
}
197+
198+
void Br::HandleMultiAilDetected(bool aDetected, void *aContext)
199+
{
200+
static_cast<Br *>(aContext)->HandleMultiAilDetected(aDetected);
201+
}
202+
203+
void Br::HandleMultiAilDetected(bool aDetected)
204+
{
205+
OutputLine("BR multi AIL callback: %s", aDetected ? "detected" : "cleared");
206+
}
207+
208+
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
209+
146210
otError Br::ParsePrefixTypeArgs(Arg aArgs[], PrefixType &aFlags)
147211
{
148212
otError error = OT_ERROR_NONE;
@@ -1030,6 +1094,9 @@ otError Br::Process(Arg aArgs[])
10301094
CmdEntry("disable"),
10311095
CmdEntry("enable"),
10321096
CmdEntry("init"),
1097+
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
1098+
CmdEntry("multiail"),
1099+
#endif
10331100
#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
10341101
CmdEntry("nat64prefix"),
10351102
#endif

src/cli/cli_br.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ class Br : private Utils
9393

9494
otError ParsePrefixTypeArgs(Arg aArgs[], PrefixType &aFlags);
9595
void OutputRouterInfo(const otBorderRoutingRouterEntry &aEntry, RouterOutputMode aMode);
96+
97+
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
98+
static void HandleMultiAilDetected(bool aDetected, void *aContext);
99+
void HandleMultiAilDetected(bool aDetected);
100+
#endif
96101
};
97102

98103
} // namespace Cli

src/core/api/border_routing_api.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,22 @@ uint16_t otBorderRoutingCountPeerBrs(otInstance *aInstance, uint32_t *aMinAge)
257257

258258
#endif
259259

260+
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
261+
262+
bool otBorderRoutingIsMultiAilDetected(otInstance *aInstance)
263+
{
264+
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().IsMultiAilDetected();
265+
}
266+
267+
void otBorderRoutingSetMultiAilCallback(otInstance *aInstance,
268+
otBorderRoutingMultiAilCallback aCallback,
269+
void *aContext)
270+
{
271+
AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().SetMultiAilCallback(aCallback, aContext);
272+
}
273+
274+
#endif
275+
260276
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
261277

262278
void otBorderRoutingDhcp6PdSetEnabled(otInstance *aInstance, bool aEnabled)

0 commit comments

Comments
 (0)