[network-data] refactor anycast dest lookup to NetworkData::Leader (#10493)

This commit refactors the code and methods responsible for looking up
anycast destination, moving them from the `MeshForwarder` class to
the more appropriate `NetworkData::Leader` class. This better aligns
the responsibilities of each module (e.g. `RouteLookup()` is provided
by `NetworkData::Leader). This is a pure refactor with no changes or
enhancements to the existing implementation.
This commit is contained in:
Abtin Keshavarzian
2024-07-09 11:24:37 -07:00
committed by GitHub
parent bf5ddb908e
commit 695e7a50a3
4 changed files with 166 additions and 141 deletions
-9
View File
@@ -404,13 +404,6 @@ private:
#endif
};
enum AnycastType : uint8_t
{
kAnycastDhcp6Agent,
kAnycastNeighborDiscoveryAgent,
kAnycastService,
};
struct RxInfo : public InstanceLocator
{
static constexpr uint16_t kInfoStringSize = 70;
@@ -557,8 +550,6 @@ private:
void SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::Headers &aIp6Headers);
Error UpdateIp6Route(Message &aMessage);
Error UpdateIp6RouteFtd(const Ip6::Header &aIp6Header, Message &aMessage);
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,
+1 -132
View File
@@ -408,102 +408,6 @@ exit:
return error;
}
void MeshForwarder::EvaluateRoutingCost(uint16_t aDest, uint8_t &aBestCost, uint16_t &aBestDest) const
{
uint8_t cost = Get<RouterTable>().GetPathCost(aDest);
if ((aBestDest == Mle::kInvalidRloc16) || (cost < aBestCost))
{
aBestDest = aDest;
aBestCost = cost;
}
}
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 = Mle::kInvalidRloc16;
switch (aType)
{
case kAnycastDhcp6Agent:
case kAnycastNeighborDiscoveryAgent:
{
NetworkData::OnMeshPrefixConfig config;
Lowpan::Context context;
SuccessOrExit(Get<NetworkData::Leader>().GetContext(aServiceId, context));
while (Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, config) == kErrorNone)
{
if (config.GetPrefix() != context.mPrefix)
{
continue;
}
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<NetworkData::Leader>().GetNextService(iterator, config) == kErrorNone)
{
if (config.mServiceId != aServiceId)
{
continue;
}
EvaluateRoutingCost(config.mServerConfig.mRloc16, bestCost, bestDest);
}
break;
}
}
if (Mle::IsChildRloc16(bestDest))
{
// If the selected destination is a child, we use its parent
// as the destination unless the device itself is the
// parent of the `bestDest`.
uint16_t bestDestParent = Mle::ParentRloc16ForRloc16(bestDest);
if (!Get<Mle::Mle>().HasRloc16(bestDestParent))
{
bestDest = bestDestParent;
}
}
aMeshDest = bestDest;
exit:
return (bestDest != Mle::kInvalidRloc16) ? kErrorNone : kErrorNoRoute;
}
Error MeshForwarder::UpdateIp6RouteFtd(const Ip6::Header &aIp6Header, Message &aMessage)
{
Mle::MleRouter &mle = Get<Mle::MleRouter>();
@@ -524,42 +428,7 @@ Error MeshForwarder::UpdateIp6RouteFtd(const Ip6::Header &aIp6Header, Message &a
{
uint16_t aloc16 = aIp6Header.GetDestination().GetIid().GetLocator();
if (aloc16 == Mle::kAloc16Leader)
{
mMeshDest = mle.GetLeaderRloc16();
}
else if (aloc16 <= Mle::kAloc16DhcpAgentEnd)
{
uint8_t contextId = static_cast<uint8_t>(aloc16 - Mle::kAloc16DhcpAgentStart + 1);
SuccessOrExit(error = AnycastRouteLookup(contextId, kAnycastDhcp6Agent, mMeshDest));
}
else if (aloc16 <= Mle::kAloc16ServiceEnd)
{
uint8_t serviceId = static_cast<uint8_t>(aloc16 - Mle::kAloc16ServiceStart);
SuccessOrExit(error = AnycastRouteLookup(serviceId, kAnycastService, mMeshDest));
}
else if (aloc16 <= Mle::kAloc16CommissionerEnd)
{
SuccessOrExit(error = Get<NetworkData::Leader>().FindBorderAgentRloc(mMeshDest));
}
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
else if (aloc16 == Mle::kAloc16BackboneRouterPrimary)
{
VerifyOrExit(Get<BackboneRouter::Leader>().HasPrimary(), error = kErrorDrop);
mMeshDest = Get<BackboneRouter::Leader>().GetServer16();
}
#endif
else if ((aloc16 >= Mle::kAloc16NeighborDiscoveryAgentStart) &&
(aloc16 <= Mle::kAloc16NeighborDiscoveryAgentEnd))
{
uint8_t contextId = static_cast<uint8_t>(aloc16 - Mle::kAloc16NeighborDiscoveryAgentStart + 1);
SuccessOrExit(error = AnycastRouteLookup(contextId, kAnycastNeighborDiscoveryAgent, mMeshDest));
}
else
{
ExitNow(error = kErrorDrop);
}
SuccessOrExit(error = Get<NetworkData::Leader>().AnycastLookup(aloc16, mMeshDest));
// If the selected ALOC destination, `mMeshDest`, is a sleepy
// child of this device, prepare the message for indirect tx
+23
View File
@@ -363,6 +363,19 @@ public:
*/
void IncrementVersionAndStableVersion(void);
/**
* Performs anycast ALOC route lookup using the Network Data.
*
* @param[in] aAloc16 The ALOC16 destination to lookup.
* @param[out] aRloc16 A reference to return the RLOC16 for the selected route.
*
* @retval kErrorNone Successfully lookup best option for @p aAloc16. @p aRloc16 is updated.
* @retval kErrorNoRoute No valid route was found.
* @retval kErrorDrop The @p aAloc16 is not valid.
*
*/
Error AnycastLookup(uint16_t aAloc16, uint16_t &aRloc16) const;
/**
* Returns CONTEXT_ID_RESUSE_DELAY value.
*
@@ -467,6 +480,13 @@ private:
static constexpr uint8_t kMinServiceId = 0x00;
static constexpr uint8_t kMaxServiceId = 0x0f;
enum AnycastType : uint8_t
{
kAnycastDhcp6Agent,
kAnycastNdAgent,
kAnycastService,
};
class ChangedFlags
{
public:
@@ -551,6 +571,9 @@ private:
void HandleTimer(void);
Error AnycastLookup(uint8_t aServiceId, AnycastType aType, uint16_t &aRloc16) const;
void EvaluateRoutingCost(uint16_t aDest, uint8_t &aBestCost, uint16_t &aBestDest) const;
void RegisterNetworkData(uint16_t aRloc16, const NetworkData &aNetworkData);
Error AddPrefix(const PrefixTlv &aPrefix, ChangedFlags &aChangedFlags);
+142
View File
@@ -115,6 +115,148 @@ exit:
return;
}
Error Leader::AnycastLookup(uint16_t aAloc16, uint16_t &aRloc16) const
{
Error error = kErrorNone;
if (aAloc16 == Mle::kAloc16Leader)
{
aRloc16 = Get<Mle::Mle>().GetLeaderRloc16();
}
else if (aAloc16 <= Mle::kAloc16DhcpAgentEnd)
{
uint8_t contextId = static_cast<uint8_t>(aAloc16 - Mle::kAloc16DhcpAgentStart + 1);
error = AnycastLookup(contextId, kAnycastDhcp6Agent, aRloc16);
}
else if (aAloc16 <= Mle::kAloc16ServiceEnd)
{
uint8_t serviceId = static_cast<uint8_t>(aAloc16 - Mle::kAloc16ServiceStart);
error = AnycastLookup(serviceId, kAnycastService, aRloc16);
}
else if (aAloc16 <= Mle::kAloc16CommissionerEnd)
{
error = FindBorderAgentRloc(aRloc16);
}
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
else if (aAloc16 == Mle::kAloc16BackboneRouterPrimary)
{
VerifyOrExit(Get<BackboneRouter::Leader>().HasPrimary(), error = kErrorDrop);
aRloc16 = Get<BackboneRouter::Leader>().GetServer16();
}
#endif
else if ((aAloc16 >= Mle::kAloc16NeighborDiscoveryAgentStart) && (aAloc16 <= Mle::kAloc16NeighborDiscoveryAgentEnd))
{
uint8_t contextId = static_cast<uint8_t>(aAloc16 - Mle::kAloc16NeighborDiscoveryAgentStart + 1);
error = AnycastLookup(contextId, kAnycastNdAgent, aRloc16);
}
else
{
ExitNow(error = kErrorDrop);
}
exit:
return error;
}
Error Leader::AnycastLookup(uint8_t aServiceId, AnycastType aType, uint16_t &aRloc16) const
{
Iterator iterator = kIteratorInit;
uint8_t bestCost = Mle::kMaxRouteCost;
uint16_t bestDest = Mle::kInvalidRloc16;
switch (aType)
{
case kAnycastDhcp6Agent:
case kAnycastNdAgent:
{
OnMeshPrefixConfig config;
Lowpan::Context context;
SuccessOrExit(GetContext(aServiceId, context));
while (GetNextOnMeshPrefix(iterator, config) == kErrorNone)
{
if (config.GetPrefix() != context.mPrefix)
{
continue;
}
switch (aType)
{
case kAnycastDhcp6Agent:
if (!(config.mDhcp || config.mConfigure))
{
continue;
}
break;
case kAnycastNdAgent:
if (!config.mNdDns)
{
continue;
}
break;
default:
OT_ASSERT(false);
break;
}
EvaluateRoutingCost(config.mRloc16, bestCost, bestDest);
}
break;
}
case kAnycastService:
{
ServiceConfig config;
while (GetNextService(iterator, config) == kErrorNone)
{
if (config.mServiceId != aServiceId)
{
continue;
}
EvaluateRoutingCost(config.mServerConfig.mRloc16, bestCost, bestDest);
}
break;
}
}
if (Mle::IsChildRloc16(bestDest))
{
// If the selected destination is a child, we use its parent
// as the destination unless the device itself is the
// parent of the `bestDest`.
uint16_t bestDestParent = Mle::ParentRloc16ForRloc16(bestDest);
if (!Get<Mle::Mle>().HasRloc16(bestDestParent))
{
bestDest = bestDestParent;
}
}
aRloc16 = bestDest;
exit:
return (bestDest != Mle::kInvalidRloc16) ? kErrorNone : kErrorNoRoute;
}
void Leader::EvaluateRoutingCost(uint16_t aDest, uint8_t &aBestCost, uint16_t &aBestDest) const
{
uint8_t cost = Get<RouterTable>().GetPathCost(aDest);
if ((aBestDest == Mle::kInvalidRloc16) || (cost < aBestCost))
{
aBestDest = aDest;
aBestCost = cost;
}
}
void Leader::RemoveBorderRouter(uint16_t aRloc16, MatchMode aMatchMode)
{
ChangedFlags flags;