netdev_findbyaddr() will not use a routing table if one is available. It will also make a better decision in the case there there is no routing table but only a single network interface.

This commit is contained in:
Gregory Nutt 2013-10-05 13:16:18 -06:00
parent 566857bcbd
commit 95ed790c54
10 changed files with 128 additions and 53 deletions

View File

@ -5702,4 +5702,10 @@
touschscreen drive is basically functional) (2013-10-3)
* arch/arm/src/sama5/chip/sam_lcdc.h: Add SAMA5 LCD register
definition header file (2013-10-4).
* net/netdev_findbyaddr.c: Now (1) uses the routing table
if available to look up the router to get to a remote network,
and (2) if there is only a single network device and no
route, then it will simply return that single device. The
ARP logic will use the default router address associated with
the interface in this case (2013-10-5).

View File

@ -176,7 +176,7 @@ static inline void netclose_disconnect(FAR struct socket *psock)
/* Notify the device driver of the availaibilty of TX data */
netdev_txnotify(&conn->ripaddr);
netdev_txnotify(conn->ripaddr);
/* Wait for the disconnect event */

View File

@ -202,21 +202,21 @@ FAR struct uip_driver_s *netdev_findbyname(FAR const char *ifname);
/* net_findbyaddr.c **********************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0
FAR struct uip_driver_s *netdev_findbyaddr(FAR const uip_ipaddr_t *raddr);
FAR struct uip_driver_s *netdev_findbyaddr(const uip_ipaddr_t addr);
#endif
/* net_txnotify.c ************************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0
void netdev_txnotify(const uip_ipaddr_t *raddr);
void netdev_txnotify(const uip_ipaddr_t addr);
#endif
/* net_rxnotify.c ************************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET_RXAVAIL)
void netdev_rxnotify(const uip_ipaddr_t *raddr);
void netdev_rxnotify(const uip_ipaddr_t addr);
#else
# define netdev_rxnotify(raddr)
# define netdev_rxnotify(addr)
#endif
/* net_count.c ***************************************************************/

View File

