aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorHannes Frederic Sowa <hannes@stressinduktion.org>2015-03-23 18:36:05 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-23 22:12:09 -0400
commit1855b7c3e8537c2a4f5a53c797624713bb3becb4 (patch)
tree51a7bac158c3051729d0f9a0061cf033c0e3fafc /net/ipv6
parent5f40ef77adb237954d615a76621df1b80a329b31 (diff)
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: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c11
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/sysctl_net_ipv6.c16
3 files changed, 22 insertions, 7 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 9b51fdb42ba9..d2d238334a11 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1712,6 +1712,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
1712{ 1712{
1713 struct in6_addr addr; 1713 struct in6_addr addr;
1714 struct inet6_dev *idev = ifp->idev; 1714 struct inet6_dev *idev = ifp->idev;
1715 struct net *net = dev_net(ifp->idev->dev);
1715 1716
1716 if (addrconf_dad_end(ifp)) { 1717 if (addrconf_dad_end(ifp)) {
1717 in6_ifa_put(ifp); 1718 in6_ifa_put(ifp);
@@ -1730,11 +1731,9 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
1730 struct inet6_ifaddr *ifp2; 1731 struct inet6_ifaddr *ifp2;
1731 u32 valid_lft, preferred_lft; 1732 u32 valid_lft, preferred_lft;
1732 int pfxlen = ifp->prefix_len; 1733 int pfxlen = ifp->prefix_len;
1733 const unsigned int idgen_retries = 3;
1734 const unsigned int idgen_delay = 1 * HZ;
1735 int retries = ifp->stable_privacy_retry + 1; 1734 int retries = ifp->stable_privacy_retry + 1;
1736 1735
1737 if (retries > idgen_retries) { 1736 if (retries > net->ipv6.sysctl.idgen_retries) {
1738 net_info_ratelimited("%s: privacy stable address generation failed because of DAD conflicts!\n", 1737 net_info_ratelimited("%s: privacy stable address generation failed because of DAD conflicts!\n",
1739 ifp->idev->dev->name); 1738 ifp->idev->dev->name);
1740 goto errdad; 1739 goto errdad;
@@ -1769,7 +1768,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
1769 ifp2->state = INET6_IFADDR_STATE_PREDAD; 1768 ifp2->state = INET6_IFADDR_STATE_PREDAD;
1770 spin_unlock_bh(&ifp2->lock); 1769 spin_unlock_bh(&ifp2->lock);
1771 1770
1772 addrconf_mod_dad_work(ifp2, idgen_delay); 1771 addrconf_mod_dad_work(ifp2, net->ipv6.sysctl.idgen_delay);
1773 in6_ifa_put(ifp2); 1772 in6_ifa_put(ifp2);
1774lock_errdad: 1773lock_errdad:
1775 spin_lock_bh(&ifp->lock); 1774 spin_lock_bh(&ifp->lock);
@@ -2899,8 +2898,6 @@ static int ipv6_generate_stable_address(struct in6_addr *address,
2899 u8 dad_count, 2898 u8 dad_count,
2900 const struct inet6_dev *idev) 2899 const struct inet6_dev *idev)
2901{ 2900{
2902 static const int idgen_retries = 3;
2903
2904 static DEFINE_SPINLOCK(lock); 2901 static DEFINE_SPINLOCK(lock);
2905 static __u32 digest[SHA_DIGEST_WORDS]; 2902 static __u32 digest[SHA_DIGEST_WORDS];
2906 static __u32 workspace[SHA_WORKSPACE_WORDS]; 2903 static __u32 workspace[SHA_WORKSPACE_WORDS];
@@ -2950,7 +2947,7 @@ retry:
2950 2947
2951 if (ipv6_reserved_interfaceid(temp)) { 2948 if (ipv6_reserved_interfaceid(temp)) {
2952 dad_count++; 2949 dad_count++;
2953 if (dad_count > idgen_retries) 2950 if (dad_count > dev_net(idev->dev)->ipv6.sysctl.idgen_retries)
2954 return -1; 2951 return -1;
2955 goto retry; 2952 goto retry;
2956 } 2953 }
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 6bafcc2c79e3..d8dcc526339e 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -766,6 +766,8 @@ static int __net_init inet6_net_init(struct net *net)
766 net->ipv6.sysctl.icmpv6_time = 1*HZ; 766 net->ipv6.sysctl.icmpv6_time = 1*HZ;
767 net->ipv6.sysctl.flowlabel_consistency = 1; 767 net->ipv6.sysctl.flowlabel_consistency = 1;
768 net->ipv6.sysctl.auto_flowlabels = 0; 768 net->ipv6.sysctl.auto_flowlabels = 0;
769 net->ipv6.sysctl.idgen_retries = 3;
770 net->ipv6.sysctl.idgen_delay = 1 * HZ;
769 atomic_set(&net->ipv6.fib6_sernum, 1); 771 atomic_set(&net->ipv6.fib6_sernum, 1);
770 772
771 err = ipv6_init_mibs(net); 773 err = ipv6_init_mibs(net);
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index c5c10fafcfe2..30f5a4ad04eb 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -54,6 +54,20 @@ static struct ctl_table ipv6_table_template[] = {
54 .mode = 0644, 54 .mode = 0644,
55 .proc_handler = proc_dointvec 55 .proc_handler = proc_dointvec
56 }, 56 },
57 {
58 .procname = "idgen_retries",
59 .data = &init_net.ipv6.sysctl.idgen_retries,
60 .maxlen = sizeof(int),
61 .mode = 0644,
62 .proc_handler = proc_dointvec,
63 },
64 {
65 .procname = "idgen_delay",
66 .data = &init_net.ipv6.sysctl.idgen_delay,
67 .maxlen = sizeof(int),
68 .mode = 0644,
69 .proc_handler = proc_dointvec_jiffies,
70 },
57 { } 71 { }
58}; 72};
59 73
@@ -93,6 +107,8 @@ static int __net_init ipv6_sysctl_net_init(struct net *net)
93 ipv6_table[2].data = &net->ipv6.sysctl.flowlabel_consistency; 107 ipv6_table[2].data = &net->ipv6.sysctl.flowlabel_consistency;
94 ipv6_table[3].data = &net->ipv6.sysctl.auto_flowlabels; 108 ipv6_table[3].data = &net->ipv6.sysctl.auto_flowlabels;
95 ipv6_table[4].data = &net->ipv6.sysctl.fwmark_reflect; 109 ipv6_table[4].data = &net->ipv6.sysctl.fwmark_reflect;
110 ipv6_table[5].data = &net->ipv6.sysctl.idgen_retries;
111 ipv6_table[6].data = &net->ipv6.sysctl.idgen_delay;
96 112
97 ipv6_route_table = ipv6_route_sysctl_init(net); 113 ipv6_route_table = ipv6_route_sysctl_init(net);
98 if (!ipv6_route_table) 114 if (!ipv6_route_table)