]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: add sysctl to disable rfc4862 5.5.3e lifetime handling
authorPatrick Rohr <prohr@google.com>
Mon, 25 Sep 2023 21:47:11 +0000 (14:47 -0700)
committerJakub Kicinski <kuba@kernel.org>
Tue, 3 Oct 2023 22:51:04 +0000 (15:51 -0700)
This change adds a sysctl to opt-out of RFC4862 section 5.5.3e's valid
lifetime derivation mechanism.

RFC4862 section 5.5.3e prescribes that the valid lifetime in a Router
Advertisement PIO shall be ignored if it less than 2 hours and to reset
the lifetime of the corresponding address to 2 hours. An in-progress
6man draft (see draft-ietf-6man-slaac-renum-07 section 4.2) is currently
looking to remove this mechanism. While this draft has not been moving
particularly quickly for other reasons, there is widespread consensus on
section 4.2 which updates RFC4862 section 5.5.3e.

Cc: Maciej Żenczykowski <maze@google.com>
Cc: Lorenzo Colitti <lorenzo@google.com>
Cc: Jen Linkova <furry@google.com>
Signed-off-by: Patrick Rohr <prohr@google.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20230925214711.959704-1-prohr@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Documentation/networking/ip-sysctl.rst
include/linux/ipv6.h
net/ipv6/addrconf.c

index 5bfa1837968cee5eacafc77b216729b495bf65b8..f7dfde3b09a96017a5d616709aa8865a1b3bf00f 100644 (file)
@@ -2311,6 +2311,17 @@ accept_ra_pinfo - BOOLEAN
                - enabled if accept_ra is enabled.
                - disabled if accept_ra is disabled.
 
+ra_honor_pio_life - BOOLEAN
+       Whether to use RFC4862 Section 5.5.3e to determine the valid
+       lifetime of an address matching a prefix sent in a Router
+       Advertisement Prefix Information Option.
+
+       - If enabled, the PIO valid lifetime will always be honored.
+       - If disabled, RFC4862 section 5.5.3e is used to determine
+         the valid lifetime of the address.
+
+       Default: 0 (disabled)
+
 accept_ra_rt_info_min_plen - INTEGER
        Minimum prefix length of Route Information in RA.
 
index e400ff757f136e72e81277d48063551e445b4970..5e605e384aac815edebe293c02ae3e3a06f94ea4 100644 (file)
@@ -82,6 +82,7 @@ struct ipv6_devconf {
        __u32           ioam6_id_wide;
        __u8            ioam6_enabled;
        __u8            ndisc_evict_nocarrier;
+       __u8            ra_honor_pio_life;
 
        struct ctl_table_header *sysctl_header;
 };
index 0b6ee962c84e27906a1bc0dcd01d7088abb44cb2..c2d471ad7922cf466f0dd1c7307d5f329172f711 100644 (file)
@@ -236,6 +236,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
        .ioam6_id               = IOAM6_DEFAULT_IF_ID,
        .ioam6_id_wide          = IOAM6_DEFAULT_IF_ID_WIDE,
        .ndisc_evict_nocarrier  = 1,
+       .ra_honor_pio_life      = 0,
 };
 
 static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -297,6 +298,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
        .ioam6_id               = IOAM6_DEFAULT_IF_ID,
        .ioam6_id_wide          = IOAM6_DEFAULT_IF_ID_WIDE,
        .ndisc_evict_nocarrier  = 1,
+       .ra_honor_pio_life      = 0,
 };
 
 /* Check if link is ready: is it up and is a valid qdisc available */
@@ -2657,22 +2659,23 @@ int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev,
                        stored_lft = ifp->valid_lft - (now - ifp->tstamp) / HZ;
                else
                        stored_lft = 0;
-               if (!create && stored_lft) {
+
+               /* RFC4862 Section 5.5.3e:
+                * "Note that the preferred lifetime of the
+                *  corresponding address is always reset to
+                *  the Preferred Lifetime in the received
+                *  Prefix Information option, regardless of
+                *  whether the valid lifetime is also reset or
+                *  ignored."
+                *
+                * So we should always update prefered_lft here.
+                */
+               update_lft = !create && stored_lft;
+
+               if (update_lft && !in6_dev->cnf.ra_honor_pio_life) {
                        const u32 minimum_lft = min_t(u32,
                                stored_lft, MIN_VALID_LIFETIME);
                        valid_lft = max(valid_lft, minimum_lft);
-
-                       /* RFC4862 Section 5.5.3e:
-                        * "Note that the preferred lifetime of the
-                        *  corresponding address is always reset to
-                        *  the Preferred Lifetime in the received
-                        *  Prefix Information option, regardless of
-                        *  whether the valid lifetime is also reset or
-                        *  ignored."
-                        *
-                        * So we should always update prefered_lft here.
-                        */
-                       update_lft = 1;
                }
 
                if (update_lft) {
@@ -6846,6 +6849,15 @@ static const struct ctl_table addrconf_sysctl[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
+       {
+               .procname       = "ra_honor_pio_life",
+               .data           = &ipv6_devconf.ra_honor_pio_life,
+               .maxlen         = sizeof(u8),
+               .mode           = 0644,
+               .proc_handler   = proc_dou8vec_minmax,
+               .extra1         = SYSCTL_ZERO,
+               .extra2         = SYSCTL_ONE,
+       },
 #ifdef CONFIG_IPV6_ROUTER_PREF
        {
                .procname       = "accept_ra_rtr_pref",