Improve icmp handling if MULTINIC enabled. From Max Neklyudov
This commit is contained in:
parent
adb617cdcd
commit
8ecb84ed89
@ -70,6 +70,8 @@
|
|||||||
* Public Types
|
* Public Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct devif_callback_s; /* Forward reference */
|
||||||
|
|
||||||
/* This structure collects information that is specific to a specific network
|
/* This structure collects information that is specific to a specific network
|
||||||
* interface driver. If the hardware platform supports only a single instance
|
* interface driver. If the hardware platform supports only a single instance
|
||||||
* of this structure.
|
* of this structure.
|
||||||
@ -190,6 +192,17 @@ struct net_driver_s
|
|||||||
sq_queue_t grplist;
|
sq_queue_t grplist;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Application callbacks:
|
||||||
|
*
|
||||||
|
* Network device event handlers are retained in a 'list' and are called
|
||||||
|
* for events specified in the flags set within struct devif_callback_s.
|
||||||
|
* The following network event flags may be specified:
|
||||||
|
*
|
||||||
|
* NETDEV_DOWN - The network is down
|
||||||
|
*/
|
||||||
|
|
||||||
|
FAR struct devif_callback_s *d_callbacks;
|
||||||
|
|
||||||
/* Driver callbacks */
|
/* Driver callbacks */
|
||||||
|
|
||||||
int (*d_ifup)(FAR struct net_driver_s *dev);
|
int (*d_ifup)(FAR struct net_driver_s *dev);
|
||||||
|
@ -115,6 +115,7 @@
|
|||||||
* OUT: Cleared (only) by the socket layer logic to indicate
|
* OUT: Cleared (only) by the socket layer logic to indicate
|
||||||
* that the reply was processed, suppressing further
|
* that the reply was processed, suppressing further
|
||||||
* attempts to process the reply.
|
* attempts to process the reply.
|
||||||
|
* NETDEV_DOWN: IN: The network device has been taken down.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define TCP_ACKDATA (1 << 0)
|
#define TCP_ACKDATA (1 << 0)
|
||||||
@ -138,8 +139,10 @@
|
|||||||
#define TCP_TIMEDOUT (1 << 9)
|
#define TCP_TIMEDOUT (1 << 9)
|
||||||
#define ICMP_ECHOREPLY (1 << 10)
|
#define ICMP_ECHOREPLY (1 << 10)
|
||||||
#define ICMPv6_ECHOREPLY ICMP_ECHOREPLY
|
#define ICMPv6_ECHOREPLY ICMP_ECHOREPLY
|
||||||
|
#define NETDEV_DOWN (1 << 11)
|
||||||
|
|
||||||
#define TCP_CONN_EVENTS (TCP_CLOSE | TCP_ABORT | TCP_CONNECTED | TCP_TIMEDOUT)
|
#define TCP_CONN_EVENTS (TCP_CLOSE | TCP_ABORT | TCP_CONNECTED | \
|
||||||
|
TCP_TIMEDOUT | NETDEV_DOWN)
|
||||||
|
|
||||||
/* IPv4/IPv6 Helpers */
|
/* IPv4/IPv6 Helpers */
|
||||||
|
|
||||||
|
@ -69,17 +69,13 @@
|
|||||||
#define ICMPBUF ((struct icmp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
#define ICMPBUF ((struct icmp_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Variables
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Variables
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_ICMP_PING
|
|
||||||
FAR struct devif_callback_s *g_icmp_echocallback = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -182,9 +178,9 @@ void icmp_input(FAR struct net_driver_s *dev)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_ICMP_PING
|
#ifdef CONFIG_NET_ICMP_PING
|
||||||
else if (picmp->type == ICMP_ECHO_REPLY && g_icmp_echocallback)
|
else if (picmp->type == ICMP_ECHO_REPLY && dev->d_callbacks)
|
||||||
{
|
{
|
||||||
(void)devif_callback_execute(dev, picmp, ICMP_ECHOREPLY, g_icmp_echocallback);
|
(void)devif_callback_execute(dev, picmp, ICMP_ECHOREPLY, dev->d_callbacks);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -70,8 +70,8 @@
|
|||||||
|
|
||||||
/* Allocate a new ICMP data callback */
|
/* Allocate a new ICMP data callback */
|
||||||
|
|
||||||
#define icmp_callback_alloc() devif_callback_alloc(&g_icmp_echocallback)
|
#define icmp_callback_alloc() devif_callback_alloc(&dev->d_callbacks)
|
||||||
#define icmp_callback_free(cb) devif_callback_free(cb, &g_icmp_echocallback)
|
#define icmp_callback_free(cb) devif_callback_free(cb, &dev->d_callbacks)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
@ -87,7 +87,7 @@ struct icmp_ping_s
|
|||||||
int png_result; /* 0: success; <0:negated errno on fail */
|
int png_result; /* 0: success; <0:negated errno on fail */
|
||||||
in_addr_t png_addr; /* The peer to be ping'ed */
|
in_addr_t png_addr; /* The peer to be ping'ed */
|
||||||
uint16_t png_id; /* Used to match requests with replies */
|
uint16_t png_id; /* Used to match requests with replies */
|
||||||
uint16_t png_seqno; /* IN: seqno to send; OUT: seqno recieved */
|
uint16_t png_seqno; /* IN: seqno to send; OUT: seqno received */
|
||||||
uint16_t png_datlen; /* The length of data to send in the ECHO request */
|
uint16_t png_datlen; /* The length of data to send in the ECHO request */
|
||||||
bool png_sent; /* true... the PING request has been sent */
|
bool png_sent; /* true... the PING request has been sent */
|
||||||
};
|
};
|
||||||
@ -164,13 +164,25 @@ static uint16_t ping_interrupt(FAR struct net_driver_s *dev, FAR void *conn,
|
|||||||
nllvdbg("flags: %04x\n", flags);
|
nllvdbg("flags: %04x\n", flags);
|
||||||
if (pstate)
|
if (pstate)
|
||||||
{
|
{
|
||||||
|
/* Check if the network is still up
|
||||||
|
*
|
||||||
|
* REVISIT: Now does the ICMP logic know that this was the correct device?
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((flags & NETDEV_DOWN) != 0)
|
||||||
|
{
|
||||||
|
nlldbg("ERROR: Interface is down\n");
|
||||||
|
pstate->png_result = -ENETUNREACH;
|
||||||
|
goto end_wait;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if this is a ICMP ECHO reply. If so, return the sequence
|
/* Check if this is a ICMP ECHO reply. If so, return the sequence
|
||||||
* number to the caller. NOTE: We may not even have sent the
|
* number to the caller. NOTE: We may not even have sent the
|
||||||
* requested ECHO request; this could have been the delayed ECHO
|
* requested ECHO request; this could have been the delayed ECHO
|
||||||
* response from a previous ping.
|
* response from a previous ping.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((flags & ICMP_ECHOREPLY) != 0 && conn != NULL)
|
else if ((flags & ICMP_ECHOREPLY) != 0 && conn != NULL)
|
||||||
{
|
{
|
||||||
FAR struct icmp_iphdr_s *icmp = (FAR struct icmp_iphdr_s *)conn;
|
FAR struct icmp_iphdr_s *icmp = (FAR struct icmp_iphdr_s *)conn;
|
||||||
|
|
||||||
@ -332,7 +344,22 @@ int icmp_ping(in_addr_t addr, uint16_t id, uint16_t seqno, uint16_t datalen,
|
|||||||
net_lock_t save;
|
net_lock_t save;
|
||||||
#ifdef CONFIG_NET_ARP_SEND
|
#ifdef CONFIG_NET_ARP_SEND
|
||||||
int ret;
|
int ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
|
FAR struct net_driver_s *dev;
|
||||||
|
|
||||||
|
/* Get the device that will be used to route this ICMP ECHO request */
|
||||||
|
|
||||||
|
dev = netdev_findby_ipv4addr(g_ipv4_allzeroaddr, addr);
|
||||||
|
if (dev == 0)
|
||||||
|
{
|
||||||
|
ndbg("ERROR: Not reachable\n");
|
||||||
|
return -ENETUNREACH;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_ARP_SEND
|
||||||
/* Make sure that the IP address mapping is in the ARP table */
|
/* Make sure that the IP address mapping is in the ARP table */
|
||||||
|
|
||||||
ret = arp_send(addr);
|
ret = arp_send(addr);
|
||||||
@ -362,7 +389,7 @@ int icmp_ping(in_addr_t addr, uint16_t id, uint16_t seqno, uint16_t datalen,
|
|||||||
state.png_cb = icmp_callback_alloc();
|
state.png_cb = icmp_callback_alloc();
|
||||||
if (state.png_cb)
|
if (state.png_cb)
|
||||||
{
|
{
|
||||||
state.png_cb->flags = (ICMP_POLL | ICMP_ECHOREPLY);
|
state.png_cb->flags = (ICMP_POLL | ICMP_ECHOREPLY | NETDEV_DOWN);
|
||||||
state.png_cb->priv = (void*)&state;
|
state.png_cb->priv = (void*)&state;
|
||||||
state.png_cb->event = ping_interrupt;
|
state.png_cb->event = ping_interrupt;
|
||||||
state.png_result = -EINTR; /* Assume sem-wait interrupted by signal */
|
state.png_result = -EINTR; /* Assume sem-wait interrupted by signal */
|
||||||
@ -370,7 +397,7 @@ int icmp_ping(in_addr_t addr, uint16_t id, uint16_t seqno, uint16_t datalen,
|
|||||||
/* Notify the device driver of the availability of TX data */
|
/* Notify the device driver of the availability of TX data */
|
||||||
|
|
||||||
#ifdef CONFIG_NETDEV_MULTINIC
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
netdev_ipv4_txnotify(g_ipv4_allzeroaddr, state.png_addr);
|
netdev_ipv4_txnotify_dev(dev);
|
||||||
#else
|
#else
|
||||||
netdev_ipv4_txnotify(state.png_addr);
|
netdev_ipv4_txnotify(state.png_addr);
|
||||||
#endif
|
#endif
|
||||||
|
@ -96,7 +96,7 @@ void icmp_poll(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Perform the application callback */
|
/* Perform the application callback */
|
||||||
|
|
||||||
(void)devif_callback_execute(dev, NULL, ICMP_POLL, g_icmp_echocallback);
|
(void)devif_callback_execute(dev, NULL, ICMP_POLL, dev->d_callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NET && CONFIG_NET_ICMP && CONFIG_NET_ICMP_PING */
|
#endif /* CONFIG_NET && CONFIG_NET_ICMP && CONFIG_NET_ICMP_PING */
|
||||||
|
@ -130,6 +130,7 @@ FAR struct net_driver_s *netdev_default(void);
|
|||||||
#ifdef CONFIG_NET_IPv4
|
#ifdef CONFIG_NET_IPv4
|
||||||
# ifdef CONFIG_NETDEV_MULTINIC
|
# ifdef CONFIG_NETDEV_MULTINIC
|
||||||
void netdev_ipv4_txnotify(in_addr_t lipaddr, in_addr_t ripaddr);
|
void netdev_ipv4_txnotify(in_addr_t lipaddr, in_addr_t ripaddr);
|
||||||
|
void netdev_ipv4_txnotify_dev(FAR struct net_driver_s *dev);
|
||||||
# else
|
# else
|
||||||
void netdev_ipv4_txnotify(in_addr_t ripaddr);
|
void netdev_ipv4_txnotify(in_addr_t ripaddr);
|
||||||
# endif
|
# endif
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
|
|
||||||
#include "socket/socket.h"
|
#include "socket/socket.h"
|
||||||
#include "netdev/netdev.h"
|
#include "netdev/netdev.h"
|
||||||
|
#include "devif/devif.h"
|
||||||
#include "igmp/igmp.h"
|
#include "igmp/igmp.h"
|
||||||
#include "icmpv6/icmpv6.h"
|
#include "icmpv6/icmpv6.h"
|
||||||
#include "route/route.h"
|
#include "route/route.h"
|
||||||
@ -1024,7 +1025,7 @@ void netdev_ifup(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
void netdev_ifdown(FAR struct net_driver_s *dev)
|
void netdev_ifdown(FAR struct net_driver_s *dev)
|
||||||
{
|
{
|
||||||
/* Make sure that the device supports the d_ifdown() method */
|
/* Check sure that the device supports the d_ifdown() method */
|
||||||
|
|
||||||
if (dev->d_ifdown)
|
if (dev->d_ifdown)
|
||||||
{
|
{
|
||||||
@ -1041,6 +1042,11 @@ void netdev_ifdown(FAR struct net_driver_s *dev)
|
|||||||
dev->d_flags &= ~IFF_UP;
|
dev->d_flags &= ~IFF_UP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Notify clients that the network has been taken down */
|
||||||
|
|
||||||
|
(void)devif_callback_execute(dev, NULL, NETDEV_DOWN,
|
||||||
|
dev->d_callbacks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,6 +247,10 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype)
|
|||||||
devfmt = NETDEV_DEFAULT_FORMAT;
|
devfmt = NETDEV_DEFAULT_FORMAT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* There are no clients of the device yet */
|
||||||
|
|
||||||
|
dev->d_callbacks = NULL;
|
||||||
|
|
||||||
/* Get the next available device number and sssign a device name to
|
/* Get the next available device number and sssign a device name to
|
||||||
* the interface
|
* the interface
|
||||||
*/
|
*/
|
||||||
|
@ -166,4 +166,35 @@ void netdev_ipv6_txnotify(FAR const net_ipv6addr_t ripaddr)
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_IPv6 */
|
#endif /* CONFIG_NET_IPv6 */
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: netdev_ipv4_txnotify_dev
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Notify the device driver that new TX data is available. This variant
|
||||||
|
* would be called when the upper level logic already understands how the
|
||||||
|
* packet will be routed.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* dev - The network device driver state structure.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Called from normal user mode
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
|
void netdev_ipv4_txnotify_dev(FAR struct net_driver_s *dev)
|
||||||
|
{
|
||||||
|
if (dev && dev->d_txavail)
|
||||||
|
{
|
||||||
|
/* Notify the device driver that new TX data is available. */
|
||||||
|
|
||||||
|
(void)dev->d_txavail(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NET_IPv6 */
|
||||||
|
|
||||||
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */
|
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */
|
||||||
|
Loading…
Reference in New Issue
Block a user