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.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 101e0e70ba27..a65935a9afd9 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -776,6 +776,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
776 struct inet6_dev *idev = ifp->idev; 776 struct inet6_dev *idev = ifp->idev;
777 struct in6_addr addr, *tmpaddr; 777 struct in6_addr addr, *tmpaddr;
778 unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp; 778 unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp;
779 unsigned long regen_advance;
779 int tmp_plen; 780 int tmp_plen;
780 int ret = 0; 781 int ret = 0;
781 int max_addresses; 782 int max_addresses;
@@ -836,8 +837,23 @@ retry:
836 tmp_tstamp = ifp->tstamp; 837 tmp_tstamp = ifp->tstamp;
837 spin_unlock_bh(&ifp->lock); 838 spin_unlock_bh(&ifp->lock);
838 839
840 regen_advance = idev->cnf.regen_max_retry *
841 idev->cnf.dad_transmits *
842 idev->nd_parms->retrans_time / HZ;
839 write_unlock(&idev->lock); 843 write_unlock(&idev->lock);
840 844
845 /* A temporary address is created only if this calculated Preferred
846 * Lifetime is greater than REGEN_ADVANCE time units. In particular,
847 * an implementation must not create a temporary address with a zero
848 * Preferred Lifetime.
849 */
850 if (tmp_prefered_lft <= regen_advance) {
851 in6_ifa_put(ifp);
852 in6_dev_put(idev);
853 ret = -1;
854 goto out;
855 }
856
841 addr_flags = IFA_F_TEMPORARY; 857 addr_flags = IFA_F_TEMPORARY;
842 /* set in addrconf_prefix_rcv() */ 858 /* set in addrconf_prefix_rcv() */
843 if (ifp->flags & IFA_F_OPTIMISTIC) 859 if (ifp->flags & IFA_F_OPTIMISTIC)
@@ -1831,6 +1847,9 @@ ok:
1831 * lifetimes of an existing temporary address 1847 * lifetimes of an existing temporary address
1832 * when processing a Prefix Information Option. 1848 * when processing a Prefix Information Option.
1833 */ 1849 */
1850 if (ifp != ift->ifpub)
1851 continue;
1852
1834 spin_lock(&ift->lock); 1853 spin_lock(&ift->lock);
1835 flags = ift->flags; 1854 flags = ift->flags;
1836 if (ift->valid_lft > valid_lft && 1855 if (ift->valid_lft > valid_lft &&
@@ -2437,7 +2456,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2437 2456
2438 ASSERT_RTNL(); 2457 ASSERT_RTNL();
2439 2458
2440 if (dev == init_net.loopback_dev && how == 1) 2459 if ((dev->flags & IFF_LOOPBACK) && how == 1)
2441 how = 0; 2460 how = 0;
2442 2461
2443 rt6_ifdown(dev); 2462 rt6_ifdown(dev);
@@ -2450,7 +2469,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2450 /* Step 1: remove reference to ipv6 device from parent device. 2469 /* Step 1: remove reference to ipv6 device from parent device.
2451 Do not dev_put! 2470 Do not dev_put!
2452 */ 2471 */
2453 if (how == 1) { 2472 if (how) {
2454 idev->dead = 1; 2473 idev->dead = 1;
2455 2474
2456 /* protected by rtnl_lock */ 2475 /* protected by rtnl_lock */
@@ -2482,12 +2501,12 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2482 write_lock_bh(&idev->lock); 2501 write_lock_bh(&idev->lock);
2483 2502
2484 /* Step 3: clear flags for stateless addrconf */ 2503 /* Step 3: clear flags for stateless addrconf */
2485 if (how != 1) 2504 if (!how)
2486 idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY); 2505 idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
2487 2506
2488 /* Step 4: clear address list */ 2507 /* Step 4: clear address list */
2489#ifdef CONFIG_IPV6_PRIVACY 2508#ifdef CONFIG_IPV6_PRIVACY
2490 if (how == 1 && del_timer(&idev->regen_timer)) 2509 if (how && del_timer(&idev->regen_timer))
2491 in6_dev_put(idev); 2510 in6_dev_put(idev);
2492 2511
2493 /* clear tempaddr list */ 2512 /* clear tempaddr list */
@@ -2524,7 +2543,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2524 2543
2525 /* Step 5: Discard multicast list */ 2544 /* Step 5: Discard multicast list */
2526 2545
2527 if (how == 1) 2546 if (how)
2528 ipv6_mc_destroy_dev(idev); 2547 ipv6_mc_destroy_dev(idev);
2529 else 2548 else
2530 ipv6_mc_down(idev); 2549 ipv6_mc_down(idev);
@@ -2533,7 +2552,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2533 2552
2534 /* Shot the device (if unregistered) */ 2553 /* Shot the device (if unregistered) */
2535 2554
2536 if (how == 1) { 2555 if (how) {
2537 addrconf_sysctl_unregister(idev); 2556 addrconf_sysctl_unregister(idev);
2538 neigh_parms_release(&nd_tbl, idev->nd_parms); 2557 neigh_parms_release(&nd_tbl, idev->nd_parms);
2539 neigh_ifdown(&nd_tbl, dev); 2558 neigh_ifdown(&nd_tbl, dev);