[mesh-forwarder] do not remove router on link failures (#4753)

A router coming out of reset sends a Link Request to re-establish its
router role and links to neighboring routers. The existing
implementation only responds to such Link Requests when a valid
neighbor entry is found. This check is too strict and can cause
partitions to remain for a couple minutes. The Thread Specification
only requires a router to check that the Router ID is currently
allocated.

This commit updates the implementation to be conformant with the
Thread Specification and allows routers coming out of reset to
resynchronize even when a neighboring router has detect a link
failure.
This commit is contained in:
Jonathan Hui
2020-03-30 11:47:37 -07:00
committed by GitHub
parent ec9968e1d1
commit f8de062657
3 changed files with 33 additions and 1 deletions
+1 -1
View File
@@ -810,7 +810,7 @@ Neighbor *MeshForwarder::UpdateNeighborOnSentFrame(Mac::TxFrame &aFrame, otError
if (neighbor->GetLinkFailures() >= Mle::kFailedRouterTransmissions)
{
Get<Mle::MleRouter>().RemoveNeighbor(*neighbor);
Get<Mle::MleRouter>().RemoveRouterLink(*static_cast<Router *>(neighbor));
}
}
+23
View File
@@ -3267,6 +3267,29 @@ bool MleRouter::IsMinimalChild(uint16_t aRloc16)
return rval;
}
void MleRouter::RemoveRouterLink(Router &aRouter)
{
switch (mRole)
{
case OT_DEVICE_ROLE_CHILD:
if (&aRouter == &mParent)
{
BecomeDetached();
}
break;
#if OPENTHREAD_FTD
case OT_DEVICE_ROLE_ROUTER:
case OT_DEVICE_ROLE_LEADER:
mRouterTable.RemoveNeighbor(aRouter);
break;
#endif
default:
break;
}
}
void MleRouter::RemoveNeighbor(Neighbor &aNeighbor)
{
if (&aNeighbor == &mParent)
+9
View File
@@ -327,6 +327,14 @@ public:
*/
void RemoveNeighbor(Neighbor &aNeighbor);
/**
* This method invalidates a direct link to a neighboring router (due to failed link-layer acks).
*
* @param[in] aRouter A reference to the router object.
*
*/
void RemoveRouterLink(Router &aRouter);
/**
* This method restores children information from non-volatile memory.
*
@@ -844,6 +852,7 @@ public:
uint8_t GetCost(uint16_t) { return 0; }
otError RemoveNeighbor(Neighbor &) { return BecomeDetached(); }
otError RemoveRouterLink(Router &) { return BecomeDetached(); }
Neighbor *GetNeighbor(const Mac::ExtAddress &aAddress) { return Mle::GetNeighbor(aAddress); }
Neighbor *GetNeighbor(const Mac::Address &aAddress) { return Mle::GetNeighbor(aAddress); }