git: 61f98a98250d - main - nd6: Fix regeneration of temp addresses in detached state
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 28 Sep 2026 15:47:30 UTC
The branch main has been updated by pouria:
URL: https://cgit.FreeBSD.org/src/commit/?id=61f98a98250da7bd2c80c6d93d0032961d7f2fad
commit 61f98a98250da7bd2c80c6d93d0032961d7f2fad
Author: Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
AuthorDate: 2026-09-26 19:54:16 +0000
Commit: Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
CommitDate: 2026-09-28 15:46:53 +0000
nd6: Fix regeneration of temp addresses in detached state
When an on-link prefix becomes detached, the kernel keeps
generating new RFC 8981 temporary addresses for that prefix.
Fix it by ignoring the detached addresses in regen_tmpaddr().
While here, change its return type to bool.
PR: 298533
Discussed with: markj
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D60051
---
sys/netinet6/nd6.c | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index cc9246475e40..3af6887a9a30 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -148,7 +148,7 @@ int (*send_sendso_input_hook)(struct mbuf *, struct ifnet *, int, int);
static bool nd6_is_new_addr_neighbor(const struct sockaddr_in6 *,
struct ifnet *);
static void nd6_slowtimo(void *);
-static int regen_tmpaddr(struct in6_ifaddr *);
+static bool regen_tmpaddr(struct in6_ifaddr *);
static void nd6_free(struct llentry **, int);
static void nd6_free_redirect(const struct llentry *);
static void nd6_llinfo_timer(void *);
@@ -976,7 +976,7 @@ nd6_timer(void *arg)
CK_STAILQ_FOREACH_SAFE(ia6, &V_in6_ifaddrhead, ia_link, nia6) {
/* check address lifetime */
if (IFA6_IS_INVALID(ia6)) {
- int regen = 0;
+ bool regen = false;
/*
* If the expiring address is temporary, try
@@ -990,8 +990,8 @@ nd6_timer(void *arg)
*/
if (V_ip6_use_tempaddr &&
(ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0) {
- if (regen_tmpaddr(ia6) == 0)
- regen = 1;
+ if (regen_tmpaddr(ia6))
+ regen = true;
}
in6_purgeaddr(&ia6->ia_ifa);
@@ -1010,7 +1010,7 @@ nd6_timer(void *arg)
if (V_ip6_use_tempaddr &&
(ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0 &&
(oldflags & IN6_IFF_DEPRECATED) == 0) {
- if (regen_tmpaddr(ia6) == 0) {
+ if (regen_tmpaddr(ia6)) {
/*
* A new temporary address is
* generated.
@@ -1111,7 +1111,7 @@ restart:
/*
* ia6 - deprecated/invalidated temporary address
*/
-static int
+static bool
regen_tmpaddr(struct in6_ifaddr *ia6)
{
struct ifaddr *ifa;
@@ -1120,6 +1120,11 @@ regen_tmpaddr(struct in6_ifaddr *ia6)
NET_EPOCH_ASSERT();
+ /* ignore detached prefixes */
+ if (ia6->ia6_ndpr == NULL ||
+ (ia6->ia6_ndpr->ndpr_stateflags & NDPRF_DETACHED) != 0)
+ return (false);
+
ifp = ia6->ia_ifa.ifa_ifp;
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
struct in6_ifaddr *it6;
@@ -1129,12 +1134,13 @@ regen_tmpaddr(struct in6_ifaddr *ia6)
it6 = (struct in6_ifaddr *)ifa;
- /* ignore no autoconf addresses. */
- if ((it6->ia6_flags & IN6_IFF_AUTOCONF) == 0)
+ /* ignore detached or no autoconf addresses. */
+ if ((it6->ia6_flags &
+ (IN6_IFF_AUTOCONF | IN6_IFF_DETACHED)) != IN6_IFF_AUTOCONF)
continue;
/* ignore autoconf addresses with different prefixes. */
- if (it6->ia6_ndpr == NULL || it6->ia6_ndpr != ia6->ia6_ndpr)
+ if (it6->ia6_ndpr != ia6->ia6_ndpr)
continue;
/*
@@ -1169,13 +1175,13 @@ regen_tmpaddr(struct in6_ifaddr *ia6)
ifa_free(&public_ifa6->ia_ifa);
log(LOG_NOTICE, "regen_tmpaddr: failed to create a new"
" tmp addr,errno=%d\n", e);
- return (-1);
+ return (false);
}
ifa_free(&public_ifa6->ia_ifa);
- return (0);
+ return (true);
}
- return (-1);
+ return (false);
}
/*