From ca7dd8288beef3f28ec06da0bf83555599c982b8 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Fri, 31 May 2024 12:00:30 -0700 Subject: [PATCH] [mle] simplify signaling of DUA address change (#10296) This commit simplifies how `ProcessAddressRegistrationTlv()` signals DUA address changes. Signaling now occurs after all child addresses are registered, using a new `SignalDuaAddressEvent()` method. This method checks the old and new DUA addresses to determine the appropriate event to signal. Additionally, `Child::GetDomainUnicastAddress()` is updated to return an `Error` and copy the DUA address into a provided `Ip6::Address` reference. --- src/core/thread/child.cpp | 10 +++-- src/core/thread/child.hpp | 7 ++- src/core/thread/dua_manager.cpp | 12 ++--- src/core/thread/mle_router.cpp | 78 ++++++++++++++++----------------- src/core/thread/mle_router.hpp | 3 ++ 5 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/core/thread/child.cpp b/src/core/thread/child.cpp index 92a0b0566..d627e175b 100644 --- a/src/core/thread/child.cpp +++ b/src/core/thread/child.cpp @@ -251,9 +251,9 @@ exit: } #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE -const Ip6::Address *Child::GetDomainUnicastAddress(void) const +Error Child::GetDomainUnicastAddress(Ip6::Address &aAddress) const { - const Ip6::Address *addr = nullptr; + Error error = kErrorNotFound; for (const Ip6::Address &ip6Address : mIp6Address) { @@ -261,12 +261,14 @@ const Ip6::Address *Child::GetDomainUnicastAddress(void) const if (Get().IsDomainUnicast(ip6Address)) { - ExitNow(addr = &ip6Address); + aAddress = ip6Address; + error = kErrorNone; + ExitNow(); } } exit: - return addr; + return error; } #endif diff --git a/src/core/thread/child.hpp b/src/core/thread/child.hpp index 452cd4da8..d05fd094a 100644 --- a/src/core/thread/child.hpp +++ b/src/core/thread/child.hpp @@ -325,10 +325,13 @@ public: /** * Retrieves the Domain Unicast Address registered by the child. * - * @returns A pointer to Domain Unicast Address registered by the child if there is. + * @param[out] aAddress A reference to return the DUA address. + * + * @retval kErrorNone Successfully retrieved the DUA address, @p aAddress is updated. + * @retval kErrorNotFound Could not find any DUA address. * */ - const Ip6::Address *GetDomainUnicastAddress(void) const; + Error GetDomainUnicastAddress(Ip6::Address &aAddress) const; #endif /** diff --git a/src/core/thread/dua_manager.cpp b/src/core/thread/dua_manager.cpp index 9f98b0744..7e3ccc771 100644 --- a/src/core/thread/dua_manager.cpp +++ b/src/core/thread/dua_manager.cpp @@ -480,9 +480,8 @@ void DuaManager::PerformNextRegistration(void) #endif // OPENTHREAD_CONFIG_DUA_ENABLE { #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE - uint32_t lastTransactionTime; - const Ip6::Address *duaPtr = nullptr; - Child *child = nullptr; + uint32_t lastTransactionTime; + Child *child = nullptr; OT_ASSERT(mChildIndexDuaRegistering == Mle::kMaxChildren); @@ -497,12 +496,9 @@ void DuaManager::PerformNextRegistration(void) } } - child = Get().GetChildAtIndex(mChildIndexDuaRegistering); - duaPtr = child->GetDomainUnicastAddress(); + child = Get().GetChildAtIndex(mChildIndexDuaRegistering); + SuccessOrAssert(child->GetDomainUnicastAddress(dua)); - OT_ASSERT(duaPtr != nullptr); - - dua = *duaPtr; SuccessOrExit(error = Tlv::Append(*message, dua)); SuccessOrExit(error = Tlv::Append(*message, child->GetMeshLocalIid())); diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 40c728b9a..9a4c3dd03 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -1774,8 +1774,6 @@ Error MleRouter::ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild) uint8_t count = 0; uint8_t storedCount = 0; #if OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE - bool hasOldDua = false; - bool hasNewDua = false; Ip6::Address oldDua; #endif #if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE @@ -1788,14 +1786,9 @@ Error MleRouter::ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild) Tlv::FindTlvValueStartEndOffsets(aRxInfo.mMessage, Tlv::kAddressRegistration, offset, endOffset)); #if OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE + if (aChild.GetDomainUnicastAddress(oldDua) != kErrorNone) { - const Ip6::Address *duaAddress = aChild.GetDomainUnicastAddress(); - - if (duaAddress != nullptr) - { - oldDua = *duaAddress; - hasOldDua = true; - } + oldDua.Clear(); } #endif @@ -1888,34 +1881,6 @@ Error MleRouter::ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild) address.ToString().AsCString(), aChild.GetRloc16()); } -#if OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE - if (Get().IsDomainUnicast(address)) - { - if (error == kErrorNone) - { - DuaManager::ChildDuaAddressEvent event; - - hasNewDua = true; - - if (hasOldDua) - { - event = (oldDua != address) ? DuaManager::kAddressChanged : DuaManager::kAddressUnchanged; - } - else - { - event = DuaManager::kAddressAdded; - } - - Get().HandleChildDuaAddressEvent(aChild, event); - } - else - { - // It cannot store DUA, then assume child does not have one. - hasNewDua = false; - } - } -#endif - if (address.IsMulticast()) { continue; @@ -1945,10 +1910,7 @@ Error MleRouter::ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild) Get().RemoveEntryForAddress(address); } #if OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE - if (hasOldDua && !hasNewDua) - { - Get().HandleChildDuaAddressEvent(aChild, DuaManager::kAddressRemoved); - } + SignalDuaAddressEvent(aChild, oldDua); #endif #if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE @@ -1971,6 +1933,40 @@ exit: return error; } +#if OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE +void MleRouter::SignalDuaAddressEvent(const Child &aChild, const Ip6::Address &aOldDua) const +{ + DuaManager::ChildDuaAddressEvent event = DuaManager::kAddressUnchanged; + Ip6::Address newDua; + + if (aChild.GetDomainUnicastAddress(newDua) == kErrorNone) + { + if (aOldDua.IsUnspecified()) + { + event = DuaManager::kAddressAdded; + } + else if (aOldDua != newDua) + { + event = DuaManager::kAddressChanged; + } + } + else + { + // Child has no DUA address. If there was no old DUA, no need + // to signal. + + VerifyOrExit(!aOldDua.IsUnspecified()); + + event = DuaManager::kAddressRemoved; + } + + Get().HandleChildDuaAddressEvent(aChild, event); + +exit: + return; +} +#endif // OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE + void MleRouter::HandleChildIdRequest(RxInfo &aRxInfo) { Error error = kErrorNone; diff --git a/src/core/thread/mle_router.hpp b/src/core/thread/mle_router.hpp index 955674c42..e7d7b47c0 100644 --- a/src/core/thread/mle_router.hpp +++ b/src/core/thread/mle_router.hpp @@ -687,6 +687,9 @@ private: Error ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild); Error UpdateChildAddresses(const Message &aMessage, uint16_t aOffset, uint16_t aLength, Child &aChild); bool HasNeighborWithGoodLinkQuality(void) const; +#if OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE + void SignalDuaAddressEvent(const Child &aChild, const Ip6::Address &aOldDua) const; +#endif static void HandleAddressSolicitResponse(void *aContext, otMessage *aMessage,