From 572252ef94d174774b2455c45657c8255bdf01f0 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 5 Oct 2013 12:05:51 -0600 Subject: Clean-up routing table design. --- apps/netutils/resolv/resolv.c | 4 ++ nuttx/include/net/route.h | 19 +++--- nuttx/include/queue.h | 56 ++++++++-------- nuttx/libc/net/lib_addroute.c | 13 ++-- nuttx/libc/net/lib_delroute.c | 9 ++- nuttx/net/Makefile | 11 ++-- nuttx/net/net_addroute.c | 61 ++++++++---------- nuttx/net/net_delroute.c | 35 +++++++--- nuttx/net/net_findroute.c | 132 -------------------------------------- nuttx/net/net_foreachroute.c | 18 ++++-- nuttx/net/net_route.h | 81 +++++++++++++++++++++--- nuttx/net/net_router.c | 144 ++++++++++++++++++++++++++++++++++++++++++ nuttx/net/net_sockets.c | 11 +++- nuttx/net/netdev_ioctl.c | 24 +++---- nuttx/net/recvfrom.c | 4 ++ 15 files changed, 361 insertions(+), 261 deletions(-) delete mode 100644 nuttx/net/net_findroute.c create mode 100644 nuttx/net/net_router.c diff --git a/apps/netutils/resolv/resolv.c b/apps/netutils/resolv/resolv.c index f850d6b84..5d447ee49 100644 --- a/apps/netutils/resolv/resolv.c +++ b/apps/netutils/resolv/resolv.c @@ -273,7 +273,9 @@ int recv_response_socket(int sockfd, struct sockaddr_in *addr) char buffer[RECV_BUFFER_SIZE]; struct dns_answer *ans; struct dns_hdr *hdr; +#if 0 /* Not used */ uint8_t nquestions; +#endif uint8_t nanswers; int ret; @@ -305,7 +307,9 @@ int recv_response_socket(int sockfd, struct sockaddr_in *addr) * and the extrarr are simply discarded. */ +#if 0 /* Not used */ nquestions = htons(hdr->numquestions); +#endif nanswers = htons(hdr->numanswers); /* Skip the name in the question. XXX: This should really be diff --git a/nuttx/include/net/route.h b/nuttx/include/net/route.h index 030c5b0ee..063b5e8aa 100644 --- a/nuttx/include/net/route.h +++ b/nuttx/include/net/route.h @@ -62,10 +62,9 @@ struct rtentry { - uint16_t rt_ifno; /* Interface number, e.g., the 0 in "eth0" */ - FAR struct sockaddr_storage *rt_target; /* Target address */ + FAR struct sockaddr_storage *rt_target; /* Address of the network */ FAR struct sockaddr_storage *rt_netmask; /* Network mask defining the sub-net */ - FAR struct sockaddr_storage *rt_gateway; /* Gateway address associated with the hop */ + FAR struct sockaddr_storage *rt_router; /* Gateway address associated with the hop */ }; /**************************************************************************** @@ -93,10 +92,10 @@ extern "C" * * Parameters: * sockfd - Any socket descriptor - * target - Target address (required) - * netmask - Network mask defining the sub-net (required) - * gateway - Gateway address associated with the hop (optional) - * ifno - Interface number, e.g., the 0 in "eth0" + * target - Target address on external network(required) + * netmask - Network mask defining the external network (required) + * router - Router address that on our network that can forward to the + * external network. * * Returned Value: * OK on success; -1 on failure with the errno variable set appropriately. @@ -105,7 +104,7 @@ extern "C" int addroute(int sockfd, FAR struct sockaddr_storage *target, FAR struct sockaddr_storage *netmask, - FAR struct sockaddr_storage *gateway, int ifno); + FAR struct sockaddr_storage *router); /**************************************************************************** * Function: net_delroute @@ -116,8 +115,8 @@ int addroute(int sockfd, FAR struct sockaddr_storage *target, * * Parameters: * sockfd - Any socket descriptor - * target - Target address (required) - * netmask - Network mask defining the sub-net (required) + * target - Target address on the remote network (required) + * netmask - Network mask defining the external network (required) * * Returned Value: * OK on success; -1 on failure with the errno variable set appropriately. diff --git a/nuttx/include/queue.h b/nuttx/include/queue.h index b5aa23690..88e049f4d 100644 --- a/nuttx/include/queue.h +++ b/nuttx/include/queue.h @@ -1,4 +1,4 @@ -/************************************************************************ +/**************************************************************************** * include/queue.h * * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. @@ -31,20 +31,20 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + ****************************************************************************/ #ifndef __INCLUDE_QUEUE_H #define __INCLUDE_QUEUE_H -/************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************/ + ****************************************************************************/ #include -/************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************/ + ****************************************************************************/ #define sq_init(q) do { (q)->head = NULL; (q)->tail = NULL; } while (0) #define dq_init(q) do { (q)->head = NULL; (q)->tail = NULL; } while (0) @@ -59,9 +59,9 @@ #define sq_peek(q) ((q)->head) #define dq_peek(q) ((q)->head) -/************************************************************************ +/**************************************************************************** * Global Type Declarations - ************************************************************************/ + ****************************************************************************/ struct sq_entry_s { @@ -90,9 +90,9 @@ struct dq_queue_s }; typedef struct dq_queue_s dq_queue_t; -/************************************************************************ +/**************************************************************************** * Global Function Prototypes - ************************************************************************/ + ****************************************************************************/ #ifdef __cplusplus #define EXTERN extern "C" @@ -101,24 +101,24 @@ extern "C" { #define EXTERN extern #endif -EXTERN void sq_addfirst(FAR sq_entry_t *node, sq_queue_t *queue); -EXTERN void dq_addfirst(FAR dq_entry_t *node, dq_queue_t *queue); -EXTERN void sq_addlast(FAR sq_entry_t *node, sq_queue_t *queue); -EXTERN void dq_addlast(FAR dq_entry_t *node, dq_queue_t *queue); -EXTERN void sq_addafter(FAR sq_entry_t *prev, FAR sq_entry_t *node, - sq_queue_t *queue); -EXTERN void dq_addafter(FAR dq_entry_t *prev, FAR dq_entry_t *node, - dq_queue_t *queue); -EXTERN void dq_addbefore(FAR dq_entry_t *next, FAR dq_entry_t *node, - dq_queue_t *queue); - -EXTERN FAR sq_entry_t *sq_remafter(FAR sq_entry_t *node, sq_queue_t *queue); -EXTERN void sq_rem(FAR sq_entry_t *node, sq_queue_t *queue); -EXTERN void dq_rem(FAR dq_entry_t *node, dq_queue_t *queue); -EXTERN FAR sq_entry_t *sq_remlast(sq_queue_t *queue); -EXTERN FAR dq_entry_t *dq_remlast(dq_queue_t *queue); -EXTERN FAR sq_entry_t *sq_remfirst(sq_queue_t *queue); -EXTERN FAR dq_entry_t *dq_remfirst(dq_queue_t *queue); +void sq_addfirst(FAR sq_entry_t *node, FAR sq_queue_t *queue); +void dq_addfirst(FAR dq_entry_t *node, FAR dq_queue_t *queue); +void sq_addlast(FAR sq_entry_t *node, FAR sq_queue_t *queue); +void dq_addlast(FAR dq_entry_t *node, FAR dq_queue_t *queue); +void sq_addafter(FAR sq_entry_t *prev, FAR sq_entry_t *node, + FAR sq_queue_t *queue); +void dq_addafter(FAR dq_entry_t *prev, FAR dq_entry_t *node, + FAR dq_queue_t *queue); +void dq_addbefore(FAR dq_entry_t *next, FAR dq_entry_t *node, + FAR dq_queue_t *queue); + +FAR sq_entry_t *sq_remafter(FAR sq_entry_t *node, FAR sq_queue_t *queue); +void sq_rem(FAR sq_entry_t *node, FAR sq_queue_t *queue); +void dq_rem(FAR dq_entry_t *node, FAR dq_queue_t *queue); +FAR sq_entry_t *sq_remlast(FAR sq_queue_t *queue); +FAR dq_entry_t *dq_remlast(FAR dq_queue_t *queue); +FAR sq_entry_t *sq_remfirst(FAR sq_queue_t *queue); +FAR dq_entry_t *dq_remfirst(FAR dq_queue_t *queue); #undef EXTERN #ifdef __cplusplus diff --git a/nuttx/libc/net/lib_addroute.c b/nuttx/libc/net/lib_addroute.c index 47efeba32..b588b4754 100644 --- a/nuttx/libc/net/lib_addroute.c +++ b/nuttx/libc/net/lib_addroute.c @@ -61,10 +61,10 @@ * * Parameters: * sockfd - Any socket descriptor - * target - Target address (required) - * netmask - Network mask defining the sub-net (required) - * gateway - Gateway address associated with the hop (optional) - * ifno - Interface number, e.g., the 0 in "eth0" + * target - Target address on external network(required) + * netmask - Network mask defining the external network (required) + * router - Router address that on our network that can forward to the + * external network. * * Returned Value: * OK on success; -1 on failure with the errno variable set appropriately. @@ -73,16 +73,15 @@ int addroute(int sockfd, FAR struct sockaddr_storage *target, FAR struct sockaddr_storage *netmask, - FAR struct sockaddr_storage *gateway, int ifno) + FAR struct sockaddr_storage *router) { struct rtentry entry; /* Set up the rtentry structure */ - entry.rt_ifno = ifno; /* Interface number, e.g., the 0 in "eth0" */ entry.rt_target = target; /* Target address */ entry.rt_netmask = netmask; /* Network mask defining the sub-net */ - entry.rt_gateway = gateway; /* Gateway address associated with the hop */ + entry.rt_router = router; /* Router address associated with the hop */ /* Then perform the ioctl */ diff --git a/nuttx/libc/net/lib_delroute.c b/nuttx/libc/net/lib_delroute.c index 471391483..fecec3a83 100644 --- a/nuttx/libc/net/lib_delroute.c +++ b/nuttx/libc/net/lib_delroute.c @@ -46,6 +46,7 @@ #include #include #include +#include #include /*************************************************************************** @@ -61,8 +62,8 @@ * * Parameters: * sockfd - Any socket descriptor - * target - Target address (required) - * netmask - Network mask defining the sub-net (required) + * target - Target address on the remote network (required) + * netmask - Network mask defining the external network (required) * * Returned Value: * OK on success; -1 on failure with the errno variable set appropriately. @@ -76,12 +77,10 @@ int delroute(int sockfd, FAR struct sockaddr_storage *target, /* Set up the rtentry structure */ + memset(&entry, 0, sizeof(struct rtentry)); entry.rt_target = target; /* Target address */ entry.rt_netmask = netmask; /* Network mask defining the sub-net */ - entry.rt_ifno = 0; /* (not used for deletion) */ - entry.rt_gateway = NULL; /* (not used for deletion) */ - /* Then perform the ioctl */ return ioctl(sockfd, SIOCDELRT, (unsigned long)((uintptr_t)&entry)); diff --git a/nuttx/net/Makefile b/nuttx/net/Makefile index 0aced6343..07d3fb445 100644 --- a/nuttx/net/Makefile +++ b/nuttx/net/Makefile @@ -39,10 +39,10 @@ ifeq ($(CONFIG_NET),y) # Basic networking support -SOCK_ASRCS = -SOCK_CSRCS = bind.c connect.c getsockname.c recv.c recvfrom.c socket.c \ - sendto.c net_sockets.c net_close.c net_dup.c net_dup2.c net_clone.c \ - net_vfcntl.c +SOCK_ASRCS = +SOCK_CSRCS = bind.c connect.c getsockname.c recv.c recvfrom.c socket.c +SOCK_CSRCS += sendto.c net_sockets.c net_close.c net_dup.c net_dup2.c +SOCK_CSRCS += net_clone.c net_vfcntl.c # TCP/IP support @@ -65,7 +65,8 @@ endif # Routing table support ifeq ($(CONFIG_NET_ROUTE),y) -SOCK_CSRCS += net_addroute.c net_delroute.c net_findroute.c net_foreachroute.c +SOCK_CSRCS += net_addroute.c net_allocroute.c net_delroute.c +SOCK_CSRCS += net_foreachroute.c net_router.c endif # Support for network access using streams diff --git a/nuttx/net/net_addroute.c b/nuttx/net/net_addroute.c index ee440c430..b93a84071 100644 --- a/nuttx/net/net_addroute.c +++ b/nuttx/net/net_addroute.c @@ -40,8 +40,11 @@ #include #include -#include +#include #include +#include + +#include #include "net_internal.h" #include "net_route.h" @@ -56,32 +59,6 @@ * Private Functions ****************************************************************************/ -/**************************************************************************** - * Function: net_available - * - * Description: - * Return 1 if the route is available - * - * Parameters: - * route - The next route to examine - * arg - The new route entry (cast to void*) - * - * Returned Value: - * OK on success; Negated errno on failure. - * - ****************************************************************************/ - -static int net_available(FAR struct net_route_s *route, FAR void *arg) -{ - if (!route->inuse) - { - memcpy(route, arg, sizeof(struct net_route_s)); - return 1; - } - - return 0; -} - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -100,21 +77,35 @@ static int net_available(FAR struct net_route_s *route, FAR void *arg) ****************************************************************************/ int net_addroute(uip_ipaddr_t target, uip_ipaddr_t netmask, - uip_ipaddr_t gateway, int devno) + uip_ipaddr_t router) { - struct net_route_s route; + FAR struct net_route_s *route; + uip_lock_t save; + + /* Allocate a route entry */ + + route = net_allocroute(); + if (!route) + { + ndbg("ERROR: Failed to allocate a route\n"); + return -ENOMEM; + } /* Format the new route table entry */ - route.inuse = true; - route.minor = devno; - uip_ipaddr_copy(route.target, target); - uip_ipaddr_copy(route.netmask, netmask); - uip_ipaddr_copy(route.gateway, gateway); + uip_ipaddr_copy(route->target, target); + uip_ipaddr_copy(route->netmask, netmask); + uip_ipaddr_copy(route->router, router); + + /* Get exclusive address to the networking data structures */ + + save = uip_lock(); /* Then add the new entry to the table */ - return net_foreachroute(net_available, &route) ? OK : -EAGAIN; + sq_addlast((FAR sq_entry_t *)route, (FAR sq_queue_t *)&g_routes); + uip_unlock(save); + return OK; } #endif /* CONFIG_NET && CONFIG_NET_ROUTE */ diff --git a/nuttx/net/net_delroute.c b/nuttx/net/net_delroute.c index 6aa6f8e9f..e10dbfd48 100644 --- a/nuttx/net/net_delroute.c +++ b/nuttx/net/net_delroute.c @@ -54,8 +54,9 @@ struct route_match_s { - uip_ipaddr_t target; /* The target IP address to match */ - uip_ipaddr_t netmask; /* The network mask to match */ + FAR struct net_route_s *prev; /* Predecessor in the list */ + uip_ipaddr_t target; /* The target IP address to match */ + uip_ipaddr_t netmask; /* The network mask to match */ }; /**************************************************************************** @@ -81,20 +82,37 @@ static int net_match(FAR struct net_route_s *route, FAR void *arg) { FAR struct route_match_s *match = ( FAR struct route_match_s *)arg; - /* To match, the entry has to be in use, the masked target address must - * be the same, and the masks must be the same. + /* To match, the masked target address must be the same, and the masks + * must be the same. */ - if (route->inuse && - uip_ipaddr_maskcmp(route->target, match->target, match->netmask) && + if (uip_ipaddr_maskcmp(route->target, match->target, match->netmask) && uip_ipaddr_cmp(route->target, match->netmask)) { - /* They match.. clear the route table entry */ + /* They match.. Remove the entry from the routing table */ + + if (match->prev) + { + (void)sq_remafter((FAR sq_entry_t *)match->prev, + (FAR sq_queue_t *)&g_routes); + } + else + { + (void)sq_remfirst((FAR sq_queue_t *)&g_routes); + } + + /* And free the routing table entry by adding it to the free list */ + + net_freeroute(route); + + /* Return a non-zero value to terminate the traversal */ - memset(route, 0, sizeof(struct net_route_s)); return 1; } + /* Next time we are here, this will be the previous entry */ + + match->prev = route; return 0; } @@ -121,6 +139,7 @@ int net_delroute(uip_ipaddr_t target, uip_ipaddr_t netmask) /* Set up the comparison structure */ + match.prev = NULL; uip_ipaddr_copy(match.target, target); uip_ipaddr_copy(match.netmask, netmask); diff --git a/nuttx/net/net_findroute.c b/nuttx/net/net_findroute.c deleted file mode 100644 index 55c82402e..000000000 --- a/nuttx/net/net_findroute.c +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** - * net/net_delroute.c - * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include - -#include "net_internal.h" -#include "net_route.h" - -#if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -struct route_match_s -{ - uip_ipaddr_t target; /* The target IP address to match */ - FAR struct net_route_s *route; /* The location to return the route */ -}; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Function: net_match - * - * Description: - * Return 1 if the route is available - * - * Parameters: - * route - The next route to examine - * arg - The match values (cast to void*) - * - * Returned Value: - * 0 if the entry is not a match; 1 if the entry matched and was cleared. - * - ****************************************************************************/ - -static int net_match(FAR struct net_route_s *route, FAR void *arg) -{ - FAR struct route_match_s *match = ( FAR struct route_match_s *)arg; - - /* To match, the entry has to be in use, the masked target addresses must - * be the same. In the event of multiple matches, only the first is - * returned. - */ - - if (route->inuse && - uip_ipaddr_maskcmp(route->target, match->target, route->netmask)) - { - /* They match.. clear the route table entry */ - - memcpy(match->route, route, sizeof(struct net_route_s)); - return 1; - } - - return 0; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Function: net_findroute - * - * Description: - * Given an IP address, return a copy of the routing table contents - * - * Parameters: - * - * Returned Value: - * OK on success; Negated errno on failure. - * - ****************************************************************************/ - -int net_findroute(uip_ipaddr_t target, FAR struct net_route_s *route) -{ - struct route_match_s match; - - /* Set up the comparison structure */ - - uip_ipaddr_copy(match.target, target); - match.route = route; - - /* Then remove the entry from the routing table */ - - return net_foreachroute(net_match, &match) ? OK : -ENOENT; -} - -#endif /* CONFIG_NET && CONFIG_NET_ROUTE */ diff --git a/nuttx/net/net_foreachroute.c b/nuttx/net/net_foreachroute.c index dc01e382a..f8343618d 100644 --- a/nuttx/net/net_foreachroute.c +++ b/nuttx/net/net_foreachroute.c @@ -53,10 +53,6 @@ * Public Data ****************************************************************************/ -/* This is the routing table */ - -struct net_route_s g_routes[CONFIG_NET_MAXROUTES]; - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -76,17 +72,25 @@ struct net_route_s g_routes[CONFIG_NET_MAXROUTES]; int net_foreachroute(route_handler_t handler, FAR void *arg) { + FAR struct net_route_s *route; + FAR struct net_route_s *next; uip_lock_t save; int ret = 0; - int i; /* Prevent concurrent access to the routing table */ save = uip_lock(); - for (i = 0; i < CONFIG_NET_MAXROUTES && ret == 0; i++) + /* Visit each entry in the routing table */ + + for (route = (FAR struct net_route_s *)g_routes.head; route; route = next) { - ret = handler(&g_routes[i], arg); + /* Get the next entry in the to visit. We do this BEFORE calling the + * handler because the hanlder may delete this entry. + */ + + next = route->flink; + ret = handler(route, arg); } /* Unlock uIP */ diff --git a/nuttx/net/net_route.h b/nuttx/net/net_route.h index a2ba11145..5c1fafa76 100644 --- a/nuttx/net/net_route.h +++ b/nuttx/net/net_route.h @@ -41,6 +41,10 @@ ****************************************************************************/ #include + +#include +#include + #include #ifdef CONFIG_NET_ROUTE @@ -61,11 +65,10 @@ struct net_route_s { - bool inuse; /* TRUE: This entry contains a valid route */ - uint8_t minor; /* Ethernet device minor */ - uip_ipaddr_t target; /* The destination network */ - uip_ipaddr_t netmask; /* The network address mask */ - uip_ipaddr_t gateway; /* Route packets via a gateway */ + FAR struct net_route_s *flink; /* Supports a singly linked list */ + uip_ipaddr_t target; /* The destination network */ + uip_ipaddr_t netmask; /* The network address mask */ + uip_ipaddr_t router; /* Route packets via this router */ }; /* Type of the call out function pointer provided to net_foreachroute() */ @@ -86,12 +89,61 @@ extern "C" /* This is the routing table */ -EXTERN struct net_route_s g_routes[CONFIG_NET_MAXROUTES]; +EXTERN sq_queue_t g_routes; /**************************************************************************** * Public Function Prototypes ****************************************************************************/ +/**************************************************************************** + * Function: net_initroute + * + * Description: + * Initialize to the routing table + * + * Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void net_initroute(void); + +/**************************************************************************** + * Function: net_allocroute + * + * Description: + * Allocate one route by removing it from the free list + * + * Parameters: + * None + * + * Returned Value: + * On success, a pointer to the newly allocated route table entry is + * returned; NULL is returned on failure. + * + ****************************************************************************/ + +FAR struct net_route_s *net_allocroute(void); + +/**************************************************************************** + * Function: net_allocroute + * + * Description: + * Free one route by adding it from the free list + * + * Parameters: + * route - The route to be freed + * + * Returned Value: + * None + * + ****************************************************************************/ + +void net_freeroute(FAR struct net_route_s *route); + /**************************************************************************** * Function: net_addroute * @@ -99,6 +151,10 @@ EXTERN struct net_route_s g_routes[CONFIG_NET_MAXROUTES]; * Add a new route to the routing table * * Parameters: + * target - The destination IP address on the destination network + * netmask - The mask defining the destination sub-net + * router - The IP address on one of our networks that provides the + * router to the external network * * Returned Value: * OK on success; Negated errno on failure. @@ -106,7 +162,7 @@ EXTERN struct net_route_s g_routes[CONFIG_NET_MAXROUTES]; ****************************************************************************/ int net_addroute(uip_ipaddr_t target, uip_ipaddr_t netmask, - uip_ipaddr_t gateway, int devno); + uip_ipaddr_t router); /**************************************************************************** * Function: net_delroute @@ -124,10 +180,11 @@ int net_addroute(uip_ipaddr_t target, uip_ipaddr_t netmask, int net_delroute(uip_ipaddr_t target, uip_ipaddr_t netmask); /**************************************************************************** - * Function: net_findroute + * Function: net_router * * Description: - * Given an IP address, return a copy of the routing table contents + * Given an IP address on a external network, return the address of the + * router on a local network that can forward to the external network. * * Parameters: * @@ -136,7 +193,11 @@ int net_delroute(uip_ipaddr_t target, uip_ipaddr_t netmask); * ****************************************************************************/ -int net_findroute(uip_ipaddr_t target, FAR struct net_route_s *route); +#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); +#endif /**************************************************************************** * Function: net_foreachroute diff --git a/nuttx/net/net_router.c b/nuttx/net/net_router.c new file mode 100644 index 000000000..3317f4006 --- /dev/null +++ b/nuttx/net/net_router.c @@ -0,0 +1,144 @@ +/**************************************************************************** + * net/net_router.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "net_internal.h" +#include "net_route.h" + +#if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct route_match_s +{ + uip_ipaddr_t target; /* The target IP address on an external network to match */ + uip_ipaddr_t router; /* The IP address of the router on one of our networks*/ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: net_match + * + * Description: + * Return 1 if the route is available + * + * Parameters: + * route - The next route to examine + * arg - The match values (cast to void*) + * + * Returned Value: + * 0 if the entry is not a match; 1 if the entry matched and was cleared. + * + ****************************************************************************/ + +static int net_match(FAR struct net_route_s *route, FAR void *arg) +{ + FAR struct route_match_s *match = ( FAR struct route_match_s *)arg; + + /* To match, the masked target addresses must be the same. In the event + * of multiple matches, only the first is returned. There not (yet) any + * concept for the precedence of networks. + */ + + if (uip_ipaddr_maskcmp(route->target, match->target, route->netmask)) + { + /* They match.. Copy the router address */ + + uip_ipaddr_copy(match->router, route->router); + return 1; + } + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: net_router + * + * Description: + * Given an IP address on a external network, return the address of the + * router on a local network that can forward to the external network. + * + * Parameters: + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +#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) +#endif +{ + struct route_match_s match; + int ret; + + /* Set up the comparison structure */ + + memset(&match, 0, sizeof(struct route_match_s)); + uip_ipaddr_copy(match.target, target); + + /* Then remove the entry from the routing table */ + + 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); +#endif + + return ret; +} + +#endif /* CONFIG_NET && CONFIG_NET_ROUTE */ diff --git a/nuttx/net/net_sockets.c b/nuttx/net/net_sockets.c index ddb54c98c..6e4a69235 100644 --- a/nuttx/net/net_sockets.c +++ b/nuttx/net/net_sockets.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/net_sockets.c * - * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -51,6 +51,7 @@ #include #include +#include "net_route.h" #include "net_internal.h" /**************************************************************************** @@ -103,9 +104,15 @@ void net_initialize(void) uip_initialize(); - /* Initialize the socket layer */ +#ifdef CONFIG_NET_ROUTE + /* Initialize the routing table */ + + net_initroute(); +#endif #if CONFIG_NSOCKET_DESCRIPTORS > 0 + /* Initialize the socket layer */ + netdev_seminit(); #endif diff --git a/nuttx/net/netdev_ioctl.c b/nuttx/net/netdev_ioctl.c index 12a31f0ce..1fbd902fe 100644 --- a/nuttx/net/netdev_ioctl.c +++ b/nuttx/net/netdev_ioctl.c @@ -487,7 +487,7 @@ static int netdev_rtioctl(FAR struct socket *psock, int cmd, { uip_ipaddr_t target; uip_ipaddr_t netmask; - uip_ipaddr_t gateway; + uip_ipaddr_t router; #ifdef CONFIG_NET_IPv6 FAR struct sockaddr_in6 *addr; #else @@ -507,16 +507,16 @@ static int netdev_rtioctl(FAR struct socket *psock, int cmd, addr = (FAR struct sockaddr_in6 *)rtentry->rt_netmask; netmask = (uip_ipaddr_t)addr->sin6_addr.u6_addr16; - /* The gateway is an optional argument */ + /* The router is an optional argument */ - if (rtentry->rt_gateway) + if (rtentry->rt_router) { - addr = (FAR struct sockaddr_in6 *)rtentry->rt_gateway; - gateway = (uip_ipaddr_t)addr->sin6_addr.u6_addr16; + addr = (FAR struct sockaddr_in6 *)rtentry->rt_router; + router = (uip_ipaddr_t)addr->sin6_addr.u6_addr16; } else { - gateway = NULL; + router = NULL; } #else addr = (FAR struct sockaddr_in *)rtentry->rt_target; @@ -525,19 +525,19 @@ static int netdev_rtioctl(FAR struct socket *psock, int cmd, addr = (FAR struct sockaddr_in *)rtentry->rt_netmask; netmask = (uip_ipaddr_t)addr->sin_addr.s_addr; - /* The gateway is an optional argument */ + /* The router is an optional argument */ - if (rtentry->rt_gateway) + if (rtentry->rt_router) { - addr = (FAR struct sockaddr_in *)rtentry->rt_gateway; - gateway = (uip_ipaddr_t)addr->sin_addr.s_addr; + addr = (FAR struct sockaddr_in *)rtentry->rt_router; + router = (uip_ipaddr_t)addr->sin_addr.s_addr; } else { - gateway = 0; + router = 0; } #endif - ret = net_addroute(target, netmask, gateway, rtentry->rt_ifno); + ret = net_addroute(target, netmask, router); } break; diff --git a/nuttx/net/recvfrom.c b/nuttx/net/recvfrom.c index 22b43a196..388db3930 100644 --- a/nuttx/net/recvfrom.c +++ b/nuttx/net/recvfrom.c @@ -177,9 +177,13 @@ static inline void recvfrom_newtcpdata(FAR struct uip_driver_s *dev, FAR struct uip_conn *conn = (FAR struct uip_conn *)pstate->rf_sock->s_conn; FAR uint8_t *buffer = (FAR uint8_t *)dev->d_appdata + recvlen; uint16_t buflen = dev->d_len - recvlen; +#ifdef CONFIG_DEBUG_NET uint16_t nsaved; nsaved = uip_datahandler(conn, buffer, buflen); +#else + (void)uip_datahandler(conn, buffer, buflen); +#endif /* There are complicated buffering issues that are not addressed fully * here. For example, what if up_datahandler() cannot buffer the -- cgit v1.2.3