From 2117504c7d9a109a5c8156f4dd8e82fc204398ab Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 25 Aug 2026 19:54:27 -0700 Subject: [PATCH] [mac] optimize rx frame filtering by deferring neighbor lookup (#13551) This commit refactors and reorders the frame filtering and neighbor lookup logic in `Mac::HandleReceivedFrame()`: - Defers neighbor table lookup until after destination address and destination PAN ID filtering are performed. Because neighbor table lookups can be relatively time-consuming, this avoids unnecessary lookups for frames that are discarded by destination checks. - Consolidates all source address validation, neighbor resolution (including FTD multicast router fallback), and MAC filtering under a single `if (!srcAddr.IsNone())` block, improving code structure and separation of concerns. - Simplifies the `srcAddr` determination logic. - Adds defensive `aSrcAddr.IsExtended()` checks in `ProcessReceiveSecurity()` prior to accessing the extended address (handling edge-cases where there is no source address in the frame). - Adds a `!aSrcAddr.IsNone()` check in `ProcessCsl()` to ensure a valid source address is present before processing CSL IEs. --- src/core/mac/mac.cpp | 53 ++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 62ba0fcc2..dcac46e33 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -1657,8 +1657,9 @@ Error Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Neig switch (keyIdMode) { case Frame::kKeyIdMode0: - VerifyOrExit(keyManager.IsKekSet(), error = kErrorSecurity); - macKey = &keyManager.GetKek(); + VerifyOrExit(keyManager.IsKekSet()); + macKey = &keyManager.GetKek(); + VerifyOrExit(aSrcAddr.IsExtended()); extAddress = &aSrcAddr.GetExtended(); break; @@ -1694,6 +1695,7 @@ Error Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Neig } } + VerifyOrExit(aSrcAddr.IsExtended()); extAddress = &aSrcAddr.GetExtended(); break; @@ -1867,11 +1869,11 @@ exit: void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError) { - Error error = aError; + Error error = aError; + Neighbor *neighbor = nullptr; Address srcAddr; Address dstAddr; PanId panId; - Neighbor *neighbor; mCounters.mRxTotal++; @@ -1885,7 +1887,6 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError) IgnoreError(aFrame->GetSrcAddr(srcAddr)); IgnoreError(aFrame->GetDstAddr(dstAddr)); - neighbor = !srcAddr.IsNone() ? Get().FindNeighbor(srcAddr) : nullptr; // Destination Address Filtering switch (dstAddr.GetType()) @@ -1895,15 +1896,6 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError) case Address::kTypeShort: SuccessOrExit(error = FilterDestShortAddress(dstAddr.GetShort())); - -#if OPENTHREAD_FTD - // Allow multicasts from neighbor routers if FTD - if (neighbor == nullptr && dstAddr.IsBroadcast() && Get().IsFullThreadDevice()) - { - neighbor = Get().FindRxOnlyNeighborRouter(srcAddr); - } -#endif - break; case Address::kTypeExtended: @@ -1918,30 +1910,31 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError) } // Source Address Filtering - switch (srcAddr.GetType()) + + if (!srcAddr.IsNone()) { - case Address::kTypeNone: - break; + neighbor = Get().FindNeighbor(srcAddr); - case Address::kTypeShort: - LogDebg("Received frame from short address 0x%04x", srcAddr.GetShort()); +#if OPENTHREAD_FTD + // Allow multicasts from neighbor routers if FTD + if ((neighbor == nullptr) && dstAddr.IsBroadcast() && Get().IsFullThreadDevice()) + { + neighbor = Get().FindRxOnlyNeighborRouter(srcAddr); + } +#endif - VerifyOrExit(neighbor != nullptr, error = kErrorUnknownNeighbor); + if (srcAddr.IsShort()) + { + LogDebg("Received frame from short address 0x%04x", srcAddr.GetShort()); + VerifyOrExit(neighbor != nullptr, error = kErrorUnknownNeighbor); + srcAddr.SetExtended(neighbor->GetExtAddress()); + } - srcAddr.SetExtended(neighbor->GetExtAddress()); - - OT_FALL_THROUGH; - - case Address::kTypeExtended: - - // Duplicate Address Protection VerifyOrExit(srcAddr.GetExtended() != GetExtAddress(), error = kErrorInvalidSourceAddress); #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE SuccessOrExit(error = mFilter.ApplyToRxFrame(*aFrame, srcAddr.GetExtended(), neighbor)); #endif - - break; } if (dstAddr.IsBroadcast()) @@ -2539,6 +2532,8 @@ void Mac::ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr) CslNeighbor *neighbor = nullptr; const CslIe *csl; + VerifyOrExit(!aSrcAddr.IsNone()); + VerifyOrExit(aFrame.IsVersion2015()); VerifyOrExit(aFrame.IsSecuredWith(RxFrame::kAllowKeyIdMode1));