Improve icmp handling if MULTINIC enabled. From Max Neklyudov
This commit is contained in:
parent
adb617cdcd
commit
8ecb84ed89
@ -70,6 +70,8 @@
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct devif_callback_s; /* Forward reference */
|
||||
|
||||
/* This structure collects information that is specific to a specific network
|
||||
* interface driver. If the hardware platform supports only a single instance
|
||||
* of this structure.
|
||||
@ -190,6 +192,17 @@ struct net_driver_s
|
||||
sq_queue_t grplist;
|
||||
#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 */
|
||||
|
||||
int (*d_ifup)(FAR struct net_driver_s *dev);
|
||||
|
@ -115,6 +115,7 @@
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define TCP_ACKDATA (1 << 0)
|
||||
@ -138,8 +139,10 @@
|
||||
#define TCP_TIMEDOUT (1 << 9)
|
||||
#define ICMP_ECHOREPLY (1 << 10)
|
||||
#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 */
|
||||
|
||||
|
@ -69,17 +69,13 @@
|
||||
#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
|
||||
****************************************************************************/
|
||||
@ -182,9 +178,9 @@ void icmp_input(FAR struct net_driver_s *dev)
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
|
@ -70,8 +70,8 @@
|
||||
|
||||
/* Allocate a new ICMP data callback */
|
||||
|
||||
#define icmp_callback_alloc() devif_callback_alloc(&g_icmp_echocallback)
|
||||
#define icmp_callback_free(cb) devif_callback_free(cb, &g_icmp_echocallback)
|
||||
#define icmp_callback_alloc() devif_callback_alloc(&dev->d_callbacks)
|
||||
#define icmp_callback_free(cb) devif_callback_free(cb, &dev->d_callbacks)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
@ -87,7 +87,7 @@ struct icmp_ping_s
|
||||
int png_result; /* 0: success; <0:negated errno on fail */
|
||||
in_addr_t png_addr; /* The peer to be ping'ed */
|
||||
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 */
|
||||
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);
|
||||
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
|
||||
* number to the caller. NOTE: We may not even have sent the
|
||||
* requested ECHO request; this could have been the delayed ECHO
|
||||
* 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;
|
||||
|
||||
@ -332,7 +344,22 @@ int icmp_ping(in_addr_t addr, uint16_t id, uint16_t seqno, uint16_t datalen,
|
||||
net_lock_t save;
|
||||
#ifdef CONFIG_NET_ARP_SEND
|
||||
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 */
|
||||
|
||||
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();
|
||||
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->event = ping_interrupt;
|
||||
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 */
|
||||
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
netdev_ipv4_txnotify(g_ipv4_allzeroaddr, state.png_addr);
|
||||
netdev_ipv4_txnotify_dev(dev);
|
||||
#else
|
||||
netdev_ipv4_txnotify(state.png_addr);
|
||||
#endif
|
||||
|
@ -96,7 +96,7 @@ void icmp_poll(FAR struct net_driver_s *dev)
|
||||
|
||||
/* 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 */
|
||||
|
@ -130,6 +130,7 @@ FAR struct net_driver_s *netdev_default(void);
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
# ifdef CONFIG_NETDEV_MULTINIC
|
||||
void netdev_ipv4_txnotify(in_addr_t lipaddr, in_addr_t ripaddr);
|
||||
void netdev_ipv4_txnotify_dev(FAR struct net_driver_s *dev);
|
||||
# else
|
||||
void netdev_ipv4_txnotify(in_addr_t ripaddr);
|
||||
# endif
|
||||
|
@ -65,6 +65,7 @@
|
||||
|
||||
#include "socket/socket.h"
|
||||
#include "netdev/netdev.h"
|
||||
#include "devif/devif.h"
|
||||
#include "igmp/igmp.h"
|
||||
#include "icmpv6/icmpv6.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)
|
||||
{
|
||||
/* Make sure that the device supports the d_ifdown() method */
|
||||
/* Check sure that the device supports the d_ifdown() method */
|
||||
|
||||
if (dev->d_ifdown)
|
||||
{
|
||||
@ -1041,6 +1042,11 @@ void netdev_ifdown(FAR struct net_driver_s *dev)
|
||||
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;
|
||||
#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
|
||||
* the interface
|
||||
*/
|
||||
|
@ -166,4 +166,35 @@ void netdev_ipv6_txnotify(FAR const net_ipv6addr_t ripaddr)
|
||||
}
|
||||
#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 */
|
||||
|
Loading…
Reference in New Issue
Block a user