This commit adds support for routing tables in files in a file system. This might be useful for customized, per-unit routing tables.
There are two issues with it however: 1. Reading from file system on a per packet basis could be slow. I think it probably should have a small, in-memory cache of most frequently used routes for good problem. 2. Currently the delroute logic is disabled due to a problem with the design. NuttX does not currently support truncate(). Therefore, it is not possible to delete entries from the routing table file. In this current implementation, that leaves the last entry intact at the end of the file. An alternative design might include a tag on each record to indicate if the record is valid or not. That would work but would add complexity to the other routing table functions. The existing implementation is available for testing purposes only if CONFIG_EXPERIMENTAL=y. Squashed commit of the following: net/route: The current delroute design depends on file truncation. However, NuttX does not currently support truncate. Alternative, more complex designs are possible but not implemented. At present the file routing table are otherwise functional but the delroute logic is disabled via CONFIG_EXPERIMENTAL. Enable it only if you plan to fix it. net/route: Fix some issues with locking routing table files. net/route: Add partial implementation of delroute for the case where the routing table is in a file. net/route: Add support for seeking to positions in the routing table. net/route: Add net_addroute_ipv4/6() using a file-based routing table. net/route: Add net_foreach_ipv4/4() using a file-based routing table. net/route: Initial build, configuration, and fs utilies to support routing tables in a file.
This commit is contained in:
parent
fa65bad3bf
commit
44d88abb83
17 changed files with 2002 additions and 38 deletions
|
@ -66,38 +66,32 @@ ssize_t file_pread(FAR struct file *filep, FAR void *buf, size_t nbytes,
|
|||
off_t savepos;
|
||||
off_t pos;
|
||||
ssize_t ret;
|
||||
int errcode = 0;
|
||||
|
||||
/* Perform the seek to the current position. This will not move the
|
||||
* file pointer, but will return its current setting
|
||||
*/
|
||||
|
||||
savepos = file_seek(filep, 0, SEEK_CUR);
|
||||
if (savepos == (off_t)-1)
|
||||
if (savepos < 0)
|
||||
{
|
||||
/* file_seek might fail if this if the media is not seekable */
|
||||
|
||||
return ERROR;
|
||||
return (ssize_t)savepos;
|
||||
}
|
||||
|
||||
/* Then seek to the correct position in the file */
|
||||
|
||||
pos = file_seek(filep, offset, SEEK_SET);
|
||||
if (pos == (off_t)-1)
|
||||
if (pos < 0)
|
||||
{
|
||||
/* This might fail is the offset is beyond the end of file */
|
||||
|
||||
return ERROR;
|
||||
return (ssize_t)pos;
|
||||
}
|
||||
|
||||
/* Then perform the read operation */
|
||||
|
||||
ret = file_read(filep, buf, nbytes);
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
/* Restore the file position */
|
||||
|
||||
|
@ -106,13 +100,7 @@ ssize_t file_pread(FAR struct file *filep, FAR void *buf, size_t nbytes,
|
|||
{
|
||||
/* This really should not fail */
|
||||
|
||||
errcode = -pos;
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
if (errcode != 0)
|
||||
{
|
||||
set_errno(errcode);
|
||||
ret = (ssize_t)pos;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -170,6 +158,11 @@ ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset)
|
|||
/* Let file_pread do the real work */
|
||||
|
||||
ret = file_pread(filep, buf, nbytes, offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno((int)-ret);
|
||||
ret = (ssize_t)ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
leave_cancellation_point();
|
||||
|
|
|
@ -159,7 +159,7 @@ ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset)
|
|||
if (ret < 0)
|
||||
{
|
||||
set_errno((int)-ret);
|
||||
ret = ERROR;
|
||||
ret = (ssize_t)ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ extern "C"
|
|||
|
||||
int mkdir(FAR const char *pathname, mode_t mode);
|
||||
int mkfifo(FAR const char *pathname, mode_t mode);
|
||||
int stat(const char *path, FAR struct stat *buf);
|
||||
int stat(FAR const char *path, FAR struct stat *buf);
|
||||
int fstat(int fd, FAR struct stat *buf);
|
||||
|
||||
#undef EXTERN
|
||||
|
|
|
@ -37,12 +37,23 @@ config ROUTE_IPv4_ROMROUTE
|
|||
NOTE: The read-only variable g_ipv4_nroutes must be set to the
|
||||
actual number of valid entries in the array.
|
||||
|
||||
config NET_ROUTE_IPv4_FILEROUTE
|
||||
config ROUTE_IPv4_FILEROUTE
|
||||
bool "File"
|
||||
depends on EXPERIMENTAL
|
||||
---help---
|
||||
Select to used a IPv4 routing table in a file in a mounted file system.
|
||||
|
||||
REVISIT: There is a problem with the current design. NuttX does not
|
||||
currently support truncate(). Therefore, it is not possible to delete
|
||||
entries from the routing table file.
|
||||
|
||||
In this current implementation, that leaves the last entry intact at
|
||||
the end of the file. An alternative design might include a tag on
|
||||
each record to indicate if the record is valid or not. That would work
|
||||
but would add complexity to the other routing table functions.
|
||||
|
||||
The existing 'delroute' implementation is available for testing purpose
|
||||
only if CONFIG_EXPERIMENTAL=y.
|
||||
|
||||
endchoice # IPv4 routing table
|
||||
|
||||
config ROUTE_MAX_IPv4_RAMROUTES
|
||||
|
@ -62,12 +73,12 @@ choice
|
|||
config ROUTE_IPv6_RAMROUTE
|
||||
bool "In-memory"
|
||||
---help---
|
||||
Select to used a IPv6 routing table RAM.
|
||||
Select to use a IPv6 routing table RAM.
|
||||
|
||||
config ROUTE_IPv6_ROMROUTE
|
||||
bool "Read-only"
|
||||
---help---
|
||||
Select to used a fixed read-only IPv6 routing table in FLASH or ROM.
|
||||
Select to use a fixed read-only IPv6 routing table in FLASH or ROM.
|
||||
In this case, the board-specific logic must provide a routing table
|
||||
of the form of simply array:
|
||||
|
||||
|
@ -77,11 +88,22 @@ config ROUTE_IPv6_ROMROUTE
|
|||
NOTE: The read-only variable g_ipv6_nroutes must be set to the
|
||||
actual number of valid entries in the array.
|
||||
|
||||
config NET_ROUTE_IPv6_FILEROUTE
|
||||
config ROUTE_IPv6_FILEROUTE
|
||||
bool "File"
|
||||
depends on EXPERIMENTAL
|
||||
---help---
|
||||
Select to used a IPv6 routing table in a file in a mounted file system.
|
||||
Select to use a IPv6 routing table in a file in a mounted file system.
|
||||
|
||||
REVISIT: There is a problem with the current design. NuttX does not
|
||||
currently support truncate(). Therefore, it is not possible to delete
|
||||
entries from the routing table file.
|
||||
|
||||
In this current implementation, that leaves the last entry intact at
|
||||
the end of the file. An alternative design might include a tag on
|
||||
each record to indicate if the record is valid or not. That would work
|
||||
but would add complexity to the other routing table functions.
|
||||
|
||||
The existing 'delroute' implementation is available for testing purpose
|
||||
only if CONFIG_EXPERIMENTAL=y.
|
||||
|
||||
endchoice # IPv6 routing table
|
||||
|
||||
|
@ -94,5 +116,14 @@ config ROUTE_MAX_IPv6_RAMROUTES
|
|||
eliminates dynamica memory allocations, but limits the maximum size
|
||||
of the in-memory routing table to this number.
|
||||
|
||||
config ROUTE_FILEDIR
|
||||
string "Routing table directory"
|
||||
default /tmp
|
||||
depends on ROUTE_IPv4_FILEROUTE || ROUTE_IPv6_FILEROUTE
|
||||
---help---
|
||||
Provides the full path to location in the file system where routing
|
||||
table will be accessed. This is a string and should not include
|
||||
any traling '/'.
|
||||
|
||||
endif # NET_ROUTE
|
||||
endmenu # ARP Configuration
|
||||
|
|
|
@ -57,6 +57,16 @@ else ifeq ($(CONFIG_ROUTE_IPv6_ROMROUTE),y)
|
|||
SOCK_CSRCS += net_foreach_romroute.c
|
||||
endif
|
||||
|
||||
# Support for routing tables in files
|
||||
|
||||
ifeq ($(CONFIG_ROUTE_IPv4_FILEROUTE),y)
|
||||
SOCK_CSRCS += net_fileroute.c net_add_fileroute.c net_del_fileroute.c
|
||||
SOCK_CSRCS += net_foreach_fileroute.c
|
||||
else ifeq ($(CONFIG_ROUTE_IPv6_FILEROUTE),y)
|
||||
SOCK_CSRCS += net_fileroute.c net_add_fileroute.c net_del_fileroute.c
|
||||
SOCK_CSRCS += net_foreach_fileroute.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DEBUG_NET_INFO),y)
|
||||
SOCK_CSRCS += net_dumproute.c
|
||||
endif
|
||||
|
|
284
net/route/fileroute.h
Normal file
284
net/route/fileroute.h
Normal file
|
@ -0,0 +1,284 @@
|
|||
/****************************************************************************
|
||||
* net/route/fileroute.h
|
||||
*
|
||||
* Copyright (C) 2017 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_ROUTE_FILEROUTE_H
|
||||
#define __NET_ROUTE_FILEROUTE_H 1
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "route/route.h"
|
||||
|
||||
#if defined(CONFIG_ROUTE_IPv4_FILEROUTE) || defined(CONFIG_ROUTE_IPv6_FILEROUTE)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define IPv4_ROUTE_PATH CONFIG_ROUTE_FILEDIR "/ipv4"
|
||||
#define IPv6_ROUTE_PATH CONFIG_ROUTE_FILEDIR "/ipv6"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
struct file; /* Forward reference */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_init_fileroute
|
||||
*
|
||||
* Description:
|
||||
* Initialize the in-memory, RAM routing table
|
||||
*
|
||||
* Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called early in initialization so that no special protection is needed.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void net_init_fileroute(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_openroute_ipv4/net_openroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Open the IPv4/IPv6 routing table with the specified access privileges.
|
||||
*
|
||||
* Parameters:
|
||||
* oflags - Open flags
|
||||
* filep - Location in which to return the detached file instance.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-negative file descriptor is returned on success. A negated errno
|
||||
* value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_openroute_ipv4(int oflags, FAR struct file *filep);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_openroute_ipv6(int oflags, FAR struct file *filep);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_readroute_ipv4/net_readroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Read one route entry from the IPv4/IPv6 routing table.
|
||||
*
|
||||
* Parameters:
|
||||
* filep - Detached file instance obtained by net_openroute_ipv{4|6}[_rdonly]
|
||||
* route - Location to return the next route read from the file
|
||||
*
|
||||
* Returned Value:
|
||||
* The number of bytes read on success. The special return valud of zero
|
||||
* indiates that the endof of file was encountered (and nothing was read).
|
||||
* A negated errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
ssize_t net_readroute_ipv4(FAR struct file *filep,
|
||||
FAR struct net_route_ipv4_s *route);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
ssize_t net_readroute_ipv6(FAR struct file *filep,
|
||||
FAR struct net_route_ipv6_s *route);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_writeroute_ipv4/net_writeroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Write one route entry to the IPv4/IPv6 routing table.
|
||||
*
|
||||
* Parameters:
|
||||
* filep - Detached file instance obtained by net_openroute_ipv{4|6}[_rdonly]
|
||||
* route - Location to return the next route read from the file
|
||||
*
|
||||
* Returned Value:
|
||||
* The number of bytes written on success. A negated errno value is
|
||||
* returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
ssize_t net_writeroute_ipv4(FAR struct file *filep,
|
||||
FAR const struct net_route_ipv4_s *route);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
ssize_t net_writeroute_ipv6(FAR struct file *filep,
|
||||
FAR const struct net_route_ipv6_s *route);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_seekroute_ipv4/net_seekroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Seek to a specific entry entry to the IPv4/IPv6 routing table.
|
||||
*
|
||||
* Parameters:
|
||||
* filep - Detached file instance obtained by net_openroute_ipv{4|6}[_rdonly]
|
||||
* index - The index of the routing table entry to seek to.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
off_t net_seekroute_ipv4(FAR struct file *filep, unsigned int index);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
off_t net_seekroute_ipv6(FAR struct file *filep, unsigned int index);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_routesize_ipv4/net_routesize_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Return the size of a routing table in terms of the number of entries in
|
||||
* the routing table.
|
||||
*
|
||||
* Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-negative count of the number of entries in the routing table is
|
||||
* returned on success; a negated errno value is returned on and failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* The size of the routing table may change after this size is returned
|
||||
* unless the routing table is locked to prevent any modification to the
|
||||
* routing table.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_routesize_ipv4(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_routesize_ipv6(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_lockroute_ipv4/net_lockroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Lock access to the routing table. Necessary when a routing table is
|
||||
* being reorganized due to deletion of a route.
|
||||
*
|
||||
* Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_lockroute_ipv4(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_lockroute_ipv6(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_unlockroute_ipv4/net_unlockroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Release the read lock.
|
||||
*
|
||||
* Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_unlockroute_ipv4(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_unlockroute_ipv6(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_closeroute_ipv4/net_closeroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Close the IPv4/IPv6 routing table.
|
||||
*
|
||||
* Parameters:
|
||||
* filep - Detached file instance obtained by net_openroute_ipv{4|6}[_rdonly]
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. A negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_closeroute_ipv4(FAR struct file *filep);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_closeroute_ipv6(FAR struct file *filep);
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ROUTE_IPv4_FILEROUTE || CONFIG_ROUTE_IPv6_FILEROUTE */
|
||||
#endif /* __NET_ROUTE_FILEROUTE_H */
|
141
net/route/net_add_fileroute.c
Normal file
141
net/route/net_add_fileroute.c
Normal file
|
@ -0,0 +1,141 @@
|
|||
/****************************************************************************
|
||||
* net/route/net_add_fileroute.c
|
||||
*
|
||||
* Copyright (C) 2013, 2015, 2017 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
//#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/ip.h>
|
||||
|
||||
#include "route/fileroute.h"
|
||||
#include "route/route.h"
|
||||
|
||||
#if defined(CONFIG_ROUTE_IPv4_FILEROUTE) || defined(CONFIG_ROUTE_IPv6_FILEROUTE)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_addroute_ipv4 and net_addroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Add a new route to the routing table
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; Negated errno on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_addroute_ipv4(in_addr_t target, in_addr_t netmask, in_addr_t router)
|
||||
{
|
||||
struct net_route_ipv4_s route;
|
||||
struct file fshandle;
|
||||
ssize_t nwritten;
|
||||
int ret;
|
||||
|
||||
/* Format the new routing table entry */
|
||||
|
||||
net_ipv4addr_copy(route.target, target);
|
||||
net_ipv4addr_copy(route.netmask, netmask);
|
||||
net_ipv4addr_copy(route.router, router);
|
||||
net_ipv4_dumproute("New route", &route);
|
||||
|
||||
/* Open the IPv4 routing table for append access */
|
||||
|
||||
ret = net_openroute_ipv4(O_WRONLY | O_APPEND | O_CREAT, &fshandle);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: Could not open IPv4 routing table: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Then append the new entry to the end of the routing table */
|
||||
|
||||
nwritten = net_writeroute_ipv4(&fshandle, &route);
|
||||
|
||||
(void)net_closeroute_ipv4(&fshandle);
|
||||
return nwritten >= 0 ? 0 : (int)nwritten;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_addroute_ipv6(net_ipv6addr_t target, net_ipv6addr_t netmask,
|
||||
net_ipv6addr_t router)
|
||||
{
|
||||
struct net_route_ipv6_s route;
|
||||
struct file fshandle;
|
||||
ssize_t nwritten;
|
||||
int ret;
|
||||
|
||||
/* Format the new routing table entry */
|
||||
|
||||
net_ipv6addr_copy(route.target, target);
|
||||
net_ipv6addr_copy(route.netmask, netmask);
|
||||
net_ipv6addr_copy(route.router, router);
|
||||
net_ipv6_dumproute("New route", &route);
|
||||
|
||||
/* Open the IPv6 routing table for append access */
|
||||
|
||||
ret = net_openroute_ipv6(O_WRONLY | O_APPEND | O_CREAT, &fshandle);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: Could not open IPv6 routing table: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Then append the new entry to the end of the routing table */
|
||||
|
||||
nwritten = net_writeroute_ipv6(&fshandle, &route);
|
||||
|
||||
(void)net_closeroute_ipv6(&fshandle);
|
||||
return nwritten >= 0 ? 0 : (int)nwritten;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ROUTE_IPv4_FILEROUTE || CONFIG_ROUTE_IPv6_FILEROUTE */
|
495
net/route/net_del_fileroute.c
Normal file
495
net/route/net_del_fileroute.c
Normal file
|
@ -0,0 +1,495 @@
|
|||
/****************************************************************************
|
||||
* net/route/net_del_fileroute.c
|
||||
*
|
||||
* Copyright (C) 2017 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/ip.h>
|
||||
|
||||
#include "route/fileroute.h"
|
||||
#include "route/route.h"
|
||||
|
||||
#if defined(CONFIG_ROUTE_IPv4_FILEROUTE) || defined(CONFIG_ROUTE_IPv6_FILEROUTE)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* REVISIT: There is a problem with this design. NuttX does not currently
|
||||
* support truncate(). Therefore, it is not possible to delete entries from
|
||||
* the routing table file.
|
||||
*
|
||||
* In this current implementation, that leaves the last entry intact at the
|
||||
* end of the file. An alternative design might include a tag on each
|
||||
* record to indicate if the record is valid or not. That would work but
|
||||
* would add complexity to the other routing table functions.
|
||||
*
|
||||
* The existing implementation is available only if CONFIG_EXPERIMENTAL=y.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_EXPERIMENTAL
|
||||
# warning The implementation of delroute is incomplete
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
struct route_match_ipv4_s
|
||||
{
|
||||
in_addr_t target; /* The target IP address to match */
|
||||
in_addr_t netmask; /* The network mask to match */
|
||||
unsigned int index; /* Index of match */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
struct route_match_ipv6_s
|
||||
{
|
||||
net_ipv6addr_t target; /* The target IP address to match */
|
||||
net_ipv6addr_t netmask; /* The network mask to match */
|
||||
unsigned int index; /* Index of match */
|
||||
};
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_match_ipv4
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_EXPERIMENTAL
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
static int net_match_ipv4(FAR struct net_route_ipv4_s *route, FAR void *arg)
|
||||
{
|
||||
FAR struct route_match_ipv4_s *match = (FAR struct route_match_ipv4_s *)arg;
|
||||
|
||||
/* To match, the masked target address must be the same, and the masks
|
||||
* must be the same.
|
||||
*/
|
||||
|
||||
net_ipv4_dumproute("Comparing", route);
|
||||
ninfo("With:\n");
|
||||
ninfo(" target=%08lx netmask=%08lx\n",
|
||||
htonl(match->target), htonl(match->netmask));
|
||||
|
||||
if (net_ipv4addr_maskcmp(route->target, match->target, match->netmask) &&
|
||||
net_ipv4addr_cmp(route->netmask, match->netmask))
|
||||
{
|
||||
/* They match.. a non-zero value to terminate the traversal. The last
|
||||
* value of index is the index to the matching entry.
|
||||
*/
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Next time we are here, this will be the routing table index */
|
||||
|
||||
match->index++;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
static int net_match_ipv6(FAR struct net_route_ipv6_s *route, FAR void *arg)
|
||||
{
|
||||
FAR struct route_match_ipv6_s *match = (FAR struct route_match_ipv6_s *)arg;
|
||||
|
||||
/* To match, the masked target address must be the same, and the masks
|
||||
* must be the same.
|
||||
*/
|
||||
|
||||
net_ipv6_dumproute("Comparing", route);
|
||||
ninfo("With:\n");
|
||||
ninfo(" target: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
|
||||
htons(match->target[0]), htons(match->target[1]),
|
||||
htons(match->target[2]), htons(match->target[3]),
|
||||
htons(match->target[4]), htons(match->target[5]),
|
||||
htons(match->target[6]), htons(match->target[7]));
|
||||
ninfo(" netmask: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
|
||||
htons(match->netmask[0]), htons(match->netmask[1]),
|
||||
htons(match->netmask[2]), htons(match->netmask[3]),
|
||||
htons(match->netmask[4]), htons(match->netmask[5]),
|
||||
htons(match->netmask[6]), htons(match->netmask[7]));
|
||||
|
||||
if (net_ipv6addr_maskcmp(route->target, match->target, match->netmask) &&
|
||||
net_ipv6addr_cmp(route->netmask, match->netmask))
|
||||
{
|
||||
/* They match.. a non-zero value to terminate the traversal. The last
|
||||
* value of index is the index to the matching entry.
|
||||
*/
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Next time we are here, this will be the routing table index */
|
||||
|
||||
match->index++;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_EXPERIMENTAL */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_delroute_ipv4 and net_delroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Remove an existing route from the routing table
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; Negated errno on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_delroute_ipv4(in_addr_t target, in_addr_t netmask)
|
||||
{
|
||||
#ifdef CONFIG_EXPERIMENTAL
|
||||
struct route_match_ipv4_s match;
|
||||
struct net_route_ipv4_s route;
|
||||
struct file fshandle;
|
||||
ssize_t nwritten;
|
||||
ssize_t nread;
|
||||
off_t pos;
|
||||
int nentries;
|
||||
int index;
|
||||
int ret;
|
||||
|
||||
/* We must lock out other accesses to the routing table while we remove
|
||||
* entry
|
||||
*/
|
||||
|
||||
ret = net_lockroute_ipv4();
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: net_lockroute_ipv4 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the size of the routing table entry (in entries) */
|
||||
|
||||
nentries = net_routesize_ipv4();
|
||||
if (nentries < 0)
|
||||
{
|
||||
ret = nentries;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
else if (nentries == 0)
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Set up the comparison structure */
|
||||
|
||||
net_ipv4addr_copy(match.target, target);
|
||||
net_ipv4addr_copy(match.netmask, netmask);
|
||||
match.index = 0;
|
||||
|
||||
/* Then find the index into the routing table where the match can be found */
|
||||
|
||||
ret = net_foreachroute_ipv4(net_match_ipv4, &match);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* And error occurred */
|
||||
|
||||
goto errout_with_lock;
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
/* No match found */
|
||||
|
||||
ret = -ENOENT;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Open the routing table for read/write access */
|
||||
|
||||
ret = net_openroute_ipv4(O_RDWR, &fshandle);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: Could not open IPv4 routing table: %d\n", ret);
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Loop, copying each entry, to the previous entry thus removing the entry
|
||||
* to be deleted.
|
||||
*/
|
||||
|
||||
for (index = match.index + 1; index < nentries; index++)
|
||||
{
|
||||
/* Seek to the current entry to be moved */
|
||||
|
||||
pos = net_seekroute_ipv4(&fshandle, index);
|
||||
if (pos < 0)
|
||||
{
|
||||
nerr("ERROR: net_readroute_ipv4 failed: %ld\n", (long)pos);
|
||||
ret =(int)pos;
|
||||
goto errout_with_fshandle;
|
||||
}
|
||||
|
||||
/* Read the routing table entry at this position */
|
||||
|
||||
nread = net_readroute_ipv4(&fshandle, &route);
|
||||
if (nread < 0)
|
||||
{
|
||||
nerr("ERROR: net_readroute_ipv4 failed: %ld\n", (long)nread);
|
||||
ret = (int)nread;
|
||||
goto errout_with_fshandle;
|
||||
}
|
||||
else if (nread == 0)
|
||||
{
|
||||
nerr("ERROR: Undexpected end of file\n");
|
||||
ret = -EINVAL;
|
||||
goto errout_with_fshandle;
|
||||
}
|
||||
|
||||
/* Seek to the previous entry to be replaced */
|
||||
|
||||
pos = net_seekroute_ipv4(&fshandle, index - 1);
|
||||
if (pos < 0)
|
||||
{
|
||||
nerr("ERROR: net_readroute_ipv4 failed: %ld\n", (long)pos);
|
||||
ret =(int)pos;
|
||||
goto errout_with_fshandle;
|
||||
}
|
||||
|
||||
/* Now write the record to its new location */
|
||||
|
||||
nwritten = net_writeroute_ipv4(&fshandle, &route);
|
||||
if (nwritten < 0)
|
||||
{
|
||||
nerr("ERROR: net_readroute_ipv4 failed: %ld\n", (long)nwritten);
|
||||
ret = (int)nwritten;
|
||||
goto errout_with_fshandle;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now truncate the one duplicate entry at the end of the file. This may
|
||||
* result in a zero length file.
|
||||
*/
|
||||
#warning Missing logic
|
||||
|
||||
ret = OK;
|
||||
|
||||
errout_with_fshandle:
|
||||
(void)net_closeroute_ipv4(&fshandle);
|
||||
|
||||
errout_with_lock:
|
||||
(void)net_unlockroute_ipv4();
|
||||
return ret;
|
||||
#else
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_delroute_ipv6(net_ipv6addr_t target, net_ipv6addr_t netmask)
|
||||
{
|
||||
#ifdef CONFIG_EXPERIMENTAL
|
||||
struct route_match_ipv6_s match;
|
||||
struct net_route_ipv6_s route;
|
||||
struct file fshandle;
|
||||
ssize_t nwritten;
|
||||
ssize_t nread;
|
||||
off_t pos;
|
||||
int nentries;
|
||||
int index;
|
||||
int ret;
|
||||
|
||||
/* We must lock out other accesses to the routing table while we remove
|
||||
* entry
|
||||
*/
|
||||
|
||||
ret = net_lockroute_ipv6();
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: net_lockroute_ipv6 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the size of the routing table entry (in entries) */
|
||||
|
||||
nentries = net_routesize_ipv6();
|
||||
if (nentries < 0)
|
||||
{
|
||||
ret = nentries;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
else if (nentries == 0)
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Set up the comparison structure */
|
||||
|
||||
net_ipv6addr_copy(match.target, target);
|
||||
net_ipv6addr_copy(match.netmask, netmask);
|
||||
match.index = 0;
|
||||
|
||||
/* Then find the index into the routing table where the match can be found */
|
||||
|
||||
ret = net_foreachroute_ipv6(net_match_ipv6, &match);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* And error occurred */
|
||||
|
||||
ret = ret;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
/* No match found */
|
||||
|
||||
ret = -ENOENT;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Open the routing table for read/write access */
|
||||
|
||||
ret = net_openroute_ipv6(O_RDWR, &fshandle);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: Could not open IPv6 routing table: %d\n", ret);
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Loop, copying each entry, to the previous entry thus removing the entry
|
||||
* to be deleted.
|
||||
*/
|
||||
|
||||
for (index = match.index + 1; index < nentries; index++)
|
||||
{
|
||||
/* Seek to the current entry to be moved */
|
||||
|
||||
pos = net_seekroute_ipv6(&fshandle, index);
|
||||
if (pos < 0)
|
||||
{
|
||||
nerr("ERROR: net_readroute_ipv6 failed: %ld\n", (long)pos);
|
||||
ret =(int)pos;
|
||||
goto errout_with_fshandle;
|
||||
}
|
||||
|
||||
/* Read the routing table entry at this position */
|
||||
|
||||
nread = net_readroute_ipv6(&fshandle, &route);
|
||||
if (nread < 0)
|
||||
{
|
||||
nerr("ERROR: net_readroute_ipv6 failed: %ld\n", (long)nread);
|
||||
ret = (int)nread;
|
||||
goto errout_with_fshandle;
|
||||
}
|
||||
else if (nread == 0)
|
||||
{
|
||||
nerr("ERROR: Undexpected end of file\n");
|
||||
ret = -EINVAL;
|
||||
goto errout_with_fshandle;
|
||||
}
|
||||
|
||||
/* Seek to the previous entry to be replaced */
|
||||
|
||||
pos = net_seekroute_ipv6(&fshandle, index - 1);
|
||||
if (pos < 0)
|
||||
{
|
||||
nerr("ERROR: net_readroute_ipv6 failed: %ld\n", (long)pos);
|
||||
ret =(int)pos;
|
||||
goto errout_with_fshandle;
|
||||
}
|
||||
|
||||
/* Now write the record to its new location */
|
||||
|
||||
nwritten = net_writeroute_ipv6(&fshandle, &route);
|
||||
if (nwritten < 0)
|
||||
{
|
||||
nerr("ERROR: net_readroute_ipv6 failed: %ld\n", (long)nwritten);
|
||||
ret = (int)nwritten;
|
||||
goto errout_with_fshandle;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now truncate the one duplicate entry at the end of the file. This may
|
||||
* result in a zero length file.
|
||||
*/
|
||||
#warning Missing logic
|
||||
|
||||
ret = OK;
|
||||
|
||||
errout_with_fshandle:
|
||||
(void)net_closeroute_ipv6(&fshandle);
|
||||
|
||||
errout_with_lock:
|
||||
(void)net_unlockroute_ipv6();
|
||||
return ret;
|
||||
#else
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ROUTE_IPv4_FILEROUTE || CONFIG_ROUTE_IPv6_FILEROUTE */
|
|
@ -57,11 +57,11 @@
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_RAMROUTE
|
||||
struct route_match_s
|
||||
struct route_match_ipv4_s
|
||||
{
|
||||
FAR struct net_route_ipv4_s *prev; /* Predecessor in the list */
|
||||
in_addr_t target; /* The target IP address to match */
|
||||
in_addr_t netmask; /* The network mask to match */
|
||||
in_addr_t target; /* The target IP address to match */
|
||||
in_addr_t netmask; /* The network mask to match */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -96,7 +96,7 @@ struct route_match_ipv6_s
|
|||
#ifdef CONFIG_ROUTE_IPv4_RAMROUTE
|
||||
static int net_match_ipv4(FAR struct net_route_ipv4_s *route, FAR void *arg)
|
||||
{
|
||||
FAR struct route_match_s *match = (FAR struct route_match_s *)arg;
|
||||
FAR struct route_match_ipv4_s *match = (FAR struct route_match_ipv4_s *)arg;
|
||||
|
||||
/* To match, the masked target address must be the same, and the masks
|
||||
* must be the same.
|
||||
|
@ -211,7 +211,7 @@ static int net_match_ipv6(FAR struct net_route_ipv6_s *route, FAR void *arg)
|
|||
#ifdef CONFIG_ROUTE_IPv4_RAMROUTE
|
||||
int net_delroute_ipv4(in_addr_t target, in_addr_t netmask)
|
||||
{
|
||||
struct route_match_s match;
|
||||
struct route_match_ipv4_s match;
|
||||
|
||||
/* Set up the comparison structure */
|
||||
|
||||
|
|
786
net/route/net_fileroute.c
Normal file
786
net/route/net_fileroute.c
Normal file
|
@ -0,0 +1,786 @@
|
|||
/****************************************************************************
|
||||
* net/route/net_fileroute.c
|
||||
*
|
||||
* Copyright (C) 2017 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "route/fileroute.h"
|
||||
#include "route/route.h"
|
||||
|
||||
#if defined(CONFIG_ROUTE_IPv4_FILEROUTE) || defined(CONFIG_ROUTE_IPv6_FILEROUTE)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Defintions
|
||||
****************************************************************************/
|
||||
|
||||
/* Special "impossible" PID value used to indicate that there is no holder
|
||||
* of the lock.
|
||||
*/
|
||||
|
||||
#define NO_HOLDER ((pid_t)-1)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
/* Semaphore used to lock a routing table for exclusive write-only access */
|
||||
|
||||
static sem_t g_ipv4_exclsem;
|
||||
static pid_t g_ipv4_holder = NO_HOLDER;
|
||||
static int g_ipv4_count;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
/* Semaphore used to lock a routing table for exclusive write-only access */
|
||||
|
||||
static sem_t g_ipv6_exclsem;
|
||||
static pid_t g_ipv6_holder = NO_HOLDER;
|
||||
static int g_ipv6_count;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_openroute_detached
|
||||
*
|
||||
* Description:
|
||||
* Open and detach the routing table.
|
||||
*
|
||||
* Parameters:
|
||||
* pathname - The full path to the routing table entry
|
||||
* oflags - Open flags
|
||||
* filep - Location in which to return the detached file instance.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-negative file descriptor is returned on success. A negated errno
|
||||
* value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int net_openroute_detached(FAR const char *pathname, int oflags,
|
||||
FAR struct file *filep)
|
||||
{
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
/* Open the file for read/write access. Here we borrow the file descriptor
|
||||
* of this tread of execution. We won't use it for long.
|
||||
*/
|
||||
|
||||
fd = open(pathname, oflags, 0644);
|
||||
if (fd < 0)
|
||||
{
|
||||
int errcode = get_errno();
|
||||
nerr("ERROR: Failed to open %s: %d\n", pathname, errcode);
|
||||
return -errcode;
|
||||
}
|
||||
|
||||
/* Now detach the file descriptor */
|
||||
|
||||
ret = file_detach(fd, filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: file_detach() failed: %d\n", ret);
|
||||
(void)close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_routesize
|
||||
*
|
||||
* Description:
|
||||
* Return the size of a routing table in terms of the number of entries in
|
||||
* the routing table.
|
||||
*
|
||||
* Parameters:
|
||||
* path - The path to the routing table
|
||||
* entrysize - The size of one entry in the routing table
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-negative count of the number of entries in the routing table is
|
||||
* returned on success; a negated errno value is returned on and failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int net_routesize(FAR const char *path, size_t entrysize)
|
||||
{
|
||||
struct stat buf;
|
||||
int ret;
|
||||
|
||||
/* Get information about the file */
|
||||
|
||||
ret = stat(path, &buf);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode;
|
||||
|
||||
/* stat() failed, but is that because the routing table has not been
|
||||
* created yet?
|
||||
*/
|
||||
|
||||
errcode = errno;
|
||||
if (errcode == ENOENT)
|
||||
{
|
||||
/* The routing table file has not been created. Return size zero. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Some other error */
|
||||
|
||||
return -errcode;
|
||||
}
|
||||
|
||||
/* The directory entry at this path must be a regular file */
|
||||
|
||||
if (S_ISREG(buf.st_mode))
|
||||
{
|
||||
unsigned int nentries = buf.st_size / entrysize;
|
||||
|
||||
#ifdef CONFIG_DEBUG_NET_WARN
|
||||
if (nentries * entrysize != buf.st_size)
|
||||
{
|
||||
nwarn("WARNING: Size of routing table is not an even mutliple of entries\n");
|
||||
nwarn(" %lu != %lu / %lu\n",
|
||||
(unsigned long)nentries,
|
||||
(unsigned long)buf.st_size,
|
||||
(unsigned long)entrysize);
|
||||
}
|
||||
#endif
|
||||
|
||||
return nentries;
|
||||
}
|
||||
|
||||
/* It is probably a directory (should check for sure) */
|
||||
|
||||
return -EISDIR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_init_fileroute
|
||||
*
|
||||
* Description:
|
||||
* Initialize the in-memory, RAM routing table
|
||||
*
|
||||
* Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called early in initialization so that no special protection is needed.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void net_init_fileroute(void)
|
||||
{
|
||||
/* Initialize semaphores */
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
sem_init(&g_ipv4_exclsem, 0, 1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
sem_init(&g_ipv6_exclsem, 0, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_openroute_ipv4/net_openroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Open the IPv4/IPv6 routing table with the specified access privileges.
|
||||
*
|
||||
* Parameters:
|
||||
* oflags - Open flags
|
||||
* filep - Location in which to return the detached file instance.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-negative file descriptor is returned on success. A negated errno
|
||||
* value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_openroute_ipv4(int oflags, FAR struct file *filep)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Lock the route.. we don't want to open it while it is subject to
|
||||
* modification.
|
||||
*/
|
||||
|
||||
ret = net_lockroute_ipv4();
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: net_lockroute_ipv4() failed: %d\n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Open the file for read/write access. */
|
||||
|
||||
ret = net_openroute_detached(IPv4_ROUTE_PATH, oflags, filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: net_openroute_detached() failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
(void)net_unlockroute_ipv4();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_openroute_ipv6(int oflags, FAR struct file *filep)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Lock the route.. we don't want to open it while it is subject to
|
||||
* modification.
|
||||
*/
|
||||
|
||||
ret = net_lockroute_ipv6();
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: net_lockroute_ipv6() failed: %d\n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Open the file for read/write access. */
|
||||
|
||||
ret = net_openroute_detached(IPv6_ROUTE_PATH, oflags, filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: net_openroute_detached() failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
(void)net_unlockroute_ipv6();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_readroute_ipv4/net_readroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Read one route entry from the IPv4/IPv6 routing table.
|
||||
*
|
||||
* Parameters:
|
||||
* filep - Detached file instance obtained by net_openroute_ipv{4|6}[_rdonly]
|
||||
* route - Location to return the next route read from the file
|
||||
*
|
||||
* Returned Value:
|
||||
* The number of bytes read on success. The special return valud of zero
|
||||
* indiates that the endof of file was encountered (and nothing was read).
|
||||
* A negated errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
ssize_t net_readroute_ipv4(FAR struct file *filep,
|
||||
FAR struct net_route_ipv4_s *route)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
/* Lock the route.. we don't want to read from it while it is subject to
|
||||
* modification.
|
||||
*/
|
||||
|
||||
ret = (ssize_t)net_lockroute_ipv4();
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: net_lockroute_ipv4() failed: %d\n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read one record from the current position in the routing table */
|
||||
|
||||
ret = file_read(filep, route, sizeof(struct net_route_ipv4_s));
|
||||
}
|
||||
|
||||
(void)net_unlockroute_ipv4();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
ssize_t net_readroute_ipv6(FAR struct file *filep,
|
||||
FAR struct net_route_ipv6_s *route)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
/* Lock the route.. we don't want to read from it while it is subject to
|
||||
* modification.
|
||||
*/
|
||||
|
||||
ret = (ssize_t)net_lockroute_ipv6();
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: net_lockroute_ipv6() failed: %d\n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read one record from the current position in the routing table */
|
||||
|
||||
ret = file_read(filep, route, sizeof(struct net_route_ipv6_s));
|
||||
}
|
||||
|
||||
(void)net_unlockroute_ipv6();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_writeroute_ipv4/net_writeroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Write one route entry to the IPv4/IPv6 routing table.
|
||||
*
|
||||
* Parameters:
|
||||
* filep - Detached file instance obtained by net_openroute_ipv{4|6}[_rdonly]
|
||||
* route - Location to return the next route read from the file
|
||||
*
|
||||
* Returned Value:
|
||||
* The number of bytes written on success. A negated errno value is
|
||||
* returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
ssize_t net_writeroute_ipv4(FAR struct file *filep,
|
||||
FAR const struct net_route_ipv4_s *route)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
/* Lock the route.. we don't want to write to it while it is subject to
|
||||
* modification.
|
||||
*/
|
||||
|
||||
ret = (ssize_t)net_lockroute_ipv4();
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: net_lockroute_ipv4() failed: %d\n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Write one record at the current position in the routing table */
|
||||
|
||||
ret = file_write(filep, route, sizeof(struct net_route_ipv4_s));
|
||||
}
|
||||
|
||||
(void)net_unlockroute_ipv4();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
ssize_t net_writeroute_ipv6(FAR struct file *filep,
|
||||
FAR const struct net_route_ipv6_s *route)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
/* Lock the route.. we don't want to write to it while it is subject to
|
||||
* modification.
|
||||
*/
|
||||
|
||||
ret = (ssize_t)net_lockroute_ipv6();
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: net_lockroute_ipv6() failed: %d\n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Write one record at the current position in the routing table */
|
||||
|
||||
ret = file_write(filep, route, sizeof(struct net_route_ipv6_s));
|
||||
}
|
||||
|
||||
(void)net_unlockroute_ipv6();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_seekroute_ipv4/net_seekroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Seek to a specific entry entry to the IPv4/IPv6 routing table.
|
||||
*
|
||||
* Parameters:
|
||||
* filep - Detached file instance obtained by net_openroute_ipv{4|6}[_rdonly]
|
||||
* index - The index of the routing table entry to seek to.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
off_t net_seekroute_ipv4(FAR struct file *filep, unsigned int index)
|
||||
{
|
||||
off_t offset;
|
||||
off_t ret;
|
||||
|
||||
/* Convert the index to a file offset */
|
||||
|
||||
offset = (off_t)index * sizeof(struct net_route_ipv4_s);
|
||||
|
||||
/* Then seek to that position */
|
||||
|
||||
ret = file_seek(filep, offset, SEEK_SET);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: file_seek() failed: %ld\n", (long)ret);
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
off_t net_seekroute_ipv6(FAR struct file *filep, unsigned int index)
|
||||
{
|
||||
off_t offset;
|
||||
off_t ret;
|
||||
|
||||
/* Convert the index to a file offset */
|
||||
|
||||
offset = (off_t)index * sizeof(struct net_route_ipv6_s);
|
||||
|
||||
/* Then seek to that position */
|
||||
|
||||
ret = file_seek(filep, offset, SEEK_SET);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: file_seek() failed: %ld\n", (long)ret);
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_routesize_ipv4/net_routesize_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Return the size of a routing table in terms of the number of entries in
|
||||
* the routing table.
|
||||
*
|
||||
* Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-negative count of the number of entries in the routing table is
|
||||
* returned on success; a negated errno value is returned on and failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* The size of the routing table may change after this size is returned
|
||||
* unless the routing table is locked to prevent any modification to the
|
||||
* routing table.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_routesize_ipv4(void)
|
||||
{
|
||||
return net_routesize(IPv4_ROUTE_PATH, sizeof(struct net_route_ipv4_s));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_routesize_ipv6(void)
|
||||
{
|
||||
return net_routesize(IPv6_ROUTE_PATH, sizeof(struct net_route_ipv6_s));
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_lockroute_ipv4/net_lockroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Lock access to the routing table. Necessary when a routing table is
|
||||
* being reorganized due to deletion of a route.
|
||||
*
|
||||
* Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_lockroute_ipv4(void)
|
||||
{
|
||||
pid_t me = getpid();
|
||||
int ret;
|
||||
|
||||
/* Are we already the holder of the lock? */
|
||||
|
||||
if (g_ipv4_holder == me)
|
||||
{
|
||||
/* Yes.. just increment the count of locks held */
|
||||
|
||||
g_ipv4_count++;
|
||||
ret = OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No.. wait to get the lock */
|
||||
|
||||
ret = sem_wait(&g_ipv4_exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = get_errno();
|
||||
nerr("ERROR: sem_wait() failed: %d\n", errcode);
|
||||
ret = -errcode;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUGASSERT(g_ipv4_holder == NO_HOLDER && g_ipv4_count == 0);
|
||||
|
||||
/* We are now the holder with one count */
|
||||
|
||||
g_ipv4_holder = me;
|
||||
g_ipv4_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_lockroute_ipv6(void)
|
||||
{
|
||||
pid_t me = getpid();
|
||||
int ret;
|
||||
|
||||
/* Are we already the holder of the lock? */
|
||||
|
||||
if (g_ipv6_holder == me)
|
||||
{
|
||||
/* Yes.. just increment the count of locks held */
|
||||
|
||||
g_ipv6_count++;
|
||||
ret = OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No.. wait to get the lock */
|
||||
|
||||
ret = sem_wait(&g_ipv6_exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = get_errno();
|
||||
nerr("ERROR: sem_wait() failed: %d\n", errcode);
|
||||
ret = -errcode;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUGASSERT(g_ipv6_holder == NO_HOLDER && g_ipv6_count == 0);
|
||||
|
||||
/* We are now the holder with one count */
|
||||
|
||||
g_ipv6_holder = me;
|
||||
g_ipv6_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_unlockroute_ipv4/net_unlockroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Release the read lock.
|
||||
*
|
||||
* Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_unlockroute_ipv4(void)
|
||||
{
|
||||
pid_t me = getpid();
|
||||
int ret;
|
||||
|
||||
/* If would be an error if we are called with on a thread that does not
|
||||
* hold the lock.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(me == g_ipv4_holder && g_ipv4_count > 0);
|
||||
|
||||
/* Release the count on the lock. If this is the last count, then release
|
||||
* the lock.
|
||||
*/
|
||||
|
||||
if (g_ipv4_count > 1)
|
||||
{
|
||||
/* Not the last count... just decrement the count and return success */
|
||||
|
||||
g_ipv4_count--;
|
||||
ret = OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is the last count. Release the lock */
|
||||
|
||||
g_ipv4_holder = NO_HOLDER;
|
||||
g_ipv4_count = 0;
|
||||
|
||||
ret = sem_post(&g_ipv4_exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = get_errno();
|
||||
nerr("ERROR: sem_post() failed: %d\n", errcode);
|
||||
ret = -errcode;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_unlockroute_ipv6(void)
|
||||
{
|
||||
pid_t me = getpid();
|
||||
int ret;
|
||||
|
||||
/* If would be an error if we are called with on a thread that does not
|
||||
* hold the lock.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(me == g_ipv6_holder && g_ipv6_count > 0);
|
||||
|
||||
/* Release the count on the lock. If this is the last count, then release
|
||||
* the lock.
|
||||
*/
|
||||
|
||||
if (g_ipv6_count > 1)
|
||||
{
|
||||
/* Not the last count... just decrement the count and return success */
|
||||
|
||||
g_ipv6_count--;
|
||||
ret = OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is the last count. Release the lock */
|
||||
|
||||
g_ipv6_holder = NO_HOLDER;
|
||||
g_ipv6_count = 0;
|
||||
|
||||
ret = sem_post(&g_ipv6_exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = get_errno();
|
||||
nerr("ERROR: sem_post() failed: %d\n", errcode);
|
||||
ret = -errcode;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_closeroute_ipv4/net_closeroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Close the IPv4/IPv6 routing table.
|
||||
*
|
||||
* Parameters:
|
||||
* filep - Detached file instance obtained by net_openroute_ipv{4|6}[_rdonly]
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. A negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_closeroute_ipv4(FAR struct file *filep)
|
||||
{
|
||||
return file_close_detached(filep);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_closeroute_ipv6(FAR struct file *filep)
|
||||
{
|
||||
return file_close_detached(filep);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ROUTE_IPv4_FILEROUTE || CONFIG_ROUTE_IPv6_FILEROUTE */
|
213
net/route/net_foreach_fileroute.c
Normal file
213
net/route/net_foreach_fileroute.c
Normal file
|
@ -0,0 +1,213 @@
|
|||
/****************************************************************************
|
||||
* net/route/net_foreach_fileroute.c
|
||||
*
|
||||
* Copyright (C) 2017 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "route/fileroute.h"
|
||||
#include "route/route.h"
|
||||
|
||||
#if defined(CONFIG_ROUTE_IPv4_FILEROUTE) || defined(CONFIG_ROUTE_IPv6_FILEROUTE)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: net_foreachroute_ipv4 and net_foreachroute_ipv6
|
||||
*
|
||||
* Description:
|
||||
* Traverse the routing table
|
||||
*
|
||||
* Parameters:
|
||||
* handler - Will be called for each route in the routing table.
|
||||
* arg - An arbitrary value that will be passed tot he handler.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) returned if the entire table was search. A negated errno
|
||||
* value will be returned in the event of a failure. Handlers may also
|
||||
* terminate the search early with any non-zero, non-negative value.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv4_FILEROUTE
|
||||
int net_foreachroute_ipv4(route_handler_t handler, FAR void *arg)
|
||||
{
|
||||
struct net_route_ipv4_s route;
|
||||
struct file fshandle;
|
||||
ssize_t nread;
|
||||
int ret = 0;
|
||||
|
||||
/* Open the IPv4 routing table for read-only access */
|
||||
|
||||
ret = net_openroute_ipv4(O_RDONLY, &fshandle);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* Special case: the routing table has not yet been created. This is
|
||||
* not an error. We will just want to return successful completion of
|
||||
* the traversal.
|
||||
*/
|
||||
|
||||
if (ret == -ENOENT)
|
||||
{
|
||||
/* The routing table does not exit.. return successful completion */
|
||||
|
||||
ninfo("The IPv4 routing table file does not exist\n");
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Some other error occurred. */
|
||||
|
||||
nerr("ERROR: Could not open IPv4 routing table: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read each entry from the routing table */
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
nread = net_readroute_ipv4(&fshandle, &route);
|
||||
if (nread < 0)
|
||||
{
|
||||
/* File read error */
|
||||
|
||||
nerr("ERROR: net_readroute_ipv4() failed: %ld\n", (long)nread);
|
||||
ret = (int)nread;
|
||||
break;
|
||||
}
|
||||
else if (nread == 0)
|
||||
{
|
||||
/* End of file */
|
||||
|
||||
ret = OK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Call the handler. */
|
||||
|
||||
ret = handler(&route, arg);
|
||||
if (ret != OK)
|
||||
{
|
||||
/* Terminate early if the handler returns any non-zero value. */
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
(void)net_closeroute_ipv4(&fshandle);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROUTE_IPv6_FILEROUTE
|
||||
int net_foreachroute_ipv6(route_handler_ipv6_t handler, FAR void *arg)
|
||||
{
|
||||
struct net_route_ipv6_s route;
|
||||
struct file fshandle;
|
||||
ssize_t nread;
|
||||
int ret = 0;
|
||||
|
||||
/* Open the IPv6 routing table for read-only access */
|
||||
|
||||
ret = net_openroute_ipv6(O_RDONLY, &fshandle);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* Special case: the routing table has not yet been created. This is
|
||||
* not an error. We will just want to return successful completion of
|
||||
* the traversal.
|
||||
*/
|
||||
|
||||
if (ret == -ENOENT)
|
||||
{
|
||||
/* The routing table does not exit.. return successful completion */
|
||||
|
||||
ninfo("The IPv6 routing table file does not exist\n");
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Some other error occurred. */
|
||||
|
||||
nerr("ERROR: Could not open IPv6 routing table: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read each entry from the routing table */
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
nread = net_readroute_ipv6(&fshandle, &route);
|
||||
if (nread < 0)
|
||||
{
|
||||
/* File read error */
|
||||
|
||||
nerr("ERROR: net_readroute_ipv6() failed: %ld\n", (long)nread);
|
||||
ret = (int)nread;
|
||||
break;
|
||||
}
|
||||
else if (nread == 0)
|
||||
{
|
||||
/* End of file */
|
||||
|
||||
ret = OK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Call the handler. */
|
||||
|
||||
ret = handler(&route, arg);
|
||||
if (ret != OK)
|
||||
{
|
||||
/* Terminate early if the handler returns any non-zero value. */
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
(void)net_closeroute_ipv6(&fshandle);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ROUTE_IPv4_FILEROUTE || CONFIG_ROUTE_IPv6_FILEROUTE */
|
|
@ -66,7 +66,9 @@
|
|||
* arg - An arbitrary value that will be passed tot he handler.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 if in use; 1 if avaialble and the new entry was added
|
||||
* Zero (OK) returned if the entire table was search. A negated errno
|
||||
* value will be returned in the event of a failure. Handlers may also
|
||||
* terminate the search early with any non-zero, non-negative value.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
|
|
@ -41,8 +41,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "route/romroute.h"
|
||||
#include "route/route.h"
|
||||
|
||||
|
@ -63,7 +61,9 @@
|
|||
* arg - An arbitrary value that will be passed tot he handler.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 if in use; 1 if avaialble and the new entry was added
|
||||
* Zero (OK) returned if the entire table was search. A negated errno
|
||||
* value will be returned in the event of a failure. Handlers may also
|
||||
* terminate the search early with any non-zero, non-negative value.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <nuttx/config.h>
|
||||
|
||||
#include "route/ramroute.h"
|
||||
#include "route/fileroute.h"
|
||||
#include "route/route.h"
|
||||
|
||||
#ifdef CONFIG_NET_ROUTE
|
||||
|
@ -67,6 +68,10 @@ void net_init_route(void)
|
|||
#if defined(CONFIG_ROUTE_IPv4_RAMROUTE) || defined(CONFIG_ROUTE_IPv6_RAMROUTE)
|
||||
net_init_ramroute();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ROUTE_IPv4_FILEROUTE) || defined(CONFIG_ROUTE_IPv6_FILEROUTE)
|
||||
net_init_fileroute();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_ROUTE */
|
||||
|
|
|
@ -129,7 +129,7 @@ extern struct net_route_ipv6_queue_s g_ipv6_routes;
|
|||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -69,7 +69,7 @@ extern const unsigned int g_ipv6_nroutes;
|
|||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* CONFIG_ROUTE_IPv4_ROMROUTE || CONFIG_ROUTE_IPv6_ROMROUTE */
|
||||
|
|
|
@ -266,9 +266,13 @@ void netdev_ipv6_router(FAR struct net_driver_s *dev,
|
|||
* Traverse the routing table
|
||||
*
|
||||
* Parameters:
|
||||
* handler - Will be called for each route in the routing table.
|
||||
* arg - An arbitrary value that will be passed tot he handler.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; Negated errno on failure.
|
||||
* Zero (OK) returned if the entire table was search. A negated errno
|
||||
* value will be returned in the event of a failure. Handlers may also
|
||||
* terminate the search early with any non-zero, non-negative value.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
|
Loading…
Reference in a new issue