[mle] enhance neighbor aging & suppress Link Requests on FTD children (#10985)

This commit updates neighbor aging and recovery on FTD children. An
FTD child establishes links with neighboring routers to receive
multicast MPL (re)transmissions.

If the device is an FTD child and has more than `mChildRouterLinks`
neighbors, it uses a longer neighbor age (`kMaxNeighborAgeOnChild =
150s`) and removes the neighboring router upon expiration without
attempting to re-establish the link.

This differs from the existing behavior (which is still used when the
device is a router or an FTD child with `mChildRouterLinks` or fewer
neighbors), where a 100-second age is used, and the device attempts
to re-establish links upon expiration by sending Link Requests.

Link Requests from FTD children are suppressed when a neighboring
router becomes unavailable, and the child already has more than
`mChildRouterLinks` neighbors. This helps reduce unnecessary network
traffic on denser networks, especially when a router device is
powered off.
This commit is contained in:
Abtin Keshavarzian
2025-01-22 15:52:55 -08:00
committed by GitHub
parent 5d2d77e74e
commit e363faedee
2 changed files with 42 additions and 16 deletions
+40 -15
View File
@@ -1728,26 +1728,51 @@ void MleRouter::HandleTimeTick(void)
router.SetSelectableAsParent(false);
}
#endif
if (router.IsStateValid() && (age >= kMaxNeighborAge))
if (router.IsStateValid())
{
// Once router age expires, we send Link Request every
// time tick (second), up to max attempts. Each rx is
// randomly delayed (one second window). After the last
// attempt, we wait for the "Link Accept" timeout
// (~3 seconds), before the router is removed.
// Neighbor router age and link recovery
//
// If the device is an FTD child and has more than
// `mChildRouterLinks` neighbors, it uses a longer age,
// `kMaxNeighborAgeOnChild`, and removes the neighboring
// router upon expiration without trying to re-establish
// its link with it.
//
// Otherwise, if the device itself is a router, or it is an
// FTD child with `mChildRouterLinks` or fewer neighbors,
// it uses a shorter `kMaxNeighborAge`. Upon expiration, it
// tries to re-establish its link with the neighboring router.
if (!mDelayedSender.HasAnyScheduledLinkRequest(router) && !router.IsWaitingForLinkAccept())
if (IsChild() && (mRouterTable.GetNeighborCount(kLinkQuality1) > mChildRouterLinks))
{
LogInfo("No Adv from router 0x%04x - sending Link Request", router.GetRloc16());
router.SetLinkRequestAttemptsToMax();
if (age >= kMaxNeighborAgeOnChild)
{
LogInfo("No Adv from router 0x%04x - removing router", router.GetRloc16());
mDelayedSender.RemoveScheduledLinkRequest(router);
RemoveNeighbor(router);
continue;
}
}
if (router.HasRemainingLinkRequestAttempts())
else if (age >= kMaxNeighborAge)
{
router.DecrementLinkRequestAttempts();
mDelayedSender.ScheduleLinkRequest(
router, Random::NonCrypto::GetUint32InRange(0, kMaxLinkRequestDelayOnRouter));
// We send a Link Request every time tick (second), up to
// max attempts. Each transmission is randomly delayed
// (one-second window). After the last attempt, we wait for
// the "Link Accept" timeout (~3 seconds) before removing the
// neighboring router.
if (!mDelayedSender.HasAnyScheduledLinkRequest(router) && !router.IsWaitingForLinkAccept())
{
LogInfo("No Adv from router 0x%04x - sending Link Request", router.GetRloc16());
router.SetLinkRequestAttemptsToMax();
}
if (router.HasRemainingLinkRequestAttempts())
{
router.DecrementLinkRequestAttempts();
mDelayedSender.ScheduleLinkRequest(
router, Random::NonCrypto::GetUint32InRange(0, kMaxLinkRequestDelayOnRouter));
}
}
}
+2 -1
View File
@@ -503,7 +503,8 @@ private:
#endif
static constexpr uint32_t kMaxUnicastAdvertisementDelay = 1000; // Max random delay for unciast Adv tx
static constexpr uint32_t kMaxNeighborAge = 100000; // Max neighbor age (in msec)
static constexpr uint32_t kMaxNeighborAge = 100000; // Max neighbor age on router (in msec)
static constexpr uint32_t kMaxNeighborAgeOnChild = 150000; // Max neighbor age on FTD child (in msec)
static constexpr uint32_t kMaxLeaderToRouterTimeout = 90000; // (in msec)
static constexpr uint8_t kMinDowngradeNeighbors = 7;
static constexpr uint8_t kNetworkIdTimeout = 120; // (in sec)