mirror of
https://github.com/espressif/openthread.git
synced 2026-08-19 00:49:53 +00:00
[low-power] add an Enh-ACK frame link layer counter (#5583)
On the transmitter side, only maintain a single frame counter, and never reuse it. On the receiver side, maintain a second incoming frame counter eFC alongside FC for each device, where eFC >= FC >= 0. When an Enh-ACK is received, verify it against eFC. Update eFC to be equal to the received frame counter. Do not touch FC. When a frame other than Enh-ACK is received, verify it against FC. Update both eFC and FC to be equal to the received frame counter.
This commit is contained in:
+34
-21
@@ -1637,6 +1637,12 @@ otError Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Ne
|
||||
}
|
||||
|
||||
aNeighbor->SetLinkFrameCounter(frameCounter + 1);
|
||||
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
||||
if ((frameCounter + 1) > aNeighbor->GetLinkAckFrameCounter())
|
||||
{
|
||||
aNeighbor->SetLinkAckFrameCounter(frameCounter + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (keySequence > keyManager.GetCurrentKeySequence())
|
||||
{
|
||||
@@ -1658,8 +1664,10 @@ otError Mac::ProcessEnhAckSecurity(TxFrame &aTxFrame, RxFrame &aAckFrame)
|
||||
uint8_t txKeyId;
|
||||
uint8_t ackKeyId;
|
||||
uint8_t keyIdMode;
|
||||
uint32_t frameCounter;
|
||||
Address srcAddr;
|
||||
Neighbor * neighbor;
|
||||
Address dstAddr;
|
||||
Neighbor * neighbor = nullptr;
|
||||
KeyManager &keyManager = Get<KeyManager>();
|
||||
const Key * macKey;
|
||||
|
||||
@@ -1677,35 +1685,32 @@ otError Mac::ProcessEnhAckSecurity(TxFrame &aTxFrame, RxFrame &aAckFrame)
|
||||
|
||||
VerifyOrExit(txKeyId == ackKeyId, OT_NOOP);
|
||||
|
||||
IgnoreError(aAckFrame.GetFrameCounter(frameCounter));
|
||||
otLogDebgMac("Rx security - Ack frame counter %u", frameCounter);
|
||||
|
||||
IgnoreError(aAckFrame.GetSrcAddr(srcAddr));
|
||||
|
||||
if (srcAddr.IsShort())
|
||||
if (!srcAddr.IsNone())
|
||||
{
|
||||
neighbor = Get<NeighborTable>().FindNeighbor(srcAddr);
|
||||
|
||||
if (neighbor != nullptr)
|
||||
{
|
||||
srcAddr.SetExtended(neighbor->GetExtAddress());
|
||||
}
|
||||
}
|
||||
|
||||
if (!srcAddr.IsExtended())
|
||||
else
|
||||
{
|
||||
// Get Enh-ACK source address from transmitted frame destination address
|
||||
IgnoreError(aTxFrame.GetDstAddr(srcAddr));
|
||||
IgnoreError(aTxFrame.GetDstAddr(dstAddr));
|
||||
|
||||
if (srcAddr.IsShort())
|
||||
if (!dstAddr.IsNone())
|
||||
{
|
||||
neighbor = Get<NeighborTable>().FindNeighbor(srcAddr);
|
||||
|
||||
if (neighbor != nullptr)
|
||||
{
|
||||
srcAddr.SetExtended(neighbor->GetExtAddress());
|
||||
}
|
||||
// Get neighbor from destination address of transmitted frame
|
||||
neighbor = Get<NeighborTable>().FindNeighbor(dstAddr);
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrExit(srcAddr.IsExtended(), OT_NOOP);
|
||||
if (!srcAddr.IsExtended() && neighbor != nullptr)
|
||||
{
|
||||
srcAddr.SetExtended(neighbor->GetExtAddress());
|
||||
}
|
||||
|
||||
VerifyOrExit(srcAddr.IsExtended() && neighbor != nullptr, OT_NOOP);
|
||||
|
||||
ackKeyId--;
|
||||
|
||||
@@ -1726,9 +1731,17 @@ otError Mac::ProcessEnhAckSecurity(TxFrame &aTxFrame, RxFrame &aAckFrame)
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
if (aAckFrame.ProcessReceiveAesCcm(srcAddr.GetExtended(), *macKey) == OT_ERROR_NONE)
|
||||
if (neighbor->IsStateValid())
|
||||
{
|
||||
error = OT_ERROR_NONE;
|
||||
VerifyOrExit(frameCounter >= neighbor->GetLinkAckFrameCounter(), OT_NOOP);
|
||||
}
|
||||
|
||||
error = aAckFrame.ProcessReceiveAesCcm(srcAddr.GetExtended(), *macKey);
|
||||
SuccessOrExit(error);
|
||||
|
||||
if (neighbor->IsStateValid())
|
||||
{
|
||||
neighbor->SetLinkAckFrameCounter(frameCounter + 1);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
@@ -118,6 +118,7 @@ otError KeyManager::SetMasterKey(const MasterKey &aKey)
|
||||
parent = &Get<Mle::MleRouter>().GetParent();
|
||||
parent->SetKeySequence(0);
|
||||
parent->SetLinkFrameCounter(0);
|
||||
parent->SetLinkAckFrameCounter(0);
|
||||
parent->SetMleFrameCounter(0);
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
@@ -126,6 +127,7 @@ otError KeyManager::SetMasterKey(const MasterKey &aKey)
|
||||
{
|
||||
router.SetKeySequence(0);
|
||||
router.SetLinkFrameCounter(0);
|
||||
router.SetLinkAckFrameCounter(0);
|
||||
router.SetMleFrameCounter(0);
|
||||
}
|
||||
|
||||
@@ -134,6 +136,7 @@ otError KeyManager::SetMasterKey(const MasterKey &aKey)
|
||||
{
|
||||
child.SetKeySequence(0);
|
||||
child.SetLinkFrameCounter(0);
|
||||
child.SetLinkAckFrameCounter(0);
|
||||
child.SetMleFrameCounter(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2630,6 +2630,7 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
|
||||
VerifyOrExit(keySequence > neighbor->GetKeySequence(), error = OT_ERROR_DUPLICATED);
|
||||
neighbor->SetKeySequence(keySequence);
|
||||
neighbor->SetLinkFrameCounter(0);
|
||||
neighbor->SetLinkAckFrameCounter(0);
|
||||
}
|
||||
|
||||
neighbor->SetMleFrameCounter(frameCounter + 1);
|
||||
@@ -3261,6 +3262,7 @@ void Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo &
|
||||
mParentCandidate.SetExtAddress(extAddress);
|
||||
mParentCandidate.SetRloc16(sourceAddress);
|
||||
mParentCandidate.SetLinkFrameCounter(linkFrameCounter);
|
||||
mParentCandidate.SetLinkAckFrameCounter(linkFrameCounter);
|
||||
mParentCandidate.SetMleFrameCounter(mleFrameCounter);
|
||||
mParentCandidate.SetVersion(static_cast<uint8_t>(version));
|
||||
mParentCandidate.SetDeviceMode(DeviceMode(DeviceMode::kModeFullThreadDevice | DeviceMode::kModeRxOnWhenIdle |
|
||||
@@ -3557,6 +3559,7 @@ void Mle::HandleChildUpdateResponse(const Message & aMessage,
|
||||
}
|
||||
|
||||
mParent.SetLinkFrameCounter(linkFrameCounter);
|
||||
mParent.SetLinkAckFrameCounter(linkFrameCounter);
|
||||
mParent.SetMleFrameCounter(mleFrameCounter);
|
||||
|
||||
mParent.SetState(Neighbor::kStateValid);
|
||||
|
||||
@@ -953,6 +953,7 @@ otError MleRouter::HandleLinkAccept(const Message & aMessage,
|
||||
router->SetExtAddress(extAddr);
|
||||
router->SetRloc16(sourceAddress);
|
||||
router->SetLinkFrameCounter(linkFrameCounter);
|
||||
router->SetLinkAckFrameCounter(linkFrameCounter);
|
||||
router->SetMleFrameCounter(mleFrameCounter);
|
||||
router->SetLastHeard(TimerMilli::GetNow());
|
||||
router->SetDeviceMode(DeviceMode(DeviceMode::kModeFullThreadDevice | DeviceMode::kModeRxOnWhenIdle |
|
||||
@@ -2288,6 +2289,7 @@ void MleRouter::HandleChildIdRequest(const Message & aMessage,
|
||||
|
||||
child->SetLastHeard(TimerMilli::GetNow());
|
||||
child->SetLinkFrameCounter(linkFrameCounter);
|
||||
child->SetLinkAckFrameCounter(linkFrameCounter);
|
||||
child->SetMleFrameCounter(mleFrameCounter);
|
||||
child->SetKeySequence(aKeySequence);
|
||||
child->SetDeviceMode(mode);
|
||||
@@ -2609,6 +2611,7 @@ void MleRouter::HandleChildUpdateResponse(const Message & aMessage,
|
||||
{
|
||||
case OT_ERROR_NONE:
|
||||
child->SetLinkFrameCounter(linkFrameCounter);
|
||||
child->SetLinkAckFrameCounter(linkFrameCounter);
|
||||
break;
|
||||
case OT_ERROR_NOT_FOUND:
|
||||
break;
|
||||
|
||||
@@ -415,6 +415,31 @@ public:
|
||||
*/
|
||||
void SetLinkFrameCounter(uint32_t aFrameCounter) { mValidPending.mValid.mLinkFrameCounter = aFrameCounter; }
|
||||
|
||||
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
||||
/**
|
||||
* This method gets the link ACK frame counter value.
|
||||
*
|
||||
* @returns The link ACK frame counter value.
|
||||
*
|
||||
*/
|
||||
uint32_t GetLinkAckFrameCounter(void) const { return mValidPending.mValid.mLinkAckFrameCounter; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This method sets the link ACK frame counter value.
|
||||
*
|
||||
* @param[in] aAckFrameCounter The link ACK frame counter value.
|
||||
*
|
||||
*/
|
||||
void SetLinkAckFrameCounter(uint32_t aAckFrameCounter)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
||||
mValidPending.mValid.mLinkAckFrameCounter = aAckFrameCounter;
|
||||
#else
|
||||
OT_UNUSED_VARIABLE(aAckFrameCounter);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets the MLE frame counter value.
|
||||
*
|
||||
@@ -582,6 +607,9 @@ private:
|
||||
{
|
||||
uint32_t mLinkFrameCounter; ///< The Link Frame Counter
|
||||
uint32_t mMleFrameCounter; ///< The MLE Frame Counter
|
||||
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
||||
uint32_t mLinkAckFrameCounter; ///< The Link Ack Frame Counter
|
||||
#endif
|
||||
} mValid;
|
||||
struct
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user