mirror of
https://github.com/apache/nuttx.git
synced 2026-05-18 00:34:10 +08:00
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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user