]> www.infradead.org Git - users/willy/pagecache.git/commitdiff
ipv6: Convert net.ipv6.conf.${DEV}.XXX sysctl to per-netns RTNL.
authorKuniyuki Iwashima <kuniyu@amazon.com>
Wed, 15 Jan 2025 08:05:59 +0000 (17:05 +0900)
committerJakub Kicinski <kuba@kernel.org>
Mon, 20 Jan 2025 20:16:04 +0000 (12:16 -0800)
net.ipv6.conf.${DEV}.XXX sysctl are changed under RTNL:

  * forwarding
  * ignore_routes_with_linkdown
  * disable_ipv6
  * proxy_ndp
  * addr_gen_mode
  * stable_secret
  * disable_policy

Let's use rtnl_net_lock() there.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250115080608.28127-3-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ipv6/addrconf.c

index c3729382be3bd4c2d680f21201fdf1b86c72817c..fb0ef98c79b015c30b5787c4302c25a3735af4bd 100644 (file)
@@ -852,7 +852,7 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
        struct inet6_dev *idev;
 
        for_each_netdev(net, dev) {
-               idev = __in6_dev_get(dev);
+               idev = __in6_dev_get_rtnl_net(dev);
                if (idev) {
                        int changed = (!idev->cnf.forwarding) ^ (!newf);
 
@@ -865,13 +865,12 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
 
 static int addrconf_fixup_forwarding(const struct ctl_table *table, int *p, int newf)
 {
-       struct net *net;
+       struct net *net = (struct net *)table->extra2;
        int old;
 
-       if (!rtnl_trylock())
+       if (!rtnl_net_trylock(net))
                return restart_syscall();
 
-       net = (struct net *)table->extra2;
        old = *p;
        WRITE_ONCE(*p, newf);
 
@@ -881,7 +880,7 @@ static int addrconf_fixup_forwarding(const struct ctl_table *table, int *p, int
                                                     NETCONFA_FORWARDING,
                                                     NETCONFA_IFINDEX_DEFAULT,
                                                     net->ipv6.devconf_dflt);
-               rtnl_unlock();
+               rtnl_net_unlock(net);
                return 0;
        }
 
@@ -903,7 +902,7 @@ static int addrconf_fixup_forwarding(const struct ctl_table *table, int *p, int
                                                     net->ipv6.devconf_all);
        } else if ((!newf) ^ (!old))
                dev_forward_change((struct inet6_dev *)table->extra1);
-       rtnl_unlock();
+       rtnl_net_unlock(net);
 
        if (newf)
                rt6_purge_dflt_routers(net);
@@ -916,7 +915,7 @@ static void addrconf_linkdown_change(struct net *net, __s32 newf)
        struct inet6_dev *idev;
 
        for_each_netdev(net, dev) {
-               idev = __in6_dev_get(dev);
+               idev = __in6_dev_get_rtnl_net(dev);
                if (idev) {
                        int changed = (!idev->cnf.ignore_routes_with_linkdown) ^ (!newf);
 
@@ -933,13 +932,12 @@ static void addrconf_linkdown_change(struct net *net, __s32 newf)
 
 static int addrconf_fixup_linkdown(const struct ctl_table *table, int *p, int newf)
 {
-       struct net *net;
+       struct net *net = (struct net *)table->extra2;
        int old;
 
-       if (!rtnl_trylock())
+       if (!rtnl_net_trylock(net))
                return restart_syscall();
 
-       net = (struct net *)table->extra2;
        old = *p;
        WRITE_ONCE(*p, newf);
 
@@ -950,7 +948,7 @@ static int addrconf_fixup_linkdown(const struct ctl_table *table, int *p, int ne
                                                     NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
                                                     NETCONFA_IFINDEX_DEFAULT,
                                                     net->ipv6.devconf_dflt);
-               rtnl_unlock();
+               rtnl_net_unlock(net);
                return 0;
        }
 
@@ -964,7 +962,8 @@ static int addrconf_fixup_linkdown(const struct ctl_table *table, int *p, int ne
                                                     NETCONFA_IFINDEX_ALL,
                                                     net->ipv6.devconf_all);
        }
-       rtnl_unlock();
+
+       rtnl_net_unlock(net);
 
        return 1;
 }
@@ -6370,7 +6369,7 @@ static void addrconf_disable_change(struct net *net, __s32 newf)
        struct inet6_dev *idev;
 
        for_each_netdev(net, dev) {
-               idev = __in6_dev_get(dev);
+               idev = __in6_dev_get_rtnl_net(dev);
                if (idev) {
                        int changed = (!idev->cnf.disable_ipv6) ^ (!newf);
 
@@ -6391,7 +6390,7 @@ static int addrconf_disable_ipv6(const struct ctl_table *table, int *p, int newf
                return 0;
        }
 
-       if (!rtnl_trylock())
+       if (!rtnl_net_trylock(net))
                return restart_syscall();
 
        old = *p;
@@ -6400,10 +6399,11 @@ static int addrconf_disable_ipv6(const struct ctl_table *table, int *p, int newf
        if (p == &net->ipv6.devconf_all->disable_ipv6) {
                WRITE_ONCE(net->ipv6.devconf_dflt->disable_ipv6, newf);
                addrconf_disable_change(net, newf);
-       } else if ((!newf) ^ (!old))
+       } else if ((!newf) ^ (!old)) {
                dev_disable_change((struct inet6_dev *)table->extra1);
+       }
 
-       rtnl_unlock();
+       rtnl_net_unlock(net);
        return 0;
 }
 
@@ -6446,20 +6446,20 @@ static int addrconf_sysctl_proxy_ndp(const struct ctl_table *ctl, int write,
        if (write && old != new) {
                struct net *net = ctl->extra2;
 
-               if (!rtnl_trylock())
+               if (!rtnl_net_trylock(net))
                        return restart_syscall();
 
-               if (valp == &net->ipv6.devconf_dflt->proxy_ndp)
+               if (valp == &net->ipv6.devconf_dflt->proxy_ndp) {
                        inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
                                                     NETCONFA_PROXY_NEIGH,
                                                     NETCONFA_IFINDEX_DEFAULT,
                                                     net->ipv6.devconf_dflt);
-               else if (valp == &net->ipv6.devconf_all->proxy_ndp)
+               } else if (valp == &net->ipv6.devconf_all->proxy_ndp) {
                        inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
                                                     NETCONFA_PROXY_NEIGH,
                                                     NETCONFA_IFINDEX_ALL,
                                                     net->ipv6.devconf_all);
-               else {
+               else {
                        struct inet6_dev *idev = ctl->extra1;
 
                        inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
@@ -6467,7 +6467,7 @@ static int addrconf_sysctl_proxy_ndp(const struct ctl_table *ctl, int write,
                                                     idev->dev->ifindex,
                                                     &idev->cnf);
                }
-               rtnl_unlock();
+               rtnl_net_unlock(net);
        }
 
        return ret;
@@ -6487,7 +6487,7 @@ static int addrconf_sysctl_addr_gen_mode(const struct ctl_table *ctl, int write,
                .mode = ctl->mode,
        };
 
-       if (!rtnl_trylock())
+       if (!rtnl_net_trylock(net))
                return restart_syscall();
 
        new_val = *((u32 *)ctl->data);
@@ -6517,7 +6517,7 @@ static int addrconf_sysctl_addr_gen_mode(const struct ctl_table *ctl, int write,
 
                        WRITE_ONCE(net->ipv6.devconf_dflt->addr_gen_mode, new_val);
                        for_each_netdev(net, dev) {
-                               idev = __in6_dev_get(dev);
+                               idev = __in6_dev_get_rtnl_net(dev);
                                if (idev &&
                                    idev->cnf.addr_gen_mode != new_val) {
                                        WRITE_ONCE(idev->cnf.addr_gen_mode,
@@ -6531,7 +6531,7 @@ static int addrconf_sysctl_addr_gen_mode(const struct ctl_table *ctl, int write,
        }
 
 out:
-       rtnl_unlock();
+       rtnl_net_unlock(net);
 
        return ret;
 }
@@ -6553,7 +6553,7 @@ static int addrconf_sysctl_stable_secret(const struct ctl_table *ctl, int write,
        lctl.maxlen = IPV6_MAX_STRLEN;
        lctl.data = str;
 
-       if (!rtnl_trylock())
+       if (!rtnl_net_trylock(net))
                return restart_syscall();
 
        if (!write && !secret->initialized) {
@@ -6583,7 +6583,7 @@ static int addrconf_sysctl_stable_secret(const struct ctl_table *ctl, int write,
                struct net_device *dev;
 
                for_each_netdev(net, dev) {
-                       struct inet6_dev *idev = __in6_dev_get(dev);
+                       struct inet6_dev *idev = __in6_dev_get_rtnl_net(dev);
 
                        if (idev) {
                                WRITE_ONCE(idev->cnf.addr_gen_mode,
@@ -6598,7 +6598,7 @@ static int addrconf_sysctl_stable_secret(const struct ctl_table *ctl, int write,
        }
 
 out:
-       rtnl_unlock();
+       rtnl_net_unlock(net);
 
        return err;
 }
@@ -6682,7 +6682,7 @@ int addrconf_disable_policy(const struct ctl_table *ctl, int *valp, int val)
                return 0;
        }
 
-       if (!rtnl_trylock())
+       if (!rtnl_net_trylock(net))
                return restart_syscall();
 
        WRITE_ONCE(*valp, val);
@@ -6691,7 +6691,7 @@ int addrconf_disable_policy(const struct ctl_table *ctl, int *valp, int val)
                struct net_device *dev;
 
                for_each_netdev(net, dev) {
-                       idev = __in6_dev_get(dev);
+                       idev = __in6_dev_get_rtnl_net(dev);
                        if (idev)
                                addrconf_disable_policy_idev(idev, val);
                }
@@ -6700,7 +6700,7 @@ int addrconf_disable_policy(const struct ctl_table *ctl, int *valp, int val)
                addrconf_disable_policy_idev(idev, val);
        }
 
-       rtnl_unlock();
+       rtnl_net_unlock(net);
        return 0;
 }