diff --git a/src/core/thread/network_data_leader_ftd.cpp b/src/core/thread/network_data_leader_ftd.cpp index a4fa20a49..c3f219a9c 100644 --- a/src/core/thread/network_data_leader_ftd.cpp +++ b/src/core/thread/network_data_leader_ftd.cpp @@ -1319,9 +1319,34 @@ void Leader::HandleNetworkDataRestoredAfterReset(void) { const PrefixTlv *prefix; TlvIterator tlvIterator(GetTlvsStart(), GetTlvsEnd()); + Iterator iterator = kIteratorInit; + ChangedFlags flags; + uint16_t rloc16; mWaitingForNetDataSync = false; + // Remove entries in Network Data from any un-allocated Router ID. + // This acts as a safeguard against an edge case where the leader + // is reset at an inopportune time, such as right after it removed + // an allocated router ID and sent MLE advertisement but before it + // got the chance to send the updated Network Data to other + // routers. + + while (GetNextServer(iterator, rloc16) == kErrorNone) + { + if (!Get().IsAllocated(Mle::RouterIdFromRloc16(rloc16))) + { + // After we `RemoveRloc()` the Network Data gets changed + // and the `iterator` will not be valid anymore. So we set + // it to `kIteratorInit` to restart the loop. + + RemoveRloc(rloc16, kMatchModeRouterId, flags); + iterator = kIteratorInit; + } + } + + IncrementVersions(flags); + // Synchronize internal 6LoWPAN Context ID Set with the // recently obtained Network Data.