From db7fd231f0f2b5b15ea44f7c873550ace30ab77f Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Thu, 23 Apr 2026 08:02:05 +0200 Subject: [PATCH] [thread-tlv] simplify `Ip6AddressesTlv` implementation (#12965) This commit simplifies the `Ip6AddressesTlv` by removing the dedicated class definition and instead defining it as a `TlvInfo` for the `ThreadTlv::kIp6Addresses` type. The usage of `Ip6AddressesTlv` is updated in `BbrManager`, `MlrManager`, and related tests to use `Tlv::StartTlv()` and `Tlv::EndTlv()` when appending the TLV to messages. --- src/core/backbone_router/bbr_manager.cpp | 17 +++++------ src/core/thread/mlr_manager.cpp | 15 +++++----- src/core/thread/thread_tlvs.hpp | 37 ++---------------------- tests/nexus/test_1_2_BBR_TC_2.cpp | 13 ++++----- 4 files changed, 24 insertions(+), 58 deletions(-) diff --git a/src/core/backbone_router/bbr_manager.cpp b/src/core/backbone_router/bbr_manager.cpp index 515b392d1..98b504ef7 100644 --- a/src/core/backbone_router/bbr_manager.cpp +++ b/src/core/backbone_router/bbr_manager.cpp @@ -153,7 +153,7 @@ void Manager::HandleMulticastListenerRegistration(const Coap::Msg &aMsg) VerifyOrExit(isPrimary, status = kMlrBbrNotPrimary); - VerifyOrExit(Tlv::FindTlvValueOffsetRange(aMsg.mMessage, Ip6AddressesTlv::kIp6Addresses, offsetRange) == kErrorNone, + VerifyOrExit(Tlv::FindTlvValueOffsetRange(aMsg.mMessage, Ip6AddressesTlv::kType, offsetRange) == kErrorNone, error = kErrorParse); VerifyOrExit(offsetRange.GetLength() % sizeof(Ip6::Address) == 0, status = kMlrGeneralFailure); VerifyOrExit(offsetRange.GetLength() / sizeof(Ip6::Address) <= Ip6AddressesTlv::kMaxAddresses, @@ -296,16 +296,16 @@ void Manager::SendMulticastListenerRegistrationResponse(const Coap::Msg &aMsg, if (aFailedAddressNum > 0) { - Ip6AddressesTlv addressesTlv; + Tlv::Bookmark tlvBookmark; - addressesTlv.Init(); - addressesTlv.SetLength(sizeof(Ip6::Address) * aFailedAddressNum); - SuccessOrExit(error = message->Append(addressesTlv)); + SuccessOrExit(error = Tlv::StartTlv(*message, Ip6AddressesTlv::kType, tlvBookmark)); for (uint8_t i = 0; i < aFailedAddressNum; i++) { SuccessOrExit(error = message->Append(aFailedAddresses[i])); } + + SuccessOrExit(error = Tlv::EndTlv(*message, tlvBookmark)); } SuccessOrExit(error = Get().SendMessage(*message, aMsg.mMessageInfo)); @@ -322,7 +322,7 @@ void Manager::SendBackboneMulticastListenerRegistration(const Ip6::Address *aAdd Error error = kErrorNone; Coap::Message *message = nullptr; Ip6::MessageInfo messageInfo; - Ip6AddressesTlv addressesTlv; + Tlv::Bookmark tlvBookmark; BackboneTmfAgent &backboneTmf = Get(); OT_ASSERT(aAddressNum >= Ip6AddressesTlv::kMinAddresses && aAddressNum <= Ip6AddressesTlv::kMaxAddresses); @@ -330,10 +330,9 @@ void Manager::SendBackboneMulticastListenerRegistration(const Ip6::Address *aAdd message = backboneTmf.AllocateAndInitNonConfirmablePostMessage(kUriBackboneMlr); VerifyOrExit(message != nullptr, error = kErrorNoBufs); - addressesTlv.Init(); - addressesTlv.SetLength(sizeof(Ip6::Address) * aAddressNum); - SuccessOrExit(error = message->Append(addressesTlv)); + SuccessOrExit(error = Tlv::StartTlv(*message, Ip6AddressesTlv::kType, tlvBookmark)); SuccessOrExit(error = message->AppendBytes(aAddresses, sizeof(Ip6::Address) * aAddressNum)); + SuccessOrExit(error = Tlv::EndTlv(*message, tlvBookmark)); SuccessOrExit(error = Tlv::Append(*message, aTimeout)); diff --git a/src/core/thread/mlr_manager.cpp b/src/core/thread/mlr_manager.cpp index 40ad9db0c..6f35e537e 100644 --- a/src/core/thread/mlr_manager.cpp +++ b/src/core/thread/mlr_manager.cpp @@ -356,20 +356,19 @@ Error MlrManager::SendMlrMessage(const Ip6::Address *aAddresses, { OT_UNUSED_VARIABLE(aTimeout); - Error error = kErrorNone; - Coap::Message *message = nullptr; - Ip6::Address destAddr; - Ip6AddressesTlv addressesTlv; + Error error = kErrorNone; + Coap::Message *message = nullptr; + Ip6::Address destAddr; + Tlv::Bookmark tlvBookmark; VerifyOrExit(Get().HasPrimary(), error = kErrorInvalidState); message = Get().AllocateAndInitConfirmablePostMessage(kUriMlr); VerifyOrExit(message != nullptr, error = kErrorNoBufs); - addressesTlv.Init(); - addressesTlv.SetLength(sizeof(Ip6::Address) * aAddressNum); - SuccessOrExit(error = message->Append(addressesTlv)); + SuccessOrExit(error = Tlv::StartTlv(*message, Ip6AddressesTlv::kType, tlvBookmark)); SuccessOrExit(error = message->AppendBytes(aAddresses, sizeof(Ip6::Address) * aAddressNum)); + SuccessOrExit(error = Tlv::EndTlv(*message, tlvBookmark)); #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE if (Get().IsActive()) @@ -453,7 +452,7 @@ Error MlrManager::ParseMlrResponse(Error aResult, Coap::Msg *aMsg, uint8_t &aSta SuccessOrExit(error = Tlv::Find(aMsg->mMessage, aStatus)); - if (ThreadTlv::FindTlvValueOffsetRange(aMsg->mMessage, Ip6AddressesTlv::kIp6Addresses, offsetRange) == kErrorNone) + if (Tlv::FindTlvValueOffsetRange(aMsg->mMessage, Ip6AddressesTlv::kType, offsetRange) == kErrorNone) { VerifyOrExit(offsetRange.GetLength() % sizeof(Ip6::Address) == 0, error = kErrorParse); VerifyOrExit(offsetRange.GetLength() / sizeof(Ip6::Address) <= Ip6AddressesTlv::kMaxAddresses, diff --git a/src/core/thread/thread_tlvs.hpp b/src/core/thread/thread_tlvs.hpp index a1b007362..444d85180 100644 --- a/src/core/thread/thread_tlvs.hpp +++ b/src/core/thread/thread_tlvs.hpp @@ -149,46 +149,15 @@ typedef TlvInfo ThreadNetworkDataTlv; #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 /** - * Implements IPv6 Addresses TLV generation and parsing. + * Defines IPv6 Addresses TLV constants and types. */ -OT_TOOL_PACKED_BEGIN -class Ip6AddressesTlv : public ThreadTlv, public TlvInfo +class Ip6AddressesTlv : public TlvInfo { public: // Thread 1.2.0 5.19.13 limits the number of IPv6 addresses to [1, 15]. static constexpr uint8_t kMinAddresses = 1; static constexpr uint8_t kMaxAddresses = OT_IP6_MAX_MLR_ADDRESSES; - - /** - * Initializes the TLV. - */ - void Init(void) { SetType(kIp6Addresses); } - - /** - * Indicates whether or not the TLV appears to be well-formed. - * - * @retval TRUE If the TLV appears to be well-formed. - * @retval FALSE If the TLV does not appear to be well-formed. - */ - bool IsValid(void) const - { - return GetLength() >= sizeof(Ip6::Address) * Ip6AddressesTlv::kMinAddresses && - GetLength() <= sizeof(Ip6::Address) * Ip6AddressesTlv::kMaxAddresses && - (GetLength() % sizeof(Ip6::Address)) == 0; - } - - /** - * Returns a pointer to the IPv6 address entry. - * - * @param[in] aIndex The index into the IPv6 address list. - * - * @returns A reference to the IPv6 address. - */ - const Ip6::Address &GetIp6Address(uint8_t aIndex) const - { - return *reinterpret_cast(GetValue() + (aIndex * sizeof(Ip6::Address))); - } -} OT_TOOL_PACKED_END; +}; #endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 diff --git a/tests/nexus/test_1_2_BBR_TC_2.cpp b/tests/nexus/test_1_2_BBR_TC_2.cpp index 3d7b5c1d3..d62670ef0 100644 --- a/tests/nexus/test_1_2_BBR_TC_2.cpp +++ b/tests/nexus/test_1_2_BBR_TC_2.cpp @@ -293,20 +293,19 @@ void Test_1_2_BBR_TC_2(void) Log("Step 10: Router_1 sends MLR.req to BR_1 (DUT)"); { - Ip6::Address ma1; - Coap::Message *message; - Ip6AddressesTlv addressesTlv; - Ip6::Address destAddr; + Ip6::Address ma1; + Coap::Message *message; + Tlv::Bookmark tlvBookmark; + Ip6::Address destAddr; SuccessOrQuit(ma1.FromString(kMa1Address)); message = router1.Get().AllocateAndInitConfirmablePostMessage(kUriMlr); VerifyOrQuit(message != nullptr); - addressesTlv.Init(); - addressesTlv.SetLength(sizeof(Ip6::Address)); - SuccessOrQuit(message->Append(addressesTlv)); + SuccessOrQuit(Tlv::StartTlv(*message, Ip6AddressesTlv::kType, tlvBookmark)); SuccessOrQuit(message->Append(ma1)); + SuccessOrQuit(Tlv::EndTlv(*message, tlvBookmark)); destAddr = br1.Get().GetMeshLocalEid(); SuccessOrQuit(router1.Get().SendMessageTo(*message, destAddr, nullptr, nullptr));