This is a note to let you know that I've just added the patch titled net: add sysctl accept_ra_min_rtr_lft to the 5.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: net-add-sysctl-accept_ra_min_rtr_lft.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From stable-owner@xxxxxxxxxxxxxxx Fri Oct 13 23:21:23 2023 From: Patrick Rohr <prohr@xxxxxxxxxx> Date: Fri, 13 Oct 2023 14:21:12 -0700 Subject: net: add sysctl accept_ra_min_rtr_lft To: stable@xxxxxxxxxxxxxxx Cc: "Greg KH" <gregkh@xxxxxxxxxxxxxxxxxxx>, "Sasha Levin" <sashal@xxxxxxxxxx>, "Maciej Żenczykowski" <maze@xxxxxxxxxx>, "Lorenzo Colitti" <lorenzo@xxxxxxxxxx>, "Patrick Rohr" <prohr@xxxxxxxxxx>, "David S . Miller" <davem@xxxxxxxxxxxxx> Message-ID: <20231013212114.3445624-2-prohr@xxxxxxxxxx> From: Patrick Rohr <prohr@xxxxxxxxxx> commit 1671bcfd76fdc0b9e65153cf759153083755fe4c upstream. This change adds a new sysctl accept_ra_min_rtr_lft to specify the minimum acceptable router lifetime in an RA. If the received RA router lifetime is less than the configured value (and not 0), the RA is ignored. This is useful for mobile devices, whose battery life can be impacted by networks that configure RAs with a short lifetime. On such networks, the device should never gain IPv6 provisioning and should attempt to drop RAs via hardware offload, if available. Signed-off-by: Patrick Rohr <prohr@xxxxxxxxxx> Cc: Maciej Żenczykowski <maze@xxxxxxxxxx> Cc: Lorenzo Colitti <lorenzo@xxxxxxxxxx> Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- Documentation/networking/ip-sysctl.rst | 8 ++++++++ include/linux/ipv6.h | 1 + include/uapi/linux/ipv6.h | 3 +++ net/ipv6/addrconf.c | 10 ++++++++++ net/ipv6/ndisc.c | 18 ++++++++++++++++-- 5 files changed, 38 insertions(+), 2 deletions(-) --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -2070,6 +2070,14 @@ accept_ra_min_hop_limit - INTEGER Default: 1 +accept_ra_min_rtr_lft - INTEGER + Minimum acceptable router lifetime in Router Advertisement. + + RAs with a router lifetime less than this value shall be + ignored. RAs with a router lifetime of 0 are unaffected. + + Default: 0 + accept_ra_pinfo - BOOLEAN Learn Prefix Information in Router Advertisement. --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -33,6 +33,7 @@ struct ipv6_devconf { __s32 accept_ra_defrtr; __u32 ra_defrtr_metric; __s32 accept_ra_min_hop_limit; + __s32 accept_ra_min_rtr_lft; __s32 accept_ra_pinfo; __s32 ignore_routes_with_linkdown; #ifdef CONFIG_IPV6_ROUTER_PREF --- a/include/uapi/linux/ipv6.h +++ b/include/uapi/linux/ipv6.h @@ -196,6 +196,9 @@ enum { DEVCONF_IOAM6_ENABLED, DEVCONF_IOAM6_ID, DEVCONF_IOAM6_ID_WIDE, + DEVCONF_NDISC_EVICT_NOCARRIER, + DEVCONF_ACCEPT_UNTRACKED_NA, + DEVCONF_ACCEPT_RA_MIN_RTR_LFT, DEVCONF_MAX }; --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -209,6 +209,7 @@ static struct ipv6_devconf ipv6_devconf .ra_defrtr_metric = IP6_RT_PRIO_USER, .accept_ra_from_local = 0, .accept_ra_min_hop_limit= 1, + .accept_ra_min_rtr_lft = 0, .accept_ra_pinfo = 1, #ifdef CONFIG_IPV6_ROUTER_PREF .accept_ra_rtr_pref = 1, @@ -268,6 +269,7 @@ static struct ipv6_devconf ipv6_devconf_ .ra_defrtr_metric = IP6_RT_PRIO_USER, .accept_ra_from_local = 0, .accept_ra_min_hop_limit= 1, + .accept_ra_min_rtr_lft = 0, .accept_ra_pinfo = 1, #ifdef CONFIG_IPV6_ROUTER_PREF .accept_ra_rtr_pref = 1, @@ -5589,6 +5591,7 @@ static inline void ipv6_store_devconf(st array[DEVCONF_IOAM6_ENABLED] = cnf->ioam6_enabled; array[DEVCONF_IOAM6_ID] = cnf->ioam6_id; array[DEVCONF_IOAM6_ID_WIDE] = cnf->ioam6_id_wide; + array[DEVCONF_ACCEPT_RA_MIN_RTR_LFT] = cnf->accept_ra_min_rtr_lft; } static inline size_t inet6_ifla6_size(void) @@ -6781,6 +6784,13 @@ static const struct ctl_table addrconf_s .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec, + }, + { + .procname = "accept_ra_min_rtr_lft", + .data = &ipv6_devconf.accept_ra_min_rtr_lft, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, }, { .procname = "accept_ra_pinfo", --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1223,6 +1223,8 @@ static void ndisc_router_discovery(struc return; } + lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime); + if (!ipv6_accept_ra(in6_dev)) { ND_PRINTK(2, info, "RA: %s, did not accept ra for dev: %s\n", @@ -1230,6 +1232,13 @@ static void ndisc_router_discovery(struc goto skip_linkparms; } + if (lifetime != 0 && lifetime < in6_dev->cnf.accept_ra_min_rtr_lft) { + ND_PRINTK(2, info, + "RA: router lifetime (%ds) is too short: %s\n", + lifetime, skb->dev->name); + goto skip_linkparms; + } + #ifdef CONFIG_IPV6_NDISC_NODETYPE /* skip link-specific parameters from interior routers */ if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) { @@ -1282,8 +1291,6 @@ static void ndisc_router_discovery(struc goto skip_defrtr; } - lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime); - #ifdef CONFIG_IPV6_ROUTER_PREF pref = ra_msg->icmph.icmp6_router_pref; /* 10b is handled as if it were 00b (medium) */ @@ -1430,6 +1437,13 @@ skip_linkparms: goto out; } + if (lifetime != 0 && lifetime < in6_dev->cnf.accept_ra_min_rtr_lft) { + ND_PRINTK(2, info, + "RA: router lifetime (%ds) is too short: %s\n", + lifetime, skb->dev->name); + goto out; + } + #ifdef CONFIG_IPV6_ROUTE_INFO if (!in6_dev->cnf.accept_ra_from_local && ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, Patches currently in stable-queue which might be from stable-owner@xxxxxxxxxxxxxxx are queue-5.15/net-release-reference-to-inet6_dev-pointer.patch queue-5.15/net-add-sysctl-accept_ra_min_rtr_lft.patch queue-5.15/net-change-accept_ra_min_rtr_lft-to-affect-all-ra-lifetimes.patch