[mle] clear router table before processing RouteTlv (#3334)

This commit removes the call to clear the `mRouterTable` from
`SetStateRouter()` and instead performs it before processing of a
received RouteTlv (before `ProcessRouteTlv()`). This ensures that
router table and router id allocation list are not deleted after a
router node reset recovery.

This change addresses a rare subtle issue where if a router node and a
leader node are reset sequentially within a short time interval, the
router node upon reset can delete the router id allocation list
(RouteTlv) which in turn causes the leader to ignore "MLE Link Accept"
message it receives from router (after leader resets and tries to
recover) and thus cause the leader to form a new partition. This can
potentially lead to a situation where the two nodes stay in two
partitions without merging.
This commit is contained in:
Abtin Keshavarzian
2018-11-30 12:27:41 -08:00
committed by Jonathan Hui
parent 8ad315f725
commit 305330114a
+3 -4
View File
@@ -322,8 +322,6 @@ otError MleRouter::SetStateRouter(uint16_t aRloc16)
netif.GetIp6().GetMpl().SetTimerExpirations(kMplRouterDataMessageTimerExpirations);
netif.GetMac().SetBeaconEnabled(true);
mRouterTable.Clear();
// remove children that do not have matching RLOC16
for (ChildTable::Iterator iter(GetInstance(), ChildTable::kInStateValidOrRestoring); !iter.IsDone(); iter++)
{
@@ -926,8 +924,8 @@ otError MleRouter::HandleLinkAccept(const Message & aMessage,
// Route
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kRoute, sizeof(route), route));
VerifyOrExit(route.IsValid(), error = OT_ERROR_PARSE);
mRouterTable.Clear();
SuccessOrExit(error = ProcessRouteTlv(route));
router = mRouterTable.GetRouter(routerId);
VerifyOrExit(router != NULL);
@@ -3976,8 +3974,9 @@ void MleRouter::HandleAddressSolicitResponse(Coap::Header * aHeader,
// assign short address
SetRouterId(routerId);
SuccessOrExit(SetStateRouter(GetRloc16(mRouterId)));
SuccessOrExit(SetStateRouter(GetRloc16(mRouterId)));
mRouterTable.Clear();
mRouterTable.ProcessTlv(routerMaskTlv);
router = mRouterTable.GetRouter(routerId);