From 1316bcebc8a620372c769248f2d557e49f0ad768 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 8 Jun 2026 09:12:47 -0700 Subject: [PATCH] [mle] introduce `ComposeRloc()` and `ComposeAloc()` (#13199) This commit introduces `ComposeRloc()` and `ComposeAloc()` in the `Mle` module and updates the codebase to use them. These methods streamline the construction of Routing Locators and Anycast Locators by automatically combining the Mesh-Local Prefix with the provided RLOC16 or ALOC16. This centralizes address composition logic within `Mle` instead of relying on manually formatting `Ip6::Address` instances across various modules. --- src/core/backbone_router/bbr_local.cpp | 3 +-- src/core/net/dhcp6_client.cpp | 2 +- src/core/net/dhcp6_server.cpp | 9 ++++++++- src/core/net/dhcp6_server.hpp | 21 ++++++++++----------- src/core/net/nd_agent.cpp | 5 ++--- src/core/thread/address_resolver.cpp | 2 +- src/core/thread/mesh_forwarder_ftd.cpp | 2 +- src/core/thread/mle.cpp | 19 +++++++++---------- src/core/thread/mle.hpp | 16 ++++++++++++++++ src/core/thread/mlr_manager.cpp | 3 +-- src/core/thread/network_data_service.cpp | 3 +-- src/core/thread/tmf.cpp | 2 +- src/core/utils/mesh_diag.cpp | 4 ++-- tests/nexus/test_pbbr_aloc.cpp | 3 +-- tests/nexus/test_service.cpp | 4 ++-- 15 files changed, 57 insertions(+), 41 deletions(-) diff --git a/src/core/backbone_router/bbr_local.cpp b/src/core/backbone_router/bbr_local.cpp index be6947c35..60c796813 100644 --- a/src/core/backbone_router/bbr_local.cpp +++ b/src/core/backbone_router/bbr_local.cpp @@ -55,7 +55,6 @@ Local::Local(Instance &aInstance) { // Primary Backbone Router Aloc mBbrPrimaryAloc.InitAsThreadOriginMeshLocal(); - mBbrPrimaryAloc.GetAddress().GetIid().InitAsLocator(Mle::Aloc16::ForPrimaryBackboneRouter()); // All Network Backbone Routers Multicast Address. mAllNetworkBackboneRouters.Clear(); @@ -214,7 +213,7 @@ void Local::SetState(State aState) if (aState == kStatePrimary) { // Add Primary Backbone Router ALOC for Primary Backbone Router. - mBbrPrimaryAloc.GetAddress().SetPrefix(Get().GetMeshLocalPrefix()); + Get().ComposeAloc(Mle::Aloc16::ForPrimaryBackboneRouter(), mBbrPrimaryAloc.GetAddress()); Get().AddUnicastAddress(mBbrPrimaryAloc); } diff --git a/src/core/net/dhcp6_client.cpp b/src/core/net/dhcp6_client.cpp index f05132a38..6104d5658 100644 --- a/src/core/net/dhcp6_client.cpp +++ b/src/core/net/dhcp6_client.cpp @@ -268,7 +268,7 @@ void Client::Solicit(uint16_t aRloc16) #if OPENTHREAD_ENABLE_DHCP6_MULTICAST_SOLICIT messageInfo.SetPeerAddr(Ip6::Address::GetRealmLocalAllRoutersMulticast()); #else - messageInfo.GetPeerAddr().InitAsRoutingLocator(Get().GetMeshLocalPrefix(), aRloc16); + Get().ComposeRloc(aRloc16, messageInfo.GetPeerAddr()); #endif messageInfo.SetSockAddr(Get().GetMeshLocalRloc()); messageInfo.mPeerPort = kDhcpServerPort; diff --git a/src/core/net/dhcp6_server.cpp b/src/core/net/dhcp6_server.cpp index 98014eaee..6beb1556f 100644 --- a/src/core/net/dhcp6_server.cpp +++ b/src/core/net/dhcp6_server.cpp @@ -164,7 +164,8 @@ void Server::AddPrefixAgent(const Ip6::Prefix &aIp6Prefix, uint8_t aContextId) VerifyOrExit(newEntry != nullptr, error = kErrorNoBufs); - newEntry->Set(aIp6Prefix, Get().GetMeshLocalPrefix(), aContextId); + newEntry->SetPrefix(aIp6Prefix); + newEntry->ComposeAloc(GetInstance(), aContextId); Get().AddUnicastAddress(newEntry->GetAloc()); mPrefixAgentsCount++; @@ -411,6 +412,12 @@ exit: return error; } +void Server::PrefixAgent::ComposeAloc(Instance &aInstance, uint8_t aContextId) +{ + mAloc.InitAsThreadOriginMeshLocal(); + aInstance.Get().ComposeAloc((Ip6::Address::kAloc16Mask << 8) + aContextId, mAloc.GetAddress()); +} + } // namespace Dhcp6 } // namespace ot diff --git a/src/core/net/dhcp6_server.hpp b/src/core/net/dhcp6_server.hpp index e1444993c..a7fd4da36 100644 --- a/src/core/net/dhcp6_server.hpp +++ b/src/core/net/dhcp6_server.hpp @@ -141,20 +141,19 @@ private: } /** - * Sets the ALOC. + * Sets the IPv6 prefix. * - * @param[in] aPrefix The IPv6 prefix. - * @param[in] aMeshLocalPrefix The Mesh Local Prefix. + * @param[in] aPrefix The IPv6 prefix. + */ + void SetPrefix(const Ip6::Prefix &aPrefix) { mPrefix = aPrefix; } + + /** + * Composes the ALOC address. + * + * @param[in] aInstance The OpenThread instance. * @param[in] aContextId The 6LoWPAN Context ID. */ - void Set(const Ip6::Prefix &aPrefix, const Ip6::NetworkPrefix &aMeshLocalPrefix, uint8_t aContextId) - { - mPrefix = aPrefix; - - mAloc.InitAsThreadOrigin(); - mAloc.GetAddress().InitAsAnycastLocator(aMeshLocalPrefix, (Ip6::Address::kAloc16Mask << 8) + aContextId); - mAloc.mMeshLocal = true; - } + void ComposeAloc(Instance &aInstance, uint8_t aContextId); private: Ip6::Netif::UnicastAddress mAloc; diff --git a/src/core/net/nd_agent.cpp b/src/core/net/nd_agent.cpp index 45f2e0b70..e68354848 100644 --- a/src/core/net/nd_agent.cpp +++ b/src/core/net/nd_agent.cpp @@ -102,9 +102,8 @@ void Agent::UpdateService(void) { uint16_t aloc16 = Mle::Aloc16::FromNdAgentContextId(lowpanContext.GetContextId()); - mAloc.InitAsThreadOrigin(); - mAloc.GetAddress().InitAsAnycastLocator(Get().GetMeshLocalPrefix(), aloc16); - mAloc.mMeshLocal = true; + mAloc.InitAsThreadOriginMeshLocal(); + Get().ComposeAloc(aloc16, mAloc.GetAddress()); Get().AddUnicastAddress(mAloc); ExitNow(); } diff --git a/src/core/thread/address_resolver.cpp b/src/core/thread/address_resolver.cpp index f88398e1b..f659a8be4 100644 --- a/src/core/thread/address_resolver.cpp +++ b/src/core/thread/address_resolver.cpp @@ -776,7 +776,7 @@ template <> void AddressResolver::HandleTmf(Coap::Msg &aMsg) if (child.RemoveIp6Address(target) == kErrorNone) { - destination.InitAsRoutingLocator(Get().GetMeshLocalPrefix(), child.GetRloc16()); + Get().ComposeRloc(child.GetRloc16(), destination); SendAddressError(target, meshLocalIid, destination); ExitNow(); diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index d9be90ad2..c2c273717 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -536,7 +536,7 @@ void MeshForwarder::SendDestinationUnreachable(uint16_t aMeshSource, const Ip6:: { Ip6::MessageInfo messageInfo; - messageInfo.GetPeerAddr().InitAsRoutingLocator(Get().GetMeshLocalPrefix(), aMeshSource); + Get().ComposeRloc(aMeshSource, messageInfo.GetPeerAddr()); IgnoreError(Get().SendError(Ip6::Icmp6Header::kTypeDstUnreach, Ip6::Icmp6Header::kCodeDstUnreachNoRoute, messageInfo, aIp6Headers)); diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 256e7438c..6a9bb7637 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -848,7 +848,7 @@ void Mle::SetRloc16(uint16_t aRloc16) // We can always call `AddUnicastAddress(mMeshLocat16)` and if // the address is already added, it will perform no action. - mMeshLocalRloc.GetAddress().GetIid().SetLocator(aRloc16); + ComposeRloc(aRloc16, mMeshLocalRloc.GetAddress()); Get().AddUnicastAddress(mMeshLocalRloc); #if OPENTHREAD_FTD Get().RestartAddressQueries(); @@ -887,24 +887,23 @@ void Mle::SetLeaderData(uint32_t aPartitionId, uint8_t aWeighting, uint8_t aLead mLeaderData.SetLeaderRouterId(aLeaderRouterId); } -void Mle::ComposeLeaderRloc(Ip6::Address &aAddress) const +void Mle::ComposeRloc(uint16_t aRloc16, Ip6::Address &aAddress) const { - aAddress.InitAsRoutingLocator(mMeshLocalPrefix, GetLeaderRloc16()); + aAddress.InitAsRoutingLocator(mMeshLocalPrefix, aRloc16); } -void Mle::ComposeLeaderAloc(Ip6::Address &aAddress) const -{ - aAddress.InitAsAnycastLocator(mMeshLocalPrefix, Aloc16::ForLeader()); -} +void Mle::ComposeLeaderRloc(Ip6::Address &aAddress) const { ComposeRloc(GetLeaderRloc16(), aAddress); } + +void Mle::ComposeLeaderAloc(Ip6::Address &aAddress) const { ComposeAloc(Aloc16::ForLeader(), aAddress); } void Mle::ComposeCommissionerAloc(uint16_t aSessionId, Ip6::Address &aAddress) const { - aAddress.InitAsAnycastLocator(mMeshLocalPrefix, Aloc16::FromCommissionerSessionId(aSessionId)); + ComposeAloc(Aloc16::FromCommissionerSessionId(aSessionId), aAddress); } void Mle::ComposeServiceAloc(uint8_t aServiceId, Ip6::Address &aAddress) const { - aAddress.InitAsAnycastLocator(mMeshLocalPrefix, Aloc16::FromServiceId(aServiceId)); + ComposeAloc(Aloc16::FromServiceId(aServiceId), aAddress); } const LeaderData &Mle::GetLeaderData(void) @@ -2676,7 +2675,7 @@ void Mle::InformPreviousParent(void) SuccessOrExit(error = message->SetLength(0)); messageInfo.SetSockAddr(GetMeshLocalEid()); - messageInfo.GetPeerAddr().InitAsRoutingLocator(mMeshLocalPrefix, mPreviousParentRloc); + ComposeRloc(mPreviousParentRloc, messageInfo.GetPeerAddr()); SuccessOrExit(error = Get().SendDatagram(*message, messageInfo, Ip6::kProtoNone)); diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 50a8aaba8..5326c433e 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -565,6 +565,22 @@ public: */ uint16_t GetLeaderRloc16(void) const { return Rloc16FromRouterId(GetLeaderId()); } + /** + * Composes a Routing Locator (RLOC) address for a given RLOC16. + * + * @param[in] aRloc16 The RLOC16 value. + * @param[out] aAddress A reference to an address to return the RLOC. + */ + void ComposeRloc(uint16_t aRloc16, Ip6::Address &aAddress) const; + + /** + * Composes an Anycast Locator (ALOC) address for a given ALOC16. + * + * @param[in] aAloc16 The ALOC16 value. + * @param[out] aAddress A reference to an address to return the ALOC. + */ + void ComposeAloc(uint16_t aAloc16, Ip6::Address &aAddress) const { ComposeRloc(aAloc16, aAddress); } + /** * Composes the Leader's RLOC. * diff --git a/src/core/thread/mlr_manager.cpp b/src/core/thread/mlr_manager.cpp index 8f6bec7f7..954846f11 100644 --- a/src/core/thread/mlr_manager.cpp +++ b/src/core/thread/mlr_manager.cpp @@ -532,8 +532,7 @@ Error Manager::SendMessage(const Ip6::Address *aAddresses, } else { - destAddr.InitAsRoutingLocator(Get().GetMeshLocalPrefix(), - Get().GetServer16()); + Get().ComposeRloc(Get().GetServer16(), destAddr); } error = Get().SendMessageTo(*message, destAddr, aResponseHandler, this); diff --git a/src/core/thread/network_data_service.cpp b/src/core/thread/network_data_service.cpp index 428ad04dd..a4e1b90e6 100644 --- a/src/core/thread/network_data_service.cpp +++ b/src/core/thread/network_data_service.cpp @@ -158,8 +158,7 @@ Error Iterator::GetNextDnsSrpUnicastInfo(DnsSrpUnicastType aType, DnsSrpUnicastI // contains a port number and use the RLOC as the // IPv6 address. - aInfo.mSockAddr.GetAddress().InitAsRoutingLocator(Get().GetMeshLocalPrefix(), - mServerSubTlv->GetServer16()); + Get().ComposeRloc(mServerSubTlv->GetServer16(), aInfo.mSockAddr.GetAddress()); aInfo.mSockAddr.SetPort(BigEndian::ReadUint16(mServerSubTlv->GetServerData())); aInfo.mVersion = 0; ExitNow(); diff --git a/src/core/thread/tmf.cpp b/src/core/thread/tmf.cpp index bc924540a..44e94fe7a 100644 --- a/src/core/thread/tmf.cpp +++ b/src/core/thread/tmf.cpp @@ -247,7 +247,7 @@ Error Agent::SendMessageToRloc(Message &aMessage, uint16_t aRloc16, ResponseHand { Ip6::MessageInfo messageInfo; - messageInfo.GetPeerAddr().InitAsRoutingLocator(Get().GetMeshLocalPrefix(), aRloc16); + Get().ComposeRloc(aRloc16, messageInfo.GetPeerAddr()); PrepareMessageInfo(messageInfo); return SendMessage(aMessage, messageInfo, aHandler, aContext); diff --git a/src/core/utils/mesh_diag.cpp b/src/core/utils/mesh_diag.cpp index 249a11e5f..60fc48a8c 100644 --- a/src/core/utils/mesh_diag.cpp +++ b/src/core/utils/mesh_diag.cpp @@ -99,7 +99,7 @@ Error MeshDiag::DiscoverTopology(const DiscoverConfig &aConfig, DiscoverCallback continue; } - destination.InitAsRoutingLocator(Get().GetMeshLocalPrefix(), Mle::Rloc16FromRouterId(routerId)); + Get().ComposeRloc(Mle::Rloc16FromRouterId(routerId), destination); SuccessOrExit(error = Get().SendCommand(kUriDiagnosticGetRequest, Message::kPriorityLow, destination, tlvs, tlvsLength, HandleDiagGetResponse, this)); @@ -165,7 +165,7 @@ Error MeshDiag::SendQuery(uint16_t aRloc16, const uint8_t *aTlvs, uint8_t aTlvsL VerifyOrExit(Mle::IsRouterRloc16(aRloc16), error = kErrorInvalidArgs); VerifyOrExit(Get().IsAllocated(Mle::RouterIdFromRloc16(aRloc16)), error = kErrorNotFound); - destination.InitAsRoutingLocator(Get().GetMeshLocalPrefix(), aRloc16); + Get().ComposeRloc(aRloc16, destination); SuccessOrExit(error = Get().SendCommand(kUriDiagnosticGetQuery, Message::kPriorityNormal, destination, aTlvs, aTlvsLength)); diff --git a/tests/nexus/test_pbbr_aloc.cpp b/tests/nexus/test_pbbr_aloc.cpp index bf2cf4f41..0556e94ef 100644 --- a/tests/nexus/test_pbbr_aloc.cpp +++ b/tests/nexus/test_pbbr_aloc.cpp @@ -91,8 +91,7 @@ void TestPbbrAloc(void) nexus.SendAndVerifyEchoRequest(router, aloc); // 2. PBBR ALOC - aloc.SetPrefix(leader.Get().GetMeshLocalPrefix()); - aloc.GetIid().InitAsLocator(Mle::Aloc16::ForPrimaryBackboneRouter()); + leader.Get().ComposeAloc(Mle::Aloc16::ForPrimaryBackboneRouter(), aloc); Log("Pinging PBBR ALOC %s from ROUTER", aloc.ToString().AsCString()); nexus.SendAndVerifyEchoRequest(router, aloc); diff --git a/tests/nexus/test_service.cpp b/tests/nexus/test_service.cpp index a1e036926..3b7afb653 100644 --- a/tests/nexus/test_service.cpp +++ b/tests/nexus/test_service.cpp @@ -110,8 +110,8 @@ void TestService(void) Ip6::Address aloc0; Ip6::Address aloc1; - aloc0.InitAsAnycastLocator(leader.Get().GetMeshLocalPrefix(), Mle::Aloc16::FromServiceId(0)); - aloc1.InitAsAnycastLocator(leader.Get().GetMeshLocalPrefix(), Mle::Aloc16::FromServiceId(1)); + leader.Get().ComposeServiceAloc(0, aloc0); + leader.Get().ComposeServiceAloc(1, aloc1); // Initial check: no ALOCs for (Node &node : nexus.GetNodes())