mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
ipv6: mcast: Don't hold RTNL in ipv6_sock_mc_close().
In __ipv6_sock_mc_close(), per-socket mld data is protected by lock_sock(), and only __dev_get_by_index() and __in6_dev_get() require RTNL. Let's call __ipv6_sock_mc_drop() and drop RTNL in ipv6_sock_mc_close(). Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20250702230210.3115355-9-kuni1840@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
2ceb71ce7d
commit
1e589db389
@ -334,28 +334,10 @@ void __ipv6_sock_mc_close(struct sock *sk)
|
|||||||
{
|
{
|
||||||
struct ipv6_pinfo *np = inet6_sk(sk);
|
struct ipv6_pinfo *np = inet6_sk(sk);
|
||||||
struct ipv6_mc_socklist *mc_lst;
|
struct ipv6_mc_socklist *mc_lst;
|
||||||
struct net *net = sock_net(sk);
|
|
||||||
|
|
||||||
ASSERT_RTNL();
|
|
||||||
|
|
||||||
while ((mc_lst = sock_dereference(np->ipv6_mc_list, sk)) != NULL) {
|
while ((mc_lst = sock_dereference(np->ipv6_mc_list, sk)) != NULL) {
|
||||||
struct net_device *dev;
|
|
||||||
|
|
||||||
np->ipv6_mc_list = mc_lst->next;
|
np->ipv6_mc_list = mc_lst->next;
|
||||||
|
__ipv6_sock_mc_drop(sk, mc_lst);
|
||||||
dev = __dev_get_by_index(net, mc_lst->ifindex);
|
|
||||||
if (dev) {
|
|
||||||
struct inet6_dev *idev = __in6_dev_get(dev);
|
|
||||||
|
|
||||||
ip6_mc_leave_src(sk, mc_lst, idev);
|
|
||||||
if (idev)
|
|
||||||
__ipv6_dev_mc_dec(idev, &mc_lst->addr);
|
|
||||||
} else {
|
|
||||||
ip6_mc_leave_src(sk, mc_lst, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
|
|
||||||
kfree_rcu(mc_lst, rcu);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,11 +348,9 @@ void ipv6_sock_mc_close(struct sock *sk)
|
|||||||
if (!rcu_access_pointer(np->ipv6_mc_list))
|
if (!rcu_access_pointer(np->ipv6_mc_list))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
__ipv6_sock_mc_close(sk);
|
__ipv6_sock_mc_close(sk);
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
rtnl_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ip6_mc_source(int add, int omode, struct sock *sk,
|
int ip6_mc_source(int add, int omode, struct sock *sk,
|
||||||
|
Loading…
Reference in New Issue
Block a user