2017-09-29 20:04:45 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* net/route/net_cacheroute.c
|
|
|
|
*
|
2020-03-29 19:57:53 +02:00
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
|
|
* this work for additional information regarding copyright ownership. The
|
|
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
|
|
* "License"); you may not use this file except in compliance with the
|
|
|
|
* License. You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
* License for the specific language governing permissions and limitations
|
|
|
|
* under the License.
|
2017-09-29 20:04:45 +02:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Included Files
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <debug.h>
|
|
|
|
|
2018-01-05 15:57:22 +01:00
|
|
|
#include <nuttx/semaphore.h>
|
|
|
|
|
2017-09-29 20:04:45 +02:00
|
|
|
#include "route/cacheroute.h"
|
|
|
|
#include "route/route.h"
|
|
|
|
|
|
|
|
#if defined(CONFIG_ROUTE_IPv4_CACHEROUTE) || defined(CONFIG_ROUTE_IPv6_CACHEROUTE)
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Pre-processor Definitions
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/* Configuration ************************************************************/
|
|
|
|
|
|
|
|
#ifndef CONFIG_ROUTE_MAX_IPv4_CACHEROUTES
|
|
|
|
# define CONFIG_ROUTE_MAX_IPv4_CACHEROUTES 4
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef CONFIG_ROUTE_MAX_IPv6_CACHEROUTES
|
|
|
|
# define CONFIG_ROUTE_MAX_IPv6_CACHEROUTES 4
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Routing table initializer */
|
|
|
|
|
|
|
|
#define cacheroute_init(rr) \
|
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
(rr)->head = NULL; \
|
|
|
|
(rr)->tail = NULL; \
|
|
|
|
} \
|
2018-10-30 01:00:30 +01:00
|
|
|
while (0)
|
2017-09-29 20:04:45 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
2020-01-13 21:26:04 +01:00
|
|
|
* Private Types
|
2017-09-29 20:04:45 +02:00
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv4_CACHEROUTE
|
|
|
|
/* This structure describes one entry in the routing table cache */
|
|
|
|
|
|
|
|
struct net_cache_ipv4_entry_s
|
|
|
|
{
|
|
|
|
struct net_route_ipv4_s entry;
|
|
|
|
FAR struct net_cache_ipv4_entry_s *flink;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* This structure describes the head of a routing table cache list */
|
|
|
|
|
|
|
|
struct net_cache_ipv4_queue_s
|
|
|
|
{
|
|
|
|
FAR struct net_cache_ipv4_entry_s *head;
|
|
|
|
FAR struct net_cache_ipv4_entry_s *tail;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv6_CACHEROUTE
|
|
|
|
/* This structure describes one entry in the routing table cache */
|
|
|
|
|
|
|
|
struct net_cache_ipv6_entry_s
|
|
|
|
{
|
|
|
|
struct net_route_ipv6_s entry;
|
|
|
|
FAR struct net_cache_ipv6_entry_s *flink;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* This structure describes the head of a routing table cache list */
|
|
|
|
|
|
|
|
struct net_cache_ipv6_queue_s
|
|
|
|
{
|
|
|
|
FAR struct net_cache_ipv6_entry_s *head;
|
|
|
|
FAR struct net_cache_ipv6_entry_s *tail;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Private Data
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/* These are the routing tables */
|
|
|
|
|
|
|
|
#if defined(CONFIG_ROUTE_IPv4_CACHEROUTE)
|
|
|
|
/* The in-memory cache as a singly linked list. */
|
|
|
|
|
|
|
|
static struct net_cache_ipv4_queue_s g_ipv4_cache;
|
|
|
|
|
|
|
|
/* List of free routing table cache entries */
|
|
|
|
|
|
|
|
static struct net_cache_ipv4_queue_s g_free_ipv4cache;
|
|
|
|
|
|
|
|
/* Pre-allocated routing table cache entries */
|
|
|
|
|
|
|
|
static struct net_cache_ipv4_entry_s
|
|
|
|
g_prealloc_ipv4cache[CONFIG_ROUTE_MAX_IPv4_CACHEROUTES];
|
|
|
|
|
|
|
|
/* Serializes access to the routing table cache */
|
|
|
|
|
2022-03-12 07:13:40 +01:00
|
|
|
static sem_t g_ipv4_cachelock = SEM_INITIALIZER(1);
|
2017-09-29 20:04:45 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(CONFIG_ROUTE_IPv6_CACHEROUTE)
|
|
|
|
/* The in-memory routing tables are represented as singly linked lists. */
|
|
|
|
|
|
|
|
static struct net_cache_ipv6_queue_s g_ipv6_cache;
|
|
|
|
|
|
|
|
/* List of free routing table cache entries */
|
|
|
|
|
|
|
|
static struct net_cache_ipv6_queue_s g_free_ipv6cache;
|
|
|
|
|
|
|
|
/* Pre-allocated routing table cache entries */
|
|
|
|
|
|
|
|
static struct net_cache_ipv6_entry_s
|
|
|
|
g_prealloc_ipv6cache[CONFIG_ROUTE_MAX_IPv6_CACHEROUTES];
|
|
|
|
|
|
|
|
/* Serializes access to the routing table cache */
|
|
|
|
|
2022-03-12 07:13:40 +01:00
|
|
|
static sem_t g_ipv6_cachelock = SEM_INITIALIZER(1);
|
2017-09-29 20:04:45 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
2019-07-03 02:02:23 +02:00
|
|
|
* Public Functions
|
2017-09-29 20:04:45 +02:00
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: net_lock_ipv4_cache and net_lock_ipv6_cache
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Lock the routing table cache list.
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2017-09-29 20:04:45 +02:00
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* Zero (OK) is returned on success; A negated errno value is returned on
|
|
|
|
* any failure.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2020-01-02 17:49:34 +01:00
|
|
|
#define net_lock_ipv4_cache() nxsem_wait_uninterruptible(&g_ipv4_cachelock)
|
|
|
|
#define net_lock_ipv6_cache() nxsem_wait_uninterruptible(&g_ipv6_cachelock)
|
2017-09-29 20:04:45 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: net_unlock_ipv4_cache and net_unlock_ipv6_cache
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Unlock the routing table cache list.
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2017-09-29 20:04:45 +02:00
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2022-04-17 17:14:13 +02:00
|
|
|
#define net_unlock_ipv4_cache() nxsem_post(&g_ipv4_cachelock)
|
|
|
|
#define net_unlock_ipv6_cache() nxsem_post(&g_ipv6_cachelock)
|
2017-09-29 20:04:45 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: net_add_newest_ipv4 and net_add_newest_ipv6
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Add a new entry to the routing table cache list. The list is ordered
|
|
|
|
* by "new-ness" so this would be the entry at the head of the list.
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2017-09-29 20:04:45 +02:00
|
|
|
* cache - The cache entry to add to the head of the routing table cache
|
|
|
|
* list.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* Caller has the routing table cache locked.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv4_CACHEROUTE
|
|
|
|
static void net_add_newest_ipv4(FAR struct net_cache_ipv4_entry_s *cache)
|
|
|
|
{
|
|
|
|
cache->flink = g_ipv4_cache.head;
|
|
|
|
if (!g_ipv4_cache.head)
|
|
|
|
{
|
|
|
|
g_ipv4_cache.tail = cache;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_ipv4_cache.head = cache;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv6_CACHEROUTE
|
|
|
|
static void net_add_newest_ipv6(FAR struct net_cache_ipv6_entry_s *cache)
|
|
|
|
{
|
|
|
|
cache->flink = g_ipv6_cache.head;
|
|
|
|
if (!g_ipv6_cache.head)
|
|
|
|
{
|
|
|
|
g_ipv6_cache.tail = cache;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_ipv6_cache.head = cache;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: net_remove_oldest_ipv4 and net_remove_oldest_ipv6
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Remove the oldest entry from the routing table cache list. The list is
|
|
|
|
* ordered
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2017-09-29 20:04:45 +02:00
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* On success, a pointer to the oldest routing table cache entry is
|
|
|
|
* returned. NULL would be returned if the routing table cache is empty.
|
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* Caller has the routing table cache locked.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv4_CACHEROUTE
|
|
|
|
FAR struct net_cache_ipv4_entry_s *net_remove_oldest_ipv4(void)
|
|
|
|
{
|
|
|
|
FAR struct net_cache_ipv4_entry_s *cache;
|
|
|
|
FAR struct net_cache_ipv4_entry_s *prev;
|
|
|
|
|
|
|
|
cache = g_ipv4_cache.tail;
|
|
|
|
if (cache != NULL)
|
|
|
|
{
|
|
|
|
if (g_ipv4_cache.head == g_ipv4_cache.tail)
|
|
|
|
{
|
|
|
|
g_ipv4_cache.head = NULL;
|
|
|
|
g_ipv4_cache.tail = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (prev = g_ipv4_cache.head;
|
|
|
|
prev != NULL && prev->flink != cache;
|
|
|
|
prev = prev->flink);
|
|
|
|
|
|
|
|
if (prev != NULL)
|
|
|
|
{
|
|
|
|
prev->flink = NULL;
|
|
|
|
g_ipv4_cache.tail = prev;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cache->flink = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cache;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv6_CACHEROUTE
|
|
|
|
FAR struct net_cache_ipv6_entry_s *net_remove_oldest_ipv6(void)
|
|
|
|
{
|
|
|
|
FAR struct net_cache_ipv6_entry_s *cache;
|
|
|
|
FAR struct net_cache_ipv6_entry_s *prev;
|
|
|
|
|
|
|
|
cache = g_ipv6_cache.tail;
|
|
|
|
if (cache != NULL)
|
|
|
|
{
|
|
|
|
if (g_ipv6_cache.head == g_ipv6_cache.tail)
|
|
|
|
{
|
|
|
|
g_ipv6_cache.head = NULL;
|
|
|
|
g_ipv6_cache.tail = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (prev = g_ipv6_cache.head;
|
|
|
|
prev != NULL && prev->flink != cache;
|
|
|
|
prev = prev->flink);
|
|
|
|
|
|
|
|
if (prev != NULL)
|
|
|
|
{
|
|
|
|
prev->flink = NULL;
|
|
|
|
g_ipv6_cache.tail = prev;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cache->flink = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cache;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: net_alloccache_ipv4 and net_alloccache_ipv6
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Allocate one routing table cache entry by removing it from the free
|
|
|
|
* list. If the free list is empty, then remove the entry at the tail
|
|
|
|
* of the current routing table cache.
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2017-09-29 20:04:45 +02:00
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* On success, a pointer to the newly allocated routing table cache entry
|
|
|
|
* is returned. Should never fail
|
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* Caller has the routing table cache locked.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv4_CACHEROUTE
|
|
|
|
FAR struct net_cache_ipv4_entry_s *net_alloccache_ipv4(void)
|
|
|
|
{
|
|
|
|
FAR struct net_cache_ipv4_entry_s *cache;
|
|
|
|
|
|
|
|
/* Remove the first entry from the free list */
|
|
|
|
|
|
|
|
cache = g_free_ipv4cache.head;
|
|
|
|
if (cache != NULL)
|
|
|
|
{
|
|
|
|
g_free_ipv4cache.head = cache->flink;
|
|
|
|
if (g_free_ipv4cache.head == NULL)
|
|
|
|
{
|
|
|
|
g_free_ipv4cache.tail = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cache->flink = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If the free list is empty, then remove the oldest entry at the tail of
|
|
|
|
* the routing table cache.
|
|
|
|
*/
|
|
|
|
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* If the free list is empty, then the cache list cannot be empty */
|
|
|
|
|
|
|
|
cache = net_remove_oldest_ipv4();
|
|
|
|
DEBUGASSERT(cache != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return cache;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv6_CACHEROUTE
|
|
|
|
FAR struct net_cache_ipv6_entry_s *net_alloccache_ipv6(void)
|
|
|
|
{
|
|
|
|
FAR struct net_cache_ipv6_entry_s *cache;
|
|
|
|
|
|
|
|
/* Remove the first entry from the free list */
|
|
|
|
|
|
|
|
cache = g_free_ipv6cache.head;
|
|
|
|
if (cache != NULL)
|
|
|
|
{
|
|
|
|
g_free_ipv6cache.head = cache->flink;
|
|
|
|
if (g_free_ipv6cache.head == NULL)
|
|
|
|
{
|
|
|
|
g_free_ipv6cache.tail = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cache->flink = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If the free list is empty, then remove the oldest entry at the tail of
|
|
|
|
* the routing table cache.
|
|
|
|
*/
|
|
|
|
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* If the free list is empty, then the cache list cannot be empty */
|
|
|
|
|
|
|
|
cache = net_remove_oldest_ipv6();
|
|
|
|
DEBUGASSERT(cache != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return cache;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: net_reset_ipv4_cache and net_reset_ipv6_cache
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Clear the routing table cache and return the entries to the free list.
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2017-09-29 20:04:45 +02:00
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv4_CACHEROUTE
|
|
|
|
static void net_reset_ipv4_cache(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
cacheroute_init(&g_ipv4_cache);
|
|
|
|
cacheroute_init(&g_free_ipv4cache);
|
|
|
|
|
2021-02-19 15:01:46 +01:00
|
|
|
/* Add all of the pre-allocated routing table cache entries to
|
|
|
|
* a free list
|
|
|
|
*/
|
2017-09-29 20:04:45 +02:00
|
|
|
|
|
|
|
for (i = 0; i < CONFIG_ROUTE_MAX_IPv4_CACHEROUTES; i++)
|
|
|
|
{
|
|
|
|
net_add_newest_ipv4(&g_prealloc_ipv4cache[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv6_CACHEROUTE
|
|
|
|
static void net_reset_ipv6_cache(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
cacheroute_init(&g_ipv6_cache);
|
|
|
|
cacheroute_init(&g_free_ipv6cache);
|
|
|
|
|
|
|
|
/* Add all of the pre-allocated routing table entries to a free list */
|
|
|
|
|
|
|
|
for (i = 0; i < CONFIG_ROUTE_MAX_IPv6_CACHEROUTES; i++)
|
|
|
|
{
|
|
|
|
net_add_newest_ipv6(&g_prealloc_ipv6cache[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
2020-01-13 21:26:04 +01:00
|
|
|
* Public Functions
|
2017-09-29 20:04:45 +02:00
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: net_init_cacheroute
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Initialize the in-memory, routing table cache
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2017-09-29 20:04:45 +02:00
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* Called early in initialization so that no special protection is needed.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
void net_init_cacheroute(void)
|
|
|
|
{
|
|
|
|
/* Initialize the routing table cash and the free list */
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv4_CACHEROUTE
|
|
|
|
net_reset_ipv4_cache();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv6_CACHEROUTE
|
|
|
|
net_reset_ipv6_cache();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: net_addcache_ipv4 and net_addcache_ipv6
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Add one route to the routing table cache
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2017-09-29 20:04:45 +02:00
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* Zero (OK) is returned on success; a negated errno value is returned
|
|
|
|
* on any failure.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv4_CACHEROUTE
|
|
|
|
int net_addcache_ipv4(FAR struct net_route_ipv4_s *route)
|
|
|
|
{
|
|
|
|
FAR struct net_cache_ipv4_entry_s *cache;
|
2017-10-02 15:09:31 +02:00
|
|
|
FAR struct net_cache_ipv4_entry_s *prev;
|
2017-09-29 20:04:45 +02:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
DEBUGASSERT(route != NULL);
|
|
|
|
|
|
|
|
/* Get exclusive access to the cache */
|
|
|
|
|
|
|
|
ret = net_lock_ipv4_cache();
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-03-11 19:48:17 +01:00
|
|
|
/* First, check if the route already exists in the cache.
|
|
|
|
*
|
|
|
|
* Visit each entry in the cache
|
|
|
|
*/
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2017-10-02 15:09:31 +02:00
|
|
|
for (prev = NULL, cache = g_ipv4_cache.head;
|
|
|
|
cache != NULL;
|
|
|
|
prev = cache, cache = cache->flink)
|
|
|
|
{
|
|
|
|
/* To match, the masked target addresses and netmasks must be the
|
|
|
|
* same.
|
|
|
|
*/
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2017-10-02 15:09:31 +02:00
|
|
|
if (net_ipv4addr_cmp(route->target, cache->entry.target) &&
|
|
|
|
net_ipv4addr_cmp(route->netmask, cache->entry.netmask))
|
|
|
|
{
|
|
|
|
/* If the route already exists and is already at the head of the
|
|
|
|
* list, then do nothing. It is already the most recently used.
|
|
|
|
*/
|
|
|
|
|
2017-10-02 16:10:12 +02:00
|
|
|
if (prev == NULL)
|
|
|
|
{
|
|
|
|
net_unlock_ipv4_cache();
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Otherwise, remove the cache entry from the middle or end of
|
|
|
|
* the list.
|
|
|
|
*/
|
|
|
|
|
|
|
|
prev->flink = cache->flink;
|
|
|
|
if (g_ipv4_cache.tail == cache)
|
|
|
|
{
|
|
|
|
g_ipv4_cache.tail = prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
cache->flink = NULL;
|
|
|
|
break;
|
2017-10-02 15:09:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we did not find the entry in the list, then we will have to
|
|
|
|
* allocate a new entry.
|
|
|
|
*/
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2017-10-02 15:09:31 +02:00
|
|
|
if (cache == NULL)
|
|
|
|
{
|
|
|
|
/* Allocate a new cache entry (should never fail) */
|
|
|
|
|
|
|
|
cache = net_alloccache_ipv4();
|
|
|
|
DEBUGASSERT(cache != NULL);
|
|
|
|
|
|
|
|
/* Copy the routing table entry into the allocated cache entry. */
|
|
|
|
|
|
|
|
memcpy(&cache->entry, route, sizeof(struct net_route_ipv4_s));
|
|
|
|
}
|
2017-09-29 20:04:45 +02:00
|
|
|
|
|
|
|
/* Then add the new cache entry as the newest entry in the table */
|
|
|
|
|
|
|
|
net_add_newest_ipv4(cache);
|
|
|
|
net_unlock_ipv4_cache();
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv6_CACHEROUTE
|
|
|
|
int net_addcache_ipv6(FAR struct net_route_ipv6_s *route)
|
|
|
|
{
|
|
|
|
FAR struct net_cache_ipv6_entry_s *cache;
|
2017-10-02 15:09:31 +02:00
|
|
|
FAR struct net_cache_ipv6_entry_s *prev;
|
2017-09-29 20:04:45 +02:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
DEBUGASSERT(route != NULL);
|
|
|
|
|
|
|
|
/* Get exclusive access to the cache */
|
|
|
|
|
|
|
|
ret = net_lock_ipv6_cache();
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-03-11 19:48:17 +01:00
|
|
|
/* First, check if the route already exists in the cache.
|
|
|
|
*
|
|
|
|
* Visit each entry in the cache.
|
|
|
|
*/
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2017-10-02 15:09:31 +02:00
|
|
|
for (prev = NULL, cache = g_ipv6_cache.head;
|
|
|
|
cache != NULL;
|
|
|
|
prev = cache, cache = cache->flink)
|
|
|
|
{
|
|
|
|
/* To match, the masked target addresses and netmasks must be the
|
|
|
|
* same.
|
|
|
|
*/
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2017-10-02 15:09:31 +02:00
|
|
|
if (net_ipv6addr_cmp(route->target, cache->entry.target) &&
|
|
|
|
net_ipv6addr_cmp(route->netmask, cache->entry.netmask))
|
|
|
|
{
|
|
|
|
/* If the route already exists and is already at the head of the
|
|
|
|
* list, then do nothing. It is already the most recently used.
|
|
|
|
*/
|
|
|
|
|
2017-10-02 16:10:12 +02:00
|
|
|
if (prev == NULL)
|
|
|
|
{
|
|
|
|
net_unlock_ipv6_cache();
|
|
|
|
return OK;
|
|
|
|
}
|
2017-10-02 15:09:31 +02:00
|
|
|
|
2017-10-02 16:10:12 +02:00
|
|
|
/* Otherwise, remove the cache entry from the middle or end of
|
|
|
|
* the list.
|
|
|
|
*/
|
2017-10-02 15:09:31 +02:00
|
|
|
|
2017-10-02 16:10:12 +02:00
|
|
|
prev->flink = cache->flink;
|
|
|
|
if (g_ipv6_cache.tail == cache)
|
|
|
|
{
|
|
|
|
g_ipv6_cache.tail = prev;
|
|
|
|
}
|
2017-10-02 15:09:31 +02:00
|
|
|
|
2017-10-02 16:10:12 +02:00
|
|
|
cache->flink = NULL;
|
|
|
|
break;
|
2017-10-02 15:09:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we did not find the entry in the list, then we will have to
|
|
|
|
* allocate a new entry.
|
|
|
|
*/
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2017-10-02 15:09:31 +02:00
|
|
|
if (cache == NULL)
|
|
|
|
{
|
|
|
|
/* Allocate a new cache entry (should never fail) */
|
|
|
|
|
|
|
|
cache = net_alloccache_ipv6();
|
|
|
|
DEBUGASSERT(cache != NULL);
|
|
|
|
|
|
|
|
/* Copy the routing table entry into the allocated cache entry */
|
|
|
|
|
|
|
|
memcpy(&cache->entry, route, sizeof(struct net_route_ipv6_s));
|
|
|
|
}
|
2017-09-29 20:04:45 +02:00
|
|
|
|
|
|
|
/* Then add the new cache entry as the newest entry in the table */
|
|
|
|
|
|
|
|
net_add_newest_ipv6(cache);
|
|
|
|
net_unlock_ipv6_cache();
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: net_foreachcache_ipv4/net_foreachcache_ipv6
|
|
|
|
*
|
|
|
|
* Description:
|
2020-02-23 09:50:23 +01:00
|
|
|
* Traverse the routing table cache
|
2017-09-29 20:04:45 +02:00
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2017-09-29 20:04:45 +02:00
|
|
|
* handler - Will be called for each route in the routing table cache.
|
Fix typos (and nxstyle errors)
ReleaseNotes,
arch/arm/src/cxd56xx/cxd56_dmac_common.h,
arch/arm/src/efm32/efm32_dma.h,
arch/arm/src/lpc54xx/lpc54_lcd.c,
arch/arm/src/rp2040/rp2040_dmac.h,
arch/arm/src/stm32/stm32_dma.h,
arch/arm/src/stm32f0l0g0/stm32_dma.h,
arch/arm/src/stm32f7/stm32_dma.h,
arch/arm/src/stm32h7/stm32_dma.h,
arch/arm/src/stm32l4/stm32l4_dma.h,
arch/renesas/src/rx65n/rx65n_dtc.h,
fs/spiffs/src/spiffs_vfs.c,
net/route/cacheroute.h,
net/route/net_cacheroute.c,
net/route/net_foreach_fileroute.c,
net/route/net_foreach_ramroute.c,
net/route/net_foreach_romroute.c, and
net/route/route.h:
* Fix the following typos:
- remove spurious "are"
- "tot he" -> "to the"
arch/arm/src/stm32f0l0g0/stm32_dma.h and
arch/arm/src/stm32l4/stm32l4_dma.h:
* Fix nxstyle errors.
2021-03-21 18:07:36 +01:00
|
|
|
* arg - An arbitrary value that will be passed to the handler.
|
2017-09-29 20:04:45 +02:00
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* Zero (OK) returned if the entire table was searched. A negated errno
|
|
|
|
* value will be returned in the event of a failure. Handlers may also
|
|
|
|
* terminate the search early with any non-zero value.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_IPv4
|
|
|
|
int net_foreachcache_ipv4(route_handler_ipv4_t handler, FAR void *arg)
|
|
|
|
{
|
|
|
|
FAR struct net_cache_ipv4_entry_s *cache;
|
|
|
|
FAR struct net_cache_ipv4_entry_s *next;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
/* Get exclusive access to the cache */
|
|
|
|
|
|
|
|
ret = net_lock_ipv4_cache();
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Visit each entry in the routing table */
|
|
|
|
|
|
|
|
for (cache = g_ipv4_cache.head; ret == 0 && cache != NULL; cache = next)
|
|
|
|
{
|
|
|
|
/* Get the next entry in the to visit. We do this BEFORE calling the
|
2020-02-23 09:50:23 +01:00
|
|
|
* handler because the handler may delete this entry.
|
2017-09-29 20:04:45 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
next = cache->flink;
|
|
|
|
ret = handler(&cache->entry, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unlock the cache */
|
|
|
|
|
|
|
|
net_unlock_ipv4_cache();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_IPv6
|
|
|
|
int net_foreachcache_ipv6(route_handler_ipv6_t handler, FAR void *arg)
|
|
|
|
{
|
|
|
|
FAR struct net_cache_ipv6_entry_s *cache;
|
|
|
|
FAR struct net_cache_ipv6_entry_s *next;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
/* Get exclusive access to the cache */
|
|
|
|
|
|
|
|
ret = net_lock_ipv6_cache();
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Visit each entry in the routing table */
|
|
|
|
|
|
|
|
for (cache = g_ipv6_cache.head; ret == 0 && cache != NULL; cache = next)
|
|
|
|
{
|
|
|
|
/* Get the next entry in the to visit. We do this BEFORE calling the
|
2020-02-23 09:50:23 +01:00
|
|
|
* handler because the handler may delete this entry.
|
2017-09-29 20:04:45 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
next = cache->flink;
|
|
|
|
ret = handler(&cache->entry, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unlock the cache */
|
|
|
|
|
|
|
|
net_unlock_ipv6_cache();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: net_flushcache_ipv4 and net_flushcache_ipv6
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Flush the content of the routing table cache
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2017-09-29 20:04:45 +02:00
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv4_CACHEROUTE
|
|
|
|
void net_flushcache_ipv4(void)
|
|
|
|
{
|
2020-03-29 19:57:53 +02:00
|
|
|
int ret;
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2020-03-29 19:57:53 +02:00
|
|
|
/* Get exclusive access to the cache */
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2020-03-29 19:57:53 +02:00
|
|
|
ret = net_lock_ipv4_cache();
|
|
|
|
if (ret >= 0)
|
|
|
|
{
|
|
|
|
/* Reset the cache */
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2020-03-29 19:57:53 +02:00
|
|
|
net_reset_ipv4_cache();
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2020-03-29 19:57:53 +02:00
|
|
|
/* Unlock the cache */
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2020-03-29 19:57:53 +02:00
|
|
|
net_unlock_ipv4_cache();
|
|
|
|
}
|
2017-09-29 20:04:45 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROUTE_IPv6_CACHEROUTE
|
|
|
|
void net_flushcache_ipv6(void)
|
|
|
|
{
|
2020-03-29 19:57:53 +02:00
|
|
|
int ret;
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2020-03-29 19:57:53 +02:00
|
|
|
/* Get exclusive access to the cache */
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2020-03-29 19:57:53 +02:00
|
|
|
ret = net_lock_ipv6_cache();
|
|
|
|
if (ret >= 0)
|
|
|
|
{
|
|
|
|
/* Reset the cache */
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2020-03-29 19:57:53 +02:00
|
|
|
net_reset_ipv6_cache();
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2020-03-29 19:57:53 +02:00
|
|
|
/* Unlock the cache */
|
2017-09-29 20:04:45 +02:00
|
|
|
|
2020-03-29 19:57:53 +02:00
|
|
|
net_unlock_ipv6_cache();
|
|
|
|
}
|
2017-09-29 20:04:45 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* CONFIG_ROUTE_IPv4_CACHEROUTE || CONFIG_ROUTE_IPv6_CACHEROUTE */
|