Re: [REGRESSION] net/ipv6/addrconf: Temporary addresses with short lifetimes generating when they shouldn't, causing applications to fail

From: Alex Henrie
Date: Fri Dec 29 2023 - 23:13:12 EST


On Fri, Dec 29, 2023 at 9:33 AM Dan Moulding <dan@xxxxxxxx> wrote:
>
> I think a maintainer will probably need to make a call here and decide
> how to proceed.
>
> > TEMP_PREFERRED_LIFETIME is an administratively set variable: The user
> > can change it to whatever they want whenever they want, and the
> > operating system can adjust it automatically too.
>
> Agreed. And the behavior it seems you really want is to prevent the
> user from administratively setting it to a value that is lower than
> REGEN_ADVANCE, so that it won't stop generating new temporary
> addresses altogether.
>
> But preventing the user from configuring it to a value that is too low
> is different from generating new temporary addresses with preferred
> lifetimes that are greater than the currently configured value of
> TEMP_PREFERRED_LIFETIME. I still believe it would be better, and would
> be in conformance with the RFC, to simply not allow the user to
> configure a too-short TEMP_PREFERRED_LIFETIME instead of tinkering
> with the lifetimes of generated temporary addresses.

In RFC 4941, REGEN_ADVANCE is a constant value of 5 seconds.[1]
However, Linux uses a variable regen_advance that depends on the
Retrans Timer value in the router advertisement.[2][3][4] Let's
imagine that when the user tries to set
/proc/sys/net/ipv6/conf/*/temp_prefered_lft to 3 seconds, they get an
error message that says "Sorry, the network requires at least 4
seconds." After a few minutes, network conditions change, and now 5
seconds is the minimum. Should the kernel just give up on using
private addresses? Or, the minimum might drop to 3 seconds, which is
what the user really wanted. Should the operating system tell the user
to change the value?

What I think you're getting at is that Linux might be violating the
spec by allowing TEMP_PREFERRED_LIFETIME to be less than 5 seconds.
The RFC says: [5]

> When processing a Router Advertisement with a Prefix
> Information option carrying a global scope prefix for the purposes of
> address autoconfiguration (i.e., the A bit is set), the node MUST
> perform the following steps:

> 5. A temporary address is created only if this calculated Preferred
> Lifetime is greater than REGEN_ADVANCE time units.

The right solution might be to make Linux use a constant value for
REGEN_ADVANCE instead of a variable. I think that's how it used to
work before commit 76506a986dc3 (IPv6: fix DESYNC_FACTOR,
2016-10-13).[6] If regen_advance can't change depending on network
conditions then it can't cause private address generation to randomly
stop working. I don't understand why the protocol would require
REGEN_ADVANCE to be a constant, but interpreting the RFC literally, it
would seem that Linux is technically non-compliant.

-Alex

[1] https://datatracker.ietf.org/doc/html/rfc4941#section-5
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv6/addrconf.c?h=v6.7-rc7#n1377
[3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv6/ndisc.c?h=v6.7-rc7#n1438
[4] https://datatracker.ietf.org/doc/html/rfc4861#section-4.2
[5] https://datatracker.ietf.org/doc/html/rfc4941#section-3.3
[6] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76506a986dc31394fd1f2741db037d29c7e57843