From 22560958bc5c670faaa7366ab2d8f86d251c1026 Mon Sep 17 00:00:00 2001 From: nuttxs Date: Mon, 7 Jul 2025 16:02:11 +0800 Subject: [PATCH] net/arp: reducing unnecessary ARP requests can mitigate network congestion and avoid packet delays caused by waiting for ARP responses Signed-off-by: nuttxs --- net/arp/arp.h | 4 ++-- net/arp/arp_out.c | 2 +- net/arp/arp_send.c | 2 +- net/arp/arp_table.c | 30 +++++++++++++++++++++++------- net/netdev/netdev_findbyaddr.c | 3 ++- net/netdev/netdev_ioctl.c | 2 +- 6 files changed, 30 insertions(+), 13 deletions(-) diff --git a/net/arp/arp.h b/net/arp/arp.h index fed80f1696..1c4d44849c 100644 --- a/net/arp/arp.h +++ b/net/arp/arp.h @@ -425,7 +425,7 @@ void arp_notify(in_addr_t ipaddr); struct ether_addr; /* Forward reference */ int arp_find(in_addr_t ipaddr, FAR uint8_t *ethaddr, - FAR struct net_driver_s *dev); + FAR struct net_driver_s *dev, bool check_expiry); /**************************************************************************** * Name: arp_delete @@ -620,7 +620,7 @@ void arp_acd_setup(FAR struct net_driver_s *dev); # define arp_wait_cancel(n) (0) # define arp_wait(n,t) (0) # define arp_notify(i) -# define arp_find(i,e,d) (-ENOSYS) +# define arp_find(i,e,d,u) (-ENOSYS) # define arp_delete(i,d) (-ENOSYS) # define arp_cleanup(d) # define arp_update(d,i,m); diff --git a/net/arp/arp_out.c b/net/arp/arp_out.c index a5add3199a..ffb3370660 100644 --- a/net/arp/arp_out.c +++ b/net/arp/arp_out.c @@ -262,7 +262,7 @@ void arp_out(FAR struct net_driver_s *dev) /* Check if we already have this destination address in the ARP table */ - ret = arp_find(ipaddr, ethaddr.ether_addr_octet, dev); + ret = arp_find(ipaddr, ethaddr.ether_addr_octet, dev, false); if (ret < 0) { ninfo("ARP request for IP %08lx\n", (unsigned long)ipaddr); diff --git a/net/arp/arp_send.c b/net/arp/arp_send.c index 803292a338..625e04c869 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -314,7 +314,7 @@ int arp_send(in_addr_t ipaddr) * issue. */ - ret = arp_find(ipaddr, NULL, dev); + ret = arp_find(ipaddr, NULL, dev, true); if (ret >= 0) { /* We have it! Break out with success */ diff --git a/net/arp/arp_table.c b/net/arp/arp_table.c index fb977f92ee..fbee886e51 100644 --- a/net/arp/arp_table.c +++ b/net/arp/arp_table.c @@ -186,6 +186,7 @@ arp_return_old_entry(FAR struct arp_entry_s *e1, FAR struct arp_entry_s *e2) * Input Parameters: * ipaddr - Refers to an IP address in network order * dev - Device structure + * check_expiry - Expiry check * * Assumptions: * The network is locked to assure exclusive access to the ARP table. @@ -194,7 +195,8 @@ arp_return_old_entry(FAR struct arp_entry_s *e1, FAR struct arp_entry_s *e2) ****************************************************************************/ static FAR struct arp_entry_s *arp_lookup(in_addr_t ipaddr, - FAR struct net_driver_s *dev) + FAR struct net_driver_s *dev, + bool check_expiry) { FAR struct arp_entry_s *tabptr; int i; @@ -205,10 +207,23 @@ static FAR struct arp_entry_s *arp_lookup(in_addr_t ipaddr, { tabptr = &g_arptable[i]; if (tabptr->at_dev == dev && - net_ipv4addr_cmp(ipaddr, tabptr->at_ipaddr) && - clock_systime_ticks() - tabptr->at_time <= ARP_MAXAGE_TICK) + net_ipv4addr_cmp(ipaddr, tabptr->at_ipaddr)) { - return tabptr; + /* Find matching entries */ + + if (!check_expiry) + { + return tabptr; /* Ignore expiration time */ + } + + /* Check if it has expired */ + + if (clock_systime_ticks() - tabptr->at_time <= ARP_MAXAGE_TICK) + { + return tabptr; + } + + return NULL; /* Expired */ } } @@ -401,6 +416,7 @@ void arp_hdr_update(FAR struct net_driver_s *dev, FAR uint16_t *pipaddr, * used simply to determine if the Ethernet MAC address is * available. * dev - Device structure + * check_expiry - Expiry check * * Assumptions * The network is locked to assure exclusive access to the ARP table. @@ -408,14 +424,14 @@ void arp_hdr_update(FAR struct net_driver_s *dev, FAR uint16_t *pipaddr, ****************************************************************************/ int arp_find(in_addr_t ipaddr, FAR uint8_t *ethaddr, - FAR struct net_driver_s *dev) + FAR struct net_driver_s *dev, bool check_expiry) { FAR struct arp_entry_s *tabptr; struct arp_table_info_s info; /* Check if the IPv4 address is already in the ARP table. */ - tabptr = arp_lookup(ipaddr, dev); + tabptr = arp_lookup(ipaddr, dev, check_expiry); if (tabptr != NULL) { /* Addresses that have failed to be searched will return a special @@ -485,7 +501,7 @@ int arp_delete(in_addr_t ipaddr, FAR struct net_driver_s *dev) #endif /* Check if the IPv4 address is in the ARP table. */ - tabptr = arp_lookup(ipaddr, dev); + tabptr = arp_lookup(ipaddr, dev, false); if (tabptr != NULL) { /* Notify to netlink */ diff --git a/net/netdev/netdev_findbyaddr.c b/net/netdev/netdev_findbyaddr.c index 88143b721a..98f01260b4 100644 --- a/net/netdev/netdev_findbyaddr.c +++ b/net/netdev/netdev_findbyaddr.c @@ -128,7 +128,8 @@ netdev_prefixlen_findby_lipv4addr(in_addr_t lipaddr, FAR int8_t *prefixlen) if (len > bestpref #ifdef CONFIG_NET_ARP - || (len == bestpref && arp_find(lipaddr, NULL, dev) == OK) + || (len == bestpref + && arp_find(lipaddr, NULL, dev, true) == OK) #endif ) { diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index d4ab1a956a..134f5b10bf 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -1452,7 +1452,7 @@ static int netdev_arp_ioctl(FAR struct socket *psock, int cmd, req->arp_pa.sa_family == AF_INET) { ret = arp_find(addr->sin_addr.s_addr, - (FAR uint8_t *)req->arp_ha.sa_data, dev); + (FAR uint8_t *)req->arp_ha.sa_data, dev, true); if (ret >= 0) { /* Return the mapped hardware address. */