From 1363316f5e2fa1f3ce03abb1a91bc941a4992cab Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Wed, 7 Apr 2021 15:20:08 -0700 Subject: [PATCH] [mesh-forwarder] use path cost in DHCPv6 ALOC lookup (#6423) --- src/core/thread/mesh_forwarder.hpp | 1 + src/core/thread/mesh_forwarder_ftd.cpp | 105 ++++++++++++++++++------ src/core/thread/network_data_leader.cpp | 24 ------ src/core/thread/network_data_leader.hpp | 12 --- 4 files changed, 83 insertions(+), 59 deletions(-) diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index 3aa543737..e205a88c2 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -440,6 +440,7 @@ private: void SendDestinationUnreachable(uint16_t aMeshSource, const Message &aMessage); Error UpdateIp6Route(Message &aMessage); Error UpdateIp6RouteFtd(Ip6::Header &ip6Header, Message &aMessage); + Error ContextIdRouteLookup(uint8_t aContextId, uint16_t &aMeshDest) const; Error UpdateMeshRoute(Message &aMessage); bool UpdateReassemblyList(void); void UpdateFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader, diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index 3bbf8389f..5ef3af6fa 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -402,6 +402,85 @@ exit: return error; } +Error MeshForwarder::ContextIdRouteLookup(uint8_t aContextId, uint16_t &aMeshDest) const +{ + Lowpan::Context context; + NetworkData::Iterator iterator = NetworkData::kIteratorInit; + NetworkData::OnMeshPrefixConfig config; + uint8_t bestCost = Mle::kMaxRouteCost; + uint16_t bestDest = Mac::kShortAddrInvalid; + uint8_t routerId; + + SuccessOrExit(Get().GetContext(aContextId, context)); + + while (Get().GetNextOnMeshPrefix(iterator, config) == kErrorNone) + { + uint16_t server16 = config.mRloc16; + uint8_t curCost = 0x00; + const Neighbor *neighbor; + + if (config.GetPrefix() != context.mPrefix) + { + continue; + } + + // Path cost + curCost = Get().GetCost(server16); + + if (!Mle::MleRouter::IsActiveRouter(server16)) + { + // Assume best link between remote child server and its parent. + curCost += 1; + } + + // Cost if the server is direct neighbor. + neighbor = Get().FindNeighbor(server16); + + if (neighbor != nullptr && neighbor->IsStateValid()) + { + uint8_t cost; + + if (!Mle::MleRouter::IsActiveRouter(server16)) + { + // Cost calculated only from Link Quality In as the parent only maintains + // one-direction link info. + cost = Mle::MleRouter::LinkQualityToCost(neighbor->GetLinkInfo().GetLinkQuality()); + } + else + { + cost = Get().GetLinkCost(Mle::Mle::RouterIdFromRloc16(server16)); + } + + // Choose the minimum cost + if (cost < curCost) + { + curCost = cost; + } + } + + if ((bestDest == Mac::kShortAddrInvalid) || (curCost < bestCost)) + { + bestDest = server16; + bestCost = curCost; + } + } + + routerId = Mle::Mle::RouterIdFromRloc16(bestDest); + + if (!(Mle::Mle::IsActiveRouter(bestDest) || + Mle::Mle::Rloc16FromRouterId(routerId) == Get().GetRloc16())) + { + // if agent is neither active router nor child of this device + // use the parent of the ED Agent as Dest + bestDest = Mle::Mle::Rloc16FromRouterId(routerId); + } + + aMeshDest = bestDest; + +exit: + return (bestDest != Mac::kShortAddrInvalid) ? kErrorNone : kErrorNoRoute; +} + Error MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header, Message &aMessage) { Mle::MleRouter &mle = Get(); @@ -428,24 +507,8 @@ Error MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header, Message &aMessage } else if (aloc16 <= Mle::kAloc16DhcpAgentEnd) { - uint16_t agentRloc16; - uint8_t routerId; - VerifyOrExit((Get().GetRlocByContextId( - static_cast(aloc16 & Mle::kAloc16DhcpAgentMask), agentRloc16) == kErrorNone), - error = kErrorDrop); - - routerId = Mle::Mle::RouterIdFromRloc16(agentRloc16); - - // if agent is active router or the child of the device - if ((Mle::Mle::IsActiveRouter(agentRloc16)) || (Mle::Mle::Rloc16FromRouterId(routerId) == mle.GetRloc16())) - { - mMeshDest = agentRloc16; - } - else - { - // use the parent of the ED Agent as Dest - mMeshDest = Mle::Mle::Rloc16FromRouterId(routerId); - } + uint8_t contextId = static_cast(aloc16 & Mle::kAloc16DhcpAgentMask); + SuccessOrExit(error = ContextIdRouteLookup(contextId, mMeshDest)); } else if (aloc16 <= Mle::kAloc16ServiceEnd) { @@ -931,11 +994,7 @@ Error MeshForwarder::GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint cost = Get().GetLinkCost(Mle::Mle::RouterIdFromRloc16(server16)); } - // Choose the minimum cost - if (cost < curCost) - { - curCost = cost; - } + curCost = OT_MIN(curCost, cost); } if ((bestDest == Mac::kShortAddrInvalid) || (curCost < bestCost)) diff --git a/src/core/thread/network_data_leader.cpp b/src/core/thread/network_data_leader.cpp index 28b8a518c..922dfc8ad 100644 --- a/src/core/thread/network_data_leader.cpp +++ b/src/core/thread/network_data_leader.cpp @@ -177,30 +177,6 @@ exit: return error; } -Error LeaderBase::GetRlocByContextId(uint8_t aContextId, uint16_t &aRloc16) const -{ - Error error = kErrorNotFound; - Lowpan::Context lowpanContext; - - if ((GetContext(aContextId, lowpanContext)) == kErrorNone) - { - Iterator iterator = kIteratorInit; - OnMeshPrefixConfig config; - - while (GetNextOnMeshPrefix(iterator, config) == kErrorNone) - { - if (lowpanContext.mPrefix.ContainsPrefix(config.GetPrefix())) - { - aRloc16 = config.mRloc16; - ExitNow(error = kErrorNone); - } - } - } - -exit: - return error; -} - bool LeaderBase::IsOnMesh(const Ip6::Address &aAddress) const { const PrefixTlv *prefix = nullptr; diff --git a/src/core/thread/network_data_leader.hpp b/src/core/thread/network_data_leader.hpp index 3735ad010..e3c56961f 100644 --- a/src/core/thread/network_data_leader.hpp +++ b/src/core/thread/network_data_leader.hpp @@ -254,18 +254,6 @@ public: */ Error SteeringDataCheckJoiner(const MeshCoP::JoinerDiscerner &aDiscerner) const; - /** - * This method gets the RLOC of DHCP Agent of specified contextId. - * - * @param[in] aContextId A pointer to the Commissioning Data value. - * @param[out] aRloc16 The reference of which for output the RLOC16. - * - * @retval kErrorNone Successfully get the RLOC of DHCP Agent. - * @retval kErrorNotFound The specified @p aContextId could not be found. - * - */ - Error GetRlocByContextId(uint8_t aContextId, uint16_t &aRloc16) const; - /** * This method gets the Service ID for the specified service. *