diff --git a/src/core/common/instance.cpp b/src/core/common/instance.cpp index 72a768d6a..2262f02a0 100644 --- a/src/core/common/instance.cpp +++ b/src/core/common/instance.cpp @@ -264,10 +264,6 @@ void Instance::GetBufferInfo(BufferInfo &aInfo) Get().GetReassemblyQueue().GetInfo(aInfo.m6loReassemblyMessages, aInfo.m6loReassemblyBuffers); -#if OPENTHREAD_FTD - Get().GetResolvingQueue().GetInfo(aInfo.mArpMessages, aInfo.mArpBuffers); -#endif - Get().GetSendQueue().GetInfo(aInfo.mIp6Messages, aInfo.mIp6Buffers); #if OPENTHREAD_FTD diff --git a/src/core/common/message.hpp b/src/core/common/message.hpp index 344d938a9..69af1e3a3 100644 --- a/src/core/common/message.hpp +++ b/src/core/common/message.hpp @@ -203,15 +203,16 @@ protected: #endif ChildMask mChildMask; // ChildMask to indicate which sleepy children need to receive this. - uint8_t mType : 3; // The message type. - uint8_t mSubType : 4; // The message sub type. - bool mDirectTx : 1; // Whether a direct transmission is required. - bool mLinkSecurity : 1; // Whether link security is enabled. - uint8_t mPriority : 2; // The message priority level (higher value is higher priority). - bool mInPriorityQ : 1; // Whether the message is queued in normal or priority queue. - bool mTxSuccess : 1; // Whether the direct tx of the message was successful. - bool mDoNotEvict : 1; // Whether this message may be evicted. - bool mMulticastLoop : 1; // Whether this multicast message may be looped back. + uint8_t mType : 3; // The message type. + uint8_t mSubType : 4; // The message sub type. + bool mDirectTx : 1; // Whether a direct transmission is required. + bool mLinkSecurity : 1; // Whether link security is enabled. + uint8_t mPriority : 2; // The message priority level (higher value is higher priority). + bool mInPriorityQ : 1; // Whether the message is queued in normal or priority queue. + bool mTxSuccess : 1; // Whether the direct tx of the message was successful. + bool mDoNotEvict : 1; // Whether this message may be evicted. + bool mMulticastLoop : 1; // Whether this multicast message may be looped back. + bool mResolvingAddress : 1; // Whether the message is pending an address query resolution. #if OPENTHREAD_CONFIG_MULTI_RADIO uint8_t mRadioType : 2; // The radio link type the message was received on, or should be sent on. bool mIsRadioTypeSet : 1; // Whether the radio type is set. @@ -1030,6 +1031,23 @@ public: */ void SetDoNotEvict(bool aDoNotEvict) { GetMetadata().mDoNotEvict = aDoNotEvict; } + /** + * This method indicates whether the message is waiting for an address query resolution. + * + * @retval TRUE If the message is waiting for address query resolution. + * @retval FALSE If the message is not waiting for address query resolution. + * + */ + bool IsResolvingAddress(void) const { return GetMetadata().mResolvingAddress; } + + /** + * This method sets whether the message is waiting for an address query resolution. + * + * @param[in] aResolvingAddress TRUE if message is waiting for address resolution, FALSE otherwise. + * + */ + void SetResolvingAddress(bool aResolvingAddress) { GetMetadata().mResolvingAddress = aResolvingAddress; } + /** * This method indicates whether or not link security is enabled for the message. * diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index 4567afdbb..05eddb515 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -267,7 +267,7 @@ Message *MeshForwarder::PrepareNextDirectTransmission(void) for (curMessage = mSendQueue.GetHead(); curMessage; curMessage = nextMessage) { - if (!curMessage->IsDirectTransmission()) + if (!curMessage->IsDirectTransmission() || curMessage->IsResolvingAddress()) { nextMessage = curMessage->GetNext(); continue; @@ -311,12 +311,9 @@ Message *MeshForwarder::PrepareNextDirectTransmission(void) ExitNow(); #if OPENTHREAD_FTD - case kErrorAddressQuery: - mSendQueue.Dequeue(*curMessage); - mResolvingQueue.Enqueue(*curMessage); + curMessage->SetResolvingAddress(true); continue; - #endif default: diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index 476c7d055..bbf6d62ee 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -311,15 +311,6 @@ public: */ void ResetCounters(void) { memset(&mIpCounters, 0, sizeof(mIpCounters)); } -#if OPENTHREAD_FTD - /** - * This method returns a reference to the resolving queue. - * - * @returns A reference to the resolving queue. - * - */ - const PriorityQueue &GetResolvingQueue(void) const { return mResolvingQueue; } -#endif #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE /** * This method handles a deferred ack. @@ -536,10 +527,6 @@ private: uint16_t & aSourcePort, uint16_t & aDestPort); -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE - otError ForwardDuaToBackboneLink(Message &aMessage, const Ip6::Address &aDst); -#endif - #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) const char *MessageActionToString(MessageAction aAction, Error aError); const char *MessagePriorityToString(const Message &aMessage); @@ -605,7 +592,6 @@ private: #if OPENTHREAD_FTD FragmentPriorityList mFragmentPriorityList; - PriorityQueue mResolvingQueue; IndirectSender mIndirectSender; #endif diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index dcc25e90a..ffe80bff9 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -141,103 +141,84 @@ Error MeshForwarder::SendMessage(Message &aMessage) void MeshForwarder::HandleResolved(const Ip6::Address &aEid, Error aError) { Ip6::Address ip6Dst; - bool enqueuedMessage = false; + bool didUpdate = false; - for (Message &message : mResolvingQueue) + for (Message &message : mSendQueue) { - if (message.GetType() != Message::kTypeIp6) + if (!message.IsResolvingAddress()) { continue; } IgnoreError(message.Read(Ip6::Header::kDestinationFieldOffset, ip6Dst)); - if (ip6Dst == aEid) + if (ip6Dst != aEid) { - mResolvingQueue.Dequeue(message); - - if (aError == kErrorNone) - { -#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE - // Pass back to IPv6 layer for DUA destination resolved by Backbone Query - if (ForwardDuaToBackboneLink(message, ip6Dst) != kErrorNone) -#endif - { - mSendQueue.Enqueue(message); - enqueuedMessage = true; - } - } - else - { - LogMessage(kMessageDrop, message, aError); - message.Free(); - } + continue; } + + if (aError != kErrorNone) + { + LogMessage(kMessageDrop, message, kErrorAddressQuery); + mSendQueue.DequeueAndFree(message); + continue; + } + +#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE + // Pass back to IPv6 layer for DUA destination resolved + // by Backbone Query + if (Get().IsPrimary() && Get().IsDomainUnicast(ip6Dst) && + Get().LookUp(ip6Dst) == Get().GetRloc16()) + { + uint8_t hopLimit; + + mSendQueue.Dequeue(message); + + // Avoid decreasing Hop Limit twice + IgnoreError(message.Read(Ip6::Header::kHopLimitFieldOffset, hopLimit)); + hopLimit++; + message.Write(Ip6::Header::kHopLimitFieldOffset, hopLimit); + + IgnoreError(Get().HandleDatagram(message, nullptr, nullptr, /* aFromHost */ false)); + continue; + } +#endif + + message.SetResolvingAddress(false); + didUpdate = true; } - if (enqueuedMessage) + if (didUpdate) { mScheduleTransmissionTask.Post(); } } -#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE -Error MeshForwarder::ForwardDuaToBackboneLink(Message &aMessage, const Ip6::Address &aDst) -{ - Error error = kErrorNone; - uint8_t ttl; - - VerifyOrExit(Get().IsPrimary() && Get().IsDomainUnicast(aDst), - error = kErrorNoRoute); - - VerifyOrExit(Get().LookUp(aDst) == Get().GetRloc16(), error = kErrorNoRoute); - - // Avoid decreasing TTL twice - IgnoreError(aMessage.Read(Ip6::Header::kHopLimitFieldOffset, ttl)); - ttl++; - aMessage.Write(Ip6::Header::kHopLimitFieldOffset, ttl); - - IgnoreError(Get().HandleDatagram(aMessage, nullptr, nullptr, /* aFromHost */ false)); - -exit: - return error; -} -#endif - Error MeshForwarder::EvictMessage(Message::Priority aPriority) { - Error error = kErrorNotFound; - PriorityQueue *queues[] = {&mResolvingQueue, &mSendQueue}; - Message * evict = nullptr; + Error error = kErrorNotFound; + Message *evict = nullptr; - // search for a lower priority message to evict (choose lowest priority message among all queues) - for (PriorityQueue *queue : queues) + // Search for a lower priority message to evict + for (uint8_t priority = 0; priority < aPriority; priority++) { - for (uint8_t priority = 0; priority < aPriority; priority++) + for (Message *message = mSendQueue.GetHeadForPriority(static_cast(priority)); message; + message = message->GetNext()) { - for (Message *message = queue->GetHeadForPriority(static_cast(priority)); message; - message = message->GetNext()) + if (message->GetPriority() != priority) { - if (message->GetPriority() != priority) - { - break; - } - - if (message->GetDoNotEvict()) - { - continue; - } - - evict = message; - aPriority = static_cast(priority); break; } - } - } - if (evict != nullptr) - { - ExitNow(error = kErrorNone); + if (message->GetDoNotEvict()) + { + continue; + } + + evict = message; + error = kErrorNone; + ExitNow(); + } } for (uint8_t priority = aPriority; priority < Message::kNumPriorities; priority++)