@ -187,6 +187,12 @@ int net_delroute(uip_ipaddr_t target, uip_ipaddr_t netmask);
* router on a local network that can forward to the external network.
*
* Parameters:
* target - An IP address on a remote network to use in the lookup.
* router - The address of router on a local network that can forward our
* packets to the target.
*
* NOTE: For IPv6, router will be an array, for IPv4 it will be a scalar
* value. Hence, the change in the function signature.
*
* Returned Value:
* OK on success; Negated errno on failure.
@ -194,9 +200,9 @@ int net_delroute(uip_ipaddr_t target, uip_ipaddr_t netmask);
****************************************************************************/
#ifdef CONFIG_NET_IPv6
int net_router(uip_ipaddr_t target, uip_ipaddr_t *router);
#else
int net_router(uip_ipaddr_t target, uip_ipaddr_t router);
#else
int net_router(uip_ipaddr_t target, uip_ipaddr_t *router);
#endif
/****************************************************************************

View File

@ -109,6 +109,12 @@ static int net_match(FAR struct net_route_s *route, FAR void *arg)
* router on a local network that can forward to the external network.
*
* Parameters:
* target - An IP address on a remote network to use in the lookup.
* router - The address of router on a local network that can forward our
* packets to the target.
*
* NOTE: For IPv6, router will be an array, for IPv4 it will be a scalar
* value. Hence, the change in the function signature.
*
* Returned Value:
* OK on success; Negated errno on failure.
@ -116,9 +122,9 @@ static int net_match(FAR struct net_route_s *route, FAR void *arg)
****************************************************************************/
#ifdef CONFIG_NET_IPv6
int net_router(uip_ipaddr_t target, uip_ipaddr_t *router)
#else
int net_router(uip_ipaddr_t target, uip_ipaddr_t router)
#else
int net_router(uip_ipaddr_t target, uip_ipaddr_t *router)
#endif
{
struct route_match_s match;
@ -133,9 +139,9 @@ int net_router(uip_ipaddr_t target, uip_ipaddr_t router)
ret = net_foreachroute(net_match, &match) ? OK : -ENOENT;
#ifdef CONFIG_NET_IPv6
uip_ipaddr_copy(*router, match.target);
#else
uip_ipaddr_copy(router, match.target);
#else
uip_ipaddr_copy(*router, match.target);
#endif
return ret;

View File

@ -47,6 +47,7 @@
#include <nuttx/net/uip/uip-arch.h>
#include "net_route.h"
#include "net_internal.h"
/****************************************************************************
@ -73,16 +74,40 @@
* Function: netdev_maskcmp
****************************************************************************/
static inline bool netdev_maskcmp(const uip_ipaddr_t *ipaddr,
const uip_ipaddr_t *raddr,
const uip_ipaddr_t *netmask)
/****************************************************************************
* Function: netdev_finddevice
*
* Description:
* Find a previously registered network device by matching a local address
* with the subnet served by the device
*
* Parameters:
* addr - Pointer to the remote address of a connection
*
* Returned Value:
* Pointer to driver on success; null on failure
*
* Assumptions:
* Called from normal user mode
*
****************************************************************************/
static FAR struct uip_driver_s *netdev_finddevice(const uip_ipaddr_t addr)
{
#ifndef CONFIG_NET_IPv6
return (*ipaddr & *netmask) == (*raddr & *netmask);
#else
# warning "Not implemented for IPv6"
return false;
#endif
struct uip_driver_s *dev;
netdev_semtake();
for (dev = g_netdevices; dev; dev = dev->flink)
{
if (uip_ipaddr_maskcmp(dev->d_ipaddr, addr, dev->d_netmask))
{
netdev_semgive();
return dev;
}
}
netdev_semgive();
return NULL;
}
/****************************************************************************
@ -93,11 +118,11 @@ static inline bool netdev_maskcmp(const uip_ipaddr_t *ipaddr,
* Function: netdev_findbyaddr
*
* Description:
* Find a previously registered network device by matching a remote address
* with the subnet served by the device
* Find a previously registered network device by matching an arbitrary
* IP address.
*
* Parameters:
* raddr - Pointer to the remote address of a connection
* addr - Pointer to the remote address of a connection
*
* Returned Value:
* Pointer to driver on success; null on failure
@ -107,24 +132,69 @@ static inline bool netdev_maskcmp(const uip_ipaddr_t *ipaddr,
*
****************************************************************************/
FAR struct uip_driver_s *netdev_findbyaddr(const uip_ipaddr_t *raddr)
FAR struct uip_driver_s *netdev_findbyaddr(const uip_ipaddr_t addr)
{
struct uip_driver_s *dev;
#ifdef CONFIG_NET_ROUTE
uip_ipaddr_t router;
int ret;
#endif
if (raddr)
/* First, see if the address maps to the a local network */
dev = netdev_finddevice(addr);
if (dev)
{
netdev_semtake();
for (dev = g_netdevices; dev; dev = dev->flink)
{
if (netdev_maskcmp(&dev->d_ipaddr, raddr, &dev->d_netmask))
{
netdev_semgive();
return dev;
}
}
netdev_semgive();
return dev;
}
return NULL;
/* No.. The address lies on an external network */
#ifdef CONFIG_NET_ROUTE
/* If we have a routing table, then perhaps we can find the the local
* address of a router that can forward packets to the external network.
*/
#ifdef CONFIG_NET_IPv6
ret = net_router(addr, router);
#else
ret = net_router(addr, &router);
#endif
if (ret >= 0)
{
/* Success... try to find the network device associated with the local
* router address
*/
dev = netdev_finddevice(router);
if (dev)
{
return dev;
}
}
#endif /* CONFIG_NET_ROUTE */
/* 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.
*/
netdev_semtake();
if (g_netdevices && !g_netdevices->flink)
{
dev = g_netdevices;
}
netdev_semgive();
/* 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.
*/
return dev;
}
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */

View File

@ -90,25 +90,12 @@
*
****************************************************************************/
void netdev_txnotify(const uip_ipaddr_t *raddr)
void netdev_txnotify(const uip_ipaddr_t raddr)
{
/* Find the device driver that serves the subnet of the remote address */
struct uip_driver_s *dev = netdev_findbyaddr(raddr);
/* The above lookup will fail if the packet is being sent out of our
* out subnet to a router. REVISIT: For now, we fall back and try "eth0".
*/
if (dev == NULL)
{
/* If the destination address is not in our subnet, assume eth0 as the
* default device.
*/
dev = netdev_findbyname("eth0");
}
if (dev && dev->d_txavail)
{
/* Notify the device driver that new TX data is available. */

View File

@ -576,7 +576,7 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
/* Notify the device driver of the availaibilty of TX data */
netdev_txnotify(&conn->ripaddr);
netdev_txnotify(conn->ripaddr);
/* Wait for the send to complete or an error to occur: NOTES: (1)
* uip_lockedwait will also terminate if a signal is received, (2) interrupts

View File

@ -402,7 +402,7 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
/* Notify the device driver of the availabilty of TX data */
netdev_txnotify(&conn->ripaddr);
netdev_txnotify(conn->ripaddr);
/* Wait for either the receive to complete or for an error/timeout to occur.
* NOTES: (1) uip_lockedwait will also terminate if a signal is received, (2)

View File

@ -352,7 +352,7 @@ int uip_ping(uip_ipaddr_t addr, uint16_t id, uint16_t seqno,
/* Notify the device driver of the availaibilty of TX data */
netdev_txnotify(&state.png_addr);
netdev_txnotify(state.png_addr);
/* Wait for either the full round trip transfer to complete or
* for timeout to occur. (1) uip_lockedwait will also terminate if a