aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Wurster <gwurster@scs.carleton.ca>2010-09-27 03:10:10 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-26 15:35:13 -0400
commit7a876b0efcba3804da3051313445fa7be751cab7 (patch)
tree2135dfa1c8ffa8807e831d0817f49a31caf22cc2
parentaed65501e8c072b52c5b4dc807cd938659329673 (diff)
IPv6: Temp addresses are immediately deleted.
There is a bug in the interaction between ipv6_create_tempaddr and addrconf_verify. Because ipv6_create_tempaddr uses the cstamp and tstamp from the public address in creating a private address, if we have not received a router advertisement in a while, tstamp + temp_valid_lft might be < now. If this happens, the new address is created inside ipv6_create_tempaddr, then the loop within addrconf_verify starts again and the address is immediately deleted. We are left with no temporary addresses on the interface, and no more will be created until the public IP address is updated. To avoid this, set the expiry time to be the minimum of the time left on the public address or the config option PLUS the current age of the public interface. Signed-off-by: Glenn Wurster <gwurster@scs.carleton.ca> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv6/addrconf.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 8ed6763dae96..ef6fc16ae5d9 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -836,7 +836,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
836{ 836{
837 struct inet6_dev *idev = ifp->idev; 837 struct inet6_dev *idev = ifp->idev;
838 struct in6_addr addr, *tmpaddr; 838 struct in6_addr addr, *tmpaddr;
839 unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp; 839 unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp, age;
840 unsigned long regen_advance; 840 unsigned long regen_advance;
841 int tmp_plen; 841 int tmp_plen;
842 int ret = 0; 842 int ret = 0;
@@ -886,12 +886,13 @@ retry:
886 goto out; 886 goto out;
887 } 887 }
888 memcpy(&addr.s6_addr[8], idev->rndid, 8); 888 memcpy(&addr.s6_addr[8], idev->rndid, 8);
889 age = (jiffies - ifp->tstamp) / HZ;
889 tmp_valid_lft = min_t(__u32, 890 tmp_valid_lft = min_t(__u32,
890 ifp->valid_lft, 891 ifp->valid_lft,
891 idev->cnf.temp_valid_lft); 892 idev->cnf.temp_valid_lft + age);
892 tmp_prefered_lft = min_t(__u32, 893 tmp_prefered_lft = min_t(__u32,
893 ifp->prefered_lft, 894 ifp->prefered_lft,
894 idev->cnf.temp_prefered_lft - 895 idev->cnf.temp_prefered_lft + age -
895 idev->cnf.max_desync_factor); 896 idev->cnf.max_desync_factor);
896 tmp_plen = ifp->prefix_len; 897 tmp_plen = ifp->prefix_len;
897 max_addresses = idev->cnf.max_addresses; 898 max_addresses = idev->cnf.max_addresses;