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
             {