Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 20 Jun 2025 16:17:03 GMT
From:      Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= <des@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 41399ce61bcc - main - inet6: RFC 8981 SLAAC Temporary Address Extensions
Message-ID:  <202506201617.55KGH31w024827@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=41399ce61bcc56711cba3fed1ab5b4e72c937576

commit 41399ce61bcc56711cba3fed1ab5b4e72c937576
Author:     Marek Zarychta <zarychtam@plan-b.pwste.edu.pl>
AuthorDate: 2025-05-17 06:56:20 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-06-20 16:16:21 +0000

    inet6: RFC 8981 SLAAC Temporary Address Extensions
    
    Deprecate the use of MD5 as the algorithm for generating temporary
    interface identifiers (IIDs) for IPv6 addresses, improving cryptographic
    robustness.
    
    Introduce per-address randomized IIDs, ensuring that each temporary
    address uses a distinct interface identifier to enhance privacy and
    avoid correlation across addresses.
    
    Update the IID generation logic to respect the Reserved IPv6 Interface
    Identifiers list.
    
    Enhance sysctl_ip6_temppltime() so that ip6_temp_max_desync_factor is
    dynamically recalculated whenever ip6_temp_preferred_lifetime is updated
    via sysctl. This ensures that MAX_DESYNC_FACTOR remains approximately
    1/32 of the preferred lifetime plus 10 minutes. DESYNC_FACTOR is also
    regenerated after each update.
    
    Timers related to temporary address regeneration were updated to match
    the design recommendations in RFC 8981.
    
    A new read-only sysctl variable net.inet6.ip6.temp_max_desync_factor
    is introduced to expose the computed value of MAX_DESYNC_FACTOR to
    userland for observability and debugging.
    
    Input validation to reject temppltime values too small or too large is
    included.
    
    This all brings the temporary address lifetime handling closer to the
    intended design in RFC 8981 and improves robustness against
    misconfiguration.
    
    PR:             245103
    MFC after:      1 month
    Differential Revision:  https://reviews.freebsd.org/D50108
---
 sys/netinet6/in6_proto.c |  8 ++++++--
 sys/netinet6/ip6_input.c | 10 +++++++++-
 sys/netinet6/nd6.h       |  4 +++-
 sys/netinet6/nd6_rtr.c   |  3 ++-
 4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index 8541e19eebf8..b289d4eeb0a2 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -217,15 +217,19 @@ SYSCTL_NODE(_net_inet6,	IPPROTO_ESP, ipsec6, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
 static int
 sysctl_ip6_temppltime(SYSCTL_HANDLER_ARGS)
 {
-	int error, val;
+	int error, val, ndf;
 
 	val = V_ip6_temp_preferred_lifetime;
 	error = sysctl_handle_int(oidp, &val, 0, req);
 	if (error != 0 || !req->newptr)
 		return (error);
-	if (val < V_ip6_desync_factor + V_ip6_temp_regen_advance)
+	ndf =  TEMP_MAX_DESYNC_FACTOR_BASE + (val >> 2) + (val >> 3);
+	if (val < ndf + V_ip6_temp_regen_advance ||
+	    val > V_ip6_temp_valid_lifetime)
 		return (EINVAL);
 	V_ip6_temp_preferred_lifetime = val;
+	V_ip6_temp_max_desync_factor = ndf;
+	V_ip6_desync_factor = arc4random() % ndf;
 	return (0);
 }
 
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 68e4be66537b..45fd23ea6c21 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -173,6 +173,11 @@ SYSCTL_BOOL(_net_inet6_ip6, OID_AUTO, source_address_validation,
     CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_sav), true,
     "Drop incoming packets with source address that is a local address");
 
