From 970fe23dd73781423684f46c31476513f845ad42 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Mon, 12 Apr 2021 16:09:41 -0700 Subject: [PATCH] [mesh-forwarder] combine anycast routing functions (#6423) --- src/core/thread/mesh_forwarder.hpp | 6 +- src/core/thread/mesh_forwarder_ftd.cpp | 245 ++++++++++--------------- 2 files changed, 97 insertions(+), 154 deletions(-) diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index 19a6e690f..643a4bce4 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -343,6 +343,7 @@ private: { kAnycastDhcp6Agent, kAnycastNeighborDiscoveryAgent, + kAnycastService, }; #if OPENTHREAD_FTD @@ -446,7 +447,8 @@ 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, AnycastType aType, uint16_t &aMeshDest) const; + void EvaluateRoutingCost(uint16_t aDest, uint8_t &aBestCost, uint16_t &aBestDest) const; + Error AnycastRouteLookup(uint8_t aServiceId, AnycastType aType, uint16_t &aMeshDest) const; Error UpdateMeshRoute(Message &aMessage); bool UpdateReassemblyList(void); void UpdateFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader, @@ -484,8 +486,6 @@ private: const Mac::Address &aMeshDest, Message::Priority & aPriority); - Error GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint16_t &aMeshDest); - bool CalcIePresent(const Message *aMessage); uint16_t CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent); #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index 37775d6de..4581e9300 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -402,83 +402,113 @@ exit: return error; } -Error MeshForwarder::ContextIdRouteLookup(uint8_t aContextId, AnycastType aType, uint16_t &aMeshDest) const +void MeshForwarder::EvaluateRoutingCost(uint16_t aDest, uint8_t &aBestCost, uint16_t &aBestDest) 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; + const Neighbor *neighbor; + uint8_t curCost = 0x00; - SuccessOrExit(Get().GetContext(aContextId, context)); + // Path cost + curCost = Get().GetCost(aDest); - while (Get().GetNextOnMeshPrefix(iterator, config) == kErrorNone) + if (!Mle::MleRouter::IsActiveRouter(aDest)) { - uint16_t server16 = config.mRloc16; - uint8_t curCost = 0x00; - const Neighbor *neighbor; + // Assume best link between remote child server and its parent. + curCost += 1; + } - if (config.GetPrefix() != context.mPrefix) + // Cost if the server is direct neighbor. + neighbor = Get().FindNeighbor(aDest); + + if (neighbor != nullptr && neighbor->IsStateValid()) + { + uint8_t cost; + + if (!Mle::MleRouter::IsActiveRouter(aDest)) { - continue; + // 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(aDest)); } - switch (aType) + // Choose the minimum cost + curCost = OT_MIN(curCost, cost); + } + + if ((aBestDest == Mac::kShortAddrInvalid) || (curCost < aBestCost)) + { + aBestDest = aDest; + aBestCost = curCost; + } +} + +Error MeshForwarder::AnycastRouteLookup(uint8_t aServiceId, AnycastType aType, uint16_t &aMeshDest) const +{ + NetworkData::Iterator iterator = NetworkData::kIteratorInit; + uint8_t bestCost = Mle::kMaxRouteCost; + uint16_t bestDest = Mac::kShortAddrInvalid; + uint8_t routerId; + + switch (aType) + { + case kAnycastDhcp6Agent: + case kAnycastNeighborDiscoveryAgent: + { + NetworkData::OnMeshPrefixConfig config; + Lowpan::Context context; + + SuccessOrExit(Get().GetContext(aServiceId, context)); + + while (Get().GetNextOnMeshPrefix(iterator, config) == kErrorNone) { - case kAnycastDhcp6Agent: - if (!(config.mDhcp || config.mConfigure)) + if (config.GetPrefix() != context.mPrefix) { continue; } - break; - case kAnycastNeighborDiscoveryAgent: - if (!config.mNdDns) + + switch (aType) + { + case kAnycastDhcp6Agent: + if (!(config.mDhcp || config.mConfigure)) + { + continue; + } + break; + case kAnycastNeighborDiscoveryAgent: + if (!config.mNdDns) + { + continue; + } + break; + default: + OT_ASSERT(false); + break; + } + + EvaluateRoutingCost(config.mRloc16, bestCost, bestDest); + } + + break; + } + case kAnycastService: + { + NetworkData::ServiceConfig config; + + while (Get().GetNextService(iterator, config) == kErrorNone) + { + if (config.mServiceId != aServiceId) { continue; } - break; + + EvaluateRoutingCost(config.mServerConfig.mRloc16, bestCost, bestDest); } - // 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; - } + break; + } } routerId = Mle::Mle::RouterIdFromRloc16(bestDest); @@ -524,11 +554,12 @@ Error MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header, Message &aMessage else if (aloc16 <= Mle::kAloc16DhcpAgentEnd) { uint8_t contextId = static_cast(aloc16 - Mle::kAloc16DhcpAgentStart + 1); - SuccessOrExit(error = ContextIdRouteLookup(contextId, kAnycastDhcp6Agent, mMeshDest)); + SuccessOrExit(error = AnycastRouteLookup(contextId, kAnycastDhcp6Agent, mMeshDest)); } else if (aloc16 <= Mle::kAloc16ServiceEnd) { - SuccessOrExit(error = GetDestinationRlocByServiceAloc(aloc16, mMeshDest)); + uint8_t serviceId = static_cast(aloc16 - Mle::kAloc16ServiceStart); + SuccessOrExit(error = AnycastRouteLookup(serviceId, kAnycastService, mMeshDest)); } else if (aloc16 <= Mle::kAloc16CommissionerEnd) { @@ -546,7 +577,7 @@ Error MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header, Message &aMessage (aloc16 <= Mle::kAloc16NeighborDiscoveryAgentEnd)) { uint8_t contextId = static_cast(aloc16 - Mle::kAloc16NeighborDiscoveryAgentStart + 1); - SuccessOrExit(error = ContextIdRouteLookup(contextId, kAnycastNeighborDiscoveryAgent, mMeshDest)); + SuccessOrExit(error = AnycastRouteLookup(contextId, kAnycastNeighborDiscoveryAgent, mMeshDest)); } else { @@ -965,94 +996,6 @@ exit: return; } -Error MeshForwarder::GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint16_t &aMeshDest) -{ - Error error = kErrorNone; - uint8_t serviceId = Mle::Mle::ServiceIdFromAloc(aServiceAloc); - const NetworkData::ServiceTlv *serviceTlv = Get().FindServiceById(serviceId); - - if (serviceTlv != nullptr) - { - const NetworkData::NetworkDataTlv *cur = serviceTlv->GetSubTlvs(); - const NetworkData::NetworkDataTlv *end = serviceTlv->GetNext(); - Neighbor * neighbor; - uint16_t server16; - uint8_t bestCost = Mle::kMaxRouteCost; - uint8_t curCost = 0x00; - uint16_t bestDest = Mac::kShortAddrInvalid; - - while (cur < end) - { - switch (cur->GetType()) - { - case NetworkData::NetworkDataTlv::kTypeServer: - server16 = static_cast(cur)->GetServer16(); - - // 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)); - } - - curCost = OT_MIN(curCost, cost); - } - - if ((bestDest == Mac::kShortAddrInvalid) || (curCost < bestCost)) - { - bestDest = server16; - bestCost = curCost; - } - - break; - - default: - break; - } - - cur = cur->GetNext(); - } - - if (bestDest != Mac::kShortAddrInvalid) - { - aMeshDest = bestDest; - } - else - { - // ServiceTLV without ServerTLV? Can't forward packet anywhere. - ExitNow(error = kErrorNoRoute); - } - } - else - { - // Unknown service, can't forward - ExitNow(error = kErrorNoRoute); - } - -exit: - return error; -} - // LCOV_EXCL_START #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE) && (OPENTHREAD_CONFIG_LOG_MAC == 1)