aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorHannes Frederic Sowa <hannes@stressinduktion.org>2015-03-23 18:36:02 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-23 22:12:09 -0400
commit64236f3f3d742469e4027b83a9515e84e9ab21b4 (patch)
tree3338532cb9cc0d047ff38b0c11bdd09119f44336 /net/ipv6
parent622c81d57b392cc9be836670eb464a4dfaa9adfe (diff)
ipv6: introduce IFA_F_STABLE_PRIVACY flag
We need to mark appropriate addresses so we can do retries in case their DAD failed. 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.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6813268ce8b8..c2357b6f62dd 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2199,6 +2199,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
2199 __u32 valid_lft; 2199 __u32 valid_lft;
2200 __u32 prefered_lft; 2200 __u32 prefered_lft;
2201 int addr_type; 2201 int addr_type;
2202 u32 addr_flags = 0;
2202 struct inet6_dev *in6_dev; 2203 struct inet6_dev *in6_dev;
2203 struct net *net = dev_net(dev); 2204 struct net *net = dev_net(dev);
2204 2205
@@ -2309,6 +2310,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
2309 IN6_ADDR_GEN_MODE_STABLE_PRIVACY && 2310 IN6_ADDR_GEN_MODE_STABLE_PRIVACY &&
2310 !ipv6_generate_stable_address(&addr, 0, 2311 !ipv6_generate_stable_address(&addr, 0,
2311 in6_dev)) { 2312 in6_dev)) {
2313 addr_flags |= IFA_F_STABLE_PRIVACY;
2312 goto ok; 2314 goto ok;
2313 } else if (ipv6_generate_eui64(addr.s6_addr + 8, dev) && 2315 } else if (ipv6_generate_eui64(addr.s6_addr + 8, dev) &&
2314 ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev)) { 2316 ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev)) {
@@ -2328,7 +2330,6 @@ ok:
2328 2330
2329 if (ifp == NULL && valid_lft) { 2331 if (ifp == NULL && valid_lft) {
2330 int max_addresses = in6_dev->cnf.max_addresses; 2332 int max_addresses = in6_dev->cnf.max_addresses;
2331 u32 addr_flags = 0;
2332 2333
2333#ifdef CONFIG_IPV6_OPTIMISTIC_DAD 2334#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
2334 if (in6_dev->cnf.optimistic_dad && 2335 if (in6_dev->cnf.optimistic_dad &&
@@ -2807,10 +2808,11 @@ static void init_loopback(struct net_device *dev)
2807 } 2808 }
2808} 2809}
2809 2810
2810static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr) 2811static void addrconf_add_linklocal(struct inet6_dev *idev,
2812 const struct in6_addr *addr, u32 flags)
2811{ 2813{
2812 struct inet6_ifaddr *ifp; 2814 struct inet6_ifaddr *ifp;
2813 u32 addr_flags = IFA_F_PERMANENT; 2815 u32 addr_flags = flags | IFA_F_PERMANENT;
2814 2816
2815#ifdef CONFIG_IPV6_OPTIMISTIC_DAD 2817#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
2816 if (idev->cnf.optimistic_dad && 2818 if (idev->cnf.optimistic_dad &&
@@ -2818,7 +2820,6 @@ static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr
2818 addr_flags |= IFA_F_OPTIMISTIC; 2820 addr_flags |= IFA_F_OPTIMISTIC;
2819#endif 2821#endif
2820 2822
2821
2822 ifp = ipv6_add_addr(idev, addr, NULL, 64, IFA_LINK, addr_flags, 2823 ifp = ipv6_add_addr(idev, addr, NULL, 64, IFA_LINK, addr_flags,
2823 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); 2824 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME);
2824 if (!IS_ERR(ifp)) { 2825 if (!IS_ERR(ifp)) {
@@ -2916,7 +2917,8 @@ static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route)
2916 2917
2917 if (idev->addr_gen_mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY) { 2918 if (idev->addr_gen_mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY) {
2918 if (!ipv6_generate_stable_address(&addr, 0, idev)) 2919 if (!ipv6_generate_stable_address(&addr, 0, idev))
2919 addrconf_add_linklocal(idev, &addr); 2920 addrconf_add_linklocal(idev, &addr,
2921 IFA_F_STABLE_PRIVACY);
2920 else if (prefix_route) 2922 else if (prefix_route)
2921 addrconf_prefix_route(&addr, 64, idev->dev, 0, 0); 2923 addrconf_prefix_route(&addr, 64, idev->dev, 0, 0);
2922 } else if (idev->addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64) { 2924 } else if (idev->addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64) {
@@ -2925,7 +2927,7 @@ static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route)
2925 * couldn't generate one. 2927 * couldn't generate one.
2926 */ 2928 */
2927 if (ipv6_generate_eui64(addr.s6_addr + 8, idev->dev) == 0) 2929 if (ipv6_generate_eui64(addr.s6_addr + 8, idev->dev) == 0)
2928 addrconf_add_linklocal(idev, &addr); 2930 addrconf_add_linklocal(idev, &addr, 0);
2929 else if (prefix_route) 2931 else if (prefix_route)
2930 addrconf_prefix_route(&addr, 64, idev->dev, 0, 0); 2932 addrconf_prefix_route(&addr, 64, idev->dev, 0, 0);
2931 } 2933 }