Commit 93c839e3 authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by Jakub Kicinski
Browse files

ipv6: Convert net.ipv6.conf.${DEV}.XXX sysctl to per-netns RTNL.



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: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250115080608.28127-3-kuniyu@amazon.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f7a6082b
Loading
Loading
Loading
Loading
+30 −30
Original line number Diff line number Diff line
@@ -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;
}