From 792971d5545a8d5413152bcb0eedf38a81a73bf1 Mon Sep 17 00:00:00 2001 From: Tom Rebbert <109624508+trebbert-lutron@users.noreply.github.com> Date: Mon, 6 Oct 2025 16:07:56 -0600 Subject: [PATCH] [mle] remove all queued parent responses when starting to attach (#11996) When handling a parent request, a response is not sent if the device is not attached, or if it is attaching. However if the device starts the attachment process between queuing the parent response and actually sending it, the parent response will be sent from an invalid state. This commit causes all queued parent response messages to be removed when the device begins the attachment process, to avoid stale messages from being sent on the link. --- src/core/thread/mle.cpp | 14 ++++++++++++++ src/core/thread/mle.hpp | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 1ed8e04bc..a89f5c30c 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -3175,6 +3175,16 @@ void Mle::DelayedSender::ScheduleParentResponse(const ParentResponseInfo &aInfo, AddSchedule(kTypeParentResponse, destination, aDelay, &aInfo, sizeof(aInfo)); } +void Mle::DelayedSender::RemoveScheduledParentResponses(void) +{ + Ip6::Address destination; + + // The unspecified address will clear all parent responses to any destination + destination.Clear(); + + RemoveMatchingSchedules(kTypeParentResponse, destination); +} + void Mle::DelayedSender::ScheduleAdvertisement(const Ip6::Address &aDestination, uint32_t aDelay) { VerifyOrExit(!HasMatchingSchedule(kTypeAdvertisement, aDestination)); @@ -4426,6 +4436,10 @@ void Mle::Attacher::Attach(AttachMode aMode) VerifyOrExit(!IsAttaching()); +#if OPENTHREAD_FTD + Get().RemoveScheduledParentResponses(); +#endif + if (!Get().IsDetached()) { mAttachCounter = 0; diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 75af8864f..90a9feb3d 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -1046,6 +1046,12 @@ public: */ void ScheduleUnicastAdvertisementTo(const Router &aRouter); + /** + * Remove all parent responses that have been scheduled to be sent at a later time. Used when a precondition + * of the parent responses has changed. + */ + void RemoveScheduledParentResponses(void) { mDelayedSender.RemoveScheduledParentResponses(); } + #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE /** * Sets steering data out of band @@ -1698,6 +1704,7 @@ private: void ScheduleChildUpdateRequestToParent(uint32_t aDelay); #if OPENTHREAD_FTD void ScheduleParentResponse(const ParentResponseInfo &aInfo, uint32_t aDelay); + void RemoveScheduledParentResponses(void); void ScheduleAdvertisement(const Ip6::Address &aDestination, uint32_t aDelay); void ScheduleMulticastDataResponse(uint32_t aDelay); void ScheduleLinkRequest(const Router &aRouter, uint32_t aDelay);