mirror of
https://github.com/espressif/openthread.git
synced 2026-08-21 01:49:52 +00:00
[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:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user