mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
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
This commit is contained in:
1 parent
0daa334c56
commit
41399ce61b
4 files changed
+20
-5
No files matched your search
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+3
-1
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user