diff --git a/include/openthread/icmp6.h b/include/openthread/icmp6.h index d249f2079..ca8c62481 100644 --- a/include/openthread/icmp6.h +++ b/include/openthread/icmp6.h @@ -58,11 +58,12 @@ extern "C" { */ typedef enum otIcmp6Type { - OT_ICMP6_TYPE_DST_UNREACH = 1, ///< Destination Unreachable - OT_ICMP6_TYPE_PACKET_TO_BIG = 2, ///< Packet To Big - OT_ICMP6_TYPE_TIME_EXCEEDED = 3, ///< Time Exceeded - OT_ICMP6_TYPE_ECHO_REQUEST = 128, ///< Echo Request - OT_ICMP6_TYPE_ECHO_REPLY = 129, ///< Echo Reply + OT_ICMP6_TYPE_DST_UNREACH = 1, ///< Destination Unreachable + OT_ICMP6_TYPE_PACKET_TO_BIG = 2, ///< Packet To Big + OT_ICMP6_TYPE_TIME_EXCEEDED = 3, ///< Time Exceeded + OT_ICMP6_TYPE_PARAMETER_PROBLEM = 4, ///< Parameter Problem + OT_ICMP6_TYPE_ECHO_REQUEST = 128, ///< Echo Request + OT_ICMP6_TYPE_ECHO_REPLY = 129, ///< Echo Reply } otIcmp6Type; /** diff --git a/src/core/net/icmp6.cpp b/src/core/net/icmp6.cpp index 51c7e9a51..c61cf64a8 100644 --- a/src/core/net/icmp6.cpp +++ b/src/core/net/icmp6.cpp @@ -92,11 +92,12 @@ otError Icmp::SendError(IcmpHeader::Type aType, const MessageInfo &aMessageInfo, const Message & aMessage) { - otError error = OT_ERROR_NONE; - MessageInfo messageInfoLocal; - Message * message = NULL; - IcmpHeader icmp6Header; - Header ip6Header; + otError error = OT_ERROR_NONE; + MessageInfo messageInfoLocal; + Message * message = NULL; + IcmpHeader icmp6Header; + Header ip6Header; + otMessageSettings settings = {true, static_cast(Message::kPriorityNet)}; VerifyOrExit(aMessage.GetLength() >= sizeof(ip6Header), error = OT_ERROR_INVALID_ARGS); @@ -112,7 +113,7 @@ otError Icmp::SendError(IcmpHeader::Type aType, messageInfoLocal = aMessageInfo; - VerifyOrExit((message = Get().NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS); + VerifyOrExit((message = Get().NewMessage(0, &settings)) != NULL, error = OT_ERROR_NO_BUFS); SuccessOrExit(error = message->SetLength(sizeof(icmp6Header) + sizeof(ip6Header))); message->Write(sizeof(icmp6Header), sizeof(ip6Header), &ip6Header); diff --git a/src/core/net/icmp6.hpp b/src/core/net/icmp6.hpp index 29a152f54..8fa524c6b 100644 --- a/src/core/net/icmp6.hpp +++ b/src/core/net/icmp6.hpp @@ -84,11 +84,12 @@ public: */ enum Type { - kTypeDstUnreach = OT_ICMP6_TYPE_DST_UNREACH, ///< Destination Unreachable - kTypePacketToBig = OT_ICMP6_TYPE_PACKET_TO_BIG, ///< Packet To Big - kTypeTimeExceeded = OT_ICMP6_TYPE_TIME_EXCEEDED, ///< Time Exceeded - kTypeEchoRequest = OT_ICMP6_TYPE_ECHO_REQUEST, ///< Echo Request - kTypeEchoReply = OT_ICMP6_TYPE_ECHO_REPLY, ///< Echo Reply + kTypeDstUnreach = OT_ICMP6_TYPE_DST_UNREACH, ///< Destination Unreachable + kTypePacketToBig = OT_ICMP6_TYPE_PACKET_TO_BIG, ///< Packet To Big + kTypeTimeExceeded = OT_ICMP6_TYPE_TIME_EXCEEDED, ///< Time Exceeded + kTypeParameterProblem = OT_ICMP6_TYPE_PARAMETER_PROBLEM, ///< Parameter Problem + kTypeEchoRequest = OT_ICMP6_TYPE_ECHO_REQUEST, ///< Echo Request + kTypeEchoReply = OT_ICMP6_TYPE_ECHO_REPLY, ///< Echo Reply }; /** diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index 827947a19..0b4ce53e1 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -1349,20 +1349,36 @@ otError MeshForwarder::GetFramePriority(const uint8_t * aFrame, const Mac::Address &aMacDest, uint8_t & aPriority) { - otError error = OT_ERROR_NONE; - Ip6::Header ip6Header; - Ip6::UdpHeader udpHeader; - uint8_t headerLength; - bool nextHeaderCompressed; + otError error = OT_ERROR_NONE; + Ip6::Header ip6Header; + Ip6::UdpHeader udpHeader; + Ip6::IcmpHeader icmpHeader; + uint8_t headerLength; + bool nextHeaderCompressed; SuccessOrExit(error = DecompressIp6Header(aFrame, aFrameLength, aMacSource, aMacDest, ip6Header, headerLength, nextHeaderCompressed)); aPriority = Ip6::Ip6::DscpToPriority(ip6Header.GetDscp()); - VerifyOrExit(ip6Header.GetNextHeader() == Ip6::kProtoUdp, OT_NOOP); aFrame += headerLength; aFrameLength -= headerLength; + if (ip6Header.GetNextHeader() == Ip6::kProtoIcmp6 && aFrameLength) + { + // Just check the first byte which is an ICMPv6 type. + memcpy(&icmpHeader, aFrame, sizeof(icmpHeader.mType)); + + // Only ICMPv6 error messages are prioritized. + if (icmpHeader.IsError()) + { + aPriority = Message::kPriorityNet; + } + + ExitNow(); + } + + VerifyOrExit(ip6Header.GetNextHeader() == Ip6::kProtoUdp, OT_NOOP); + if (nextHeaderCompressed) { VerifyOrExit(Get().DecompressUdpHeader(udpHeader, aFrame, aFrameLength) >= 0, OT_NOOP);