net/arp: Redesign ARP table aging to simplify the net initialization
This commit is contained in:
parent
9d09b5aad7
commit
43706cd797
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <net/ethernet.h>
|
||||
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/net/netconfig.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
@ -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 */
|
||||
|
||||
|
@ -1,133 +0,0 @@
|
||||
/****************************************************************************
|
||||
* net/arp/arp_timer.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011, 2014 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>
|
||||
#ifdef CONFIG_NET
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/net/netconfig.h>
|
||||
|
||||
#include <arp/arp.h>
|
||||
|
||||
#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 */
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user