You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/11/27 12:19:57 UTC
[incubator-nuttx] branch master updated: net/arp: clean the arp table when netdev carrier off
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 22df553 net/arp: clean the arp table when netdev carrier off
22df553 is described below
commit 22df5534437fd6f2f95e75c032d2bbfe976c3adf
Author: songlinzhang <so...@xiaomi.com>
AuthorDate: Thu Nov 18 13:29:25 2021 +0800
net/arp: clean the arp table when netdev carrier off
Fix the arp address changed if netdev renew, since the
arp table should be cleared when the netdev carrier off
Signed-off-by: songlinzhang <so...@xiaomi.com>
---
include/nuttx/net/arp.h | 7 ++++---
net/arp/arp.h | 29 +++++++++++++++++++++++++----
net/arp/arp_arpin.c | 4 ++--
net/arp/arp_ipin.c | 2 +-
net/arp/arp_table.c | 38 +++++++++++++++++++++++++++++++++++---
net/netdev/netdev_carrier.c | 2 ++
net/netdev/netdev_ioctl.c | 40 +++++++++++++++++++++++++++++++++++-----
7 files changed, 104 insertions(+), 18 deletions(-)
diff --git a/include/nuttx/net/arp.h b/include/nuttx/net/arp.h
index 920a636..df58a27 100644
--- a/include/nuttx/net/arp.h
+++ b/include/nuttx/net/arp.h
@@ -82,9 +82,10 @@
struct arp_entry_s
{
- in_addr_t at_ipaddr; /* IP address */
- struct ether_addr at_ethaddr; /* Hardware address */
- clock_t at_time; /* Time of last usage */
+ in_addr_t at_ipaddr; /* IP address */
+ struct ether_addr at_ethaddr; /* Hardware address */
+ clock_t at_time; /* Time of last usage */
+ FAR struct net_driver_s *at_dev; /* The device driver structure */
};
/****************************************************************************
diff --git a/net/arp/arp.h b/net/arp/arp.h
index e0aec9f..a30c900 100644
--- a/net/arp/arp.h
+++ b/net/arp/arp.h
@@ -359,6 +359,22 @@ int arp_find(in_addr_t ipaddr, FAR struct ether_addr *ethaddr);
void arp_delete(in_addr_t ipaddr);
/****************************************************************************
+ * Name: arp_cleanup
+ *
+ * Description:
+ * Clear the ARP table on the network device
+ *
+ * Input Parameters:
+ * dev - The device driver structure
+ *
+ * Assumptions
+ * The network is locked to assure exclusive access to the ARP table.
+ *
+ ****************************************************************************/
+
+void arp_cleanup(FAR struct net_driver_s *dev);
+
+/****************************************************************************
* Name: arp_update
*
* Description:
@@ -366,6 +382,7 @@ void arp_delete(in_addr_t ipaddr);
* address of an existing association.
*
* Input Parameters:
+ * dev - The device driver structure
* ipaddr - The IP address as an inaddr_t
* ethaddr - Refers to a HW address uint8_t[IFHWADDRLEN]
*
@@ -378,7 +395,8 @@ void arp_delete(in_addr_t ipaddr);
*
****************************************************************************/
-int arp_update(in_addr_t ipaddr, FAR uint8_t *ethaddr);
+int arp_update(FAR struct net_driver_s *dev, in_addr_t ipaddr,
+ FAR uint8_t *ethaddr);
/****************************************************************************
* Name: arp_hdr_update
@@ -388,6 +406,7 @@ int arp_update(in_addr_t ipaddr, FAR uint8_t *ethaddr);
* address of an existing association.
*
* Input Parameters:
+ * dev - The device driver structure
* pipaddr - Refers to an IP address uint16_t[2] in network order
* ethaddr - Refers to a HW address uint8_t[IFHWADDRLEN]
*
@@ -400,7 +419,8 @@ int arp_update(in_addr_t ipaddr, FAR uint8_t *ethaddr);
*
****************************************************************************/
-void arp_hdr_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr);
+void arp_hdr_update(FAR struct net_driver_s *dev, FAR uint16_t *pipaddr,
+ FAR uint8_t *ethaddr);
/****************************************************************************
* Name: arp_snapshot
@@ -462,8 +482,9 @@ void arp_dump(FAR struct arp_hdr_s *arp);
# define arp_notify(i)
# define arp_find(i,e) (-ENOSYS)
# define arp_delete(i)
-# define arp_update(i,m);
-# define arp_hdr_update(i,m);
+# define arp_cleanup(d)
+# define arp_update(d,i,m);
+# define arp_hdr_update(d,i,m);
# define arp_snapshot(s,n) (0)
# define arp_dump(arp)
diff --git a/net/arp/arp_arpin.c b/net/arp/arp_arpin.c
index 0084137..12f8760 100644
--- a/net/arp/arp_arpin.c
+++ b/net/arp/arp_arpin.c
@@ -121,7 +121,7 @@ void arp_arpin(FAR struct net_driver_s *dev)
* with this host in the future.
*/
- arp_hdr_update(arp->ah_sipaddr, arp->ah_shwaddr);
+ arp_hdr_update(dev, arp->ah_sipaddr, arp->ah_shwaddr);
arp->ah_opcode = HTONS(ARP_REPLY);
memcpy(arp->ah_dhwaddr, arp->ah_shwaddr, ETHER_ADDR_LEN);
@@ -152,7 +152,7 @@ void arp_arpin(FAR struct net_driver_s *dev)
{
/* Yes... Insert the address mapping in the ARP table */
- arp_hdr_update(arp->ah_sipaddr, arp->ah_shwaddr);
+ arp_hdr_update(dev, arp->ah_sipaddr, arp->ah_shwaddr);
/* Then notify any logic waiting for the ARP result */
diff --git a/net/arp/arp_ipin.c b/net/arp/arp_ipin.c
index 3f562f9..f3be022 100644
--- a/net/arp/arp_ipin.c
+++ b/net/arp/arp_ipin.c
@@ -90,7 +90,7 @@ void arp_ipin(FAR struct net_driver_s *dev)
srcipaddr = net_ip4addr_conv32(IPBUF->eh_srcipaddr);
if (net_ipv4addr_maskcmp(srcipaddr, dev->d_ipaddr, dev->d_netmask))
{
- arp_hdr_update(IPBUF->eh_srcipaddr, ETHBUF->src);
+ arp_hdr_update(dev, IPBUF->eh_srcipaddr, ETHBUF->src);
}
}
diff --git a/net/arp/arp_table.c b/net/arp/arp_table.c
index 06437c7..b26534e 100644
--- a/net/arp/arp_table.c
+++ b/net/arp/arp_table.c
@@ -181,6 +181,7 @@ arp_return_old_entry(FAR struct arp_entry_s *e1, FAR struct arp_entry_s *e2)
* address of an existing association.
*
* Input Parameters:
+ * dev - The device driver structure
* ipaddr - The IP address as an inaddr_t
* ethaddr - Refers to a HW address uint8_t[IFHWADDRLEN]
*
@@ -193,7 +194,8 @@ arp_return_old_entry(FAR struct arp_entry_s *e1, FAR struct arp_entry_s *e2)
*
****************************************************************************/
-int arp_update(in_addr_t ipaddr, FAR uint8_t *ethaddr)
+int arp_update(FAR struct net_driver_s *dev, in_addr_t ipaddr,
+ FAR uint8_t *ethaddr)
{
FAR struct arp_entry_s *tabptr = &g_arptable[0];
int i;
@@ -231,6 +233,7 @@ int arp_update(in_addr_t ipaddr, FAR uint8_t *ethaddr)
tabptr->at_ipaddr = ipaddr;
memcpy(tabptr->at_ethaddr.ether_addr_octet, ethaddr, ETHER_ADDR_LEN);
+ tabptr->at_dev = dev;
tabptr->at_time = clock_systime_ticks();
return OK;
}
@@ -243,6 +246,7 @@ int arp_update(in_addr_t ipaddr, FAR uint8_t *ethaddr)
* address of an existing association.
*
* Input Parameters:
+ * dev - The device driver structure
* pipaddr - Refers to an IP address uint16_t[2] in network order
* ethaddr - Refers to a HW address uint8_t[IFHWADDRLEN]
*
@@ -255,13 +259,14 @@ int arp_update(in_addr_t ipaddr, FAR uint8_t *ethaddr)
*
****************************************************************************/
-void arp_hdr_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr)
+void arp_hdr_update(FAR struct net_driver_s *dev, FAR uint16_t *pipaddr,
+ FAR uint8_t *ethaddr)
{
in_addr_t ipaddr = net_ip4addr_conv32(pipaddr);
/* Update the ARP table */
- arp_update(ipaddr, ethaddr);
+ arp_update(dev, ipaddr, ethaddr);
}
/****************************************************************************
@@ -394,6 +399,33 @@ void arp_delete(in_addr_t ipaddr)
}
/****************************************************************************
+ * Name: arp_cleanup
+ *
+ * Description:
+ * Clear the ARP table on the network device
+ *
+ * Input Parameters:
+ * dev - The device driver structure
+ *
+ * Assumptions
+ * The network is locked to assure exclusive access to the ARP table.
+ *
+ ****************************************************************************/
+
+void arp_cleanup(FAR struct net_driver_s *dev)
+{
+ int i;
+
+ for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i)
+ {
+ if (dev == g_arptable[i].at_dev)
+ {
+ memset(&g_arptable[i], 0, sizeof(g_arptable[i]));
+ }
+ }
+}
+
+/****************************************************************************
* Name: arp_snapshot
*
* Description:
diff --git a/net/netdev/netdev_carrier.c b/net/netdev/netdev_carrier.c
index a6bfb86..fe08764 100644
--- a/net/netdev/netdev_carrier.c
+++ b/net/netdev/netdev_carrier.c
@@ -37,6 +37,7 @@
#include "netdev/netdev.h"
#include "netlink/netlink.h"
+#include "arp/arp.h"
/****************************************************************************
* Public Functions
@@ -94,6 +95,7 @@ int netdev_carrier_off(FAR struct net_driver_s *dev)
/* Notify clients that the network has been taken down */
devif_dev_event(dev, NULL, NETDEV_DOWN);
+ arp_cleanup(dev);
return OK;
}
diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c
index 1189b55..764b1e5 100644
--- a/net/netdev/netdev_ioctl.c
+++ b/net/netdev/netdev_ioctl.c
@@ -1223,6 +1223,40 @@ static int netdev_imsf_ioctl(FAR struct socket *psock, int cmd,
#endif
/****************************************************************************
+ * Name: netdev_arp_callback
+ *
+ * Description:
+ * This is a callback that checks if the Ethernet network device has the
+ * indicated name
+ *
+ * Input Parameters:
+ * dev Ethernet driver device structure
+ * req The argument of the ioctl cmd
+ *
+ * Returned Value:
+ * 1 on success
+ * 0 on error
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_ARP
+static int netdev_arp_callback(FAR struct net_driver_s *dev, FAR void *arg)
+{
+ FAR struct arpreq *req = arg;
+ FAR struct sockaddr_in *addr = (FAR struct sockaddr_in *)&req->arp_pa;
+
+ if (strncmp(dev->d_ifname, (FAR const char *)req->arp_dev,
+ sizeof(dev->d_ifname)))
+ {
+ return 0;
+ }
+
+ arp_update(dev, addr->sin_addr.s_addr,
+ (FAR uint8_t *)req->arp_ha.sa_data);
+ return 1;
+}
+#endif
+
+/****************************************************************************
* Name: netdev_arp_ioctl
*
* Description:
@@ -1256,15 +1290,11 @@ static int netdev_arp_ioctl(FAR struct socket *psock, int cmd,
req->arp_pa.sa_family == AF_INET &&
req->arp_ha.sa_family == ARPHRD_ETHER)
{
- FAR struct sockaddr_in *addr =
- (FAR struct sockaddr_in *)&req->arp_pa;
-
/* Update any existing ARP table entry for this protocol
* address -OR- add a new ARP table entry if there is not.
*/
- ret = arp_update(addr->sin_addr.s_addr,
- (FAR uint8_t *)req->arp_ha.sa_data);
+ ret = netdev_foreach(netdev_arp_callback, req) ? OK : -EINVAL;
}
else
{