From 43706cd797b4ea9608f9f981f7b52b0759968670 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Fri, 9 Nov 2018 13:54:55 -0600 Subject: [PATCH] net/arp: Redesign ARP table aging to simplify the net initialization --- include/nuttx/net/arp.h | 2 +- include/nuttx/net/net.h | 21 +----- net/arp/Make.defs | 2 +- net/arp/arp.h | 46 ------------ net/arp/arp_table.c | 155 ++++++++++++++-------------------------- net/arp/arp_timer.c | 133 ---------------------------------- net/net_initialize.c | 33 +-------- sched/init/os_start.c | 21 +----- 8 files changed, 62 insertions(+), 351 deletions(-) delete mode 100644 net/arp/arp_timer.c diff --git a/include/nuttx/net/arp.h b/include/nuttx/net/arp.h index dc4f9ada61..cb935b500e 100644 --- a/include/nuttx/net/arp.h +++ b/include/nuttx/net/arp.h @@ -83,7 +83,7 @@ struct arp_entry_s { in_addr_t at_ipaddr; /* IP address */ struct ether_addr at_ethaddr; /* Hardware address */ - uint8_t at_time; /* Time of last usage */ + clock_t at_time; /* Time of last usage */ }; /* Used with the SIOCSARP, SIOCDARP, and SIOCGARP IOCTL commands to set, diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 92735b83dc..93358a2878 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -256,7 +256,7 @@ extern "C" ****************************************************************************/ /**************************************************************************** - * Name: net_setup + * Name: net_initialize * * Description: * This is called from the OS initialization logic at power-up reset in @@ -278,25 +278,6 @@ extern "C" * ****************************************************************************/ -void net_setup(void); - -/**************************************************************************** - * Name: net_initialize - * - * Description: - * This function is called from the OS initialization logic at power-up - * reset AFTER initialization of hardware facilities such as timers and - * interrupts. This logic completes the initialization started by - * net_setup(). - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ - void net_initialize(void); /**************************************************************************** diff --git a/net/arp/Make.defs b/net/arp/Make.defs index 36001d9957..e7c6b8b4eb 100644 --- a/net/arp/Make.defs +++ b/net/arp/Make.defs @@ -36,7 +36,7 @@ # ARP support is available for Ethernet only ifeq ($(CONFIG_NET_ARP),y) -NET_CSRCS += arp_arpin.c arp_out.c arp_format.c arp_table.c arp_timer.c +NET_CSRCS += arp_arpin.c arp_out.c arp_format.c arp_table.c ifeq ($(CONFIG_NET_ARP_IPIN),y) NET_CSRCS += arp_ipin.c diff --git a/net/arp/arp.h b/net/arp/arp.h index 9764e8ff78..b905c455c7 100644 --- a/net/arp/arp.h +++ b/net/arp/arp.h @@ -176,49 +176,6 @@ struct arp_notify_s ****************************************************************************/ #ifdef CONFIG_NET_ARP -/**************************************************************************** - * Name: arp_reset - * - * Description: - * Re-initialize the ARP table. - * - ****************************************************************************/ - -void arp_reset(void); - -/**************************************************************************** - * Name: arp_timer_initialize - * - * Description: - * Initialized the 10 second timer that is need by the ARP logic in order - * to age ARP address associations - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions: - * Called once at system initialization time - * - ****************************************************************************/ - -void arp_timer_initialize(void); - -/**************************************************************************** - * Name: arp_timer - * - * Description: - * This function performs periodic timer processing in the ARP module - * and should be called at regular intervals. The recommended interval - * is 10 seconds between the calls. It is responsible for flushing old - * entries in the ARP table. - * - ****************************************************************************/ - -void arp_timer(void); - /**************************************************************************** * Name: arp_format * @@ -492,9 +449,6 @@ void arp_dump(FAR struct arp_hdr_s *arp); /* If ARP is disabled, stub out all ARP interfaces */ -# define arp_reset() -# define arp_timer_initialize() -# define arp_timer() # define arp_format(d,i); # define arp_send(i) (0) # define arp_poll(d,c) (0) diff --git a/net/arp/arp_table.c b/net/arp/arp_table.c index 71ea8267b3..27b46c02a5 100644 --- a/net/arp/arp_table.c +++ b/net/arp/arp_table.c @@ -54,6 +54,7 @@ #include #include +#include #include #include #include @@ -65,6 +66,12 @@ #ifdef CONFIG_NET_ARP +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ARP_MAXAGE_TICK SEC2TICK(10 * CONFIG_NET_ARP_MAXAGE) + /**************************************************************************** * Private Types ****************************************************************************/ @@ -82,7 +89,6 @@ struct arp_table_info_s /* The table of known address mappings */ static struct arp_entry_s g_arptable[CONFIG_NET_ARPTAB_SIZE]; -static uint8_t g_arptime; /**************************************************************************** * Private Functions @@ -134,57 +140,40 @@ static int arp_match(FAR struct net_driver_s *dev, FAR void *arg) return 1; } + +/**************************************************************************** + * Name: arp_return_old_entry + * + * Description: + * Compare and return the old ARP table entry. + * + ****************************************************************************/ + +static FAR struct arp_entry_s * +arp_return_old_entry(FAR struct arp_entry_s *e1, FAR struct arp_entry_s *e2) +{ + if (e1->at_ipaddr == 0) + { + return e1; + } + else if (e2->at_ipaddr == 0) + { + return e2; + } + else if ((int)(e1->at_time - e2->at_time) <= 0) + { + return e1; + } + else + { + return e2; + } +} + /**************************************************************************** * Public Functions ****************************************************************************/ -/**************************************************************************** - * Name: arp_reset - * - * Description: - * Re-initialize the ARP table. - * - ****************************************************************************/ - -void arp_reset(void) -{ - int i; - - for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i) - { - memset(&g_arptable[i].at_ipaddr, 0, sizeof(in_addr_t)); - } -} - -/**************************************************************************** - * Name: arp_timer - * - * Description: - * This function performs periodic timer processing in the ARP module - * and should be called at regular intervals. The recommended interval - * is 10 seconds between the calls. It is responsible for flushing old - * entries in the ARP table. - * - ****************************************************************************/ - -void arp_timer(void) -{ - FAR struct arp_entry_s *tabptr; - int i; - - ++g_arptime; - for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i) - { - tabptr = &g_arptable[i]; - - if (tabptr->at_ipaddr != 0 && - g_arptime - tabptr->at_time >= CONFIG_NET_ARP_MAXAGE) - { - tabptr->at_ipaddr = 0; - } - } -} - /**************************************************************************** * Name: arp_update * @@ -207,8 +196,8 @@ void arp_timer(void) int arp_update(in_addr_t ipaddr, FAR uint8_t *ethaddr) { - struct arp_entry_s *tabptr = NULL; - int i; + FAR struct arp_entry_s *tabptr = &g_arptable[0]; + int i; /* Walk through the ARP mapping table and try to find an entry to * update. If none is found, the IP -> MAC address mapping is @@ -217,69 +206,33 @@ int arp_update(in_addr_t ipaddr, FAR uint8_t *ethaddr) for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i) { - tabptr = &g_arptable[i]; + /* Check if the source IP address of the incoming packet matches + * the IP address in this ARP table entry. + */ - /* Only check those entries that are actually in use. */ - - if (tabptr->at_ipaddr != 0) + if (g_arptable[i].at_ipaddr != 0 && + net_ipv4addr_cmp(ipaddr, g_arptable[i].at_ipaddr)) { - /* Check if the source IP address of the incoming packet matches - * the IP address in this ARP table entry. - */ + /* An old entry found, break. */ - if (net_ipv4addr_cmp(ipaddr, tabptr->at_ipaddr)) - { - /* An old entry found, update this and return. */ - - memcpy(tabptr->at_ethaddr.ether_addr_octet, ethaddr, ETHER_ADDR_LEN); - tabptr->at_time = g_arptime; - return OK; - } - } - } - - /* If we get here, no existing ARP table entry was found, so we create one. */ - /* First, we try to find an unused entry in the ARP table. */ - - for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i) - { - tabptr = &g_arptable[i]; - if (tabptr->at_ipaddr == 0) - { + tabptr = &g_arptable[i]; break; } - } - - /* If no unused entry is found, we try to find the oldest entry and - * throw it away. - */ - - if (i == CONFIG_NET_ARPTAB_SIZE) - { - uint8_t tmpage = 0; - int j = 0; - - for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i) + else { - tabptr = &g_arptable[i]; - if (g_arptime - tabptr->at_time > tmpage) - { - tmpage = g_arptime - tabptr->at_time; - j = i; - } - } + /* Record the oldest entry. */ - i = j; - tabptr = &g_arptable[i]; + tabptr = arp_return_old_entry(tabptr, &g_arptable[i]); + } } - /* Now, i is the ARP table entry which we will fill with the new + /* Now, tabptr is the ARP table entry which we will fill with the new * information. */ tabptr->at_ipaddr = ipaddr; memcpy(tabptr->at_ethaddr.ether_addr_octet, ethaddr, ETHER_ADDR_LEN); - tabptr->at_time = g_arptime; + tabptr->at_time = clock_systimer(); return OK; } @@ -337,7 +290,8 @@ FAR struct arp_entry_s *arp_lookup(in_addr_t ipaddr) for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i) { tabptr = &g_arptable[i]; - if (net_ipv4addr_cmp(ipaddr, tabptr->at_ipaddr)) + if (net_ipv4addr_cmp(ipaddr, tabptr->at_ipaddr) && + clock_systimer() - tabptr->at_time <= ARP_MAXAGE_TICK) { return tabptr; } @@ -442,3 +396,4 @@ void arp_delete(in_addr_t ipaddr) #endif /* CONFIG_NET_ARP */ #endif /* CONFIG_NET */ + diff --git a/net/arp/arp_timer.c b/net/arp/arp_timer.c deleted file mode 100644 index 010fa4db69..0000000000 --- a/net/arp/arp_timer.c +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** - * net/arp/arp_timer.c - * - * Copyright (C) 2007-2009, 2011, 2014 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#ifdef CONFIG_NET - -#include -#include -#include - -#include -#include - -#include - -#ifdef CONFIG_NET_ARP - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* ARP timer interval = 10 seconds. CLK_TCK is the number of clock ticks - * per second - */ - -#define ARPTIMER_WDINTERVAL (10*CLK_TCK) - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static WDOG_ID g_arptimer; /* ARP timer */ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: arptimer_poll - * - * Description: - * Periodic timer handler. Called from the timer interrupt handler. - * - * Input Parameters: - * argc - The number of available arguments - * arg - The first argument - * - * Returned Value: - * None - * - * Assumptions: - * - ****************************************************************************/ - -static void arptimer_poll(int argc, wdparm_t arg, ...) -{ - /* Call the ARP timer function every 10 seconds. */ - - arp_timer(); - - /* Setup the watchdog timer again */ - - (void)wd_start(g_arptimer, ARPTIMER_WDINTERVAL, arptimer_poll, 0); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: arp_timer_initialize - * - * Description: - * Initialized the 10 second timer that is need by the ARP logic in order - * to age ARP address associations - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions: - * Called once at system initialization time - * - ****************************************************************************/ - -void arp_timer_initialize(void) -{ - /* Create and start the ARP timer */ - - g_arptimer = wd_create(); - (void)wd_start(g_arptimer, ARPTIMER_WDINTERVAL, arptimer_poll, 0); -} - -#endif /* CONFIG_NET_ARP */ -#endif /* CONFIG_NET */ diff --git a/net/net_initialize.c b/net/net_initialize.c index 8cbcecaf08..348c63079e 100644 --- a/net/net_initialize.c +++ b/net/net_initialize.c @@ -49,7 +49,6 @@ #include "devif/devif.h" #include "netdev/netdev.h" #include "ipforward/ipforward.h" -#include "arp/arp.h" #include "sixlowpan/sixlowpan.h" #include "neighbor/neighbor.h" #include "icmp/icmp.h" @@ -72,7 +71,7 @@ ****************************************************************************/ /**************************************************************************** - * Name: net_setup + * Name: net_initialize * * Description: * This is called from the OS initialization logic at power-up reset in @@ -94,16 +93,12 @@ * ****************************************************************************/ -void net_setup(void) +void net_initialize(void) { /* Initialize the locking facility */ net_lockinitialize(); - /* Clear the ARP table */ - - arp_reset(); - #ifdef CONFIG_NET_IPv6 /* Initialize the Neighbor Table data structures */ @@ -219,28 +214,4 @@ void net_setup(void) #endif } -/**************************************************************************** - * Name: net_initialize - * - * Description: - * This function is called from the OS initialization logic at power-up - * reset AFTER initialization of hardware facilities such as timers and - * interrupts. This logic completes the initialization started by - * net_setup(). - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ - -void net_initialize(void) -{ - /* Initialize the periodic ARP timer */ - - arp_timer_initialize(); -} - #endif /* CONFIG_NET */ diff --git a/sched/init/os_start.c b/sched/init/os_start.c index e5a65ea997..d4a105b135 100644 --- a/sched/init/os_start.c +++ b/sched/init/os_start.c @@ -68,9 +68,6 @@ #ifndef CONFIG_DISABLE_PTHREAD # include "pthread/pthread.h" #endif -#ifdef CONFIG_SCHED_WORKQUEUE -# include "wqueue/wqueue.h" -#endif #include "clock/clock.h" #include "timer/timer.h" #include "irq/irq.h" @@ -694,15 +691,9 @@ void os_start(void) #endif #ifdef CONFIG_NET - /* Initialize the networking system. Network initialization is - * performed in two steps: (1) net_setup() initializes static - * configuration of the network support. This must be done prior - * to registering network drivers by up_initialize(). This step - * cannot require upon any hardware-depending features such as - * timers or interrupts. - */ + /* Initialize the networking system */ - net_setup(); + net_initialize(); #endif /* The processor specific details of running the operating system @@ -717,14 +708,6 @@ void os_start(void) g_os_initstate = OSINIT_HARDWARE; -#ifdef CONFIG_NET - /* Complete initialization the networking system now that interrupts - * and timers have been configured by up_initialize(). - */ - - net_initialize(); -#endif - #ifdef CONFIG_MM_SHM /* Initialize shared memory support */