diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index 2452c94f9..3eb324339 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -1371,10 +1371,22 @@ exit: return didRemove; } +Error MeshForwarder::RxInfo::ParseIp6Headers(void) +{ + Error error = kErrorNone; + + VerifyOrExit(!mParsedIp6Headers); + SuccessOrExit(error = mIp6Headers.DecompressFrom(mFrameData, mMacAddrs, GetInstance())); + mParsedIp6Headers = true; + +exit: + return error; +} + void MeshForwarder::HandleReceivedFrame(Mac::RxFrame &aFrame) { Error error = kErrorNone; - RxInfo rxInfo; + RxInfo rxInfo(GetInstance()); VerifyOrExit(mEnabled, error = kErrorInvalidState); @@ -1610,7 +1622,7 @@ bool MeshForwarder::UpdateReassemblyList(void) return mReassemblyList.GetHead() != nullptr; } -Error MeshForwarder::FrameToMessage(const RxInfo &aRxInfo, uint16_t aDatagramSize, Message *&aMessage) +Error MeshForwarder::FrameToMessage(RxInfo &aRxInfo, uint16_t aDatagramSize, Message *&aMessage) { Error error = kErrorNone; FrameData frameData = aRxInfo.mFrameData; @@ -1630,7 +1642,7 @@ exit: return error; } -void MeshForwarder::HandleLowpanHc(const RxInfo &aRxInfo) +void MeshForwarder::HandleLowpanHc(RxInfo &aRxInfo) { Error error = kErrorNone; Message *message = nullptr; @@ -1681,32 +1693,32 @@ Error MeshForwarder::HandleDatagram(Message &aMessage, const Mac::Address &aMacS return Get().HandleDatagram(OwnedPtr(&aMessage)); } -Error MeshForwarder::GetFramePriority(const RxInfo &aRxInfo, Message::Priority &aPriority) +Error MeshForwarder::GetFramePriority(RxInfo &aRxInfo, Message::Priority &aPriority) { - Error error = kErrorNone; - Ip6::Headers headers; + Error error = kErrorNone; - SuccessOrExit(error = headers.DecompressFrom(aRxInfo.mFrameData, aRxInfo.mMacAddrs, GetInstance())); + SuccessOrExit(error = aRxInfo.ParseIp6Headers()); - aPriority = Ip6::Ip6::DscpToPriority(headers.GetIp6Header().GetDscp()); + aPriority = Ip6::Ip6::DscpToPriority(aRxInfo.mIp6Headers.GetIp6Header().GetDscp()); // Only ICMPv6 error messages are prioritized. - if (headers.IsIcmp6() && headers.GetIcmpHeader().IsError()) + if (aRxInfo.mIp6Headers.IsIcmp6() && aRxInfo.mIp6Headers.GetIcmpHeader().IsError()) { aPriority = Message::kPriorityNet; } - if (headers.IsUdp()) + if (aRxInfo.mIp6Headers.IsUdp()) { - uint16_t destPort = headers.GetUdpHeader().GetDestinationPort(); + uint16_t destPort = aRxInfo.mIp6Headers.GetUdpHeader().GetDestinationPort(); if (destPort == Mle::kUdpPort) { aPriority = Message::kPriorityNet; } - else if (Get().IsTmfMessage(headers.GetSourceAddress(), headers.GetDestinationAddress(), destPort)) + else if (Get().IsTmfMessage(aRxInfo.mIp6Headers.GetSourceAddress(), + aRxInfo.mIp6Headers.GetDestinationAddress(), destPort)) { - aPriority = Tmf::Agent::DscpToPriority(headers.GetIp6Header().GetDscp()); + aPriority = Tmf::Agent::DscpToPriority(aRxInfo.mIp6Headers.GetIp6Header().GetDscp()); } } diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index d337dfdb6..63a216985 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -411,20 +411,29 @@ private: kAnycastService, }; - struct RxInfo + struct RxInfo : public InstanceLocator { static constexpr uint16_t kInfoStringSize = 70; typedef String InfoString; + explicit RxInfo(Instance &aInstance) + : InstanceLocator(aInstance) + , mParsedIp6Headers(false) + { + } + const Mac::Address &GetSrcAddr(void) const { return mMacAddrs.mSource; } const Mac::Address &GetDstAddr(void) const { return mMacAddrs.mDestination; } bool IsLinkSecurityEnabled(void) const { return mLinkInfo.IsLinkSecurityEnabled(); } + Error ParseIp6Headers(void); InfoString ToString(void) const; FrameData mFrameData; ThreadLinkInfo mLinkInfo; Mac::Addresses mMacAddrs; + Ip6::Headers mIp6Headers; + bool mParsedIp6Headers; }; #if OPENTHREAD_FTD @@ -507,17 +516,17 @@ private: #endif void SendIcmpErrorIfDstUnreach(const Message &aMessage, const Mac::Addresses &aMacAddrs); - Error CheckReachability(const RxInfo &aRxInfo); + Error CheckReachability(RxInfo &aRxInfo); Error CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header); - void UpdateRoutes(const RxInfo &aRxInfo); - Error FrameToMessage(const RxInfo &aRxInfo, uint16_t aDatagramSize, Message *&aMessage); + void UpdateRoutes(RxInfo &aRxInfo); + Error FrameToMessage(RxInfo &aRxInfo, uint16_t aDatagramSize, Message *&aMessage); void GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr); void GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr); Message *PrepareNextDirectTransmission(void); void HandleMesh(RxInfo &aRxInfo); void ResolveRoutingLoops(uint16_t aSourceRloc16, uint16_t aDestRloc16); void HandleFragment(RxInfo &aRxInfo); - void HandleLowpanHc(const RxInfo &aRxInfo); + void HandleLowpanHc(RxInfo &aRxInfo); void PrepareMacHeaders(Mac::TxFrame &aFrame, Mac::Frame::Type aFrameType, @@ -576,7 +585,7 @@ private: void HandleTimeTick(void); void ScheduleTransmissionTask(void); - Error GetFramePriority(const RxInfo &aRxInfo, Message::Priority &aPriority); + Error GetFramePriority(RxInfo &aRxInfo, Message::Priority &aPriority); Error GetFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader, uint16_t aSrcRloc16, Message::Priority &aPriority); diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index 0d84847d4..740132b9a 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -641,12 +641,11 @@ exit: return; } -Error MeshForwarder::CheckReachability(const RxInfo &aRxInfo) +Error MeshForwarder::CheckReachability(RxInfo &aRxInfo) { - Error error; - Ip6::Headers ip6Headers; + Error error; - error = ip6Headers.DecompressFrom(aRxInfo.mFrameData, aRxInfo.mMacAddrs, GetInstance()); + error = aRxInfo.ParseIp6Headers(); switch (error) { @@ -660,11 +659,11 @@ Error MeshForwarder::CheckReachability(const RxInfo &aRxInfo) ExitNow(); } - error = CheckReachability(aRxInfo.GetDstAddr().GetShort(), ip6Headers.GetIp6Header()); + error = CheckReachability(aRxInfo.GetDstAddr().GetShort(), aRxInfo.mIp6Headers.GetIp6Header()); if (error == kErrorNoRoute) { - SendDestinationUnreachable(aRxInfo.GetSrcAddr().GetShort(), ip6Headers); + SendDestinationUnreachable(aRxInfo.GetSrcAddr().GetShort(), aRxInfo.mIp6Headers); } exit: @@ -819,27 +818,26 @@ exit: return; } -void MeshForwarder::UpdateRoutes(const RxInfo &aRxInfo) +void MeshForwarder::UpdateRoutes(RxInfo &aRxInfo) { - Ip6::Headers ip6Headers; - Neighbor *neighbor; + Neighbor *neighbor; VerifyOrExit(!aRxInfo.GetDstAddr().IsBroadcast() && aRxInfo.GetSrcAddr().IsShort()); - SuccessOrExit(ip6Headers.DecompressFrom(aRxInfo.mFrameData, aRxInfo.mMacAddrs, GetInstance())); + SuccessOrExit(aRxInfo.ParseIp6Headers()); - if (!ip6Headers.GetSourceAddress().GetIid().IsLocator() && - Get().IsOnMesh(ip6Headers.GetSourceAddress())) + if (!aRxInfo.mIp6Headers.GetSourceAddress().GetIid().IsLocator() && + Get().IsOnMesh(aRxInfo.mIp6Headers.GetSourceAddress())) { // FTDs MAY add/update EID-to-RLOC Map Cache entries by // inspecting packets being received only for on mesh // addresses. - Get().UpdateSnoopedCacheEntry(ip6Headers.GetSourceAddress(), aRxInfo.GetSrcAddr().GetShort(), - aRxInfo.GetDstAddr().GetShort()); + Get().UpdateSnoopedCacheEntry( + aRxInfo.mIp6Headers.GetSourceAddress(), aRxInfo.GetSrcAddr().GetShort(), aRxInfo.GetDstAddr().GetShort()); } - neighbor = Get().FindNeighbor(ip6Headers.GetSourceAddress()); + neighbor = Get().FindNeighbor(aRxInfo.mIp6Headers.GetSourceAddress()); VerifyOrExit(neighbor != nullptr && !neighbor->IsFullThreadDevice()); if (!Get().HasMatchingRouterIdWith(aRxInfo.GetSrcAddr().GetShort()))