Netdev List
 help / color / mirror / Atom feed
From: Fernando Fernandez Mancera <fmancera@suse.de>
To: netdev@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org, horms@kernel.org,
	pabeni@redhat.com, kuba@kernel.org, edumazet@google.com,
	dsahern@kernel.org, davem@davemloft.net,
	"Łukasz Stelmach" <steelman@post.pl>,
	"Ido Schimmel" <idosch@nvidia.com>
Subject: Re: [PATCH 1/2 net v4] ipv6: addrconf: fix temp address generation after prefix deprecation
Date: Tue, 12 May 2026 20:24:27 +0200	[thread overview]
Message-ID: <3f371efe-1b1b-464c-af21-ccd66b6c5df6@suse.de> (raw)
In-Reply-To: <20260511122645.6233-2-fmancera@suse.de>

On 5/11/26 2:26 PM, 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 after
> marking the temporary address as already having spawned a replacement
> (ifp->regen_count++).
> 
> When the router eventually restores the prefix, the temporary address
> becomes active again. However, once it naturally expires, the address
> worker sees this temporary address already tried to generate one and
> skips the regeneration.
> 
> Fix this by checking if all temporary addresses for a given prefix have
> already tried to spawn a replacement when processing a new RA. If so,
> spawn a new temporary address.
> 
> 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/
> Suggested-by: Ido Schimmel <idosch@nvidia.com>
> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
> ---
> v2: adjusted commit message, adjusted the implementation to cover all
> race conditions
> v3: regen now if ipv6_create_tempaddr failed due to timer to avoid an
> infinite loop as we restart the loop and we need to check now against
> prefered_lft again.
> v4: change the proposed fix completely, now we address the problem when
> doing manage_tempaddrs().
> ---

Sashiko feedback [1] is right about the DoS, that is a router that sends 
multiple 0-lft RA until it exhausts all spawn attempts, leaving 
temporary addresses disabled on the system.

About the leaked address, I do not think the feedback is right. If an 
ifp does not have any ift, it means something went wrong most likely. 
Either this address was removed manually (any RA would restore it, even 
with previous implementation) or for some reason that prefix didn't get 
an RA but we didn't try to generate one and we MUST do it.

I think we can cover it by avoiding to attempt create a new temporary 
address for a 0-lft RA, it makes sense to me. Something like this:

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 18a6f2de30ce..6c511e9c1bf5 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2654,7 +2654,7 @@ static void manage_tempaddrs(struct inet6_dev *idev,
  	 * We don't want that to result in creating a new temporary ip address.
  	 */
  	if ((list_empty(&idev->tempaddr_list) || all_regen) &&
-	    (valid_lft || prefered_lft))
+	    (valid_lft && prefered_lft))
  		create = true;

  	if (create && READ_ONCE(idev->cnf.use_tempaddr) > 0) {

Any thoughts?

[1] 
https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260511122645.6233-2-fmancera%40suse.de

>   net/ipv6/addrconf.c | 11 ++++++++---
>   1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 5476b6536eb7..18a6f2de30ce 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -2595,8 +2595,9 @@ static void manage_tempaddrs(struct inet6_dev *idev,
>   			     __u32 valid_lft, __u32 prefered_lft,
>   			     bool create, unsigned long now)
>   {
> -	u32 flags;
>   	struct inet6_ifaddr *ift;
> +	bool all_regen = true;
> +	u32 flags;
>   
>   	read_lock_bh(&idev->lock);
>   	/* update all temporary addresses in the list */
> @@ -2637,6 +2638,8 @@ static void manage_tempaddrs(struct inet6_dev *idev,
>   		ift->tstamp = now;
>   		if (prefered_lft > 0)
>   			ift->flags &= ~IFA_F_DEPRECATED;
> +		if (!ift->regen_count)
> +			all_regen = false;
>   
>   		spin_unlock(&ift->lock);
>   		if (!(flags&IFA_F_TENTATIVE))
> @@ -2644,12 +2647,14 @@ static void manage_tempaddrs(struct inet6_dev *idev,
>   	}
>   
>   	/* Also create a temporary address if it's enabled but no temporary
> -	 * address currently exists.
> +	 * address currently exists or if all temporary addresses already
> +	 * generated an address.
>   	 * However, we get called with valid_lft == 0, prefered_lft == 0, create == false
>   	 * as part of cleanup (ie. deleting the mngtmpaddr).
>   	 * We don't want that to result in creating a new temporary ip address.
>   	 */
> -	if (list_empty(&idev->tempaddr_list) && (valid_lft || prefered_lft))
> +	if ((list_empty(&idev->tempaddr_list) || all_regen) &&
> +	    (valid_lft || prefered_lft))
>   		create = true;
>   
>   	if (create && READ_ONCE(idev->cnf.use_tempaddr) > 0) {


      parent reply	other threads:[~2026-05-12 18:24 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-11 12:26 [PATCH 1/2 net v4] ipv6: addrconf: fix temp address generation after prefix deprecation Fernando Fernandez Mancera
2026-05-11 12:26 ` [PATCH 2/2 net v4] selftests: fib_tests: add temporary IPv6 address renewal test Fernando Fernandez Mancera
2026-05-11 17:01   ` Breno Leitao
2026-05-12  0:08     ` Jakub Kicinski
2026-05-12  8:08       ` Breno Leitao
2026-05-12 18:24 ` 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=3f371efe-1b1b-464c-af21-ccd66b6c5df6@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