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

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
...@@ -32,6 +32,8 @@ struct netns_sysctl_ipv6 { ...@@ -32,6 +32,8 @@ struct netns_sysctl_ipv6 {
int icmpv6_time; int icmpv6_time;
int anycast_src_echo_reply; int anycast_src_echo_reply;
int fwmark_reflect; int fwmark_reflect;
int idgen_retries;
int idgen_delay;
}; };
struct netns_ipv6 { struct netns_ipv6 {
......
...@@ -1712,6 +1712,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) ...@@ -1712,6 +1712,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
{ {
struct in6_addr addr; struct in6_addr addr;
struct inet6_dev *idev = ifp->idev; struct inet6_dev *idev = ifp->idev;
struct net *net = dev_net(ifp->idev->dev);
if (addrconf_dad_end(ifp)) { if (addrconf_dad_end(ifp)) {
in6_ifa_put(ifp); in6_ifa_put(ifp);
...@@ -1730,11 +1731,9 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) ...@@ -1730,11 +1731,9 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
struct inet6_ifaddr *ifp2; struct inet6_ifaddr *ifp2;
u32 valid_lft, preferred_lft; u32 valid_lft, preferred_lft;
int pfxlen = ifp->prefix_len; 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; 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", net_info_ratelimited("%s: privacy stable address generation failed because of DAD conflicts!\n",
ifp->idev->dev->name); ifp->idev->dev->name);
goto errdad; goto errdad;
...@@ -1769,7 +1768,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) ...@@ -1769,7 +1768,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
ifp2->state = INET6_IFADDR_STATE_PREDAD; ifp2->state = INET6_IFADDR_STATE_PREDAD;
spin_unlock_bh(&ifp2->lock); 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); in6_ifa_put(ifp2);
lock_errdad: lock_errdad:
spin_lock_bh(&ifp->lock); spin_lock_bh(&ifp->lock);
...@@ -2899,8 +2898,6 @@ static int ipv6_generate_stable_address(struct in6_addr *address, ...@@ -2899,8 +2898,6 @@ static int ipv6_generate_stable_address(struct in6_addr *address,
u8 dad_count, u8 dad_count,
const struct inet6_dev *idev) const struct inet6_dev *idev)
{ {
static const int idgen_retries = 3;
static DEFINE_SPINLOCK(lock); static DEFINE_SPINLOCK(lock);
static __u32 digest[SHA_DIGEST_WORDS]; static __u32 digest[SHA_DIGEST_WORDS];
static __u32 workspace[SHA_WORKSPACE_WORDS]; static __u32 workspace[SHA_WORKSPACE_WORDS];
...@@ -2950,7 +2947,7 @@ static int ipv6_generate_stable_address(struct in6_addr *address, ...@@ -2950,7 +2947,7 @@ static int ipv6_generate_stable_address(struct in6_addr *address,
if (ipv6_reserved_interfaceid(temp)) { if (ipv6_reserved_interfaceid(temp)) {
dad_count++; dad_count++;
if (dad_count > idgen_retries) if (dad_count > dev_net(idev->dev)->ipv6.sysctl.idgen_retries)
return -1; return -1;
goto retry; goto retry;
} }
......
...@@ -766,6 +766,8 @@ static int __net_init inet6_net_init(struct net *net) ...@@ -766,6 +766,8 @@ static int __net_init inet6_net_init(struct net *net)
net->ipv6.sysctl.icmpv6_time = 1*HZ; net->ipv6.sysctl.icmpv6_time = 1*HZ;
net->ipv6.sysctl.flowlabel_consistency = 1; net->ipv6.sysctl.flowlabel_consistency = 1;
net->ipv6.sysctl.auto_flowlabels = 0; 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); atomic_set(&net->ipv6.fib6_sernum, 1);
err = ipv6_init_mibs(net); err = ipv6_init_mibs(net);
......
...@@ -54,6 +54,20 @@ static struct ctl_table ipv6_table_template[] = { ...@@ -54,6 +54,20 @@ static struct ctl_table ipv6_table_template[] = {
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec .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) ...@@ -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[2].data = &net->ipv6.sysctl.flowlabel_consistency;
ipv6_table[3].data = &net->ipv6.sysctl.auto_flowlabels; ipv6_table[3].data = &net->ipv6.sysctl.auto_flowlabels;
ipv6_table[4].data = &net->ipv6.sysctl.fwmark_reflect; 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); ipv6_route_table = ipv6_route_sysctl_init(net);
if (!ipv6_route_table) if (!ipv6_route_table)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment