aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2011-07-26 09:50:49 -0400
committerDavid S. Miller <davem@davemloft.net>2011-08-01 21:05:00 -0400
commit76f793e3a47139d340185cbc1a314740c09b13d3 (patch)
tree9abd3f1753cb10d328cc87db365910ef2181ea69 /net/ipv6/addrconf.c
parent79f88ee9836d482891ba41b1a553e2baacf31b02 (diff)
ipv6: updates to privacy addresses per RFC 4941.
Update the code to handle some of the differences between RFC 3041 and RFC 4941, which obsoletes it. Also a couple of janitorial fixes. - Allow router advertisements to increase the lifetime of temporary addresses. This was not allowed by RFC 3041, but is specified by RFC 4941. It is useful when RA lifetimes are lower than TEMP_{VALID,PREFERRED}_LIFETIME: in this case, the previous code would delete or deprecate addresses prematurely. - Change the default of MAX_RETRY to 3 per RFC 4941. - Add a comment to clarify that the preferred and valid lifetimes in inet6_ifaddr are relative to the timestamp. - Shorten lines to 80 characters in a couple of places. Signed-off-by: Lorenzo Colitti <lorenzo@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c69
1 files changed, 48 insertions, 21 deletions
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);