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/nuttx.git

commit 8ef876562e8a2d83f297c033c385445daaf00e36
Author: zhanghongyu <[email protected]>
AuthorDate: Fri Jul 25 11:00:30 2025 +0800

    net/icmpv6: replace net_lock with conn_lock and conn_lock_dev
    
    Protect icmpv6 resources through netdev_lock, conn_lock, and 
icmpv6_list_lock
    
    Signed-off-by: zhanghongyu <[email protected]>
---
 .codespell-ignore-lines        |  1 +
 net/icmpv6/icmpv6_autoconfig.c | 24 +++++-------------------
 net/icmpv6/icmpv6_conn.c       |  1 +
 net/icmpv6/icmpv6_ioctl.c      |  5 +++--
 net/icmpv6/icmpv6_neighbor.c   |  4 ++--
 net/icmpv6/icmpv6_netpoll.c    | 25 ++++++++++++-------------
 net/icmpv6/icmpv6_recvmsg.c    |  5 ++---
 net/icmpv6/icmpv6_rnotify.c    |  4 ++--
 net/icmpv6/icmpv6_sendmsg.c    |  6 ++++--
 net/icmpv6/icmpv6_sockif.c     | 11 +++++++----
 10 files changed, 39 insertions(+), 47 deletions(-)

diff --git a/.codespell-ignore-lines b/.codespell-ignore-lines
index 4e1e8750889..b3cf3e346d2 100644
--- a/.codespell-ignore-lines
+++ b/.codespell-ignore-lines
@@ -177,3 +177,4 @@ libs/libc/tre-mem.c
             fs_ep, &fs_ep->sems, &fs_ep->reqq);
 #define RTPROT_RA                        9    /* RDISC/ND router 
advertisements */
   /* Followed by one or more ND options */
+   *    message using the Neighbor Discovery (ND) protocol. It then listens
diff --git a/net/icmpv6/icmpv6_autoconfig.c b/net/icmpv6/icmpv6_autoconfig.c
index 9856176a392..8a8fcd6f9c5 100644
--- a/net/icmpv6/icmpv6_autoconfig.c
+++ b/net/icmpv6/icmpv6_autoconfig.c
@@ -230,11 +230,13 @@ static int icmpv6_send_message(FAR struct net_driver_s 
*dev, bool advertise)
    * net_sem_wait will also terminate if a signal is received.
    */
 
+  netdev_unlock(dev);
   do
     {
       net_sem_wait(&state.snd_sem);
     }
   while (!state.snd_sent);
+  netdev_lock(dev);
 
   ret = state.snd_result;
   devif_dev_callback_free(dev, state.snd_cb);
@@ -271,6 +273,9 @@ errout_with_semaphore:
  *   Zero (OK) is returned on success; A negated errno value is returned on
  *   any failure.
  *
+ * Assumptions:
+ *   This function must be called with the network locked.
+ *
  ****************************************************************************/
 
 int icmpv6_autoconfig(FAR struct net_driver_s *dev)
@@ -285,22 +290,6 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
   DEBUGASSERT(dev);
   ninfo("Auto-configuring %s\n", dev->d_ifname);
 
-  /* Lock the network.
-   *
-   * NOTE:  Normally it is required that the network be in the "down" state
-   * when re-configuring the network interface.  This is thought not to be
-   * a problem here because.
-   *
-   *   1. The ICMPv6 logic here runs with the network locked so there can be
-   *      no outgoing packets with bad source IP addresses from any
-   *      asynchronous network activity using the device being reconfigured.
-   *   2. Incoming packets depend only upon the MAC filtering.  Network
-   *      drivers do not use the IP address; they filter incoming packets
-   *      using only the MAC address which is not being changed here.
-   */
-
-  net_lock();
-
   /* IPv6 Stateless Autoconfiguration
    * Reference:
    * http://www.tcpipguide.com/free/t_IPv6AutoconfigurationandRenumbering.htm
@@ -354,7 +343,6 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
 
           nerr("ERROR: IP conflict\n");
 
-          net_unlock();
           return -EEXIST;
         }
     }
@@ -369,7 +357,6 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
   ret = netdev_ipv6_add(dev, lladdr, net_ipv6_mask2pref(g_ipv6_llnetmask));
   if (ret < 0)
     {
-      net_unlock();
       return ret;
     }
 
@@ -463,7 +450,6 @@ got_lladdr:
 
   /* On success, the new address was already set (in icmpv_rnotify()). */
 
-  net_unlock();
   return ret;
 }
 
diff --git a/net/icmpv6/icmpv6_conn.c b/net/icmpv6/icmpv6_conn.c
index be4e3bbe36e..3cb6518b7de 100644
--- a/net/icmpv6/icmpv6_conn.c
+++ b/net/icmpv6/icmpv6_conn.c
@@ -125,6 +125,7 @@ void icmpv6_free(FAR struct icmpv6_conn_s *conn)
   /* Remove the connection from the active list */
 
   dq_rem(&conn->sconn.node, &g_active_icmpv6_connections);
+  nxmutex_destroy(&conn->sconn.s_lock);
 
   /* Free the connection. */
 
diff --git a/net/icmpv6/icmpv6_ioctl.c b/net/icmpv6/icmpv6_ioctl.c
index 588e9b92125..4df59448af7 100644
--- a/net/icmpv6/icmpv6_ioctl.c
+++ b/net/icmpv6/icmpv6_ioctl.c
@@ -38,6 +38,7 @@
 #include <nuttx/mm/iob.h>
 #include <nuttx/net/net.h>
 
+#include "utils/utils.h"
 #include "icmpv6/icmpv6.h"
 
 /****************************************************************************
@@ -62,7 +63,7 @@ int icmpv6_ioctl(FAR struct socket *psock, int cmd, unsigned 
long arg)
   FAR struct icmpv6_conn_s *conn = psock->s_conn;
   int ret = OK;
 
-  net_lock();
+  conn_lock(&conn->sconn);
 
   switch (cmd)
     {
@@ -91,7 +92,7 @@ int icmpv6_ioctl(FAR struct socket *psock, int cmd, unsigned 
long arg)
         break;
     }
 
-  net_unlock();
+  conn_unlock(&conn->sconn);
 
   return ret;
 }
diff --git a/net/icmpv6/icmpv6_neighbor.c b/net/icmpv6/icmpv6_neighbor.c
index be8e6827efb..991612463d2 100644
--- a/net/icmpv6/icmpv6_neighbor.c
+++ b/net/icmpv6/icmpv6_neighbor.c
@@ -272,7 +272,7 @@ int icmpv6_neighbor(FAR struct net_driver_s *dev,
    * want anything to happen until we are ready.
    */
 
-  net_lock();
+  netdev_lock(dev);
   state.snd_cb = devif_callback_alloc((dev),
                                       &(dev)->d_conncb,
                                       &(dev)->d_conncb_tail);
@@ -367,7 +367,7 @@ int icmpv6_neighbor(FAR struct net_driver_s *dev,
   devif_dev_callback_free(dev, state.snd_cb);
 
 errout_with_lock:
-  net_unlock();
+  netdev_unlock(dev);
 
 errout:
   return ret;
diff --git a/net/icmpv6/icmpv6_netpoll.c b/net/icmpv6/icmpv6_netpoll.c
index 3f2713b253c..a5984c459a9 100644
--- a/net/icmpv6/icmpv6_netpoll.c
+++ b/net/icmpv6/icmpv6_netpoll.c
@@ -36,6 +36,7 @@
 
 #include "devif/devif.h"
 #include "netdev/netdev.h"
+#include "utils/utils.h"
 #include "icmpv6/icmpv6.h"
 
 /****************************************************************************
@@ -144,20 +145,19 @@ int icmpv6_pollsetup(FAR struct socket *psock, FAR struct 
pollfd *fds)
   pollevent_t eventset = 0;
   int ret = OK;
 
-  /* Some of the following must be atomic */
-
-  net_lock();
-
   conn = psock->s_conn;
 
   /* Sanity check */
 
   if (!conn || !fds)
     {
-      ret = -EINVAL;
-      goto errout_with_lock;
+      return -EINVAL;
     }
 
+  /* Some of the following must be atomic */
+
+  conn_dev_lock(&conn->sconn, conn->dev);
+
   /* Find a container to hold the poll information */
 
   info = conn->pollinfo;
@@ -225,7 +225,7 @@ int icmpv6_pollsetup(FAR struct socket *psock, FAR struct 
pollfd *fds)
   poll_notify(&fds, 1, eventset);
 
 errout_with_lock:
-  net_unlock();
+  conn_dev_unlock(&conn->sconn, conn->dev);
   return ret;
 }
 
@@ -250,20 +250,19 @@ int icmpv6_pollteardown(FAR struct socket *psock, FAR 
struct pollfd *fds)
   FAR struct icmpv6_conn_s *conn;
   FAR struct icmpv6_poll_s *info;
 
-  /* Some of the following must be atomic */
-
-  net_lock();
-
   conn = psock->s_conn;
 
   /* Sanity check */
 
   if (!conn || !fds->priv)
     {
-      net_unlock();
       return -EINVAL;
     }
 
+  /* Some of the following must be atomic */
+
+  conn_dev_lock(&conn->sconn, conn->dev);
+
   /* Recover the socket descriptor poll state info from the poll structure */
 
   info = (FAR struct icmpv6_poll_s *)fds->priv;
@@ -284,7 +283,7 @@ int icmpv6_pollteardown(FAR struct socket *psock, FAR 
struct pollfd *fds)
       info->psock = NULL;
     }
 
-  net_unlock();
+  conn_dev_unlock(&conn->sconn, conn->dev);
 
   return OK;
 }
diff --git a/net/icmpv6/icmpv6_recvmsg.c b/net/icmpv6/icmpv6_recvmsg.c
index 5e8d0c328b9..d761fd3a49b 100644
--- a/net/icmpv6/icmpv6_recvmsg.c
+++ b/net/icmpv6/icmpv6_recvmsg.c
@@ -331,9 +331,8 @@ ssize_t icmpv6_recvmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
         }
     }
 
-  net_lock();
-
   conn = psock->s_conn;
+  conn_dev_lock(&conn->sconn, conn->dev);
   if (psock->s_type != SOCK_RAW)
     {
       /* Get the device that was used to send the ICMPv6 request. */
@@ -440,7 +439,7 @@ errout:
         }
     }
 
-  net_unlock();
+  conn_dev_unlock(&conn->sconn, conn->dev);
 
   return ret;
 }
diff --git a/net/icmpv6/icmpv6_rnotify.c b/net/icmpv6/icmpv6_rnotify.c
index 35ec5375891..2b8751c1060 100644
--- a/net/icmpv6/icmpv6_rnotify.c
+++ b/net/icmpv6/icmpv6_rnotify.c
@@ -98,7 +98,7 @@ void icmpv6_setaddresses(FAR struct net_driver_s *dev,
    *      using only the MAC address which is not being changed here.
    */
 
-  net_lock();
+  netdev_lock(dev);
 
   /* Create an address mask from the prefix */
 
@@ -152,7 +152,7 @@ void icmpv6_setaddresses(FAR struct net_driver_s *dev,
         NTOHS(dev->d_ipv6draddr[4]), NTOHS(dev->d_ipv6draddr[5]),
         NTOHS(dev->d_ipv6draddr[6]), NTOHS(dev->d_ipv6draddr[7]));
 
-  net_unlock();
+  netdev_unlock(dev);
 }
 
 /****************************************************************************
diff --git a/net/icmpv6/icmpv6_sendmsg.c b/net/icmpv6/icmpv6_sendmsg.c
index 10ac178cebb..fcab9fb80c5 100644
--- a/net/icmpv6/icmpv6_sendmsg.c
+++ b/net/icmpv6/icmpv6_sendmsg.c
@@ -377,7 +377,7 @@ ssize_t icmpv6_sendmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
   net_ipv6addr_copy(state.snd_toaddr.s6_addr16,
                     inaddr->sin6_addr.s6_addr16);
 
-  net_lock();
+  conn_dev_lock(&conn->sconn, dev);
 
   /* Set up the callback */
 
@@ -405,8 +405,10 @@ ssize_t icmpv6_sendmsg(FAR struct socket *psock, FAR 
struct msghdr *msg,
        * net_sem_timedwait will also terminate if a signal is received.
        */
 
+      conn_dev_unlock(&conn->sconn, dev);
       ret = net_sem_timedwait(&state.snd_sem,
                           _SO_TIMEOUT(conn->sconn.s_sndtimeo));
+      conn_dev_lock(&conn->sconn, dev);
       if (ret < 0)
         {
           if (ret == -ETIMEDOUT)
@@ -439,7 +441,7 @@ ssize_t icmpv6_sendmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
 
   nxsem_destroy(&state.snd_sem);
 
-  net_unlock();
+  conn_dev_unlock(&conn->sconn, dev);
 
   /* Return the negated error number in the event of a failure, or the
    * number of bytes sent on success.
diff --git a/net/icmpv6/icmpv6_sockif.c b/net/icmpv6/icmpv6_sockif.c
index dfe1a6a7aa1..1aef9dff2e9 100644
--- a/net/icmpv6/icmpv6_sockif.c
+++ b/net/icmpv6/icmpv6_sockif.c
@@ -40,6 +40,7 @@
 
 #include "icmpv6/icmpv6.h"
 #include "inet/inet.h"
+#include "utils/utils.h"
 
 #ifdef CONFIG_NET_ICMPv6_SOCKET
 
@@ -143,6 +144,8 @@ static int icmpv6_setup(FAR struct socket *psock)
           memset(&conn->filter, 0xff, sizeof(conn->filter));
         }
 
+      nxmutex_init(&conn->sconn.s_lock);
+
       /* Save the pre-allocated connection in the socket structure */
 
       psock->s_conn = conn;
@@ -322,7 +325,6 @@ static int icmpv6_getsockopt_internal(FAR struct socket 
*psock, int option,
       return -ENOPROTOOPT;
     }
 
-  net_lock();
   switch (option)
     {
       case ICMP6_FILTER:
@@ -334,7 +336,9 @@ static int icmpv6_getsockopt_internal(FAR struct socket 
*psock, int option,
               *value_len = sizeof(struct icmp6_filter);
             }
 
+          conn_lock(&conn->sconn);
           memcpy(value, &conn->filter, *value_len);
+          conn_unlock(&conn->sconn);
           ret = OK;
         }
         break;
@@ -345,7 +349,6 @@ static int icmpv6_getsockopt_internal(FAR struct socket 
*psock, int option,
         break;
     }
 
-  net_unlock();
   return ret;
 }
 
@@ -430,7 +433,6 @@ static int icmpv6_setsockopt_internal(FAR struct socket 
*psock, int option,
       return -ENOPROTOOPT;
     }
 
-  net_lock();
   switch (option)
     {
       case ICMP6_FILTER:
@@ -442,7 +444,9 @@ static int icmpv6_setsockopt_internal(FAR struct socket 
*psock, int option,
               value_len = sizeof(struct icmp6_filter);
             }
 
+          conn_lock(&conn->sconn);
           memcpy(&conn->filter, value, value_len);
+          conn_unlock(&conn->sconn);
           ret = OK;
         }
         break;
@@ -453,7 +457,6 @@ static int icmpv6_setsockopt_internal(FAR struct socket 
*psock, int option,
         break;
     }
 
-  net_unlock();
   return ret;
 }
 

Reply via email to