Message ID | 20230718213709.688186-1-prohr@google.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net-next] net: add sysctl accept_ra_min_rtr_lft | expand |
Hi Patrick, kernel test robot noticed the following build warnings: url: https://github.com/intel-lab-lkp/linux/commits/Patrick-Rohr/net-add-sysctl-accept_ra_min_rtr_lft/20230719-053943 base: net-next/main patch link: https://lore.kernel.org/r/20230718213709.688186-1-prohr%40google.com patch subject: [net-next] net: add sysctl accept_ra_min_rtr_lft config: x86_64-randconfig-m001-20230717 (https://download.01.org/0day-ci/archive/20230719/202307192116.N4bDjayg-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce: (https://download.01.org/0day-ci/archive/20230719/202307192116.N4bDjayg-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Reported-by: Dan Carpenter <dan.carpenter@linaro.org> | Closes: https://lore.kernel.org/r/202307192116.N4bDjayg-lkp@intel.com/ smatch warnings: net/ipv6/ndisc.c:1501 ndisc_router_discovery() error: uninitialized symbol 'lifetime'. vim +/lifetime +1501 net/ipv6/ndisc.c 1279 1280 if (!ndisc_parse_options(skb->dev, opt, optlen, &ndopts)) 1281 return SKB_DROP_REASON_IPV6_NDISC_BAD_OPTIONS; 1282 1283 if (!ipv6_accept_ra(in6_dev)) { 1284 ND_PRINTK(2, info, 1285 "RA: %s, did not accept ra for dev: %s\n", 1286 __func__, skb->dev->name); 1287 goto skip_linkparms; ^^^^^^^^^^^^^^^^^^^^ This goto happens before lifetime is set 1288 } 1289 1290 lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime); Set here 1291 if (lifetime != 0 && lifetime < in6_dev->cnf.accept_ra_min_rtr_lft) { 1292 ND_PRINTK(2, info, 1293 "RA: router lifetime (%ds) is too short: %s\n", 1294 lifetime, skb->dev->name); 1295 goto skip_linkparms; 1296 } 1297 1298 #ifdef CONFIG_IPV6_NDISC_NODETYPE [ SNIP ] 1464 1465 skip_linkparms: 1466 1467 /* 1468 * Process options. 1469 */ 1470 1471 if (!neigh) 1472 neigh = __neigh_lookup(&nd_tbl, &ipv6_hdr(skb)->saddr, 1473 skb->dev, 1); 1474 if (neigh) { 1475 u8 *lladdr = NULL; 1476 if (ndopts.nd_opts_src_lladdr) { 1477 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, 1478 skb->dev); 1479 if (!lladdr) { 1480 ND_PRINTK(2, warn, 1481 "RA: invalid link-layer address length\n"); 1482 goto out; 1483 } 1484 } 1485 ndisc_update(skb->dev, neigh, lladdr, NUD_STALE, 1486 NEIGH_UPDATE_F_WEAK_OVERRIDE| 1487 NEIGH_UPDATE_F_OVERRIDE| 1488 NEIGH_UPDATE_F_OVERRIDE_ISROUTER| 1489 NEIGH_UPDATE_F_ISROUTER, 1490 NDISC_ROUTER_ADVERTISEMENT, &ndopts); 1491 reason = SKB_CONSUMED; 1492 } 1493 1494 if (!ipv6_accept_ra(in6_dev)) { 1495 ND_PRINTK(2, info, 1496 "RA: %s, accept_ra is false for dev: %s\n", 1497 __func__, skb->dev->name); 1498 goto out; 1499 } 1500 1501 if (lifetime != 0 && lifetime < in6_dev->cnf.accept_ra_min_rtr_lft) { ^^^^^^^^ Uninitialized 1502 ND_PRINTK(2, info, 1503 "RA: router lifetime (%ds) is too short: %s\n", 1504 lifetime, skb->dev->name); 1505 goto out; 1506 }
diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index 4a010a7cde7f..f4cc3946d0e3 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -2287,6 +2287,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. diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 839247a4f48e..ed3d110c2eb5 100644 --- 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 diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h index ac56605fe9bc..8b6bcbf6ed4a 100644 --- a/include/uapi/linux/ipv6.h +++ b/include/uapi/linux/ipv6.h @@ -198,6 +198,7 @@ enum { DEVCONF_IOAM6_ID_WIDE, DEVCONF_NDISC_EVICT_NOCARRIER, DEVCONF_ACCEPT_UNTRACKED_NA, + DEVCONF_ACCEPT_RA_MIN_RTR_LFT, DEVCONF_MAX }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e5213e598a04..19eb4b3d26ea 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -202,6 +202,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { .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, @@ -262,6 +263,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { .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, @@ -5596,6 +5598,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_IOAM6_ID_WIDE] = cnf->ioam6_id_wide; array[DEVCONF_NDISC_EVICT_NOCARRIER] = cnf->ndisc_evict_nocarrier; array[DEVCONF_ACCEPT_UNTRACKED_NA] = cnf->accept_untracked_na; + array[DEVCONF_ACCEPT_RA_MIN_RTR_LFT] = cnf->accept_ra_min_rtr_lft; } static inline size_t inet6_ifla6_size(void) @@ -6789,6 +6792,13 @@ static const struct ctl_table addrconf_sysctl[] = { .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", .data = &ipv6_devconf.accept_ra_pinfo, diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 18634ebd20a4..6b7ee8b189c0 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1287,6 +1287,14 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb) goto skip_linkparms; } + lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime); + 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) { @@ -1339,8 +1347,6 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb) 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) */ @@ -1492,6 +1498,13 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb) 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,
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@google.com> Cc: Maciej Żenczykowski <maze@google.com> Cc: Lorenzo Colitti <lorenzo@google.com> --- Documentation/networking/ip-sysctl.rst | 8 ++++++++ include/linux/ipv6.h | 1 + include/uapi/linux/ipv6.h | 1 + net/ipv6/addrconf.c | 10 ++++++++++ net/ipv6/ndisc.c | 17 +++++++++++++++-- 5 files changed, 35 insertions(+), 2 deletions(-)