From cf21d5760a993ffedee7f6cd5983e03738b48de6 Mon Sep 17 00:00:00 2001 From: Simon Lin Date: Tue, 18 May 2021 13:22:53 +0800 Subject: [PATCH] [dua] fix Parent failed to send reregister for MTD Child on receiving `ST_DUA_REREGISTER` (#6637) This commit enhances DUA response handling for ST_DUA_REREGISTER: - Parent will stop registering DUA for MTD Child until the next Child Update Request. - MTD Child will re-register its DUA by Child Update Request or DUA.req. --- src/core/thread/dua_manager.cpp | 24 +++++++++++------------- src/core/thread/dua_manager.hpp | 7 +++---- src/core/thread/mle_router.cpp | 6 ++---- src/core/thread/mle_types.hpp | 7 ++++--- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/core/thread/dua_manager.cpp b/src/core/thread/dua_manager.cpp index d684fc2e3..b5657c18e 100644 --- a/src/core/thread/dua_manager.cpp +++ b/src/core/thread/dua_manager.cpp @@ -61,7 +61,6 @@ DuaManager::DuaManager(Instance &aInstance) #endif #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE , mChildIndexDuaRegistering(0) - , mRegisterCurrentChildIndex(false) #endif { mDelay.mValue = 0; @@ -98,7 +97,6 @@ void DuaManager::HandleDomainPrefixUpdate(BackboneRouter::Leader::DomainPrefixSt { mChildDuaMask.Clear(); mChildDuaRegisteredMask.Clear(); - mRegisterCurrentChildIndex = false; } #endif } @@ -476,7 +474,7 @@ void DuaManager::PerformNextRegistration(void) const Ip6::Address *duaPtr = nullptr; Child * child = nullptr; - if (!mRegisterCurrentChildIndex) + if (!mChildDuaMask.Get(mChildIndexDuaRegistering)) { for (Child &iter : Get().Iterate(Child::kInStateValid)) { @@ -623,8 +621,11 @@ Error DuaManager::ProcessDuaResponse(Coap::Message &aMessage) mDuaState = kRegistered; break; case ThreadStatusTlv::kDuaReRegister: - mDuaState = kToRegister; - mDelay.mFields.mCheckDelay = Mle::kImmediateReRegisterDelay; + if (Get().HasUnicastAddress(GetDomainUnicastAddress())) + { + RemoveDomainUnicastAddress(); + AddDomainUnicastAddress(); + } break; case ThreadStatusTlv::kDuaInvalid: // Domain Prefix might be invalid. @@ -649,8 +650,6 @@ Error DuaManager::ProcessDuaResponse(Coap::Message &aMessage) VerifyOrExit(child != nullptr, error = kErrorNotFound); VerifyOrExit(child->HasIp6Address(target), error = kErrorNotFound); - mRegisterCurrentChildIndex = false; - switch (status) { case ThreadStatusTlv::kDuaSuccess: @@ -658,8 +657,9 @@ Error DuaManager::ProcessDuaResponse(Coap::Message &aMessage) mChildDuaRegisteredMask.Set(mChildIndexDuaRegistering, true); break; case ThreadStatusTlv::kDuaReRegister: - mRegisterCurrentChildIndex = true; - mDelay.mFields.mCheckDelay = Mle::kImmediateReRegisterDelay; + // Parent stops registering for the Child's DUA until next Child Update Request + mChildDuaMask.Set(mChildIndexDuaRegistering, false); + mChildDuaRegisteredMask.Set(mChildIndexDuaRegistering, false); break; case ThreadStatusTlv::kDuaInvalid: case ThreadStatusTlv::kDuaDuplicate: @@ -738,16 +738,14 @@ void DuaManager::UpdateChildDomainUnicastAddress(const Child &aChild, Mle::Child #endif { IgnoreError(Get().AbortTransaction(&DuaManager::HandleDuaResponse, this)); - - // Reset mRegisterCurrentChildIndex properly - mRegisterCurrentChildIndex = mRegisterCurrentChildIndex && (aState == Mle::ChildDuaState::kRemoved); } mChildDuaMask.Set(childIndex, false); mChildDuaRegisteredMask.Set(childIndex, false); } - if (aState == Mle::ChildDuaState::kAdded || aState == Mle::ChildDuaState::kChanged) + if (aState == Mle::ChildDuaState::kAdded || aState == Mle::ChildDuaState::kChanged || + (aState == Mle::ChildDuaState::kUnchanged && !mChildDuaMask.Get(childIndex))) { if (mChildDuaMask == mChildDuaRegisteredMask) { diff --git a/src/core/thread/dua_manager.hpp b/src/core/thread/dua_manager.hpp index bc268fb86..d4b69b2af 100644 --- a/src/core/thread/dua_manager.hpp +++ b/src/core/thread/dua_manager.hpp @@ -257,10 +257,9 @@ private: // TODO: (DUA) may re-evaluate the alternative option of distributing the flags into the child table: // - Child class itself have some padding - may save some RAM // - Avoid cross reference between a bit-vector and the child entry - ChildMask mChildDuaMask; ///< Child Mask for child who registers DUA via Child Update Request. - ChildMask mChildDuaRegisteredMask; ///< Child Mask for child's DUA that was registered by the parent on behalf. - uint16_t mChildIndexDuaRegistering : 15; ///< Child Index of the DUA being registered. - bool mRegisterCurrentChildIndex : 1; ///< Re-register the child just registered. + ChildMask mChildDuaMask; ///< Child Mask for child who registers DUA via Child Update Request. + ChildMask mChildDuaRegisteredMask; ///< Child Mask for child's DUA that was registered by the parent on behalf. + uint16_t mChildIndexDuaRegistering; ///< Child Index of the DUA being registered. #endif }; diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 2b4453405..93204402e 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -2052,10 +2052,8 @@ Error MleRouter::UpdateChildAddresses(const Message &aMessage, uint16_t aOffset, if (oldDuaPtr != nullptr) { - if (oldDua != address) - { - Get().UpdateChildDomainUnicastAddress(aChild, ChildDuaState::kChanged); - } + Get().UpdateChildDomainUnicastAddress( + aChild, oldDua != address ? ChildDuaState::kChanged : ChildDuaState::kUnchanged); } else { diff --git a/src/core/thread/mle_types.hpp b/src/core/thread/mle_types.hpp index d887b2a86..229ebec37 100644 --- a/src/core/thread/mle_types.hpp +++ b/src/core/thread/mle_types.hpp @@ -296,9 +296,10 @@ static_assert(kTimeSinceLastTransactionMax * 1000 > kTimeSinceLastTransactionMax */ enum class ChildDuaState : uint8_t { - kAdded, ///< A new DUA registered by the Child via Address Registration. - kChanged, ///< A different DUA registered by the Child via Address Registration. - kRemoved, ///< DUA registered by the Child is removed and not in Address Registration. + kAdded, ///< A new DUA registered by the Child via Address Registration. + kChanged, ///< A different DUA registered by the Child via Address Registration. + kRemoved, ///< DUA registered by the Child is removed and not in Address Registration. + kUnchanged, ///< The Child registers the same DUA again. }; #endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2