[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:
Jintao Lin
2020-10-15 07:36:51 -07:00
committed by GitHub
parent c2903713a1
commit c416b72cb6
5 changed files with 71 additions and 21 deletions
+34 -21
View File
@@ -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:
+3
View File
@@ -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
+3
View File
@@ -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);
+3
View File
@@ -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;
+28
View File
@@ -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
{