From 6796a8dde653598dec5c234bf68b2b3bd246a099 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 23 Nov 2014 11:00:22 -0600 Subject: Add logic to netdev_findbyaddr() to return the correct network device for the case where a broadcast address is used. This change caused trivial ripples through other files because additional parameters are required for netdev_findbyaddr() when CONFIG_NET_MULTINIC --- nuttx/net/arp/arp_notify.c | 4 -- nuttx/net/arp/arp_send.c | 4 ++ nuttx/net/icmp/icmp_ping.c | 4 ++ nuttx/net/netdev/netdev.h | 25 +++++++++-- nuttx/net/netdev/netdev_findbyaddr.c | 86 ++++++++++++++++++++++++------------ nuttx/net/netdev/netdev_rxnotify.c | 17 +++++-- nuttx/net/netdev/netdev_txnotify.c | 22 ++++++--- nuttx/net/route/net_router.c | 2 +- nuttx/net/socket/net_close.c | 4 ++ nuttx/net/socket/net_sendfile.c | 7 ++- nuttx/net/socket/recvfrom.c | 12 ++++- nuttx/net/socket/sendto.c | 6 ++- nuttx/net/tcp/tcp_send_buffered.c | 4 ++ nuttx/net/tcp/tcp_send_unbuffered.c | 4 ++ 14 files changed, 150 insertions(+), 51 deletions(-) diff --git a/nuttx/net/arp/arp_notify.c b/nuttx/net/arp/arp_notify.c index cc3dc6fd2..37bb1686d 100644 --- a/nuttx/net/arp/arp_notify.c +++ b/nuttx/net/arp/arp_notify.c @@ -72,10 +72,6 @@ static struct arp_notify_s *g_arp_waiters; * Private Functions ****************************************************************************/ -/**************************************************************************** - * Function: arp_send_interrupt - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/nuttx/net/arp/arp_send.c b/nuttx/net/arp/arp_send.c index 8433aa964..b3803d0f1 100644 --- a/nuttx/net/arp/arp_send.c +++ b/nuttx/net/arp/arp_send.c @@ -222,7 +222,11 @@ int arp_send(in_addr_t ipaddr) /* Get the device that can route this request */ +#ifdef CONFIG_NET_MULTILINK + dev = netdev_findbyaddr(g_allzeroaddr, ipaddr); +#else dev = netdev_findbyaddr(ipaddr); +#endif if (!dev) { ndbg("ERROR: Unreachable: %08lx\n", (unsigned long)ipaddr); diff --git a/nuttx/net/icmp/icmp_ping.c b/nuttx/net/icmp/icmp_ping.c index be80b1b0a..953081735 100644 --- a/nuttx/net/icmp/icmp_ping.c +++ b/nuttx/net/icmp/icmp_ping.c @@ -371,7 +371,11 @@ int icmp_ping(net_ipaddr_t addr, uint16_t id, uint16_t seqno, /* Notify the device driver of the availability of TX data */ +#ifdef CONFIG_NET_MULTILINK + netdev_txnotify(g_allzeroaddr, state.png_addr); +#else netdev_txnotify(state.png_addr); +#endif /* Wait for either the full round trip transfer to complete or * for timeout to occur. (1) net_lockedwait will also terminate if a diff --git a/nuttx/net/netdev/netdev.h b/nuttx/net/netdev/netdev.h index 2ab83ed00..70333a283 100644 --- a/nuttx/net/netdev/netdev.h +++ b/nuttx/net/netdev/netdev.h @@ -94,7 +94,12 @@ FAR struct net_driver_s *netdev_findbyname(FAR const char *ifname); /* netdev_findbyaddr.c *******************************************************/ #if CONFIG_NSOCKET_DESCRIPTORS > 0 -FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t addr); +#ifdef CONFIG_NET_MULTILINK +FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t lipaddr, + const net_ipaddr_t ripaddr); +#else +FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t ripaddr); +#endif #endif /* netdev_default.c ***********************************************************/ @@ -106,15 +111,27 @@ FAR struct net_driver_s *netdev_default(void); /* netdev_txnotify.c *********************************************************/ #if CONFIG_NSOCKET_DESCRIPTORS > 0 -void netdev_txnotify(const net_ipaddr_t addr); +# ifdef CONFIG_NET_MULTILINK +void netdev_txnotify(const net_ipaddr_t lipaddr, const net_ipaddr_t ripaddr); +# else +void netdev_txnotify(const net_ipaddr_t ripaddr); +# endif #endif /* netdev_rxnotify.c *********************************************************/ #if CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET_RXAVAIL) -void netdev_rxnotify(const net_ipaddr_t addr); +# ifdef CONFIG_NET_MULTILINK +void netdev_rxnotify(const net_ipaddr_t lipaddr, const net_ipaddr_t ripaddr); +# else +void netdev_rxnotify(const net_ipaddr_t ripaddr); +# endif #else -# define netdev_rxnotify(addr) +# ifdef CONFIG_NET_MULTILINK +# define netdev_rxnotify(lipaddr,ripaddr) +# else +# define netdev_rxnotify(ripaddr) +# endif #endif /* netdev_count.c ************************************************************/ diff --git a/nuttx/net/netdev/netdev_findbyaddr.c b/nuttx/net/netdev/netdev_findbyaddr.c index b43ee7411..f1ea3712a 100644 --- a/nuttx/net/netdev/netdev_findbyaddr.c +++ b/nuttx/net/netdev/netdev_findbyaddr.c @@ -49,6 +49,7 @@ #include #include "netdev/netdev.h" +#include "devif/devif.h" #include "route/route.h" /**************************************************************************** @@ -71,10 +72,6 @@ * Private Functions ****************************************************************************/ -/**************************************************************************** - * Function: netdev_maskcmp - ****************************************************************************/ - /**************************************************************************** * Function: netdev_finddevice * @@ -84,7 +81,7 @@ * (since a "down" device has no meaningful address). * * Parameters: - * addr - Pointer to the remote address of a connection + * ripaddr - Remote address of a connection to use in the lookup * * Returned Value: * Pointer to driver on success; null on failure @@ -94,7 +91,7 @@ * ****************************************************************************/ -static FAR struct net_driver_s *netdev_finddevice(const net_ipaddr_t addr) +static FAR struct net_driver_s *netdev_finddevice(const net_ipaddr_t ripaddr) { FAR struct net_driver_s *dev; @@ -109,7 +106,7 @@ static FAR struct net_driver_s *netdev_finddevice(const net_ipaddr_t addr) { /* Yes.. check for an address match (under the netmask) */ - if (net_ipaddr_maskcmp(dev->d_ipaddr, addr, dev->d_netmask)) + if (net_ipaddr_maskcmp(dev->d_ipaddr, ripaddr, dev->d_netmask)) { /* Its a match */ @@ -137,7 +134,9 @@ static FAR struct net_driver_s *netdev_finddevice(const net_ipaddr_t addr) * IP address. * * Parameters: - * addr - Pointer to the remote address of a connection + * lipaddr - Local, bound address of a connection. Used only if ripaddr + * is the broadcast address. Used only if CONFIG_NET_MULTILINK. + * ripaddr - Remote address of a connection to use in the lookup * * Returned Value: * Pointer to driver on success; null on failure @@ -147,7 +146,12 @@ static FAR struct net_driver_s *netdev_finddevice(const net_ipaddr_t addr) * ****************************************************************************/ -FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t addr) +#ifdef CONFIG_NET_MULTILINK +FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t lipaddr, + const net_ipaddr_t ripaddr) +#else +FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t ripaddr) +#endif { struct net_driver_s *dev; #ifdef CONFIG_NET_ROUTE @@ -155,9 +159,42 @@ FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t addr) int ret; #endif - /* First, see if the address maps to the a local network */ + /* First, check if this is the broadcast IP address */ + + if (net_ipaddr_cmp(ripaddr, g_alloneaddr)) + { +#ifdef CONFIG_NET_MULTILINK + /* Yes.. Check the local, bound address. Is it INADDR_ANY? */ - dev = netdev_finddevice(addr); + if (net_ipaddr_cmp(lipaddr, g_allzeroaddr)) + { + /* Yes.. In this case, I think we are supposed to send the + * broadcast packet out ALL local networks. I am not sure + * of that and, in any event, there is nothing we can do + * about that here. + */ + + return NULL; + } + else + { + /* Return the device associated with the local address */ + + return netdev_finddevice(lipaddr); + } +#else + /* If there is only a single, registered network interface, then the + * decision is pretty easy. Use that device and its default router + * address. + */ + + return g_netdevices; +#endif + } + + /* Check if the address maps to a local network */ + + dev = netdev_finddevice(ripaddr); if (dev) { return dev; @@ -171,9 +208,9 @@ FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t addr) */ #ifdef CONFIG_NET_IPv6 - ret = net_router(addr, router); + ret = net_router(ripaddr, router); #else - ret = net_router(addr, &router); + ret = net_router(ripaddr, &router); #endif if (ret >= 0) { @@ -191,27 +228,20 @@ FAR struct net_driver_s *netdev_findbyaddr(const net_ipaddr_t addr) /* The above lookup will fail if the packet is being sent out of our * out subnet to a router and there is no routing information. - * - * However, if there is only a single, registered network interface, then - * the decision is pretty easy. Use that device and its default router - * address. - * - * REVISIT: This logic is lame. Also, in the case where the socket is - * bound to INADDRY_ANY, we should return the default network device - * (from netdev_default()). */ - netdev_semtake(); - if (g_netdevices && !g_netdevices->flink) - { - dev = g_netdevices; - } +#ifndef CONFIG_NET_MULTILINK + /* If there is only a single, registered network interface, then the + * decision is pretty easy. Use that device and its default router + * address. Hmmm... it is almost certainly wrong, however. + */ - netdev_semgive(); + dev = g_netdevices; +#endif /* If we will did not find the network device, then we might as well fail * because we are not configured properly to determine the route to the - * target. + * destination. */ return dev; diff --git a/nuttx/net/netdev/netdev_rxnotify.c b/nuttx/net/netdev/netdev_rxnotify.c index ce1b78f1a..e471dbb54 100644 --- a/nuttx/net/netdev/netdev_rxnotify.c +++ b/nuttx/net/netdev/netdev_rxnotify.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/netdev/netdev_rxnotify.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -81,7 +81,7 @@ * Notify the device driver that the application waits for RX data. * * Parameters: - * raddr - The remote address to send the data + * ripaddr - The remote address to send the data * * Returned Value: * None @@ -91,12 +91,21 @@ * ****************************************************************************/ -void netdev_rxnotify(const net_ipaddr_t raddr) +#ifdef CONFIG_NET_MULTILINK +void netdev_rxnotify(const net_ipaddr_t lipaddr, const net_ipaddr_t ripaddr) +#else +void netdev_rxnotify(const net_ipaddr_t ripaddr) +#endif { + FAR struct net_driver_s *dev; /* Find the device driver that serves the subnet of the remote address */ - struct net_driver_s *dev = netdev_findbyaddr(raddr); +#ifdef CONFIG_NET_MULTILINK + dev = netdev_findbyaddr(lipaddr, ripaddr); +#else + dev = netdev_findbyaddr(ripaddr); +#endif if (dev && dev->d_rxavail) { diff --git a/nuttx/net/netdev/netdev_txnotify.c b/nuttx/net/netdev/netdev_txnotify.c index c19f0a7d5..644a6a2a2 100644 --- a/nuttx/net/netdev/netdev_txnotify.c +++ b/nuttx/net/netdev/netdev_txnotify.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/netdev/netdev_txnotify.c * - * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2012, 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -51,11 +51,11 @@ #include "netdev/netdev.h" /**************************************************************************** - * Definitions + * Pre-processor Definitions ****************************************************************************/ /**************************************************************************** - * Priviate Types + * Private Types ****************************************************************************/ /**************************************************************************** @@ -81,7 +81,7 @@ * Notify the device driver that new TX data is available. * * Parameters: - * raddr - The remote address to send the data + * ripaddr - The remote address to send the data * * Returned Value: * None @@ -91,11 +91,21 @@ * ****************************************************************************/ -void netdev_txnotify(const net_ipaddr_t raddr) +#ifdef CONFIG_NET_MULTILINK +void netdev_txnotify(const net_ipaddr_t lipaddr, const net_ipaddr_t ripaddr) +#else +void netdev_txnotify(const net_ipaddr_t ripaddr) +#endif { + FAR struct net_driver_s *dev; + /* Find the device driver that serves the subnet of the remote address */ - struct net_driver_s *dev = netdev_findbyaddr(raddr); +#ifdef CONFIG_NET_MULTILINK + dev = netdev_findbyaddr(lipaddr, ripaddr); +#else + dev = netdev_findbyaddr(ripaddr); +#endif if (dev && dev->d_txavail) { diff --git a/nuttx/net/route/net_router.c b/nuttx/net/route/net_router.c index 1755b0209..1f24edfc0 100644 --- a/nuttx/net/route/net_router.c +++ b/nuttx/net/route/net_router.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/route/net_router.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without diff --git a/nuttx/net/socket/net_close.c b/nuttx/net/socket/net_close.c index 394cc6232..428f6590f 100644 --- a/nuttx/net/socket/net_close.c +++ b/nuttx/net/socket/net_close.c @@ -357,7 +357,11 @@ static inline int netclose_disconnect(FAR struct socket *psock) /* Notify the device driver of the availability of TX data */ +#ifdef CONFIG_NET_MULTILINK + netdev_txnotify(conn->lipaddr, conn->ripaddr); +#else netdev_txnotify(conn->ripaddr); +#endif #ifdef CONFIG_NET_SOLINGER /* Wait only if we are lingering */ diff --git a/nuttx/net/socket/net_sendfile.c b/nuttx/net/socket/net_sendfile.c index 807bdcc7d..4e99f596e 100644 --- a/nuttx/net/socket/net_sendfile.c +++ b/nuttx/net/socket/net_sendfile.c @@ -562,10 +562,13 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset, state.snd_datacb->priv = (void*)&state; state.snd_datacb->event = sendfile_interrupt; - /* Notify the device driver of the availaibilty of TX data */ + /* Notify the device driver of the availability of TX data */ +#ifdef CONFIG_NET_MULTILINK + netdev_txnotify(conn->lipaddr, conn->ripaddr); +#else netdev_txnotify(conn->ripaddr); - +#endif net_lockedwait(&state.snd_sem); } while (state.snd_sent >= 0 && state.snd_acked < state.snd_flen); diff --git a/nuttx/net/socket/recvfrom.c b/nuttx/net/socket/recvfrom.c index 992eb40b3..160246715 100644 --- a/nuttx/net/socket/recvfrom.c +++ b/nuttx/net/socket/recvfrom.c @@ -1090,7 +1090,13 @@ static ssize_t pkt_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, /* Notify the device driver of the receive call */ - /* netdev_rxnotify(conn->ripaddr); */ +#if 0 /* No */ +#ifdef CONFIG_NET_MULTILINK + netdev_rxnotify(conn->lipaddr, conn->ripaddr); +#else + netdev_rxnotify(conn->ripaddr); +#endif +#endif /* Wait for either the receive to complete or for an error/timeout to occur. * NOTES: (1) net_lockedwait will also terminate if a signal is received, (2) @@ -1184,7 +1190,11 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, /* Notify the device driver of the receive call */ +#ifdef CONFIG_NET_MULTILINK + netdev_rxnotify(conn->lipaddr, conn->ripaddr); +#else netdev_rxnotify(conn->ripaddr); +#endif /* Wait for either the receive to complete or for an error/timeout to occur. * NOTES: (1) net_lockedwait will also terminate if a signal is received, (2) diff --git a/nuttx/net/socket/sendto.c b/nuttx/net/socket/sendto.c index 09a5dd7d4..ae2884816 100644 --- a/nuttx/net/socket/sendto.c +++ b/nuttx/net/socket/sendto.c @@ -417,9 +417,13 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf, state.st_cb->priv = (void*)&state; state.st_cb->event = sendto_interrupt; - /* Notify the device driver of the availabilty of TX data */ + /* Notify the device driver of the availability of TX data */ +#ifdef CONFIG_NET_MULTILINK + netdev_txnotify(conn->lipaddr, conn->ripaddr); +#else netdev_txnotify(conn->ripaddr); +#endif /* Wait for either the receive to complete or for an error/timeout to occur. * NOTES: (1) net_lockedwait will also terminate if a signal is received, (2) diff --git a/nuttx/net/tcp/tcp_send_buffered.c b/nuttx/net/tcp/tcp_send_buffered.c index d516262fa..c50b81040 100644 --- a/nuttx/net/tcp/tcp_send_buffered.c +++ b/nuttx/net/tcp/tcp_send_buffered.c @@ -824,7 +824,11 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, /* Notify the device driver of the availability of TX data */ +#ifdef CONFIG_NET_MULTILINK + netdev_txnotify(conn->lipaddr, conn->ripaddr); +#else netdev_txnotify(conn->ripaddr); +#endif result = len; } diff --git a/nuttx/net/tcp/tcp_send_unbuffered.c b/nuttx/net/tcp/tcp_send_unbuffered.c index 3590024ec..9aa6cdb5a 100644 --- a/nuttx/net/tcp/tcp_send_unbuffered.c +++ b/nuttx/net/tcp/tcp_send_unbuffered.c @@ -596,7 +596,11 @@ ssize_t psock_tcp_send(FAR struct socket *psock, /* Notify the device driver of the availability of TX data */ +#ifdef CONFIG_NET_MULTILINK + netdev_txnotify(conn->lipaddr, conn->ripaddr); +#else netdev_txnotify(conn->ripaddr); +#endif /* Wait for the send to complete or an error to occur: NOTES: (1) * net_lockedwait will also terminate if a signal is received, (2) interrupts -- cgit v1.2.3