From 130e5b6a88e87ecb1d91799e44628394c2845f75 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Tue, 7 Apr 2020 13:08:23 -0700 Subject: [PATCH] [mesh-forwarder] move ICMPv6 Dst Unreach call to mesh-forwarder (#4800) --- src/core/thread/mesh_forwarder.hpp | 1 + src/core/thread/mesh_forwarder_ftd.cpp | 24 ++++++++++++++++++++---- src/core/thread/mle.cpp | 25 ++++++++----------------- src/core/thread/mle.hpp | 11 +++++------ src/core/thread/mle_router.cpp | 15 ++++----------- src/core/thread/mle_router.hpp | 11 +++++------ 6 files changed, 43 insertions(+), 44 deletions(-) diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index 961776849..7321a4478 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -384,6 +384,7 @@ private: uint16_t aMeshDest = 0xffff); void SendMesh(Message &aMessage, Mac::TxFrame &aFrame); + void SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::Header &aIp6Header); otError UpdateIp6Route(Message &aMessage); otError UpdateIp6RouteFtd(Ip6::Header &ip6Header); otError UpdateMeshRoute(Message &aMessage); diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index 4fe7e845c..1160f2f56 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -484,7 +484,7 @@ otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header) mMeshSource = Get().GetShortAddress(); - SuccessOrExit(error = mle.CheckReachability(mMeshSource, mMeshDest, ip6Header)); + SuccessOrExit(error = mle.CheckReachability(mMeshDest, ip6Header)); mMacDest.SetShort(mle.GetNextHop(mMeshDest)); if (mMacDest.GetShort() != mMeshDest) @@ -495,6 +495,11 @@ otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header) } exit: + if (error == OT_ERROR_NO_ROUTE) + { + SendDestinationUnreachable(mMeshSource, ip6Header); + } + return error; } @@ -520,7 +525,7 @@ otError MeshForwarder::CheckReachability(uint8_t * aFrame, Ip6::Header ip6Header; SuccessOrExit(error = GetIp6Header(aFrame, aFrameLength, aMeshSource, aMeshDest, ip6Header)); - error = Get().CheckReachability(aMeshSource.GetShort(), aMeshDest.GetShort(), ip6Header); + error = Get().CheckReachability(aMeshDest.GetShort(), ip6Header); exit: // the message may not contain an IPv6 header @@ -528,14 +533,25 @@ exit: { error = OT_ERROR_NONE; } - else if (error != OT_ERROR_NONE) + else if (error == OT_ERROR_NO_ROUTE) { - error = OT_ERROR_DROP; + SendDestinationUnreachable(aMeshSource.GetShort(), ip6Header); } return error; } +void MeshForwarder::SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::Header &aIp6Header) +{ + Ip6::MessageInfo messageInfo; + + messageInfo.GetPeerAddr() = Get().GetMeshLocal16(); + messageInfo.GetPeerAddr().SetLocator(aMeshSource); + + Get().SendError(Ip6::IcmpHeader::kTypeDstUnreach, Ip6::IcmpHeader::kCodeDstUnreachNoRoute, messageInfo, + aIp6Header); +} + void MeshForwarder::HandleMesh(uint8_t * aFrame, uint16_t aFrameLength, const Mac::Address & aMacSource, diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 2f7273ef1..83d54035f 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -4106,28 +4106,19 @@ bool Mle::IsMeshLocalAddress(const Ip6::Address &aAddress) const return aAddress.PrefixMatch(GetMeshLocal16()) >= MeshLocalPrefix::kLength; } -otError Mle::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header) +otError Mle::CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header) { - otError error = OT_ERROR_DROP; - Ip6::MessageInfo messageInfo; + otError error; - if (aMeshDest != GetRloc16()) + if ((aMeshDest != GetRloc16()) || Get().IsUnicastAddress(aIp6Header.GetDestination())) { - ExitNow(error = OT_ERROR_NONE); + error = OT_ERROR_NONE; + } + else + { + error = OT_ERROR_NO_ROUTE; } - if (Get().IsUnicastAddress(aIp6Header.GetDestination())) - { - ExitNow(error = OT_ERROR_NONE); - } - - messageInfo.GetPeerAddr() = GetMeshLocal16(); - messageInfo.GetPeerAddr().SetLocator(aMeshSource); - - Get().SendError(Ip6::IcmpHeader::kTypeDstUnreach, Ip6::IcmpHeader::kCodeDstUnreachNoRoute, messageInfo, - aIp6Header); - -exit: return error; } diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index dd2eb146b..cffeaaa19 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -1420,15 +1420,14 @@ protected: /** * This method checks if the destination is reachable. * - * @param[in] aMeshSource The RLOC16 of the source. - * @param[in] aMeshDest The RLOC16 of the destination. - * @param[in] aIp6Header The IPv6 header of the message. + * @param[in] aMeshDest The RLOC16 of the destination. + * @param[in] aIp6Header The IPv6 header of the message. * - * @retval OT_ERROR_NONE The destination is reachable. - * @retval OT_ERROR_DROP The destination is not reachable and the message should be dropped. + * @retval OT_ERROR_NONE The destination is reachable. + * @retval OT_ERROR_NO_ROUTE The destination is not reachable and the message should be dropped. * */ - otError CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header); + otError CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header); /** * This method returns a pointer to the neighbor object. diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 39bcde7f5..5e10a707a 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -3886,14 +3886,13 @@ exit: return; } -otError MleRouter::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header) +otError MleRouter::CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header) { - Ip6::MessageInfo messageInfo; - otError error = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; if (IsChild()) { - error = Mle::CheckReachability(aMeshSource, aMeshDest, aIp6Header); + error = Mle::CheckReachability(aMeshDest, aIp6Header); ExitNow(); } @@ -3925,13 +3924,7 @@ otError MleRouter::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, I ExitNow(); } - messageInfo.GetPeerAddr() = GetMeshLocal16(); - messageInfo.GetPeerAddr().SetLocator(aMeshSource); - - Get().SendError(Ip6::IcmpHeader::kTypeDstUnreach, Ip6::IcmpHeader::kCodeDstUnreachNoRoute, messageInfo, - aIp6Header); - - error = OT_ERROR_DROP; + error = OT_ERROR_NO_ROUTE; exit: return error; diff --git a/src/core/thread/mle_router.hpp b/src/core/thread/mle_router.hpp index a84ec5958..6e11c4332 100644 --- a/src/core/thread/mle_router.hpp +++ b/src/core/thread/mle_router.hpp @@ -493,15 +493,14 @@ public: /** * This method checks if the destination is reachable. * - * @param[in] aMeshSource The RLOC16 of the source. - * @param[in] aMeshDest The RLOC16 of the destination. - * @param[in] aIp6Header A reference to the IPv6 header of the message. + * @param[in] aMeshDest The RLOC16 of the destination. + * @param[in] aIp6Header A reference to the IPv6 header of the message. * - * @retval OT_ERROR_NONE The destination is reachable. - * @retval OT_ERROR_DROP The destination is not reachable and the message should be dropped. + * @retval OT_ERROR_NONE The destination is reachable. + * @retval OT_ERROR_NO_ROUTE The destination is not reachable and the message should be dropped. * */ - otError CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header); + otError CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header); /** * This method resolves 2-hop routing loops.