mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[mle] validate peer extended address in Link Accept (#13207)
This commit ensures that the peer's extended address matches the stored extended address when receiving a Link Accept for an already valid link, preventing unintended frame counter resets and neighbor table updates. To achieve this: - We validate that the peer's extended address (extracted from the IPv6 peer address IID) matches the router's stored extended address when processing Link Accepts for a neighbor that is already in the kStateValid state. If there is a mismatch, the packet is rejected with kErrorSecurity. - We gate InitNeighbor() and the resetting of MLE frame counters so they only execute if the neighbor is not already kStateValid. For valid neighbors, we only update link statistics (RSS, last heard, link quality, key sequence) and clear the Link Accept timeout without modifying the frame counters or average RSS history.
This commit is contained in:
+26
-11
@@ -903,6 +903,7 @@ void Mle::HandleLinkAcceptVariant(RxInfo &aRxInfo, MessageType aMessageType)
|
||||
LeaderData leaderData;
|
||||
uint8_t linkMargin;
|
||||
bool shouldUpdateRoutes = false;
|
||||
Mac::ExtAddress extAddress;
|
||||
|
||||
SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress));
|
||||
|
||||
@@ -928,6 +929,8 @@ void Mle::HandleLinkAcceptVariant(RxInfo &aRxInfo, MessageType aMessageType)
|
||||
break;
|
||||
|
||||
case Neighbor::kStateValid:
|
||||
extAddress.SetFromIid(aRxInfo.mMessageInfo.GetPeerAddr().GetIid());
|
||||
VerifyOrExit(router->GetExtAddress() == extAddress, error = kErrorSecurity);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1042,20 +1045,32 @@ void Mle::HandleLinkAcceptVariant(RxInfo &aRxInfo, MessageType aMessageType)
|
||||
OT_ASSERT(false);
|
||||
}
|
||||
|
||||
InitNeighbor(*router, aRxInfo);
|
||||
router->SetRloc16(sourceAddress);
|
||||
router->GetLinkFrameCounters().SetAll(linkFrameCounter);
|
||||
router->SetLinkAckFrameCounter(linkFrameCounter);
|
||||
router->SetMleFrameCounter(mleFrameCounter);
|
||||
router->SetVersion(version);
|
||||
router->SetDeviceMode(DeviceMode(DeviceMode::kModeFullThreadDevice | DeviceMode::kModeRxOnWhenIdle |
|
||||
DeviceMode::kModeFullNetworkData));
|
||||
if (neighborState != Neighbor::kStateValid)
|
||||
{
|
||||
InitNeighbor(*router, aRxInfo);
|
||||
router->SetRloc16(sourceAddress);
|
||||
router->GetLinkFrameCounters().SetAll(linkFrameCounter);
|
||||
router->SetLinkAckFrameCounter(linkFrameCounter);
|
||||
router->SetMleFrameCounter(mleFrameCounter);
|
||||
router->SetDeviceMode(DeviceMode(DeviceMode::kModeFullThreadDevice | DeviceMode::kModeRxOnWhenIdle |
|
||||
DeviceMode::kModeFullNetworkData));
|
||||
router->SetKeySequence(aRxInfo.mKeySequence);
|
||||
router->SetState(Neighbor::kStateValid);
|
||||
}
|
||||
else
|
||||
{
|
||||
router->GetLinkInfo().AddRss(aRxInfo.mMessage.GetAverageRss());
|
||||
router->SetLastHeard(TimerMilli::GetNow());
|
||||
}
|
||||
|
||||
router->SetLinkQualityOut(LinkQualityForLinkMargin(linkMargin));
|
||||
router->SetState(Neighbor::kStateValid);
|
||||
router->SetKeySequence(aRxInfo.mKeySequence);
|
||||
router->SetVersion(version);
|
||||
router->ClearLinkAcceptTimeout();
|
||||
|
||||
mNeighborTable.Signal(NeighborTable::kRouterAdded, *router);
|
||||
if (neighborState != Neighbor::kStateValid)
|
||||
{
|
||||
mNeighborTable.Signal(NeighborTable::kRouterAdded, *router);
|
||||
}
|
||||
|
||||
mDelayedSender.RemoveScheduledLinkRequest(*router);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user