Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 265176
b: refs/heads/master
c: 76f793e
h: refs/heads/master
v: v3
  • Loading branch information
Lorenzo Colitti authored and David S. Miller committed Aug 2, 2011
1 parent fd67a9e commit 2227378
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 79f88ee9836d482891ba41b1a553e2baacf31b02
refs/heads/master: 76f793e3a47139d340185cbc1a314740c09b13d3
2 changes: 1 addition & 1 deletion trunk/include/net/addrconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#define TEMP_VALID_LIFETIME (7*86400)
#define TEMP_PREFERRED_LIFETIME (86400)
#define REGEN_MAX_RETRY (5)
#define REGEN_MAX_RETRY (3)
#define MAX_DESYNC_FACTOR (600)

#define ADDR_CHECK_FREQUENCY (120*HZ)
Expand Down
1 change: 1 addition & 0 deletions trunk/include/net/if_inet6.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct inet6_ifaddr {
struct in6_addr addr;
__u32 prefix_len;

/* In seconds, relative to tstamp. Expiry is at tstamp + HZ * lft. */
__u32 valid_lft;
__u32 prefered_lft;
atomic_t refcnt;
Expand Down
69 changes: 48 additions & 21 deletions trunk/net/ipv6/addrconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -824,12 +824,13 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
{
struct inet6_dev *idev = ifp->idev;
struct in6_addr addr, *tmpaddr;
unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp, age;
unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_tstamp, age;
unsigned long regen_advance;
int tmp_plen;
int ret = 0;
int max_addresses;
u32 addr_flags;
unsigned long now = jiffies;

write_lock(&idev->lock);
if (ift) {
Expand Down Expand Up @@ -874,7 +875,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
goto out;
}
memcpy(&addr.s6_addr[8], idev->rndid, 8);
age = (jiffies - ifp->tstamp) / HZ;
age = (now - ifp->tstamp) / HZ;
tmp_valid_lft = min_t(__u32,
ifp->valid_lft,
idev->cnf.temp_valid_lft + age);
Expand All @@ -884,7 +885,6 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
idev->cnf.max_desync_factor);
tmp_plen = ifp->prefix_len;
max_addresses = idev->cnf.max_addresses;
tmp_cstamp = ifp->cstamp;
tmp_tstamp = ifp->tstamp;
spin_unlock_bh(&ifp->lock);

Expand Down Expand Up @@ -929,7 +929,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
ift->ifpub = ifp;
ift->valid_lft = tmp_valid_lft;
ift->prefered_lft = tmp_prefered_lft;
ift->cstamp = tmp_cstamp;
ift->cstamp = now;
ift->tstamp = tmp_tstamp;
spin_unlock_bh(&ift->lock);

Expand Down Expand Up @@ -1999,35 +1999,62 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
#ifdef CONFIG_IPV6_PRIVACY
read_lock_bh(&in6_dev->lock);
/* update all temporary addresses in the list */
list_for_each_entry(ift, &in6_dev->tempaddr_list, tmp_list) {
/*
* When adjusting the lifetimes of an existing
* temporary address, only lower the lifetimes.
* Implementations must not increase the
* lifetimes of an existing temporary address
* when processing a Prefix Information Option.
*/
list_for_each_entry(ift, &in6_dev->tempaddr_list,
tmp_list) {
int age, max_valid, max_prefered;

if (ifp != ift->ifpub)
continue;

/*
* RFC 4941 section 3.3:
* If a received option will extend the lifetime
* of a public address, the lifetimes of
* temporary addresses should be extended,
* subject to the overall constraint that no
* temporary addresses should ever remain
* "valid" or "preferred" for a time longer than
* (TEMP_VALID_LIFETIME) or
* (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR),
* respectively.
*/
age = (now - ift->cstamp) / HZ;
max_valid = in6_dev->cnf.temp_valid_lft - age;
if (max_valid < 0)
max_valid = 0;

max_prefered = in6_dev->cnf.temp_prefered_lft -
in6_dev->cnf.max_desync_factor -
age;
if (max_prefered < 0)
max_prefered = 0;

if (valid_lft > max_valid)
valid_lft = max_valid;

if (prefered_lft > max_prefered)
prefered_lft = max_prefered;

spin_lock(&ift->lock);
flags = ift->flags;
if (ift->valid_lft > valid_lft &&
ift->valid_lft - valid_lft > (jiffies - ift->tstamp) / HZ)
ift->valid_lft = valid_lft + (jiffies - ift->tstamp) / HZ;
if (ift->prefered_lft > prefered_lft &&
ift->prefered_lft - prefered_lft > (jiffies - ift->tstamp) / HZ)
ift->prefered_lft = prefered_lft + (jiffies - ift->tstamp) / HZ;
ift->valid_lft = valid_lft;
ift->prefered_lft = prefered_lft;
ift->tstamp = now;
if (prefered_lft > 0)
ift->flags &= ~IFA_F_DEPRECATED;

spin_unlock(&ift->lock);
if (!(flags&IFA_F_TENTATIVE))
ipv6_ifa_notify(0, ift);
}

if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) {
/*
* When a new public address is created as described in [ADDRCONF],
* also create a new temporary address. Also create a temporary
* address if it's enabled but no temporary address currently exists.
* When a new public address is created as
* described in [ADDRCONF], also create a new
* temporary address. Also create a temporary
* address if it's enabled but no temporary
* address currently exists.
*/
read_unlock_bh(&in6_dev->lock);
ipv6_create_tempaddr(ifp, NULL);
Expand Down

0 comments on commit 2227378

Please sign in to comment.