diff mbox

ipv6: Avoid unnecessary temporary addresses being generated

Message ID 5320BB4C.9060400@web.de
State Changes Requested, archived
Delegated to: David Miller
Headers show

Commit Message

Heiner Kallweit March 12, 2014, 7:53 p.m. UTC
tmp_prefered_lft is an offset to ifp->tstamp, not now. Therefore
age needs to be added to the condition.

Age calculation in ipv6_create_tempaddr is different from the one
in addrconf_verify and doesn't consider ADDRCONF_TIMER_FUZZ_MINUS.
This can cause age in ipv6_create_tempaddr to be less than the one
in addrconf_verify and therefore unnecessary temporary address to
be generated.
Use age calculation as in addrconf_modify to avoid this.

Signed-off-by: Heiner Kallweit <heiner.kallweit@web.de>
---
 net/ipv6/addrconf.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

David Miller March 12, 2014, 8:48 p.m. UTC | #1
From: Heiner Kallweit <heiner.kallweit@web.de>
Date: Wed, 12 Mar 2014 20:53:48 +0100

> @@ -1103,8 +1103,11 @@ retry:
>  	 * Lifetime is greater than REGEN_ADVANCE time units.  In particular,
>  	 * an implementation must not create a temporary address with a zero
>  	 * Preferred Lifetime.
> +	 * Use age calculation as in addrconf_verify to avoid unnecessary
> +	 * temporary addresses being generated.
>  	 */
> -	if (tmp_prefered_lft <= regen_advance) {
> +	age = (now - ifp->tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
> +	if (tmp_prefered_lft <= regen_advance + age) {

I think you must use tmp_tstamp here, we snapshot all of the values
above into local variables while holding the lock so that we calculate
a consistent set of values and tests.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Heiner Kallweit March 12, 2014, 9:16 p.m. UTC | #2
You're right. Fixed it and submitted v2 of patch.

> From: Heiner Kallweit <heiner.kallweit@web.de>
> Date: Wed, 12 Mar 2014 20:53:48 +0100
>
>> @@ -1103,8 +1103,11 @@ retry:
>>  	 * Lifetime is greater than REGEN_ADVANCE time units.  In particular,
>>  	 * an implementation must not create a temporary address with a zero
>>  	 * Preferred Lifetime.
>> +	 * Use age calculation as in addrconf_verify to avoid unnecessary
>> +	 * temporary addresses being generated.
>>  	 */
>> -	if (tmp_prefered_lft <= regen_advance) {
>> +	age = (now - ifp->tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
>> +	if (tmp_prefered_lft <= regen_advance + age) {
> I think you must use tmp_tstamp here, we snapshot all of the values
> above into local variables while holding the lock so that we calculate
> a consistent set of values and tests.
>

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index fdbfeca..bd64dbe 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1103,8 +1103,11 @@  retry:
 	 * Lifetime is greater than REGEN_ADVANCE time units.  In particular,
 	 * an implementation must not create a temporary address with a zero
 	 * Preferred Lifetime.
+	 * Use age calculation as in addrconf_verify to avoid unnecessary
+	 * temporary addresses being generated.
 	 */
-	if (tmp_prefered_lft <= regen_advance) {
+	age = (now - ifp->tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
+	if (tmp_prefered_lft <= regen_advance + age) {
 		in6_ifa_put(ifp);
 		in6_dev_put(idev);
 		ret = -1;