ip6mr: ip6mr_sk_done() can exit early in common cases
authorEric Dumazet <edumazet@google.com>
Fri, 4 Feb 2022 20:15:46 +0000 (12:15 -0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 5 Feb 2022 15:20:34 +0000 (15:20 +0000)
In many cases, ip6mr_sk_done() is called while no ipmr socket
has been registered.

This removes 4 rtnl acquisitions per netns dismantle,
with following callers:

igmp6_net_exit(), tcpv6_net_exit(), ndisc_net_exit()

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/ip6mr.c

index 541cd08871293eb5702e47e0645ea16394621e97..8e483e14b5709b1b8a6e9dfd6616a5bde5c273ee 100644 (file)
@@ -1575,6 +1575,9 @@ int ip6mr_sk_done(struct sock *sk)
            inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
                return err;
 
+       if (!atomic_read(&net->ipv6.devconf_all->mc_forwarding))
+               return err;
+
        rtnl_lock();
        ip6mr_for_each_table(mrt, net) {
                if (sk == rtnl_dereference(mrt->mroute_sk)) {