+SYSCTL_UINT(_net_inet6_ip6, OID_AUTO, temp_max_desync_factor,
+    CTLFLAG_RD | CTLFLAG_VNET,
+    &VNET_NAME(ip6_temp_max_desync_factor), 0,
+    "RFC 8981 max desync factor");
+
 #ifdef RSS
 static struct netisr_handler ip6_direct_nh = {
 	.nh_name = "ip6_direct",
@@ -262,7 +267,10 @@ ip6_vnet_init(void *arg __unused)
 	nd6_init();
 	frag6_init();
 
-	V_ip6_desync_factor = arc4random() % MAX_TEMP_DESYNC_FACTOR;
+	V_ip6_temp_max_desync_factor = TEMP_MAX_DESYNC_FACTOR_BASE +
+	    (V_ip6_temp_preferred_lifetime >> 2) +
+	    (V_ip6_temp_preferred_lifetime >> 3);
+	V_ip6_desync_factor = arc4random() % V_ip6_temp_max_desync_factor;
 
 	/* Skip global initialization stuff for non-default instances. */
 #ifdef VIMAGE
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index f8cf99cf09ac..9cb2571da58b 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -187,7 +187,7 @@ struct	in6_ndifreq {
 #define DEF_TEMP_VALID_LIFETIME		172800	/* 2 days */
 #define DEF_TEMP_PREFERRED_LIFETIME	86400	/* 1 day */
 #define TEMPADDR_REGEN_ADVANCE		5	/* sec */
-#define MAX_TEMP_DESYNC_FACTOR		600	/* 10 min */
+#define TEMP_MAX_DESYNC_FACTOR_BASE	300	/* 5 min */
 #define ND_COMPUTE_RTIME(x) \
 		(((MIN_RANDOM_FACTOR * (x >> 10)) + (arc4random() & \
 		((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000)
@@ -292,11 +292,13 @@ VNET_DECLARE(struct mtx, nd6_onlink_mtx);
 /* nd6_rtr.c */
 VNET_DECLARE(int, nd6_defifindex);
 VNET_DECLARE(int, ip6_desync_factor);	/* seconds */
+VNET_DECLARE(uint32_t, ip6_temp_max_desync_factor); /* seconds */
 VNET_DECLARE(u_int32_t, ip6_temp_preferred_lifetime); /* seconds */
 VNET_DECLARE(u_int32_t, ip6_temp_valid_lifetime); /* seconds */
 VNET_DECLARE(int, ip6_temp_regen_advance); /* seconds */
 #define	V_nd6_defifindex		VNET(nd6_defifindex)
 #define	V_ip6_desync_factor		VNET(ip6_desync_factor)
+#define	V_ip6_temp_max_desync_factor	VNET(ip6_temp_max_desync_factor)
 #define	V_ip6_temp_preferred_lifetime	VNET(ip6_temp_preferred_lifetime)
 #define	V_ip6_temp_valid_lifetime	VNET(ip6_temp_valid_lifetime)
 #define	V_ip6_temp_regen_advance	VNET(ip6_temp_regen_advance)
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index d9edb0d3e930..b9af0a78a584 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -94,6 +94,7 @@ VNET_DEFINE(int, nd6_defifindex);
 VNET_DEFINE(int, ip6_use_tempaddr) = 0;
 
 VNET_DEFINE(int, ip6_desync_factor);
+VNET_DEFINE(uint32_t, ip6_temp_max_desync_factor) = TEMP_MAX_DESYNC_FACTOR_BASE;
 VNET_DEFINE(u_int32_t, ip6_temp_preferred_lifetime) = DEF_TEMP_PREFERRED_LIFETIME;
 VNET_DEFINE(u_int32_t, ip6_temp_valid_lifetime) = DEF_TEMP_VALID_LIFETIME;
 
@@ -2229,7 +2230,7 @@ restart:
 
 /*
  * Get a randomized interface identifier for a temporary address
- * <draft-ietf-6man-rfc4941bis-08.txt>, Section 3.3.1.
+ * Based on RFC 8981, Section 3.3.1.
  */
 static int
 in6_get_tmp_ifid(struct in6_aliasreq *ifra)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202506201617.55KGH31w024827>