From: Fernando Fernandez Mancera <fmancera@suse.de>
To: Ido Schimmel <idosch@nvidia.com>
Cc: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org,
horms@kernel.org, pabeni@redhat.com, kuba@kernel.org,
edumazet@google.com, davem@davemloft.net, dsahern@kernel.org,
"Łukasz Stelmach" <steelman@post.pl>
Subject: Re: [PATCH 1/2 net] ipv6: addrconf: fix temp address generation after prefix deprecation
Date: Tue, 5 May 2026 00:58:30 +0200 [thread overview]
Message-ID: <c6b575dc-e4f9-4333-8175-277d49d1cdc0@suse.de> (raw)
In-Reply-To: <2532adc0-262e-433a-9b69-df6d49f662c4@suse.de>
On 5/4/26 9:51 PM, Fernando Fernandez Mancera wrote:
> On 5/4/26 6:35 PM, Ido Schimmel wrote:
>> On Mon, May 04, 2026 at 12:11:40AM +0200, Fernando Fernandez Mancera
>> wrote:
>>> When a router temporarily deprecates an IPv6 prefix (either by sending a
>>> Router Advertisement with Preferred Lifetime = 0 or by letting the
>>> lifetime expire) and later restores it, the kernel permanently loses its
>>> ability to generate temporary privacy addresses (RFC 8981) for that
>>> prefix.
>>>
>>> This happens because the address worker attempts to generate a
>>> replacement temporary address when the current one nears expiration. As
>>> the base prefix is deprecated already, the generation fails, burning the
>>> retry counter for temporary address generation of that prefix.
>>>
>>> When the router eventually restores the prefix, the temporary address
>>> becomes active again. However, once it naturally expires, the kernel
>>> sees the exhausted retry limit and permanently stops generating new
>>> privacy addresses.
>>
>> It's not clear to me to which "retry counter" you are referring to. Are
>> you referring to the counter of the temporary address or to that of the
>> "public address" from which it was generated?
>>
>> AFAICT, in the case of temporary addresses (those w/o "mngtmpaddr") this
>> isn't really a counter, but a boolean that tells you if an address was
>> already spawned from this address.
>>
>>>
>>> Fix this by verifying that the base prefix has sufficient preferred
>>> lifetime remaining before attempting to generate a new temporary
>>> address. This prevents the worker from burning through its retry counter
>>> during temporary network deprecation events like a router reboot.
>>
>> Again, I think that "retry counter" here is confusing. IIUC, what
>> happens is that the kernel marks the temporary address as having spawned
>> an address ('ifp->regen_count++'), then tries to spawn an address by
>> calling ipv6_create_tempaddr(), which fails because the preferred
>> lifetime of the public address is 0.
>>
>
> Yes, you are right. I used the word counter as the variable was ifp-
> >regen_count although for temporary addresses it is just a boolean. Let
> me modify the commit message to make it clear.
>
> Thanks Ido for reviewing!
>
I have checked sashiko feedback and it spotted another race condition.
To fix this altogether I believe we could improve ipv6_create_tempaddr()
to return meaningful return value. This way we could catch a
-ETIME/-ETIMEDOUT and reset the regen_count on the temporary address.
https://sashiko.dev/#/patchset/20260503221139.3742-3-fmancera%40suse.de?part=1
>>>
>>> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
>>> Reported-by: Łukasz Stelmach <steelman@post.pl>
>>> Closes: https://lore.kernel.org/
>>> netdev/87340td30q.fsf%25steelman@post.pl/
>>> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
>>> ---
>>> net/ipv6/addrconf.c | 4 +++-
>>> 1 file changed, 3 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
>>> index 5476b6536eb7..f6a3d9da3cb1 100644
>>> --- a/net/ipv6/addrconf.c
>>> +++ b/net/ipv6/addrconf.c
>>> @@ -4654,9 +4654,11 @@ static void addrconf_verify_rtnl(struct net *net)
>>> !ifp->regen_count && ifp->ifpub) {
>>> /* This is a non-regenerated temporary addr. */
>>> + unsigned long pub_age = (now - READ_ONCE(ifp->ifpub-
>>> >tstamp)) / HZ;
>>> unsigned long regen_advance =
>>> ipv6_get_regen_advance(ifp->idev);
>>> - if (age + regen_advance >= ifp->prefered_lft) {
>>> + if (age + regen_advance >= ifp->prefered_lft &&
>>> + pub_age + regen_advance < READ_ONCE(ifp->ifpub-
>>> >prefered_lft)) {
>>> struct inet6_ifaddr *ifpub = ifp->ifpub;
>>> if (time_before(ifp->tstamp + ifp->prefered_lft
>>> * HZ, next))
>>> next = ifp->tstamp + ifp->prefered_lft * HZ;
>>> --
>>> 2.53.0
>>>
>
prev parent reply other threads:[~2026-05-04 22:58 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-03 22:11 [PATCH 1/2 net] ipv6: addrconf: fix temp address generation after prefix deprecation Fernando Fernandez Mancera
2026-05-03 22:11 ` [PATCH 2/2 net] selftests: fib_tests: add temporary IPv6 address renewal test Fernando Fernandez Mancera
2026-05-04 16:41 ` Ido Schimmel
2026-05-04 19:45 ` Fernando Fernandez Mancera
2026-05-04 16:35 ` [PATCH 1/2 net] ipv6: addrconf: fix temp address generation after prefix deprecation Ido Schimmel
2026-05-04 19:51 ` Fernando Fernandez Mancera
2026-05-04 22:58 ` Fernando Fernandez Mancera [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c6b575dc-e4f9-4333-8175-277d49d1cdc0@suse.de \
--to=fmancera@suse.de \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=kuba@kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=steelman@post.pl \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox