[mle] track remaining Link Request attempts when re-establishing links (#11160)

This commit updates `Router` to track the number of remaining Link
Request attempts during link re-establishment (when no Advertisement
is received from a router, and the router is aged out). This helps
simplify the code managing link re-establishment.
This commit is contained in:
Abtin Keshavarzian
2025-01-15 14:29:02 -08:00
committed by GitHub
parent 09bdd1893e
commit f6cee7950d
5 changed files with 61 additions and 30 deletions
+9
View File
@@ -4614,6 +4614,15 @@ void Mle::DelayedSender::RemoveScheduledLinkRequest(const Router &aRouter)
RemoveMatchingSchedules(kTypeLinkRequest, destination);
}
bool Mle::DelayedSender::HasAnyScheduledLinkRequest(const Router &aRouter) const
{
Ip6::Address destination;
destination.SetToLinkLocalAddress(aRouter.GetExtAddress());
return HasMatchingSchedule(kTypeLinkRequest, destination);
}
void Mle::DelayedSender::ScheduleLinkAccept(const LinkAcceptInfo &aInfo, uint16_t aDelay)
{
Ip6::Address destination;
+2 -1
View File
@@ -1142,11 +1142,12 @@ private:
void ScheduleAdvertisement(const Ip6::Address &aDestination, uint16_t aDelay);
void ScheduleMulticastDataResponse(uint16_t aDelay);
void ScheduleLinkRequest(const Router &aRouter, uint16_t aDelay);
void RemoveScheduledLinkRequest(const Router &aRouter);
bool HasAnyScheduledLinkRequest(const Router &aRouter) const;
void ScheduleLinkAccept(const LinkAcceptInfo &aInfo, uint16_t aDelay);
void ScheduleDiscoveryResponse(const Ip6::Address &aDestination,
const DiscoveryResponseInfo &aInfo,
uint16_t aDelay);
void RemoveScheduledLinkRequest(const Router &aRouter);
#endif
void RemoveScheduledChildUpdateRequestToParent(void);
+22 -26
View File
@@ -1720,32 +1720,6 @@ void MleRouter::HandleTimeTick(void)
age = TimerMilli::GetNow() - router.GetLastHeard();
if (router.IsStateValid() && (age >= kMaxNeighborAge))
{
bool sendLinkRequest = true;
// Once router age expires, we send Link Request every
// time tick (second), up to `kMaxTxCount`. 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 (!router.IsWaitingForLinkAccept())
{
LogInfo("No Adv from router 0x%04x - sending Link Request", router.GetRloc16());
}
else
{
sendLinkRequest = (age < kMaxNeighborAge + kMaxTxCount * TimeMilli::kOneSecondInMsec);
}
if (sendLinkRequest)
{
mDelayedSender.ScheduleLinkRequest(
router, Random::NonCrypto::GetUint32InRange(0, kMaxLinkRequestDelayOnRouter));
}
}
#if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
router.DecrementParentReselectTimeout();
@@ -1755,6 +1729,28 @@ void MleRouter::HandleTimeTick(void)
}
#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())
{
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));
}
}
if (router.IsWaitingForLinkAccept() && (router.DecrementLinkAcceptTimeout() == 0))
{
LogInfo("Router 0x%04x - Link Accept timeout expired", router.GetRloc16());
+3 -1
View File
@@ -91,7 +91,9 @@ constexpr uint8_t kMaxRouteCost = 16; ///< Maximum path cost
#endif
constexpr uint8_t kMeshLocalPrefixContextId = 0; ///< Reserved 6lowpan context ID for Mesh Local Prefix
constexpr uint8_t kLinkAcceptTimeout = 3; ///< Timeout in seconds to rx Link Accept after Link Request tx.
constexpr uint8_t kLinkRequestAttempts = 3; ///< Number of Link Request attempts when re-establishing link.
constexpr uint8_t kLinkAcceptTimeout = 3; ///< Timeout in seconds to rx Link Accept after Link Request tx.
/**
* Specifies parent reselect timeout duration in seconds used on FTD child devices.
+25 -2
View File
@@ -118,6 +118,27 @@ public:
*/
uint8_t DecrementLinkAcceptTimeout(void) { return --mLinkAcceptTimeout; }
/**
* Sets the counter tracking the number of Link Request attempts during link re-establishment to its maximum value
* `Mle::kLinkRequestAttempts`.
*/
void SetLinkRequestAttemptsToMax(void) { mLinkRequestAttempts = Mle::kLinkRequestAttempts; }
/**
* Indicates whether there are remaining Link Request attempts (during link re-establishment).
*
* @retval TRUE There are remaining Link Request attempts.
* @retval FALSE There are no more Link Request attempts (the counter is zero).
*/
bool HasRemainingLinkRequestAttempts(void) const { return mLinkRequestAttempts > 0; }
/**
* Decrements the counter tracking the number of remaining Link Request attempts during link re-establishment.
*
* Caller MUST ensure the current counter is non-zero by checking `HasRemainingLinkRequestAttempts()`.
*/
void DecrementLinkRequestAttempts(void) { mLinkRequestAttempts--; }
/**
* Gets the router ID of the next hop to this router.
*
@@ -208,14 +229,16 @@ public:
private:
static_assert(Mle::kLinkAcceptTimeout < 4, "kLinkAcceptTimeout won't fit in mLinkAcceptTimeout (2-bit field)");
static_assert(Mle::kLinkRequestAttempts < 4, "kLinkRequestAttempts won't fit in mLinkRequestAttempts (2-bit field");
#if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
static_assert(Mle::kParentReselectTimeout <= (1U << 15) - 1,
"kParentReselectTimeout won't fit in mParentReselectTimeout (15-bit filed)");
#endif
uint8_t mNextHop; // The next hop towards this router
uint8_t mLinkAcceptTimeout : 2; // Timeout (in seconds) after sending Link Request waiting for Link Accept
uint8_t mNextHop; // The next hop towards this router
uint8_t mLinkRequestAttempts : 2; // Number of Link Request attempts
uint8_t mLinkAcceptTimeout : 2; // Timeout (in seconds) after sending Link Request waiting for Link Accept
#if !OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
uint8_t mCost : 4; // The cost to this router via neighbor router
#else