diff options
-rw-r--r-- | Documentation/networking/ip-sysctl.rst | 10 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 19 |
2 files changed, 22 insertions, 7 deletions
diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index e7ec9026e5db..4dfe0d9a57bb 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -2502,12 +2502,18 @@ use_tempaddr - INTEGER * -1 (for point-to-point devices and loopback devices) temp_valid_lft - INTEGER - valid lifetime (in seconds) for temporary addresses. + valid lifetime (in seconds) for temporary addresses. If less than the + minimum required lifetime (typically 5 seconds), temporary addresses + will not be created. Default: 172800 (2 days) temp_prefered_lft - INTEGER - Preferred lifetime (in seconds) for temporary addresses. + Preferred lifetime (in seconds) for temporary addresses. If + temp_prefered_lft is less than the minimum required lifetime (typically + 5 seconds), the preferred lifetime is the minimum required. If + temp_prefered_lft is greater than temp_valid_lft, the preferred lifetime + is temp_valid_lft. Default: 86400 (1 day) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index c2d471ad7922..3aaea56b5166 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1399,6 +1399,7 @@ retry: idev->cnf.temp_valid_lft + age); cfg.preferred_lft = cnf_temp_preferred_lft + age - idev->desync_factor; cfg.preferred_lft = min_t(__u32, ifp->prefered_lft, cfg.preferred_lft); + cfg.preferred_lft = min_t(__u32, cfg.valid_lft, cfg.preferred_lft); cfg.plen = ifp->prefix_len; tmp_tstamp = ifp->tstamp; @@ -1406,15 +1407,23 @@ retry: write_unlock_bh(&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. + /* From RFC 4941: + * + * 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. + * + * Clamp the preferred lifetime to a minimum of regen_advance, unless + * that would exceed valid_lft. + * * Use age calculation as in addrconf_verify to avoid unnecessary * temporary addresses being generated. */ age = (now - tmp_tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ; - if (cfg.preferred_lft <= regen_advance + age) { + if (cfg.preferred_lft <= regen_advance + age) + cfg.preferred_lft = regen_advance + age + 1; + if (cfg.preferred_lft > cfg.valid_lft) { in6_ifa_put(ifp); in6_dev_put(idev); ret = -1; |