[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:
Abtin Keshavarzian
2017-11-30 05:29:13 +00:00
committed by Jonathan Hui
parent a1d6ceef62
commit 935d2d07c9
4 changed files with 25 additions and 39 deletions
+1 -17
View File
@@ -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:
+21 -5
View File
@@ -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)
+2 -15
View File
@@ -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);
+1 -2
View File
@@ -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); }