From e1e192fc334b44fd4e319974d995f305c3e2fa9e Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Wed, 27 Nov 2019 08:09:51 -0600 Subject: [PATCH] net/: icmp[v6] fix ping[6] complain 'WARNING: Received after timeout'. The root cause is that icmp[v6]_pollsetup monitors ICMP[v6]_NEWDATA, but icmp[v6]_input reports ICMP[v6]_ECHOREPLY. This change lets icmp[v6]_input report report ICMP[v6]_NEWDATA to fix this issue and remove ICMP[v6]_ECHOREPLY to avoid the wrong usage in the future. --- include/nuttx/net/netdev.h | 1 - net/devif/devif.h | 34 ++++++++++------------------------ net/icmp/icmp_input.c | 4 ++-- net/icmp/icmp_netpoll.c | 2 +- net/icmp/icmp_recvfrom.c | 8 ++++++-- net/icmpv6/icmpv6_input.c | 4 ++-- net/icmpv6/icmpv6_netpoll.c | 2 +- net/icmpv6/icmpv6_recvfrom.c | 8 ++++++-- 8 files changed, 28 insertions(+), 35 deletions(-) diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h index 764d5b06b05..c1afccc6147 100644 --- a/include/nuttx/net/netdev.h +++ b/include/nuttx/net/netdev.h @@ -372,7 +372,6 @@ struct net_driver_s * socket-less packet transfers. There events include: * * ICMP data receipt: ICMP_NEWDATA, ICMPv6_NEWDATA - * ICMP ECHO replies: ICMP_ECHOREPLY, ICMPv6_ECHOREPLY * Driver Tx poll events: ARP_POLL, ICMP_POLL. ICMPv6_POLL * IP Forwarding: IPFWD_POLL * diff --git a/net/devif/devif.h b/net/devif/devif.h index affb0d2dd2c..8890ec5d295 100644 --- a/net/devif/devif.h +++ b/net/devif/devif.h @@ -57,6 +57,7 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ + /* The following flags may be set in the set of flags by the lower, device- * interfacing layer before calling through the socket layer callback. The * TCP_ACKDATA, XYZ_NEWDATA, and TCP_CLOSE flags may be set at the same time, @@ -73,8 +74,10 @@ * * TCP_NEWDATA IN: Set to indicate that the peer has sent us new data. * UDP_NEWDATA OUT: Cleared (only) by the socket layer logic to indicate - * PKT_NEWDATA that the new data was consumed, suppressing further - * BLUETOOTH_NEWDATA attempts to process the new data. + * ICMP_NEWDATA that the new data was consumed, suppressing further + * ICMPv6_NEWDATA attempts to process the new data. + * PKT_NEWDATA + * BLUETOOTH_NEWDATA * IEEE802154_NEWDATA * * TCP_SNDACK IN: Not used; always zero @@ -119,11 +122,6 @@ * Device Specific Events: These are events that may be notified through * callback lists residing in the network device structure. * - * ICMP_NEWDATA IN: Set to indicate that the peer has sent us new data. - * ICMPv6_NEWDATA OUT: Cleared (only) by the socket layer logic to indicate - * that the new data was consumed, suppressing further - * attempts to process the new data. - * * ARP_POLL IN: Used for polling the socket layer. This is provided * periodically from the drivers to support (1) timed * operations, and (2) to check if the ARP layer needs @@ -157,18 +155,6 @@ * The appdata pointer is not used in this case. * OUT: Not used * - * ICMP_ECHOREPLY IN: An ICMP Echo Reply has been received. Used to support - * ICMP ping from the socket layer. (ICMPv4 only) - * OUT: Cleared (only) by the socket layer logic to indicate - * that the reply was processed, suppressing further - * attempts to process the reply. - * - * ICMPv6_ECHOREPLY IN: An ICMP Echo Reply has been received. Used to support - * ICMP ping from the socket layer. (ICMPv6 only) - * OUT: Cleared (only) by the socket layer logic to indicate - * that the reply was processed, suppressing further - * attempts to process the reply. - * * NETDEV_DOWN: IN: The network device has been taken down. * OUT: Not used */ @@ -178,6 +164,8 @@ #define TCP_ACKDATA (1 << 0) #define TCP_NEWDATA (1 << 1) #define UDP_NEWDATA TCP_NEWDATA +#define ICMP_NEWDATA TCP_NEWDATA +#define ICMPv6_NEWDATA TCP_NEWDATA #define BLUETOOTH_NEWDATA TCP_NEWDATA #define IEEE802154_NEWDATA TCP_NEWDATA #define PKT_NEWDATA TCP_NEWDATA @@ -197,12 +185,10 @@ #define TCP_CONNECTED (1 << 8) #define TCP_TIMEDOUT (1 << 9) -/* Bits 10-12: Device specific event bits */ +/* Bits 10-11: Unused, available */ + +/* Bit 12: Device specific event bits */ -#define ICMP_NEWDATA TCP_NEWDATA -#define ICMPv6_NEWDATA TCP_NEWDATA -#define ICMP_ECHOREPLY (1 << 10) -#define ICMPv6_ECHOREPLY (1 << 11) #define NETDEV_DOWN (1 << 12) /* Bits 13-15: Encoded device specific poll events. Unlike connection diff --git a/net/icmp/icmp_input.c b/net/icmp/icmp_input.c index 0d2fdb96b03..f800f00f83b 100644 --- a/net/icmp/icmp_input.c +++ b/net/icmp/icmp_input.c @@ -328,8 +328,8 @@ void icmp_input(FAR struct net_driver_s *dev) goto drop; } - flags = devif_conn_event(dev, conn, ICMP_ECHOREPLY, conn->list); - if ((flags & ICMP_ECHOREPLY) != 0) + flags = devif_conn_event(dev, conn, ICMP_NEWDATA, conn->list); + if ((flags & ICMP_NEWDATA) != 0) { uint16_t nbuffered; diff --git a/net/icmp/icmp_netpoll.c b/net/icmp/icmp_netpoll.c index 29941aaa1ca..105225902f0 100644 --- a/net/icmp/icmp_netpoll.c +++ b/net/icmp/icmp_netpoll.c @@ -125,7 +125,7 @@ static uint16_t icmp_poll_eventhandler(FAR struct net_driver_s *dev, /* Check for data or connection availability events. */ eventset = 0; - if ((flags & ICMP_ECHOREPLY) != 0) + if ((flags & ICMP_NEWDATA) != 0) { eventset |= (POLLIN & info->fds->events); } diff --git a/net/icmp/icmp_recvfrom.c b/net/icmp/icmp_recvfrom.c index 36af8712f86..4555903a696 100644 --- a/net/icmp/icmp_recvfrom.c +++ b/net/icmp/icmp_recvfrom.c @@ -184,7 +184,7 @@ static uint16_t recvfrom_eventhandler(FAR struct net_driver_s *dev, /* Check if we have just received a ICMP ECHO reply. */ - if ((flags & ICMP_ECHOREPLY) != 0) /* No incoming data */ + if ((flags & ICMP_NEWDATA) != 0) /* No incoming data */ { unsigned int recvsize; @@ -232,6 +232,10 @@ static uint16_t recvfrom_eventhandler(FAR struct net_driver_s *dev, DEBUGASSERT(conn->nreqs > 0); conn->nreqs--; + + /* Indicate that the data has been consumed */ + + flags &= ~ICMP_NEWDATA; goto end_wait; } @@ -491,7 +495,7 @@ ssize_t icmp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, state.recv_cb = icmp_callback_alloc(dev, conn); if (state.recv_cb != NULL) { - state.recv_cb->flags = (ICMP_ECHOREPLY | NETDEV_DOWN); + state.recv_cb->flags = (ICMP_NEWDATA | NETDEV_DOWN); state.recv_cb->priv = (FAR void *)&state; state.recv_cb->event = recvfrom_eventhandler; state.recv_result = -EINTR; /* Assume sem-wait interrupted by signal */ diff --git a/net/icmpv6/icmpv6_input.c b/net/icmpv6/icmpv6_input.c index b396804c72e..bb2c1db77b1 100644 --- a/net/icmpv6/icmpv6_input.c +++ b/net/icmpv6/icmpv6_input.c @@ -455,7 +455,7 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen) { FAR struct icmpv6_echo_reply_s *reply; FAR struct icmpv6_conn_s *conn; - uint16_t flags = ICMPv6_ECHOREPLY; + uint16_t flags = ICMPv6_NEWDATA; /* Nothing consumed the ICMP reply. That might be because this is * an old, invalid reply or simply because the ping application @@ -479,7 +479,7 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen) /* Was the ECHO reply consumed by any waiting thread? */ - if ((flags & ICMPv6_ECHOREPLY) != 0) + if ((flags & ICMPv6_NEWDATA) != 0) { uint16_t nbuffered; diff --git a/net/icmpv6/icmpv6_netpoll.c b/net/icmpv6/icmpv6_netpoll.c index 5d96f89f445..1fbf964a806 100644 --- a/net/icmpv6/icmpv6_netpoll.c +++ b/net/icmpv6/icmpv6_netpoll.c @@ -125,7 +125,7 @@ static uint16_t icmpv6_poll_eventhandler(FAR struct net_driver_s *dev, /* Check for data or connection availability events. */ eventset = 0; - if ((flags & ICMPv6_ECHOREPLY) != 0) + if ((flags & ICMPv6_NEWDATA) != 0) { eventset |= (POLLIN & info->fds->events); } diff --git a/net/icmpv6/icmpv6_recvfrom.c b/net/icmpv6/icmpv6_recvfrom.c index 0a51e42f766..b26d0562457 100644 --- a/net/icmpv6/icmpv6_recvfrom.c +++ b/net/icmpv6/icmpv6_recvfrom.c @@ -187,7 +187,7 @@ static uint16_t recvfrom_eventhandler(FAR struct net_driver_s *dev, /* Check if we have just received a ICMPv6 ECHO reply. */ - if ((flags & ICMPv6_ECHOREPLY) != 0) /* No incoming data */ + if ((flags & ICMPv6_NEWDATA) != 0) /* No incoming data */ { unsigned int recvsize; @@ -239,6 +239,10 @@ static uint16_t recvfrom_eventhandler(FAR struct net_driver_s *dev, DEBUGASSERT(conn->nreqs > 0); conn->nreqs--; + + /* Indicate that the data has been consumed */ + + flags &= ~ICMPv6_NEWDATA; goto end_wait; } @@ -498,7 +502,7 @@ ssize_t icmpv6_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, state.recv_cb = icmpv6_callback_alloc(dev, conn); if (state.recv_cb) { - state.recv_cb->flags = (ICMPv6_ECHOREPLY | NETDEV_DOWN); + state.recv_cb->flags = (ICMPv6_NEWDATA | NETDEV_DOWN); state.recv_cb->priv = (FAR void *)&state; state.recv_cb->event = recvfrom_eventhandler; state.recv_result = -EINTR; /* Assume sem-wait interrupted by signal */