diff options
author | Benoit Boissinot <benoit.boissinot@ens-lyon.org> | 2008-04-02 00:01:35 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-02 00:01:35 -0700 |
commit | eac55bf97094f6b64116426864cf4666ef7587bc (patch) | |
tree | 467776de93a7fdbb75904dbd702f7c417e18aa69 /net/ipv6 | |
parent | c6fbfac2e61c9a8617f64b93e8c990b8d864bce5 (diff) | |
download | op-kernel-dev-eac55bf97094f6b64116426864cf4666ef7587bc.zip op-kernel-dev-eac55bf97094f6b64116426864cf4666ef7587bc.tar.gz |
IPv6: do not create temporary adresses with too short preferred lifetime
From RFC341:
A temporary address is created only if this calculated Preferred
Lifetime is greater than REGEN_ADVANCE time units. In particular, an
implementation must not create a temporary address with a zero
Preferred Lifetime.
Signed-off-by: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e11f10e..e7a1882 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 struct inet6_dev *idev = ifp->idev; struct in6_addr addr, *tmpaddr; unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp; + unsigned long regen_advance; int tmp_plen; int ret = 0; int max_addresses; @@ -836,8 +837,23 @@ retry: tmp_tstamp = ifp->tstamp; spin_unlock_bh(&ifp->lock); + regen_advance = idev->cnf.regen_max_retry * + idev->cnf.dad_transmits * + idev->nd_parms->retrans_time / HZ; write_unlock(&idev->lock); + /* A temporary address is created only if this calculated Preferred + * Lifetime is greater than REGEN_ADVANCE time units. In particular, + * an implementation must not create a temporary address with a zero + * Preferred Lifetime. + */ + if (tmp_prefered_lft <= regen_advance) { + in6_ifa_put(ifp); + in6_dev_put(idev); + ret = -1; + goto out; + } + addr_flags = IFA_F_TEMPORARY; /* set in addrconf_prefix_rcv() */ if (ifp->flags & IFA_F_OPTIMISTIC) |