diff options
-rw-r--r-- | include/net/addrconf.h | 2 | ||||
-rw-r--r-- | include/net/if_inet6.h | 1 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 69 |
3 files changed, 50 insertions, 22 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 582e4ae70753..cbc6bb0a6838 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | #define TEMP_VALID_LIFETIME (7*86400) | 9 | #define TEMP_VALID_LIFETIME (7*86400) |
10 | #define TEMP_PREFERRED_LIFETIME (86400) | 10 | #define TEMP_PREFERRED_LIFETIME (86400) |
11 | #define REGEN_MAX_RETRY (5) | 11 | #define REGEN_MAX_RETRY (3) |
12 | #define MAX_DESYNC_FACTOR (600) | 12 | #define MAX_DESYNC_FACTOR (600) |
13 | 13 | ||
14 | #define ADDR_CHECK_FREQUENCY (120*HZ) | 14 | #define ADDR_CHECK_FREQUENCY (120*HZ) |
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 11cf373970a9..51a7031b4aa3 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h | |||
@@ -41,6 +41,7 @@ struct inet6_ifaddr { | |||
41 | struct in6_addr addr; | 41 | struct in6_addr addr; |
42 | __u32 prefix_len; | 42 | __u32 prefix_len; |
43 | 43 | ||
44 | /* In seconds, relative to tstamp. Expiry is at tstamp + HZ * lft. */ | ||
44 | __u32 valid_lft; | 45 | __u32 valid_lft; |
45 | __u32 prefered_lft; | 46 | __u32 prefered_lft; |
46 | atomic_t refcnt; | 47 | atomic_t refcnt; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a55500cc0b29..9a852156a8f3 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -824,12 +824,13 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i | |||
824 | { | 824 | { |
825 | struct inet6_dev *idev = ifp->idev; | 825 | struct inet6_dev *idev = ifp->idev; |
826 | struct in6_addr addr, *tmpaddr; | 826 | struct in6_addr addr, *tmpaddr; |
827 | unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp, age; | 827 | unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_tstamp, age; |
828 | unsigned long regen_advance; | 828 | unsigned long regen_advance; |
829 | int tmp_plen; | 829 | int tmp_plen; |
830 | int ret = 0; | 830 | int ret = 0; |
831 | int max_addresses; | 831 | int max_addresses; |
832 | u32 addr_flags; | 832 | u32 addr_flags; |
833 | unsigned long now = jiffies; | ||
833 | 834 | ||
834 | write_lock(&idev->lock); | 835 | write_lock(&idev->lock); |
835 | if (ift) { | 836 | if (ift) { |
@@ -874,7 +875,7 @@ retry: | |||
874 | goto out; | 875 | goto out; |
875 | } | 876 | } |
876 | memcpy(&addr.s6_addr[8], idev->rndid, 8); | 877 | memcpy(&addr.s6_addr[8], idev->rndid, 8); |
877 | age = (jiffies - ifp->tstamp) / HZ; | 878 | age = (now - ifp->tstamp) / HZ; |
878 | tmp_valid_lft = min_t(__u32, | 879 | tmp_valid_lft = min_t(__u32, |
879 | ifp->valid_lft, | 880 | ifp->valid_lft, |
880 | idev->cnf.temp_valid_lft + age); | 881 | idev->cnf.temp_valid_lft + age); |
@@ -884,7 +885,6 @@ retry: | |||
884 | idev->cnf.max_desync_factor); | 885 | idev->cnf.max_desync_factor); |
885 | tmp_plen = ifp->prefix_len; | 886 | tmp_plen = ifp->prefix_len; |
886 | max_addresses = idev->cnf.max_addresses; | 887 | max_addresses = idev->cnf.max_addresses; |
887 | tmp_cstamp = ifp->cstamp; | ||
888 | tmp_tstamp = ifp->tstamp; | 888 | tmp_tstamp = ifp->tstamp; |
889 | spin_unlock_bh(&ifp->lock); | 889 | spin_unlock_bh(&ifp->lock); |
890 | 890 | ||
@@ -929,7 +929,7 @@ retry: | |||
929 | ift->ifpub = ifp; | 929 | ift->ifpub = ifp; |
930 | ift->valid_lft = tmp_valid_lft; | 930 | ift->valid_lft = tmp_valid_lft; |
931 | ift->prefered_lft = tmp_prefered_lft; | 931 | ift->prefered_lft = tmp_prefered_lft; |
932 | ift->cstamp = tmp_cstamp; | 932 | ift->cstamp = now; |
933 | ift->tstamp = tmp_tstamp; | 933 | ift->tstamp = tmp_tstamp; |
934 | spin_unlock_bh(&ift->lock); | 934 | spin_unlock_bh(&ift->lock); |
935 | 935 | ||
@@ -1999,25 +1999,50 @@ ok: | |||
1999 | #ifdef CONFIG_IPV6_PRIVACY | 1999 | #ifdef CONFIG_IPV6_PRIVACY |
2000 | read_lock_bh(&in6_dev->lock); | 2000 | read_lock_bh(&in6_dev->lock); |
2001 | /* update all temporary addresses in the list */ | 2001 | /* update all temporary addresses in the list */ |
2002 | list_for_each_entry(ift, &in6_dev->tempaddr_list, tmp_list) { | 2002 | list_for_each_entry(ift, &in6_dev->tempaddr_list, |
2003 | /* | 2003 | tmp_list) { |
2004 | * When adjusting the lifetimes of an existing | 2004 | int age, max_valid, max_prefered; |
2005 | * temporary address, only lower the lifetimes. | 2005 | |
2006 | * Implementations must not increase the | ||
2007 | * lifetimes of an existing temporary address | ||
2008 | * when processing a Prefix Information Option. | ||
2009 | */ | ||
2010 | if (ifp != ift->ifpub) | 2006 | if (ifp != ift->ifpub) |
2011 | continue; | 2007 | continue; |
2012 | 2008 | ||
2009 | /* | ||
2010 | * RFC 4941 section 3.3: | ||
2011 | * If a received option will extend the lifetime | ||
2012 | * of a public address, the lifetimes of | ||
2013 | * temporary addresses should be extended, | ||
2014 | * subject to the overall constraint that no | ||
2015 | * temporary addresses should ever remain | ||
2016 | * "valid" or "preferred" for a time longer than | ||
2017 | * (TEMP_VALID_LIFETIME) or | ||
2018 | * (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR), | ||
2019 | * respectively. | ||
2020 | */ | ||
2021 | age = (now - ift->cstamp) / HZ; | ||
2022 | max_valid = in6_dev->cnf.temp_valid_lft - age; | ||
2023 | if (max_valid < 0) | ||
2024 | max_valid = 0; | ||
2025 | |||
2026 | max_prefered = in6_dev->cnf.temp_prefered_lft - | ||
2027 | in6_dev->cnf.max_desync_factor - | ||
2028 | age; | ||
2029 | if (max_prefered < 0) | ||
2030 | max_prefered = 0; | ||
2031 | |||
2032 | if (valid_lft > max_valid) | ||
2033 | valid_lft = max_valid; | ||
2034 | |||
2035 | if (prefered_lft > max_prefered) | ||
2036 | prefered_lft = max_prefered; | ||
2037 | |||
2013 | spin_lock(&ift->lock); | 2038 | spin_lock(&ift->lock); |
2014 | flags = ift->flags; | 2039 | flags = ift->flags; |
2015 | if (ift->valid_lft > valid_lft && | 2040 | ift->valid_lft = valid_lft; |
2016 | ift->valid_lft - valid_lft > (jiffies - ift->tstamp) / HZ) | 2041 | ift->prefered_lft = prefered_lft; |
2017 | ift->valid_lft = valid_lft + (jiffies - ift->tstamp) / HZ; | 2042 | ift->tstamp = now; |
2018 | if (ift->prefered_lft > prefered_lft && | 2043 | if (prefered_lft > 0) |
2019 | ift->prefered_lft - prefered_lft > (jiffies - ift->tstamp) / HZ) | 2044 | ift->flags &= ~IFA_F_DEPRECATED; |
2020 | ift->prefered_lft = prefered_lft + (jiffies - ift->tstamp) / HZ; | 2045 | |
2021 | spin_unlock(&ift->lock); | 2046 | spin_unlock(&ift->lock); |
2022 | if (!(flags&IFA_F_TENTATIVE)) | 2047 | if (!(flags&IFA_F_TENTATIVE)) |
2023 | ipv6_ifa_notify(0, ift); | 2048 | ipv6_ifa_notify(0, ift); |
@@ -2025,9 +2050,11 @@ ok: | |||
2025 | 2050 | ||
2026 | if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) { | 2051 | if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) { |
2027 | /* | 2052 | /* |
2028 | * When a new public address is created as described in [ADDRCONF], | 2053 | * When a new public address is created as |
2029 | * also create a new temporary address. Also create a temporary | 2054 | * described in [ADDRCONF], also create a new |
2030 | * address if it's enabled but no temporary address currently exists. | 2055 | * temporary address. Also create a temporary |
2056 | * address if it's enabled but no temporary | ||
2057 | * address currently exists. | ||
2031 | */ | 2058 | */ |
2032 | read_unlock_bh(&in6_dev->lock); | 2059 | read_unlock_bh(&in6_dev->lock); |
2033 | ipv6_create_tempaddr(ifp, NULL); | 2060 | ipv6_create_tempaddr(ifp, NULL); |