[mle] keep router table next hop and cost on REED to router promotion (#8657)

This commit updates `MleRouter` such that on promotion from REED to
router role, we keep the router table's next hop and cost as what we
had as a REED, i.e., our parent being the next hop towards all other
routers and we tracked its cost towards them. As an FED, device may
have also established links with a subset of neighboring routers. We
ensure to clear the link to these neighbor to avoid using them since
the neighboring router will drop messages from us till we re-establish
link using our new RLOC16.
This commit is contained in:
Abtin Keshavarzian
2023-01-17 09:45:23 -08:00
committed by GitHub
parent 19475e3de8
commit b832cb2c49
+18 -11
View File
@@ -3393,7 +3393,6 @@ void MleRouter::HandleAddressSolicitResponse(Coap::Message *aMessage,
ThreadRouterMaskTlv routerMaskTlv;
uint8_t routerId;
Router *router;
Router *leader;
bool isRouterIdAllocated;
mAddressSolicitPending = false;
@@ -3435,30 +3434,38 @@ void MleRouter::HandleAddressSolicitResponse(Coap::Message *aMessage,
SetRouterId(routerId);
SetStateRouter(Rloc16FromRouterId(mRouterId));
mRouterTable.Clear();
// We keep the router table next hop and cost as what we had as a
// REED, i.e., our parent was the next hop towards all other
// routers and we tracked its cost towards them. As FED, we may
// have established links with a subset of neighboring routers.
// We ensure to clear these links to avoid using them (since will
// be rejected by the neighbor).
mRouterTable.ClearNeighbors();
mRouterTable.UpdateRouterIdSet(routerMaskTlv.GetIdSequence(), routerMaskTlv.GetAssignedRouterIdMask());
router = mRouterTable.FindRouterById(routerId);
VerifyOrExit(router != nullptr);
router->SetExtAddress(Get<Mac::Mac>().GetExtAddress());
router->SetNextHopToInvalid();
// Ensure we have our parent as a neighboring router, copying the
// `mParent` entry.
router = mRouterTable.FindRouterById(mParent.GetRouterId());
VerifyOrExit(router != nullptr);
// Keep link to the parent in order to respond to Parent Requests before new link is established.
router->SetFrom(mParent);
router->SetState(Neighbor::kStateValid);
router->SetNextHopToInvalid();
leader = mRouterTable.GetLeader();
OT_ASSERT(leader != nullptr);
if (leader != router)
// Ensure we have a next hop and cost towards leader.
if (mRouterTable.GetPathCostToLeader() >= kMaxRouteCost)
{
// Keep route path to the Leader reported by the parent before it is updated.
Router *leader = mRouterTable.GetLeader();
OT_ASSERT(leader != nullptr);
leader->SetNextHopAndCost(RouterIdFromRloc16(mParent.GetRloc16()), mParent.GetLeaderCost());
}