From 0071edcf7a787a9e70f5bc9d6ddcc7274d82f90b Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Fri, 16 Sep 2016 17:27:52 -0700 Subject: [PATCH] Pass up datagrams that are routed to this device but have no further route. (#617) --- src/core/net/ip6.cpp | 38 ++++++++++++++++++++++++-------- src/core/net/ip6.hpp | 4 ++-- src/core/thread/thread_netif.cpp | 13 ++++++++++- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index 7381738ad..b08788486 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -347,18 +347,19 @@ exit: return error; } -void Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageInfo &messageInfo, uint8_t aIpProto) +ThreadError Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageInfo &messageInfo, uint8_t aIpProto) { ThreadError error = kThreadError_None; Message *messageCopy = NULL; - VerifyOrExit(mReceiveIp6DatagramCallback != NULL, ;); + VerifyOrExit(mReceiveIp6DatagramCallback != NULL, error = kThreadError_NoRoute); if (mIsReceiveIp6FilterEnabled) { // do not pass messages sent to/from an RLOC VerifyOrExit(!messageInfo.GetSockAddr().IsRoutingLocator() && - !messageInfo.GetPeerAddr().IsRoutingLocator(), ;); + !messageInfo.GetPeerAddr().IsRoutingLocator(), + error = kThreadError_NoRoute); switch (aIpProto) { @@ -369,7 +370,7 @@ void Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageInfo &mes aMessage.Read(aMessage.GetOffset(), sizeof(icmp), &icmp); // do not pass ICMP Echo Request messages - VerifyOrExit(icmp.GetType() != IcmpHeader::kTypeEchoRequest, ;); + VerifyOrExit(icmp.GetType() != IcmpHeader::kTypeEchoRequest, error = kThreadError_NoRoute); } break; @@ -381,7 +382,7 @@ void Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageInfo &mes aMessage.Read(aMessage.GetOffset(), sizeof(udp), &udp); // do not pass MLE messages - VerifyOrExit(udp.GetDestinationPort() != Mle::kUdpPort, ;); + VerifyOrExit(udp.GetDestinationPort() != Mle::kUdpPort, error = kThreadError_NoRoute); } break; @@ -405,6 +406,8 @@ exit: { messageCopy->Free(); } + + return error; } ThreadError Ip6::HandleDatagram(Message &message, Netif *netif, int8_t interfaceId, const void *linkMessageInfo, @@ -515,7 +518,7 @@ ThreadError Ip6::HandleDatagram(Message &message, Netif *netif, int8_t interface { hopLimit = header.GetHopLimit(); message.Write(Header::GetHopLimitOffset(), Header::GetHopLimitSize(), &hopLimit); - SuccessOrExit(error = ForwardMessage(message, messageInfo)); + SuccessOrExit(error = ForwardMessage(message, messageInfo, nextHeader)); } } @@ -529,7 +532,7 @@ exit: return error; } -ThreadError Ip6::ForwardMessage(Message &message, MessageInfo &messageInfo) +ThreadError Ip6::ForwardMessage(Message &message, MessageInfo &messageInfo, uint8_t ipproto) { ThreadError error = kThreadError_None; int8_t interfaceId; @@ -557,8 +560,25 @@ ThreadError Ip6::ForwardMessage(Message &message, MessageInfo &messageInfo) } else { - otDumpDebgIp6("no route", &messageInfo.GetSockAddr(), 16); - ExitNow(error = kThreadError_NoRoute); + // try passing to host + error = ProcessReceiveCallback(message, messageInfo, ipproto); + + switch (error) + { + case kThreadError_None: + // the caller transfers custody in the success case, so free the message here + message.Free(); + break; + + case kThreadError_NoRoute: + otDumpDebgIp6("no route", &messageInfo.GetSockAddr(), 16); + break; + + default: + break; + } + + ExitNow(); } // submit message to interface diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp index fb3b4c8ab..e64788b7a 100644 --- a/src/core/net/ip6.hpp +++ b/src/core/net/ip6.hpp @@ -335,13 +335,13 @@ private: static void HandleSendQueue(void *aContext); void HandleSendQueue(void); - void ProcessReceiveCallback(const Message &aMessage, const MessageInfo &aMessageInfo, uint8_t aIpProto); + ThreadError ProcessReceiveCallback(const Message &aMessage, const MessageInfo &aMessageInfo, uint8_t aIpProto); ThreadError HandleExtensionHeaders(Message &message, uint8_t &nextHeader, bool receive); ThreadError HandleFragment(Message &message); ThreadError AddMplOption(Message &message, Header &header, IpProto nextHeader, uint16_t payloadLength); ThreadError HandleOptions(Message &message); ThreadError HandlePayload(Message &message, MessageInfo &messageInfo, uint8_t ipproto); - ThreadError ForwardMessage(Message &message, MessageInfo &messageInfo); + ThreadError ForwardMessage(Message &message, MessageInfo &messageInfo, uint8_t ipproto); Mpl mMpl; bool mForwardingEnabled; diff --git a/src/core/thread/thread_netif.cpp b/src/core/thread/thread_netif.cpp index d597eac72..42dd9ef3d 100644 --- a/src/core/thread/thread_netif.cpp +++ b/src/core/thread/thread_netif.cpp @@ -130,7 +130,18 @@ ThreadError ThreadNetif::GetLinkAddress(Ip6::LinkAddress &address) const ThreadError ThreadNetif::RouteLookup(const Ip6::Address &source, const Ip6::Address &destination, uint8_t *prefixMatch) { - return mNetworkDataLeader.RouteLookup(source, destination, prefixMatch, NULL); + ThreadError error; + uint16_t rloc; + + SuccessOrExit(error = mNetworkDataLeader.RouteLookup(source, destination, prefixMatch, &rloc)); + + if (rloc == mMleRouter.GetRloc16()) + { + error = kThreadError_NoRoute; + } + +exit: + return error; } ThreadError ThreadNetif::SendMessage(Message &message)