[mesh-forwarder] use path cost in DHCPv6 ALOC lookup (#6423)

This commit is contained in:
Jonathan Hui
2021-04-13 21:12:41 -07:00
parent e18df9beb1
commit 1363316f5e
4 changed files with 83 additions and 59 deletions
+1
View File
@@ -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,
+82 -23
View File
@@ -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<NetworkData::Leader>().GetContext(aContextId, context));
while (Get<NetworkData::Leader>().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<Mle::MleRouter>().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<NeighborTable>().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<Mle::MleRouter>().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<Mle::MleRouter>().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<Mle::MleRouter>();
@@ -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<NetworkData::Leader>().GetRlocByContextId(
static_cast<uint8_t>(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<uint8_t>(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<Mle::MleRouter>().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))
-24
View File
@@ -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;
-12
View File
@@ -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.
*