aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c133
1 files changed, 115 insertions, 18 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 73a23b4130a5..a60585fd85ad 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -137,6 +137,7 @@ static int addrconf_ifdown(struct net_device *dev, int how);
137static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags); 137static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags);
138static void addrconf_dad_timer(unsigned long data); 138static void addrconf_dad_timer(unsigned long data);
139static void addrconf_dad_completed(struct inet6_ifaddr *ifp); 139static void addrconf_dad_completed(struct inet6_ifaddr *ifp);
140static void addrconf_dad_run(struct inet6_dev *idev);
140static void addrconf_rs_timer(unsigned long data); 141static void addrconf_rs_timer(unsigned long data);
141static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); 142static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
142static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); 143static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
@@ -388,6 +389,9 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
388 } 389 }
389#endif 390#endif
390 391
392 if (netif_carrier_ok(dev))
393 ndev->if_flags |= IF_READY;
394
391 write_lock_bh(&addrconf_lock); 395 write_lock_bh(&addrconf_lock);
392 dev->ip6_ptr = ndev; 396 dev->ip6_ptr = ndev;
393 write_unlock_bh(&addrconf_lock); 397 write_unlock_bh(&addrconf_lock);
@@ -415,6 +419,7 @@ static struct inet6_dev * ipv6_find_idev(struct net_device *dev)
415 if ((idev = ipv6_add_dev(dev)) == NULL) 419 if ((idev = ipv6_add_dev(dev)) == NULL)
416 return NULL; 420 return NULL;
417 } 421 }
422
418 if (dev->flags&IFF_UP) 423 if (dev->flags&IFF_UP)
419 ipv6_mc_up(idev); 424 ipv6_mc_up(idev);
420 return idev; 425 return idev;
@@ -634,8 +639,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
634 } 639 }
635#endif 640#endif
636 641
637 for (ifap = &idev->addr_list; (ifa=*ifap) != NULL; 642 for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;) {
638 ifap = &ifa->if_next) {
639 if (ifa == ifp) { 643 if (ifa == ifp) {
640 *ifap = ifa->if_next; 644 *ifap = ifa->if_next;
641 __in6_ifa_put(ifp); 645 __in6_ifa_put(ifp);
@@ -643,6 +647,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
643 if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0) 647 if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0)
644 break; 648 break;
645 deleted = 1; 649 deleted = 1;
650 continue;
646 } else if (ifp->flags & IFA_F_PERMANENT) { 651 } else if (ifp->flags & IFA_F_PERMANENT) {
647 if (ipv6_prefix_equal(&ifa->addr, &ifp->addr, 652 if (ipv6_prefix_equal(&ifa->addr, &ifp->addr,
648 ifp->prefix_len)) { 653 ifp->prefix_len)) {
@@ -666,6 +671,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
666 } 671 }
667 } 672 }
668 } 673 }
674 ifap = &ifa->if_next;
669 } 675 }
670 write_unlock_bh(&idev->lock); 676 write_unlock_bh(&idev->lock);
671 677
@@ -903,11 +909,18 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
903 909
904 score.addr_type = __ipv6_addr_type(&ifa->addr); 910 score.addr_type = __ipv6_addr_type(&ifa->addr);
905 911
906 /* Rule 0: Candidate Source Address (section 4) 912 /* Rule 0:
913 * - Tentative Address (RFC2462 section 5.4)
914 * - A tentative address is not considered
915 * "assigned to an interface" in the traditional
916 * sense.
917 * - Candidate Source Address (section 4)
907 * - In any case, anycast addresses, multicast 918 * - In any case, anycast addresses, multicast
908 * addresses, and the unspecified address MUST 919 * addresses, and the unspecified address MUST
909 * NOT be included in a candidate set. 920 * NOT be included in a candidate set.
910 */ 921 */
922 if (ifa->flags & IFA_F_TENTATIVE)
923 continue;
911 if (unlikely(score.addr_type == IPV6_ADDR_ANY || 924 if (unlikely(score.addr_type == IPV6_ADDR_ANY ||
912 score.addr_type & IPV6_ADDR_MULTICAST)) { 925 score.addr_type & IPV6_ADDR_MULTICAST)) {
913 LIMIT_NETDEBUG(KERN_DEBUG 926 LIMIT_NETDEBUG(KERN_DEBUG
@@ -1215,10 +1228,8 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
1215 1228
1216/* Gets referenced address, destroys ifaddr */ 1229/* Gets referenced address, destroys ifaddr */
1217 1230
1218void addrconf_dad_failure(struct inet6_ifaddr *ifp) 1231void addrconf_dad_stop(struct inet6_ifaddr *ifp)
1219{ 1232{
1220 if (net_ratelimit())
1221 printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
1222 if (ifp->flags&IFA_F_PERMANENT) { 1233 if (ifp->flags&IFA_F_PERMANENT) {
1223 spin_lock_bh(&ifp->lock); 1234 spin_lock_bh(&ifp->lock);
1224 addrconf_del_timer(ifp); 1235 addrconf_del_timer(ifp);
@@ -1244,6 +1255,12 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
1244 ipv6_del_addr(ifp); 1255 ipv6_del_addr(ifp);
1245} 1256}
1246 1257
1258void addrconf_dad_failure(struct inet6_ifaddr *ifp)
1259{
1260 if (net_ratelimit())
1261 printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
1262 addrconf_dad_stop(ifp);
1263}
1247 1264
1248/* Join to solicited addr multicast group. */ 1265/* Join to solicited addr multicast group. */
1249 1266
@@ -1596,9 +1613,17 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
1596 not good. 1613 not good.
1597 */ 1614 */
1598 if (valid_lft >= 0x7FFFFFFF/HZ) 1615 if (valid_lft >= 0x7FFFFFFF/HZ)
1599 rt_expires = 0; 1616 rt_expires = 0x7FFFFFFF - (0x7FFFFFFF % HZ);
1600 else 1617 else
1601 rt_expires = jiffies + valid_lft * HZ; 1618 rt_expires = valid_lft * HZ;
1619
1620 /*
1621 * We convert this (in jiffies) to clock_t later.
1622 * Avoid arithmetic overflow there as well.
1623 * Overflow can happen only if HZ < USER_HZ.
1624 */
1625 if (HZ < USER_HZ && rt_expires > 0x7FFFFFFF / USER_HZ)
1626 rt_expires = 0x7FFFFFFF / USER_HZ;
1602 1627
1603 if (pinfo->onlink) { 1628 if (pinfo->onlink) {
1604 struct rt6_info *rt; 1629 struct rt6_info *rt;
@@ -1610,12 +1635,12 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
1610 ip6_del_rt(rt, NULL, NULL, NULL); 1635 ip6_del_rt(rt, NULL, NULL, NULL);
1611 rt = NULL; 1636 rt = NULL;
1612 } else { 1637 } else {
1613 rt->rt6i_expires = rt_expires; 1638 rt->rt6i_expires = jiffies + rt_expires;
1614 } 1639 }
1615 } 1640 }
1616 } else if (valid_lft) { 1641 } else if (valid_lft) {
1617 addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, 1642 addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
1618 dev, rt_expires, RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT); 1643 dev, jiffies_to_clock_t(rt_expires), RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT);
1619 } 1644 }
1620 if (rt) 1645 if (rt)
1621 dst_release(&rt->u.dst); 1646 dst_release(&rt->u.dst);
@@ -2125,9 +2150,42 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
2125{ 2150{
2126 struct net_device *dev = (struct net_device *) data; 2151 struct net_device *dev = (struct net_device *) data;
2127 struct inet6_dev *idev = __in6_dev_get(dev); 2152 struct inet6_dev *idev = __in6_dev_get(dev);
2153 int run_pending = 0;
2128 2154
2129 switch(event) { 2155 switch(event) {
2130 case NETDEV_UP: 2156 case NETDEV_UP:
2157 case NETDEV_CHANGE:
2158 if (event == NETDEV_UP) {
2159 if (!netif_carrier_ok(dev)) {
2160 /* device is not ready yet. */
2161 printk(KERN_INFO
2162 "ADDRCONF(NETDEV_UP): %s: "
2163 "link is not ready\n",
2164 dev->name);
2165 break;
2166 }
2167 } else {
2168 if (!netif_carrier_ok(dev)) {
2169 /* device is still not ready. */
2170 break;
2171 }
2172
2173 if (idev) {
2174 if (idev->if_flags & IF_READY) {
2175 /* device is already configured. */
2176 break;
2177 }
2178 idev->if_flags |= IF_READY;
2179 }
2180
2181 printk(KERN_INFO
2182 "ADDRCONF(NETDEV_CHANGE): %s: "
2183 "link becomes ready\n",
2184 dev->name);
2185
2186 run_pending = 1;
2187 }
2188
2131 switch(dev->type) { 2189 switch(dev->type) {
2132 case ARPHRD_SIT: 2190 case ARPHRD_SIT:
2133 addrconf_sit_config(dev); 2191 addrconf_sit_config(dev);
@@ -2144,6 +2202,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
2144 break; 2202 break;
2145 }; 2203 };
2146 if (idev) { 2204 if (idev) {
2205 if (run_pending)
2206 addrconf_dad_run(idev);
2207
2147 /* If the MTU changed during the interface down, when the 2208 /* If the MTU changed during the interface down, when the
2148 interface up, the changed MTU must be reflected in the 2209 interface up, the changed MTU must be reflected in the
2149 idev as well as routers. 2210 idev as well as routers.
@@ -2178,8 +2239,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
2178 */ 2239 */
2179 addrconf_ifdown(dev, event != NETDEV_DOWN); 2240 addrconf_ifdown(dev, event != NETDEV_DOWN);
2180 break; 2241 break;
2181 case NETDEV_CHANGE: 2242
2182 break;
2183 case NETDEV_CHANGENAME: 2243 case NETDEV_CHANGENAME:
2184#ifdef CONFIG_SYSCTL 2244#ifdef CONFIG_SYSCTL
2185 if (idev) { 2245 if (idev) {
@@ -2260,7 +2320,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2260 2320
2261 /* Step 3: clear flags for stateless addrconf */ 2321 /* Step 3: clear flags for stateless addrconf */
2262 if (how != 1) 2322 if (how != 1)
2263 idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD); 2323 idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
2264 2324
2265 /* Step 4: clear address list */ 2325 /* Step 4: clear address list */
2266#ifdef CONFIG_IPV6_PRIVACY 2326#ifdef CONFIG_IPV6_PRIVACY
@@ -2369,11 +2429,20 @@ out:
2369/* 2429/*
2370 * Duplicate Address Detection 2430 * Duplicate Address Detection
2371 */ 2431 */
2432static void addrconf_dad_kick(struct inet6_ifaddr *ifp)
2433{
2434 unsigned long rand_num;
2435 struct inet6_dev *idev = ifp->idev;
2436
2437 rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1);
2438 ifp->probes = idev->cnf.dad_transmits;
2439 addrconf_mod_timer(ifp, AC_DAD, rand_num);
2440}
2441
2372static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) 2442static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2373{ 2443{
2374 struct inet6_dev *idev = ifp->idev; 2444 struct inet6_dev *idev = ifp->idev;
2375 struct net_device *dev = idev->dev; 2445 struct net_device *dev = idev->dev;
2376 unsigned long rand_num;
2377 2446
2378 addrconf_join_solict(dev, &ifp->addr); 2447 addrconf_join_solict(dev, &ifp->addr);
2379 2448
@@ -2382,7 +2451,6 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2382 flags); 2451 flags);
2383 2452
2384 net_srandom(ifp->addr.s6_addr32[3]); 2453 net_srandom(ifp->addr.s6_addr32[3]);
2385 rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1);
2386 2454
2387 read_lock_bh(&idev->lock); 2455 read_lock_bh(&idev->lock);
2388 if (ifp->dead) 2456 if (ifp->dead)
@@ -2399,9 +2467,19 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2399 return; 2467 return;
2400 } 2468 }
2401 2469
2402 ifp->probes = idev->cnf.dad_transmits; 2470 if (!(idev->if_flags & IF_READY)) {
2403 addrconf_mod_timer(ifp, AC_DAD, rand_num); 2471 spin_unlock_bh(&ifp->lock);
2404 2472 read_unlock_bh(&idev->lock);
2473 /*
2474 * If the defice is not ready:
2475 * - keep it tentative if it is a permanent address.
2476 * - otherwise, kill it.
2477 */
2478 in6_ifa_hold(ifp);
2479 addrconf_dad_stop(ifp);
2480 return;
2481 }
2482 addrconf_dad_kick(ifp);
2405 spin_unlock_bh(&ifp->lock); 2483 spin_unlock_bh(&ifp->lock);
2406out: 2484out:
2407 read_unlock_bh(&idev->lock); 2485 read_unlock_bh(&idev->lock);
@@ -2484,6 +2562,22 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
2484 } 2562 }
2485} 2563}
2486 2564
2565static void addrconf_dad_run(struct inet6_dev *idev) {
2566 struct inet6_ifaddr *ifp;
2567
2568 read_lock_bh(&idev->lock);
2569 for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) {
2570 spin_lock_bh(&ifp->lock);
2571 if (!(ifp->flags & IFA_F_TENTATIVE)) {
2572 spin_unlock_bh(&ifp->lock);
2573 continue;
2574 }
2575 spin_unlock_bh(&ifp->lock);
2576 addrconf_dad_kick(ifp);
2577 }
2578 read_unlock_bh(&idev->lock);
2579}
2580
2487#ifdef CONFIG_PROC_FS 2581#ifdef CONFIG_PROC_FS
2488struct if6_iter_state { 2582struct if6_iter_state {
2489 int bucket; 2583 int bucket;
@@ -2689,6 +2783,9 @@ restart:
2689 in6_ifa_hold(ifpub); 2783 in6_ifa_hold(ifpub);
2690 spin_unlock(&ifp->lock); 2784 spin_unlock(&ifp->lock);
2691 read_unlock(&addrconf_hash_lock); 2785 read_unlock(&addrconf_hash_lock);
2786 spin_lock(&ifpub->lock);
2787 ifpub->regen_count = 0;
2788 spin_unlock(&ifpub->lock);
2692 ipv6_create_tempaddr(ifpub, ifp); 2789 ipv6_create_tempaddr(ifpub, ifp);
2693 in6_ifa_put(ifpub); 2790 in6_ifa_put(ifpub);
2694 in6_ifa_put(ifp); 2791 in6_ifa_put(ifp);