diff options
author | Hannes Frederic Sowa <hannes@stressinduktion.org> | 2015-03-23 18:36:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-23 22:12:09 -0400 |
commit | 1855b7c3e8537c2a4f5a53c797624713bb3becb4 (patch) | |
tree | 51a7bac158c3051729d0f9a0061cf033c0e3fafc /net/ipv6 | |
parent | 5f40ef77adb237954d615a76621df1b80a329b31 (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.c | 11 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 2 | ||||
-rw-r--r-- | net/ipv6/sysctl_net_ipv6.c | 16 |
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); |
1774 | lock_errdad: | 1773 | lock_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) |