mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 05:37:46 +00:00
[mle] fix bug in leader active/pending dataset synchronization (#5021)
The leader is the authoritative source when propagating active/pending operational datasets. When the leader reboots, it is possible for the leader to become out-of-sync. In particular, after the leader resets, it restores its network data and active/pending operational datasets using MLE Data Request/Response to retrieve them from a neighboring device. If the neighboring device has an older active/pending operational dataset, the leader will retrieve the older datasets and never attempt to propagate the newer datasets that it may have stored locally. This commit makes the following changes: - The leader does not accept any changes to the active/pending operational datasets. - After retrieving the latest network data from a neighboring device (as part of resynchronizing after reset), the leader will increment the full and stable network data versions to ensure that the leader propagates the latest active/pending operational datasets.
This commit is contained in:
+26
-17
@@ -3024,7 +3024,7 @@ otError Mle::HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &a
|
||||
|
||||
// if received timestamp does not match the local value and message does not contain the dataset,
|
||||
// send MLE Data Request
|
||||
if ((timestamp == NULL || timestamp->Compare(activeTimestamp) != 0) &&
|
||||
if (!IsLeader() && ((timestamp == NULL) || (timestamp->Compare(activeTimestamp) != 0)) &&
|
||||
(Tlv::FindTlvOffset(aMessage, Tlv::kActiveDataset, activeDatasetOffset) != OT_ERROR_NONE))
|
||||
{
|
||||
ExitNow(dataRequest = true);
|
||||
@@ -3045,7 +3045,7 @@ otError Mle::HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &a
|
||||
|
||||
// if received timestamp does not match the local value and message does not contain the dataset,
|
||||
// send MLE Data Request
|
||||
if ((timestamp == NULL || timestamp->Compare(pendingTimestamp) != 0) &&
|
||||
if (!IsLeader() && ((timestamp == NULL) || (timestamp->Compare(pendingTimestamp) != 0)) &&
|
||||
(Tlv::FindTlvOffset(aMessage, Tlv::kPendingDataset, pendingDatasetOffset) != OT_ERROR_NONE))
|
||||
{
|
||||
ExitNow(dataRequest = true);
|
||||
@@ -3068,25 +3068,34 @@ otError Mle::HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &a
|
||||
ExitNow(dataRequest = true);
|
||||
}
|
||||
|
||||
// Active Dataset
|
||||
if (activeTimestamp.GetLength() > 0)
|
||||
#if OPENTHREAD_FTD
|
||||
if (IsLeader())
|
||||
{
|
||||
if (activeDatasetOffset > 0)
|
||||
{
|
||||
aMessage.Read(activeDatasetOffset, sizeof(tlv), &tlv);
|
||||
IgnoreError(Get<MeshCoP::ActiveDataset>().Save(activeTimestamp, aMessage, activeDatasetOffset + sizeof(tlv),
|
||||
tlv.GetLength()));
|
||||
}
|
||||
Get<NetworkData::Leader>().IncrementVersionAndStableVersion();
|
||||
}
|
||||
|
||||
// Pending Dataset
|
||||
if (pendingTimestamp.GetLength() > 0)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (pendingDatasetOffset > 0)
|
||||
// Active Dataset
|
||||
if (activeTimestamp.GetLength() > 0)
|
||||
{
|
||||
aMessage.Read(pendingDatasetOffset, sizeof(tlv), &tlv);
|
||||
IgnoreError(Get<MeshCoP::PendingDataset>().Save(pendingTimestamp, aMessage,
|
||||
pendingDatasetOffset + sizeof(tlv), tlv.GetLength()));
|
||||
if (activeDatasetOffset > 0)
|
||||
{
|
||||
aMessage.Read(activeDatasetOffset, sizeof(tlv), &tlv);
|
||||
IgnoreError(Get<MeshCoP::ActiveDataset>().Save(activeTimestamp, aMessage,
|
||||
activeDatasetOffset + sizeof(tlv), tlv.GetLength()));
|
||||
}
|
||||
}
|
||||
|
||||
// Pending Dataset
|
||||
if (pendingTimestamp.GetLength() > 0)
|
||||
{
|
||||
if (pendingDatasetOffset > 0)
|
||||
{
|
||||
aMessage.Read(pendingDatasetOffset, sizeof(tlv), &tlv);
|
||||
IgnoreError(Get<MeshCoP::PendingDataset>().Save(pendingTimestamp, aMessage,
|
||||
pendingDatasetOffset + sizeof(tlv), tlv.GetLength()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user