net: ipv6/addrconf: ensure that regen_advance is at least 2 seconds
authorAlex Henrie <alexhenrie24@gmail.com>
Wed, 14 Feb 2024 06:26:30 +0000 (23:26 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 15 Feb 2024 14:34:40 +0000 (15:34 +0100)
RFC 8981 defines REGEN_ADVANCE as follows:

REGEN_ADVANCE = 2 + (TEMP_IDGEN_RETRIES * DupAddrDetectTransmits * RetransTimer / 1000)

Thus, allowing it to be less than 2 seconds is technically a protocol
violation.

Link: https://datatracker.ietf.org/doc/html/rfc8981#name-defined-protocol-parameters
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
net/ipv6/addrconf.c

index 7afff42612e949c912c4ff8a5abc5bfe55842a79..45830593134536e2c6e34ded39705644d04d917d 100644 (file)
@@ -2503,7 +2503,7 @@ use_tempaddr - INTEGER
 
 temp_valid_lft - INTEGER
        valid lifetime (in seconds) for temporary addresses. If less than the
-       minimum required lifetime (typically 5 seconds), temporary addresses
+       minimum required lifetime (typically 5-7 seconds), temporary addresses
        will not be created.
 
        Default: 172800 (2 days)
@@ -2511,7 +2511,7 @@ temp_valid_lft - INTEGER
 temp_prefered_lft - INTEGER
        Preferred lifetime (in seconds) for temporary addresses. If
        temp_prefered_lft is less than the minimum required lifetime (typically
-       5 seconds), temporary addresses will not be created. If
+       5-7 seconds), temporary addresses will not be created. If
        temp_prefered_lft is greater than temp_valid_lft, the preferred lifetime
        is temp_valid_lft.
 
index 2c1ed642e3f45658611f5f43b60ef400f834f4e9..65e886d7d80cc995660fb7078d40591ce02ab735 100644 (file)
@@ -1339,6 +1339,13 @@ out:
        in6_ifa_put(ifp);
 }
 
+static unsigned long ipv6_get_regen_advance(struct inet6_dev *idev)
+{
+       return 2 + idev->cnf.regen_max_retry *
+                       idev->cnf.dad_transmits *
+                       max(NEIGH_VAR(idev->nd_parms, RETRANS_TIME), HZ/100) / HZ;
+}
+
 static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, bool block)
 {
        struct inet6_dev *idev = ifp->idev;
@@ -1380,9 +1387,7 @@ retry:
 
        age = (now - ifp->tstamp) / HZ;
 
-       regen_advance = idev->cnf.regen_max_retry *
-                       idev->cnf.dad_transmits *
-                       max(NEIGH_VAR(idev->nd_parms, RETRANS_TIME), HZ/100) / HZ;
+       regen_advance = ipv6_get_regen_advance(idev);
 
        /* recalculate max_desync_factor each time and update
         * idev->desync_factor if it's larger
@@ -4595,9 +4600,7 @@ restart:
                            !ifp->regen_count && ifp->ifpub) {
                                /* This is a non-regenerated temporary addr. */
 
-                               unsigned long regen_advance = ifp->idev->cnf.regen_max_retry *
-                                       ifp->idev->cnf.dad_transmits *
-                                       max(NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME), HZ/100) / HZ;
+                               unsigned long regen_advance = ipv6_get_regen_advance(ifp->idev);
 
                                if (age + regen_advance >= ifp->prefered_lft) {
                                        struct inet6_ifaddr *ifpub = ifp->ifpub;