diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-10-02 10:51:48 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-10-02 10:51:48 -0600 |
commit | b98e458fea73dd81b1f28640e0434fdcebbe7e23 (patch) | |
tree | 6202664769d8cec058a1d7826e8ddd4fa05e83ec /nuttx/net | |
parent | 632277bf3823219dc74fd11cc666b803bfc28f66 (diff) | |
download | px4-nuttx-b98e458fea73dd81b1f28640e0434fdcebbe7e23.tar.gz px4-nuttx-b98e458fea73dd81b1f28640e0434fdcebbe7e23.tar.bz2 px4-nuttx-b98e458fea73dd81b1f28640e0434fdcebbe7e23.zip |
Add a user interface to manage the routing table
Diffstat (limited to 'nuttx/net')
-rw-r--r-- | nuttx/net/Kconfig | 2 | ||||
-rw-r--r-- | nuttx/net/net_addroute.c | 3 | ||||
-rw-r--r-- | nuttx/net/net_delroute.c | 3 | ||||
-rw-r--r-- | nuttx/net/net_findroute.c | 3 | ||||
-rw-r--r-- | nuttx/net/net_foreachroute.c | 2 | ||||
-rw-r--r-- | nuttx/net/net_route.h | 162 | ||||
-rw-r--r-- | nuttx/net/netdev_ioctl.c | 185 |
7 files changed, 340 insertions, 20 deletions
diff --git a/nuttx/net/Kconfig b/nuttx/net/Kconfig index fbc34ec78..d3e7b3b72 100644 --- a/nuttx/net/Kconfig +++ b/nuttx/net/Kconfig @@ -308,7 +308,7 @@ config NET_ROUTE bool "Routing table suport" default n ---help--- - Build in support for a routing table. See include/nuttx/net/route.h + Build in support for a routing table. See include/net/route.h config NET_MAXROUTES int "Routing table size" diff --git a/nuttx/net/net_addroute.c b/nuttx/net/net_addroute.c index 6b7ac9f6e..ee440c430 100644 --- a/nuttx/net/net_addroute.c +++ b/nuttx/net/net_addroute.c @@ -43,9 +43,8 @@ #include <string.h> #include <errno.h> -#include <nuttx/net/route.h> - #include "net_internal.h" +#include "net_route.h" #if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) diff --git a/nuttx/net/net_delroute.c b/nuttx/net/net_delroute.c index b203f0349..6aa6f8e9f 100644 --- a/nuttx/net/net_delroute.c +++ b/nuttx/net/net_delroute.c @@ -43,9 +43,8 @@ #include <string.h> #include <errno.h> -#include <nuttx/net/route.h> - #include "net_internal.h" +#include "net_route.h" #if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) diff --git a/nuttx/net/net_findroute.c b/nuttx/net/net_findroute.c index 5dea9d9ac..55c82402e 100644 --- a/nuttx/net/net_findroute.c +++ b/nuttx/net/net_findroute.c @@ -43,9 +43,8 @@ #include <string.h> #include <errno.h> -#include <nuttx/net/route.h> - #include "net_internal.h" +#include "net_route.h" #if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) diff --git a/nuttx/net/net_foreachroute.c b/nuttx/net/net_foreachroute.c index 8eb844334..dc01e382a 100644 --- a/nuttx/net/net_foreachroute.c +++ b/nuttx/net/net_foreachroute.c @@ -43,9 +43,9 @@ #include <errno.h> #include <arch/irq.h> -#include <nuttx/net/route.h> #include "net_internal.h" +#include "net_route.h" #if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) diff --git a/nuttx/net/net_route.h b/nuttx/net/net_route.h new file mode 100644 index 000000000..a2ba11145 --- /dev/null +++ b/nuttx/net/net_route.h @@ -0,0 +1,162 @@ +/**************************************************************************** + * net/net_route.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * 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. + * + ****************************************************************************/ + +#ifndef __NET_NET_ROUTE_H +#define __NET_NET_ROUTE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <nuttx/net/uip/uip.h> + +#ifdef CONFIG_NET_ROUTE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_NET_MAXROUTES +# define CONFIG_NET_MAXROUTES 4 +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* This structure describes one entry in the routing table */ + +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 */ +}; + +/* Type of the call out function pointer provided to net_foreachroute() */ + +typedef int (*route_handler_t)(FAR struct net_route_s *route, FAR void *arg); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* This is the routing table */ + +EXTERN struct net_route_s g_routes[CONFIG_NET_MAXROUTES]; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Function: net_addroute + * + * Description: + * Add a new route to the routing table + * + * Parameters: + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +int net_addroute(uip_ipaddr_t target, uip_ipaddr_t netmask, + uip_ipaddr_t gateway, int devno); + +/**************************************************************************** + * Function: net_delroute + * + * Description: + * Remove an existing route from the routing table + * + * Parameters: + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +int net_delroute(uip_ipaddr_t target, uip_ipaddr_t netmask); + +/**************************************************************************** + * 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); + +/**************************************************************************** + * Function: net_foreachroute + * + * Description: + * Traverse the route table + * + * Parameters: + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +int net_foreachroute(route_handler_t handler, FAR void *arg); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_NET_ROUTE */ +#endif /* __NET_NET_ROUTE_H */ diff --git a/nuttx/net/netdev_ioctl.c b/nuttx/net/netdev_ioctl.c index ea5c0e436..12a31f0ce 100644 --- a/nuttx/net/netdev_ioctl.c +++ b/nuttx/net/netdev_ioctl.c @@ -51,7 +51,10 @@ #include <nuttx/net/net.h> #include <net/if.h> +#include <net/route.h> #include <net/ethernet.h> +#include <netinet/in.h> + #include <nuttx/net/uip/uip-arch.h> #include <nuttx/net/uip/uip.h> @@ -61,6 +64,7 @@ #endif #include "net_internal.h" +#include "net_route.h" /**************************************************************************** * Pre-processor Definitions @@ -200,12 +204,18 @@ static void ioctl_ifdown(FAR struct uip_driver_s *dev) * ****************************************************************************/ -static int netdev_ifrioctl(FAR struct socket *psock, int cmd, struct ifreq *req) +static int netdev_ifrioctl(FAR struct socket *psock, int cmd, + FAR struct ifreq *req) { FAR struct uip_driver_s *dev; int ret = OK; nvdbg("cmd: %d\n", cmd); + if (!req) + { + ret = -EINVAL; + goto errout; + } /* Find the network device associated with the device name * in the request data. @@ -357,7 +367,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd, struct ifreq *req) default: { - ret = -EINVAL; + ret = -ENOTTY; } break;; } @@ -385,12 +395,18 @@ errout: ****************************************************************************/ #ifdef CONFIG_NET_IGMP -static int netdev_imsfioctl(FAR struct socket *psock, int cmd, struct ip_msfilter *imsf) +static int netdev_imsfioctl(FAR struct socket *psock, int cmd, + FAR struct ip_msfilter *imsf) { FAR struct uip_driver_s *dev; int ret = OK; nvdbg("cmd: %d\n", cmd); + if (!imsf) + { + ret = -EINVAL; + goto errout; + } /* Find the network device associated with the device name * in the request data. @@ -423,7 +439,7 @@ static int netdev_imsfioctl(FAR struct socket *psock, int cmd, struct ip_msfilte case SIOCGIPMSFILTER: /* Retrieve source filter addresses */ default: - ret = -EINVAL; + ret = -ENOTTY; break; } @@ -433,6 +449,142 @@ errout: #endif /**************************************************************************** + * Name: netdev_rtioctl + * + * Description: + * Perform routing table specific operations. + * + * Parameters: + * psock Socket structure + * dev Ethernet driver device structure + * cmd The ioctl command + * rtentry The argument of the ioctl cmd + * + * Return: + * >=0 on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ROUTE +static int netdev_rtioctl(FAR struct socket *psock, int cmd, + FAR struct rtentry *rtentry) +{ + int ret; + + /* Return an error if no rtentry structure is provided */ + + if (!rtentry) + { + return -EINVAL; + } + + /* Execute the command */ + + switch (cmd) + { + case SIOCADDRT: /* Add an entry to the routing table */ + { + uip_ipaddr_t target; + uip_ipaddr_t netmask; + uip_ipaddr_t gateway; +#ifdef CONFIG_NET_IPv6 + FAR struct sockaddr_in6 *addr; +#else + FAR struct sockaddr_in *addr; +#endif + /* The target address and the netmask are required value */ + + if (!rtentry->rt_target || !rtentry->rt_netmask) + { + return -EINVAL; + } + +#ifdef CONFIG_NET_IPv6 + addr = (FAR struct sockaddr_in6 *)rtentry->rt_target; + target = (uip_ipaddr_t)addr->sin6_addr.u6_addr16; + + addr = (FAR struct sockaddr_in6 *)rtentry->rt_netmask; + netmask = (uip_ipaddr_t)addr->sin6_addr.u6_addr16; + + /* The gateway is an optional argument */ + + if (rtentry->rt_gateway) + { + addr = (FAR struct sockaddr_in6 *)rtentry->rt_gateway; + gateway = (uip_ipaddr_t)addr->sin6_addr.u6_addr16; + } + else + { + gateway = NULL; + } +#else + addr = (FAR struct sockaddr_in *)rtentry->rt_target; + target = (uip_ipaddr_t)addr->sin_addr.s_addr; + + addr = (FAR struct sockaddr_in *)rtentry->rt_netmask; + netmask = (uip_ipaddr_t)addr->sin_addr.s_addr; + + /* The gateway is an optional argument */ + + if (rtentry->rt_gateway) + { + addr = (FAR struct sockaddr_in *)rtentry->rt_gateway; + gateway = (uip_ipaddr_t)addr->sin_addr.s_addr; + } + else + { + gateway = 0; + } +#endif + ret = net_addroute(target, netmask, gateway, rtentry->rt_ifno); + } + break; + + case SIOCDELRT: /* Delete an entry from the routing table */ + { + uip_ipaddr_t target; + uip_ipaddr_t netmask; +#ifdef CONFIG_NET_IPv6 + FAR struct sockaddr_in6 *addr; +#else + FAR struct sockaddr_in *addr; +#endif + + /* The target address and the netmask are required value */ + + if (!rtentry->rt_target || !rtentry->rt_netmask) + { + return -EINVAL; + } + +#ifdef CONFIG_NET_IPv6 + addr = (FAR struct sockaddr_in6 *)&rtentry->rt_target; + target = (uip_ipaddr_t)addr->sin6_addr.u6_addr16; + + addr = (FAR struct sockaddr_in6 *)&rtentry->rt_netmask; + netmask = (uip_ipaddr_t)addr->sin6_addr.u6_addr16; +#else + addr = (FAR struct sockaddr_in *)&rtentry->rt_target; + target = (uip_ipaddr_t)addr->sin_addr.s_addr; + + addr = (FAR struct sockaddr_in *)&rtentry->rt_netmask; + netmask = (uip_ipaddr_t)addr->sin_addr.s_addr; +#endif + ret = net_delroute(target, netmask); + } + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} +#endif + +/**************************************************************************** * Global Functions ****************************************************************************/ @@ -445,7 +597,7 @@ errout: * Parameters: * sockfd Socket descriptor of device * cmd The ioctl command - * req The argument of the ioctl cmd + * arg The argument of the ioctl cmd * * Return: * >=0 on success (positive non-zero values are cmd-specific) @@ -454,9 +606,11 @@ errout: * EBADF * 'sockfd' is not a valid descriptor. * EFAULT - * 'req' references an inaccessible memory area. + * 'arg' references an inaccessible memory area. + * ENOTTY + * 'cmd' not valid. * EINVAL - * 'cmd' or 'req' is not valid. + * 'arg' is not valid. * ENOTTY * 'sockfd' is not associated with a network device. * ENOTTY @@ -475,9 +629,9 @@ int netdev_ioctl(int sockfd, int cmd, unsigned long arg) * non-NULL. */ - if (!_SIOCVALID(cmd) || !arg) + if (!_SIOCVALID(cmd)) { - ret = -EINVAL; + ret = -ENOTTY; goto errout; } @@ -491,11 +645,18 @@ int netdev_ioctl(int sockfd, int cmd, unsigned long arg) /* Execute the command */ - ret = netdev_ifrioctl(psock, cmd, (FAR struct ifreq*)arg); + ret = netdev_ifrioctl(psock, cmd, (FAR struct ifreq*)((uintptr_t)arg)); #ifdef CONFIG_NET_IGMP - if (ret == -EINVAL) + if (ret == -ENOTTY) + { + + ret = netdev_imsfioctl(psock, cmd, (FAR struct ip_msfilter*)((uintptr_t)arg)); + } +#endif +#ifdef CONFIG_NET_ROUTE + if (ret == -ENOTTY) { - ret = netdev_imsfioctl(psock, cmd, (FAR struct ip_msfilter*)arg); + ret = netdev_rtioctl(psock, cmd, (FAR struct rtentry*)((uintptr_t)arg)); } #endif |