Skip to content

Commit

Permalink
[mle] enhance neighbor aging & suppress Link Requests on FTD children (
Browse files Browse the repository at this point in the history
…openthread#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.
  • Loading branch information
abtink authored Jan 22, 2025
1 parent 5d2d77e commit e363fae
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 18 deletions.
59 changes: 42 additions & 17 deletions src/core/thread/mle_router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1728,26 +1728,51 @@ void MleRouter::HandleTimeTick(void)
router.SetSelectableAsParent(false);
}
#endif

if (router.IsStateValid() && (age >= kMaxNeighborAge))
{
// 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.

if (!mDelayedSender.HasAnyScheduledLinkRequest(router) && !router.IsWaitingForLinkAccept())
if (router.IsStateValid())
{
// 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 (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));
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/core/thread/mle_router.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,8 @@ class MleRouter : public Mle
#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)
Expand Down

0 comments on commit e363fae

Please sign in to comment.