]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ipv6: mcast: Don't hold RTNL in ipv6_sock_mc_close().
authorKuniyuki Iwashima <kuniyu@google.com>
Wed, 2 Jul 2025 23:01:25 +0000 (16:01 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 9 Jul 2025 01:32:38 +0000 (18:32 -0700)
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>
net/ipv6/mcast.c

index ed40f5b132ae2e220ee07dc0100b2be70889cc85..5c5f69f23d4a2a7910e77006aec4ecf7ccfd50ba 100644 (file)
@@ -334,28 +334,10 @@ void __ipv6_sock_mc_close(struct sock *sk)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
        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) {
-               struct net_device *dev;
-
                np->ipv6_mc_list = mc_lst->next;
-
-               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);
+               __ipv6_sock_mc_drop(sk, mc_lst);
        }
 }
 
@@ -366,11 +348,9 @@ void ipv6_sock_mc_close(struct sock *sk)
        if (!rcu_access_pointer(np->ipv6_mc_list))
                return;
 
-       rtnl_lock();
        lock_sock(sk);
        __ipv6_sock_mc_close(sk);
        release_sock(sk);
-       rtnl_unlock();
 }
 
 int ip6_mc_source(int add, int omode, struct sock *sk,