mirror of
https://github.com/espressif/openthread.git
synced 2026-09-05 08:40:06 +00:00
[mle] detect duplicate/invalid child info in non-volatile (#2376)
This commit changes the `MleRouter::RestoreChildren()` so that it can detect invalid child info in non-volatile settings (e.g., if there are more entries than max allowed/supported children, or if there are duplicate entries with same ext address in the list). If any error is detected the non-volatile child info is refreshed (erased and re-written).
This commit is contained in:
committed by
Jonathan Hui
parent
a1d6ceef62
commit
935d2d07c9
+1
-17
@@ -347,23 +347,7 @@ otError Mle::Restore(void)
|
||||
{
|
||||
netif.GetMle().SetRouterId(GetRouterId(GetRloc16()));
|
||||
netif.GetMle().SetPreviousPartitionId(networkInfo.mPreviousPartitionId);
|
||||
|
||||
switch (netif.GetMle().RestoreChildren())
|
||||
{
|
||||
// If there are more saved children in non-volatile settings
|
||||
// than could be restored or the values in the settings are
|
||||
// invalid, erase all the children info in the settings and
|
||||
// refresh the info to ensure that the non-volatile settings
|
||||
// stay in sync with the child table.
|
||||
|
||||
case OT_ERROR_FAILED:
|
||||
case OT_ERROR_NO_BUFS:
|
||||
netif.GetMle().RefreshStoredChildren();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
netif.GetMle().RestoreChildren();
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
@@ -3628,19 +3628,21 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError MleRouter::RestoreChildren(void)
|
||||
void MleRouter::RestoreChildren(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
bool foundDuplicate = false;
|
||||
uint8_t index;
|
||||
|
||||
for (uint8_t i = 0; ; i++)
|
||||
for (index = 0; ; index++)
|
||||
{
|
||||
Child *child;
|
||||
Settings::ChildInfo childInfo;
|
||||
uint16_t length;
|
||||
|
||||
length = sizeof(childInfo);
|
||||
SuccessOrExit(error = otPlatSettingsGet(&GetInstance(), Settings::kKeyChildInfo, i,
|
||||
reinterpret_cast<uint8_t *>(&childInfo), &length));
|
||||
SuccessOrExit(otPlatSettingsGet(&GetInstance(), Settings::kKeyChildInfo, index,
|
||||
reinterpret_cast<uint8_t *>(&childInfo), &length));
|
||||
VerifyOrExit(length >= sizeof(childInfo), error = OT_ERROR_PARSE);
|
||||
|
||||
child = FindChild(*static_cast<Mac::ExtAddress *>(&childInfo.mExtAddress));
|
||||
@@ -3649,6 +3651,10 @@ otError MleRouter::RestoreChildren(void)
|
||||
{
|
||||
VerifyOrExit((child = NewChild()) != NULL, error = OT_ERROR_NO_BUFS);
|
||||
}
|
||||
else
|
||||
{
|
||||
foundDuplicate = true;
|
||||
}
|
||||
|
||||
memset(child, 0, sizeof(*child));
|
||||
|
||||
@@ -3662,7 +3668,17 @@ otError MleRouter::RestoreChildren(void)
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
if (foundDuplicate || (index > kMaxChildren) || (error != OT_ERROR_NONE))
|
||||
{
|
||||
// If there is any error, e.g., there are more saved children
|
||||
// in non-volatile settings than could be restored or there are
|
||||
// duplicate entries with same extended address, refresh the stored
|
||||
// children info to ensure that the non-volatile settings remain
|
||||
// consistent with the child table.
|
||||
|
||||
RefreshStoredChildren();
|
||||
}
|
||||
}
|
||||
|
||||
otError MleRouter::RemoveStoredChild(uint16_t aChildRloc16)
|
||||
|
||||
@@ -438,12 +438,8 @@ public:
|
||||
/**
|
||||
* This method restores children information from non-volatile memory.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully restored children information.
|
||||
* @retval OT_ERROR_FAILED The saved child info in non-volatile memory is invalid.
|
||||
* @retval OT_ERROR_NO_BUFS More children in settings than max children.
|
||||
*
|
||||
*/
|
||||
otError RestoreChildren(void);
|
||||
void RestoreChildren(void);
|
||||
|
||||
/**
|
||||
* This method remove a stored child information from non-volatile memory.
|
||||
@@ -467,16 +463,6 @@ public:
|
||||
*/
|
||||
otError StoreChild(uint16_t aChildRloc16);
|
||||
|
||||
/**
|
||||
* This method refreshes all the saved children information in non-volatile memory by first erasing any saved
|
||||
* child information in non-volatile memory and then saving all children info.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully refreshed all children info in non-volatile memory
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient available buffers to store child.
|
||||
*
|
||||
*/
|
||||
otError RefreshStoredChildren(void);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Neighbor object.
|
||||
*
|
||||
@@ -744,6 +730,7 @@ private:
|
||||
otError AppendActiveDataset(Message &aMessage);
|
||||
otError AppendPendingDataset(Message &aMessage);
|
||||
otError GetChildInfo(Child &aChild, otChildInfo &aChildInfo);
|
||||
otError RefreshStoredChildren(void);
|
||||
otError HandleDetachStart(void);
|
||||
otError HandleChildStart(AttachMode aMode);
|
||||
otError HandleLinkRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
@@ -93,10 +93,9 @@ public:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
otError RestoreChildren(void) {return OT_ERROR_NOT_IMPLEMENTED; }
|
||||
void RestoreChildren(void) { }
|
||||
otError RemoveStoredChild(uint16_t) {return OT_ERROR_NOT_IMPLEMENTED; }
|
||||
otError StoreChild(uint16_t) {return OT_ERROR_NOT_IMPLEMENTED; }
|
||||
otError RefreshStoredChildren(void) { return OT_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
Neighbor *GetNeighbor(uint16_t aAddress) { return Mle::GetNeighbor(aAddress); }
|
||||
Neighbor *GetNeighbor(const Mac::ExtAddress &aAddress) { return Mle::GetNeighbor(aAddress); }
|
||||
|
||||
Reference in New Issue
Block a user