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 <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu
2025-07-25 11:00:30 +08:00
committed by Xiang Xiao
parent 5032377c34
commit 8ef876562e
10 changed files with 39 additions and 47 deletions
+1
View File
@@ -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
+5 -19
View File
@@ -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;
}
+1
View File
@@ -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. */
+3 -2
View File
@@ -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;
}
+2 -2
View File
@@ -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;
+12 -13
View File
@@ -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;
}
+2 -3
View File
@@ -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;
}
+2 -2
View File
@@ -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);
}
/****************************************************************************
+4 -2
View File
@@ -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.
+7 -4
View File
@@ -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;
}