Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1855b7c3 authored by Hannes Frederic Sowa's avatar Hannes Frederic Sowa Committed by David S. Miller
Browse files

ipv6: introduce idgen_delay and idgen_retries knobs



This is specified by RFC 7217.

Cc: Erik Kline <ek@google.com>
Cc: Fernando Gont <fgont@si6networks.com>
Cc: Lorenzo Colitti <lorenzo@google.com>
Cc: YOSHIFUJI Hideaki/吉藤英明 <hideaki.yoshifuji@miraclelinux.com>
Signed-off-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5f40ef77
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ struct netns_sysctl_ipv6 {
	int icmpv6_time;
	int anycast_src_echo_reply;
	int fwmark_reflect;
	int idgen_retries;
	int idgen_delay;
};

struct netns_ipv6 {
+4 −7
Original line number Diff line number Diff line
@@ -1712,6 +1712,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
{
	struct in6_addr addr;
	struct inet6_dev *idev = ifp->idev;
	struct net *net = dev_net(ifp->idev->dev);

	if (addrconf_dad_end(ifp)) {
		in6_ifa_put(ifp);
@@ -1730,11 +1731,9 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
		struct inet6_ifaddr *ifp2;
		u32 valid_lft, preferred_lft;
		int pfxlen = ifp->prefix_len;
		const unsigned int idgen_retries = 3;
		const unsigned int idgen_delay = 1 * HZ;
		int retries = ifp->stable_privacy_retry + 1;

		if (retries > idgen_retries) {
		if (retries > net->ipv6.sysctl.idgen_retries) {
			net_info_ratelimited("%s: privacy stable address generation failed because of DAD conflicts!\n",
					     ifp->idev->dev->name);
			goto errdad;
@@ -1769,7 +1768,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
		ifp2->state = INET6_IFADDR_STATE_PREDAD;
		spin_unlock_bh(&ifp2->lock);

		addrconf_mod_dad_work(ifp2, idgen_delay);
		addrconf_mod_dad_work(ifp2, net->ipv6.sysctl.idgen_delay);
		in6_ifa_put(ifp2);
lock_errdad:
		spin_lock_bh(&ifp->lock);
@@ -2899,8 +2898,6 @@ static int ipv6_generate_stable_address(struct in6_addr *address,
					u8 dad_count,
					const struct inet6_dev *idev)
{
	static const int idgen_retries = 3;

	static DEFINE_SPINLOCK(lock);
	static __u32 digest[SHA_DIGEST_WORDS];
	static __u32 workspace[SHA_WORKSPACE_WORDS];
@@ -2950,7 +2947,7 @@ static int ipv6_generate_stable_address(struct in6_addr *address,

	if (ipv6_reserved_interfaceid(temp)) {
		dad_count++;
		if (dad_count > idgen_retries)
		if (dad_count > dev_net(idev->dev)->ipv6.sysctl.idgen_retries)
			return -1;
		goto retry;
	}
+2 −0
Original line number Diff line number Diff line
@@ -766,6 +766,8 @@ static int __net_init inet6_net_init(struct net *net)
	net->ipv6.sysctl.icmpv6_time = 1*HZ;
	net->ipv6.sysctl.flowlabel_consistency = 1;
	net->ipv6.sysctl.auto_flowlabels = 0;
	net->ipv6.sysctl.idgen_retries = 3;
	net->ipv6.sysctl.idgen_delay = 1 * HZ;
	atomic_set(&net->ipv6.fib6_sernum, 1);

	err = ipv6_init_mibs(net);
+16 −0
Original line number Diff line number Diff line
@@ -54,6 +54,20 @@ static struct ctl_table ipv6_table_template[] = {
		.mode		= 0644,
		.proc_handler	= proc_dointvec
	},
	{
		.procname	= "idgen_retries",
		.data		= &init_net.ipv6.sysctl.idgen_retries,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec,
	},
	{
		.procname	= "idgen_delay",
		.data		= &init_net.ipv6.sysctl.idgen_delay,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_jiffies,
	},
	{ }
};

@@ -93,6 +107,8 @@ static int __net_init ipv6_sysctl_net_init(struct net *net)
	ipv6_table[2].data = &net->ipv6.sysctl.flowlabel_consistency;
	ipv6_table[3].data = &net->ipv6.sysctl.auto_flowlabels;
	ipv6_table[4].data = &net->ipv6.sysctl.fwmark_reflect;
	ipv6_table[5].data = &net->ipv6.sysctl.idgen_retries;
	ipv6_table[6].data = &net->ipv6.sysctl.idgen_delay;

	ipv6_route_table = ipv6_route_sysctl_init(net);
	if (!ipv6_route_table)