Skip to content

Commit

Permalink
[mle] keep router table next hop and cost on REED to router promotion (
Browse files Browse the repository at this point in the history
…openthread#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.
  • Loading branch information
abtink authored Jan 17, 2023
1 parent 19475e3 commit b832cb2
Showing 1 changed file with 18 additions and 11 deletions.
29 changes: 18 additions & 11 deletions src/core/thread/mle_router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3393,7 +3393,6 @@ void MleRouter::HandleAddressSolicitResponse(Coap::Message *aMessage,
ThreadRouterMaskTlv routerMaskTlv;
uint8_t routerId;
Router *router;
Router *leader;
bool isRouterIdAllocated;

mAddressSolicitPending = false;
Expand Down Expand Up @@ -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());
}

Expand Down

0 comments on commit b832cb2

Please sign in to comment.