From a0ba929e3984d7f7e245c99868869966bda74111 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Thu, 27 Jun 2024 09:54:07 -0700 Subject: [PATCH] [mle] add RLOC16 related helper methods in `Mle` (#10440) This commit introduces new helper methods in the `Mle` class: - `HasRloc16()`: Checks if the device is using a given RLOC16. - `MatchesRouterId()`: Checks if this device's RLOC16 matches a given Router ID. - `HasMatchingRouterIdWith()`: Checks if this device's RLOC16 shares the same Router ID with a given RLOC16. This implies that the two devices are either directly related as parent and child or are children of the same parent within the Thread network. - `ParentRloc16ForRloc16()` derives the router RLOC16 corresponding to the parent of a given (child) RLOC16. These methods act as syntactic sugar, simplifying code and enhancing readability. --- src/core/api/thread_api.cpp | 4 +-- src/core/thread/address_resolver.cpp | 12 ++++---- src/core/thread/child_table.cpp | 2 +- src/core/thread/mesh_forwarder_ftd.cpp | 21 +++++++------ src/core/thread/mle.cpp | 4 +-- src/core/thread/mle.hpp | 36 +++++++++++++++++++++++ src/core/thread/mle_router.cpp | 2 +- src/core/thread/mle_types.hpp | 12 ++++++++ src/core/thread/network_data_leader.cpp | 2 +- src/core/thread/network_data_notifier.cpp | 2 +- src/core/thread/router_table.cpp | 32 ++++++++++---------- src/core/utils/mesh_diag.cpp | 4 +-- 12 files changed, 91 insertions(+), 42 deletions(-) diff --git a/src/core/api/thread_api.cpp b/src/core/api/thread_api.cpp index eb55386f6..d09771862 100644 --- a/src/core/api/thread_api.cpp +++ b/src/core/api/thread_api.cpp @@ -81,7 +81,7 @@ otError otThreadGetLeaderRloc(otInstance *aInstance, otIp6Address *aLeaderRloc) { Error error = kErrorNone; - VerifyOrExit(AsCoreType(aInstance).Get().GetRloc16() != Mle::kInvalidRloc16, error = kErrorDetached); + VerifyOrExit(!AsCoreType(aInstance).Get().HasRloc16(Mle::kInvalidRloc16), error = kErrorDetached); AsCoreType(aInstance).Get().GetLeaderRloc(AsCoreType(aLeaderRloc)); exit: @@ -197,7 +197,7 @@ otError otThreadGetServiceAloc(otInstance *aInstance, uint8_t aServiceId, otIp6A { Error error = kErrorNone; - VerifyOrExit(AsCoreType(aInstance).Get().GetRloc16() != Mle::kInvalidRloc16, error = kErrorDetached); + VerifyOrExit(!AsCoreType(aInstance).Get().HasRloc16(Mle::kInvalidRloc16), error = kErrorDetached); AsCoreType(aInstance).Get().GetServiceAloc(aServiceId, AsCoreType(aServiceAloc)); exit: diff --git a/src/core/thread/address_resolver.cpp b/src/core/thread/address_resolver.cpp index 913b184a0..930bfbe05 100644 --- a/src/core/thread/address_resolver.cpp +++ b/src/core/thread/address_resolver.cpp @@ -381,12 +381,15 @@ void AddressResolver::UpdateSnoopedCacheEntry(const Ip6::Address &aEid, uint16_t { uint16_t numNonEvictable = 0; CacheEntry *entry; - uint16_t deviceRloc16; VerifyOrExit(Get().IsFullThreadDevice()); #if OPENTHREAD_CONFIG_TMF_ALLOW_ADDRESS_RESOLUTION_USING_NET_DATA_SERVICES - VerifyOrExit(ResolveUsingNetDataServices(aEid, deviceRloc16) != kErrorNone); + { + uint16_t rloc16; + + VerifyOrExit(ResolveUsingNetDataServices(aEid, rloc16) != kErrorNone); + } #endif VerifyOrExit(UpdateCacheEntry(aEid, aRloc16) != kErrorNone); @@ -394,13 +397,12 @@ void AddressResolver::UpdateSnoopedCacheEntry(const Ip6::Address &aEid, uint16_t // Skip if the `aRloc16` (i.e., the source of the snooped message) // is this device or an MTD (minimal) child of the device itself. - deviceRloc16 = Get().GetRloc16(); - VerifyOrExit((aRloc16 != deviceRloc16) && !Get().HasMinimalChild(aRloc16)); + VerifyOrExit(!Get().HasRloc16(aRloc16) && !Get().HasMinimalChild(aRloc16)); // Ensure that the destination of the snooped message is this device // or a minimal child of this device. - VerifyOrExit((aDest == deviceRloc16) || Get().HasMinimalChild(aDest)); + VerifyOrExit(Get().HasRloc16(aDest) || Get().HasMinimalChild(aDest)); entry = NewCacheEntry(/* aSnoopedEntry */ true); VerifyOrExit(entry != nullptr); diff --git a/src/core/thread/child_table.cpp b/src/core/thread/child_table.cpp index 2762bad31..5e28fd626 100644 --- a/src/core/thread/child_table.cpp +++ b/src/core/thread/child_table.cpp @@ -320,7 +320,7 @@ bool ChildTable::HasMinimalChild(uint16_t aRloc16) const bool hasMinimalChild = false; const Child *child; - VerifyOrExit(Mle::RouterIdMatch(aRloc16, Get().GetRloc16())); + VerifyOrExit(Get().HasMatchingRouterIdWith(aRloc16)); child = FindChild(Child::AddressMatcher(aRloc16, Child::kInStateValidOrRestoring)); VerifyOrExit(child != nullptr); diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index 966b7f628..93ff6fd8d 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -174,7 +174,7 @@ void MeshForwarder::HandleResolved(const Ip6::Address &aEid, Error aError) // Pass back to IPv6 layer for DUA destination resolved // by Backbone Query if (Get().IsPrimary() && Get().IsDomainUnicast(ip6Dst) && - Get().LookUp(ip6Dst) == Get().GetRloc16()) + Get().HasRloc16(Get().LookUp(ip6Dst))) { uint8_t hopLimit; @@ -490,9 +490,9 @@ Error MeshForwarder::AnycastRouteLookup(uint8_t aServiceId, AnycastType aType, u // as the destination unless the device itself is the // parent of the `bestDest`. - uint16_t bestDestParent = Mle::Rloc16FromRouterId(Mle::RouterIdFromRloc16(bestDest)); + uint16_t bestDestParent = Mle::ParentRloc16ForRloc16(bestDest); - if (Get().GetRloc16() != bestDestParent) + if (!Get().HasRloc16(bestDestParent)) { bestDest = bestDestParent; } @@ -565,7 +565,7 @@ Error MeshForwarder::UpdateIp6RouteFtd(const Ip6::Header &aIp6Header, Message &a // child of this device, prepare the message for indirect tx // to the sleepy child and un-mark message for direct tx. - if (mle.IsRouterOrLeader() && Mle::IsChildRloc16(mMeshDest) && Mle::RouterIdMatch(mMeshDest, mle.GetRloc16())) + if (mle.IsRouterOrLeader() && Mle::IsChildRloc16(mMeshDest) && mle.HasMatchingRouterIdWith(mMeshDest)) { Child *child = Get().FindChild(mMeshDest, Child::kInStateValid); @@ -673,12 +673,11 @@ exit: Error MeshForwarder::CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header) { - bool isReachable = false; - uint16_t deviceRloc16 = Get().GetRloc16(); + bool isReachable = false; if (Get().IsChild()) { - if (aMeshDest == deviceRloc16) + if (Get().HasRloc16(aMeshDest)) { isReachable = Get().HasUnicastAddress(aIp6Header.GetDestination()); } @@ -690,14 +689,14 @@ Error MeshForwarder::CheckReachability(uint16_t aMeshDest, const Ip6::Header &aI ExitNow(); } - if (aMeshDest == deviceRloc16) + if (Get().HasRloc16(aMeshDest)) { isReachable = Get().HasUnicastAddress(aIp6Header.GetDestination()) || (Get().FindNeighbor(aIp6Header.GetDestination()) != nullptr); ExitNow(); } - if (Mle::RouterIdMatch(aMeshDest, deviceRloc16)) + if (Get().HasMatchingRouterIdWith(aMeshDest)) { isReachable = (Get().FindChild(aMeshDest, Child::kInStateValidOrRestoring) != nullptr); ExitNow(); @@ -735,7 +734,7 @@ void MeshForwarder::HandleMesh(FrameData &aFrameData, const Mac::Address &aMacSo UpdateRoutes(aFrameData, meshAddrs); - if (meshAddrs.mDestination.GetShort() == Get().GetRloc16() || + if (Get().HasRloc16(meshAddrs.mDestination.GetShort()) || Get().HasMinimalChild(meshAddrs.mDestination.GetShort())) { if (Lowpan::FragmentHeader::IsFragmentHeader(aFrameData)) @@ -838,7 +837,7 @@ void MeshForwarder::UpdateRoutes(const FrameData &aFrameData, const Mac::Address neighbor = Get().FindNeighbor(ip6Headers.GetSourceAddress()); VerifyOrExit(neighbor != nullptr && !neighbor->IsFullThreadDevice()); - if (!Mle::RouterIdMatch(aMeshAddrs.mSource.GetShort(), Get().GetRloc16())) + if (!Get().HasMatchingRouterIdWith(aMeshAddrs.mSource.GetShort())) { Get().RemoveNeighbor(*neighbor); } diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 4a009cad9..0b013e350 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -432,7 +432,7 @@ void Mle::Restore(void) mParent.SetVersion(parentInfo.GetVersion()); mParent.SetDeviceMode(DeviceMode(DeviceMode::kModeFullThreadDevice | DeviceMode::kModeRxOnWhenIdle | DeviceMode::kModeFullNetworkData)); - mParent.SetRloc16(Rloc16FromRouterId(RouterIdFromRloc16(networkInfo.GetRloc16()))); + mParent.SetRloc16(ParentRloc16ForRloc16(networkInfo.GetRloc16())); mParent.SetState(Neighbor::kStateRestored); mPreviousParentRloc = mParent.GetRloc16(); @@ -3558,7 +3558,7 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo) case kRoleChild: SuccessOrExit(error = Tlv::Find(aRxInfo.mMessage, sourceAddress)); - if (!RouterIdMatch(sourceAddress, GetRloc16())) + if (!HasMatchingRouterIdWith(sourceAddress)) { IgnoreError(BecomeDetached()); ExitNow(); diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 1dfcfed13..24afe67a9 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -523,6 +523,42 @@ public: */ uint16_t GetRloc16(void) const { return mRloc16; } + /** + * Indicates whether or not this device is using a given RLOC16. + * + * @param[in] aRloc16 The RLOC16 to check. + * + * @retval TRUE This device is using @p aRloc16. + * @retval FALSE This device is not using @p aRloc16. + * + */ + bool HasRloc16(uint16_t aRloc16) const { return mRloc16 == aRloc16; } + + /** + * Indicates whether or not this device RLOC16 matches a given Router ID. + * + * @param[in] aRouterId The Router ID to check. + * + * @retval TRUE This device's RLOC16 matches the @p aRouterId. + * @retval FALSE This device's RLOC16 does not match the @p aRouterId. + * + */ + bool MatchesRouterId(uint8_t aRouterId) const { return RouterIdFromRloc16(mRloc16) == aRouterId; } + + /** + * Indicates whether or not this device's RLOC16 shares the same Router ID with a given RLOC16. + * + * A shared Router ID implies that this device and the @ aRloc16 are either directly related as parent and child, + * or are children of the same parent within the Thread network. + * + * @param[in] aRloc16 The RLOC16 to check. + * + * @retval TRUE This device and @p aRloc16 have a matching router ID. + * @retval FALSE This device and @p aRloc16 do not have a matching router ID. + * + */ + bool HasMatchingRouterIdWith(uint16_t aRloc16) const { return RouterIdMatch(mRloc16, aRloc16); } + /** * Returns the mesh local RLOC IPv6 address assigned to the Thread interface. * diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index e03712345..6948f9e43 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -2786,7 +2786,7 @@ Error MleRouter::SendChildIdResponse(Child &aChild) SuccessOrExit(error = message->AppendLeaderDataTlv()); SuccessOrExit(error = message->AppendActiveAndPendingTimestampTlvs()); - if ((aChild.GetRloc16() == 0) || !RouterIdMatch(aChild.GetRloc16(), GetRloc16())) + if ((aChild.GetRloc16() == 0) || !HasMatchingRouterIdWith(aChild.GetRloc16())) { uint16_t rloc16; diff --git a/src/core/thread/mle_types.hpp b/src/core/thread/mle_types.hpp index a228d06ee..f8ee58cbf 100644 --- a/src/core/thread/mle_types.hpp +++ b/src/core/thread/mle_types.hpp @@ -681,6 +681,18 @@ inline uint16_t CommissionerAloc16FromId(uint16_t aSessionId) */ inline uint16_t Rloc16FromRouterId(uint8_t aRouterId) { return static_cast(aRouterId << kRouterIdOffset); } +/** + * Derives the router RLOC16 corresponding to the parent of a given (child) RLOC16. + * + * If @p aRloc16 itself refers to a router, then the same RLOC16 value is returned. + * + * @param[in] aRloc16 An RLOC16. + * + * @returns The router RLOC16 corresponding to the parent associated with @p aRloc16. + * + */ +inline uint16_t ParentRloc16ForRloc16(uint16_t aRloc16) { return Rloc16FromRouterId(RouterIdFromRloc16(aRloc16)); } + /** * Indicates whether or not @p aRloc16 refers to a router. * diff --git a/src/core/thread/network_data_leader.cpp b/src/core/thread/network_data_leader.cpp index 95b978907..efb6225bd 100644 --- a/src/core/thread/network_data_leader.cpp +++ b/src/core/thread/network_data_leader.cpp @@ -324,7 +324,7 @@ int Leader::CompareRouteEntries(int8_t aFirstPreference, // On MTD, prefer the BR that is this device itself. This handles // the uncommon case where an MTD itself may be acting as BR. - result = ThreeWayCompare((aFirstRloc == Get().GetRloc16()), (aSecondRloc == Get().GetRloc16())); + result = ThreeWayCompare((Get().HasRloc16(aFirstRloc)), Get().HasRloc16(aSecondRloc)); #endif #if OPENTHREAD_FTD diff --git a/src/core/thread/network_data_notifier.cpp b/src/core/thread/network_data_notifier.cpp index bbcd35bf3..d77c6c397 100644 --- a/src/core/thread/network_data_notifier.cpp +++ b/src/core/thread/network_data_notifier.cpp @@ -138,7 +138,7 @@ Error Notifier::RemoveStaleChildEntries(void) for (uint16_t rloc16 : rlocs) { - if (Mle::IsChildRloc16(rloc16) && Mle::RouterIdMatch(Get().GetRloc16(), rloc16) && + if (Mle::IsChildRloc16(rloc16) && Get().HasMatchingRouterIdWith(rloc16) && Get().FindChild(rloc16, Child::kInStateValid) == nullptr) { error = SendServerDataNotification(rloc16); diff --git a/src/core/thread/router_table.cpp b/src/core/thread/router_table.cpp index 16a4d98c5..e882a6f16 100644 --- a/src/core/thread/router_table.cpp +++ b/src/core/thread/router_table.cpp @@ -268,7 +268,7 @@ Router *RouterTable::FindNeighbor(uint16_t aRloc16) { Router *router = nullptr; - VerifyOrExit(aRloc16 != Get().GetRloc16()); + VerifyOrExit(!Get().HasRloc16(aRloc16)); router = FindRouter(Router::AddressMatcher(aRloc16, Router::kInStateValid)); exit: @@ -362,7 +362,7 @@ uint8_t RouterTable::GetLinkCost(const Router &aRouter) const { uint8_t rval = Mle::kMaxRouteCost; - VerifyOrExit(aRouter.GetRloc16() != Get().GetRloc16() && aRouter.IsStateValid()); + VerifyOrExit(!Get().HasRloc16(aRouter.GetRloc16()) && aRouter.IsStateValid()); rval = CostForLinkQuality(aRouter.GetTwoWayLinkQuality()); @@ -400,7 +400,6 @@ uint8_t RouterTable::GetPathCostToLeader(void) const { return GetPathCost(Get().IsAttached()); - if (aDestRloc16 == Get().GetRloc16()) + if (Get().HasRloc16(aDestRloc16)) { // Destination is this device, return cost as zero. aPathCost = 0; @@ -417,14 +416,13 @@ void RouterTable::GetNextHopAndPathCost(uint16_t aDestRloc16, uint16_t &aNextHop ExitNow(); } - destRouterId = Mle::RouterIdFromRloc16(aDestRloc16); - - router = FindRouterById(destRouterId); + router = FindRouterById(Mle::RouterIdFromRloc16(aDestRloc16)); nextHop = (router != nullptr) ? FindNextHopOf(*router) : nullptr; if (Get().IsChild()) { const Router &parent = Get().GetParent(); + bool destIsParentOrItsChild; if (parent.IsStateValid()) { @@ -436,11 +434,13 @@ void RouterTable::GetNextHopAndPathCost(uint16_t aDestRloc16, uint16_t &aNextHop // check if we have a next hop towards the destination and // add its cost to the link cost to parent. - VerifyOrExit((destRouterId == parent.GetRouterId()) || (nextHop != nullptr)); + destIsParentOrItsChild = Mle::RouterIdMatch(aDestRloc16, parent.GetRloc16()); + + VerifyOrExit(destIsParentOrItsChild || (nextHop != nullptr)); aPathCost = CostForLinkQuality(parent.GetLinkQualityIn()); - if (destRouterId != parent.GetRouterId()) + if (!destIsParentOrItsChild) { aPathCost += router->GetCost(); } @@ -450,7 +450,7 @@ void RouterTable::GetNextHopAndPathCost(uint16_t aDestRloc16, uint16_t &aNextHop } else // Role is router or leader { - if (destRouterId == Mle::RouterIdFromRloc16(Get().GetRloc16())) + if (Get().HasMatchingRouterIdWith(aDestRloc16)) { // Destination is a one of our children. @@ -590,7 +590,7 @@ void RouterTable::UpdateRoutes(const Mle::RouteTlv &aRouteTlv, uint8_t aNeighbor for (uint8_t routerId = 0, index = 0; routerId <= Mle::kMaxRouterId; index += aRouteTlv.IsRouterIdSet(routerId) ? 1 : 0, routerId++) { - if (routerId != Mle::RouterIdFromRloc16(Get().GetRloc16())) + if (!Get().MatchesRouterId(routerId)) { continue; } @@ -625,7 +625,7 @@ void RouterTable::UpdateRoutes(const Mle::RouteTlv &aRouteTlv, uint8_t aNeighbor router = FindRouterById(routerId); - if (router == nullptr || router->GetRloc16() == Get().GetRloc16() || router == neighbor) + if (router == nullptr || Get().HasRloc16(router->GetRloc16()) || router == neighbor) { continue; } @@ -737,8 +737,8 @@ void RouterTable::FillRouteTlv(Mle::RouteTlv &aRouteTlv, const Neighbor *aNeighb break; } - if ((routerId == Mle::RouterIdFromRloc16(Get().GetRloc16())) || - (routerId == aNeighbor->GetRouterId()) || (routerId == Get().GetLeaderId())) + if (Get().MatchesRouterId(routerId) || (routerId == aNeighbor->GetRouterId()) || + (routerId == Get().GetLeaderId())) { // Route64 TLV must contain this device and the // neighboring router to ensure that at least this @@ -775,7 +775,7 @@ void RouterTable::FillRouteTlv(Mle::RouteTlv &aRouteTlv, const Neighbor *aNeighb routerRloc16 = Mle::Rloc16FromRouterId(routerId); - if (routerRloc16 == Get().GetRloc16()) + if (Get().HasRloc16(routerRloc16)) { aRouteTlv.SetRouteData(routerIndex, kLinkQuality0, kLinkQuality0, 1); } @@ -895,7 +895,7 @@ void RouterTable::LogRouteTable(void) const string.Append(" %2d 0x%04x", router.GetRouterId(), router.GetRloc16()); - if (router.GetRloc16() == Get().GetRloc16()) + if (Get().HasRloc16(router.GetRloc16())) { string.Append(" - me"); } diff --git a/src/core/utils/mesh_diag.cpp b/src/core/utils/mesh_diag.cpp index 5e470b3f4..33c001d65 100644 --- a/src/core/utils/mesh_diag.cpp +++ b/src/core/utils/mesh_diag.cpp @@ -506,7 +506,7 @@ Error MeshDiag::RouterInfo::ParseFrom(const Message &aMessage) } mRouterId = Mle::RouterIdFromRloc16(mRloc16); - mIsThisDevice = (mRloc16 == mle.GetRloc16()); + mIsThisDevice = mle.HasRloc16(mRloc16); mIsThisDeviceParent = mle.IsChild() && (mRloc16 == mle.GetParent().GetRloc16()); mIsLeader = (mRouterId == mle.GetLeaderId()); mIsBorderRouter = aMessage.Get().ContainsBorderRouterWithRloc(mRloc16); @@ -582,7 +582,7 @@ Error MeshDiag::ChildIterator::GetNextChildInfo(ChildInfo &aChildInfo) entry.GetMode().Get(aChildInfo.mMode); aChildInfo.mLinkQuality = entry.GetLinkQuality(); - aChildInfo.mIsThisDevice = (aChildInfo.mRloc16 == mMessage->Get().GetRloc16()); + aChildInfo.mIsThisDevice = mMessage->Get().HasRloc16(aChildInfo.mRloc16); aChildInfo.mIsBorderRouter = mMessage->Get().ContainsBorderRouterWithRloc(aChildInfo.mRloc16); exit: