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; }
