net: ipv6/addrconf: introduce a regen_min_advance sysctl
authorAlex Henrie <alexhenrie24@gmail.com>
Wed, 14 Feb 2024 06:26:31 +0000 (23:26 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 15 Feb 2024 14:34:40 +0000 (15:34 +0100)
In RFC 8981, REGEN_ADVANCE cannot be less than 2 seconds, and the RFC
does not permit the creation of temporary addresses with lifetimes
shorter than that:

> When processing a Router Advertisement with a
> Prefix Information option carrying a prefix for the purposes of
> address autoconfiguration (i.e., the A bit is set), the host MUST
> perform the following steps:

> 5.  A temporary address is created only if this calculated preferred
>     lifetime is greater than REGEN_ADVANCE time units.

However, some users want to change their IPv6 address as frequently as
possible regardless of the RFC's arbitrary minimum lifetime. For the
benefit of those users, add a regen_min_advance sysctl parameter that
can be set to below or above 2 seconds.

Link: https://datatracker.ietf.org/doc/html/rfc8981
Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Documentation/networking/ip-sysctl.rst
include/linux/ipv6.h
include/net/addrconf.h
net/ipv6/addrconf.c

index 45830593134536e2c6e34ded39705644d04d917d..407d917d1a367ebadf31b65209f99524e35431fe 100644 (file)
@@ -2535,6 +2535,16 @@ max_desync_factor - INTEGER
 
        Default: 600
 
+regen_min_advance - INTEGER
+       How far in advance (in seconds), at minimum, to create a new temporary
+       address before the current one is deprecated. This value is added to
+       the amount of time that may be required for duplicate address detection
+       to determine when to create a new address. Linux permits setting this
+       value to less than the default of 2 seconds, but a value less than 2
+       does not conform to RFC 8981.
+
+       Default: 2
+
 regen_max_retry - INTEGER
        Number of attempts before give up attempting to generate
        valid temporary addresses.
index 5e605e384aac815edebe293c02ae3e3a06f94ea4..ef3aa060a289ea4eecf4d6e8c1dc614101f37c3f 100644 (file)
@@ -27,6 +27,7 @@ struct ipv6_devconf {
        __s32           use_tempaddr;
        __s32           temp_valid_lft;
        __s32           temp_prefered_lft;
+       __s32           regen_min_advance;
        __s32           regen_max_retry;
        __s32           max_desync_factor;
        __s32           max_addresses;
index 61ebe723ee4d5078afdeec1ec70d392d0ef54ec4..30d6f1e84e465e06a88bbbffaee70fdbd4ec5dd3 100644 (file)
@@ -8,8 +8,9 @@
 
 #define MIN_VALID_LIFETIME             (2*3600)        /* 2 hours */
 
-#define TEMP_VALID_LIFETIME            (7*86400)
-#define TEMP_PREFERRED_LIFETIME                (86400)
+#define TEMP_VALID_LIFETIME            (7*86400)       /* 1 week */
+#define TEMP_PREFERRED_LIFETIME                (86400)         /* 24 hours */
+#define REGEN_MIN_ADVANCE              (2)             /* 2 seconds */
 #define REGEN_MAX_RETRY                        (3)
 #define MAX_DESYNC_FACTOR              (600)
 
index 65e886d7d80cc995660fb7078d40591ce02ab735..283823fba96a84c3d52c9dd53a14cffdcaf52354 100644 (file)
@@ -195,6 +195,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
        .use_tempaddr           = 0,
        .temp_valid_lft         = TEMP_VALID_LIFETIME,
        .temp_prefered_lft      = TEMP_PREFERRED_LIFETIME,
+       .regen_min_advance      = REGEN_MIN_ADVANCE,
        .regen_max_retry        = REGEN_MAX_RETRY,
        .max_desync_factor      = MAX_DESYNC_FACTOR,
        .max_addresses          = IPV6_MAX_ADDRESSES,
@@ -257,6 +258,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
        .use_tempaddr           = 0,
        .temp_valid_lft         = TEMP_VALID_LIFETIME,
        .temp_prefered_lft      = TEMP_PREFERRED_LIFETIME,
+       .regen_min_advance      = REGEN_MIN_ADVANCE,
        .regen_max_retry        = REGEN_MAX_RETRY,
        .max_desync_factor      = MAX_DESYNC_FACTOR,
        .max_addresses          = IPV6_MAX_ADDRESSES,
@@ -1341,7 +1343,7 @@ out:
 
 static unsigned long ipv6_get_regen_advance(struct inet6_dev *idev)
 {
-       return 2 + idev->cnf.regen_max_retry *
+       return idev->cnf.regen_min_advance + idev->cnf.regen_max_retry *
                        idev->cnf.dad_transmits *
                        max(NEIGH_VAR(idev->nd_parms, RETRANS_TIME), HZ/100) / HZ;
 }
@@ -6819,6 +6821,13 @@ static const struct ctl_table addrconf_sysctl[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
+       {
+               .procname       = "regen_min_advance",
+               .data           = &ipv6_devconf.regen_min_advance,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec,
+       },
        {
                .procname       = "regen_max_retry",
                .data           = &ipv6_devconf.regen_max_retry,