forked from mirrors/linux
		
	net: add sysctl accept_ra_min_rtr_lft
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> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									5c9f7b04aa
								
							
						
					
					
						commit
						1671bcfd76
					
				
					 5 changed files with 36 additions and 2 deletions
				
			
		| 
						 | 
					@ -2288,6 +2288,14 @@ accept_ra_min_hop_limit - INTEGER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Default: 1
 | 
						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
 | 
					accept_ra_pinfo - BOOLEAN
 | 
				
			||||||
	Learn Prefix Information in Router Advertisement.
 | 
						Learn Prefix Information in Router Advertisement.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,7 @@ struct ipv6_devconf {
 | 
				
			||||||
	__s32		accept_ra_defrtr;
 | 
						__s32		accept_ra_defrtr;
 | 
				
			||||||
	__u32		ra_defrtr_metric;
 | 
						__u32		ra_defrtr_metric;
 | 
				
			||||||
	__s32		accept_ra_min_hop_limit;
 | 
						__s32		accept_ra_min_hop_limit;
 | 
				
			||||||
 | 
						__s32		accept_ra_min_rtr_lft;
 | 
				
			||||||
	__s32		accept_ra_pinfo;
 | 
						__s32		accept_ra_pinfo;
 | 
				
			||||||
	__s32		ignore_routes_with_linkdown;
 | 
						__s32		ignore_routes_with_linkdown;
 | 
				
			||||||
#ifdef CONFIG_IPV6_ROUTER_PREF
 | 
					#ifdef CONFIG_IPV6_ROUTER_PREF
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -198,6 +198,7 @@ enum {
 | 
				
			||||||
	DEVCONF_IOAM6_ID_WIDE,
 | 
						DEVCONF_IOAM6_ID_WIDE,
 | 
				
			||||||
	DEVCONF_NDISC_EVICT_NOCARRIER,
 | 
						DEVCONF_NDISC_EVICT_NOCARRIER,
 | 
				
			||||||
	DEVCONF_ACCEPT_UNTRACKED_NA,
 | 
						DEVCONF_ACCEPT_UNTRACKED_NA,
 | 
				
			||||||
 | 
						DEVCONF_ACCEPT_RA_MIN_RTR_LFT,
 | 
				
			||||||
	DEVCONF_MAX
 | 
						DEVCONF_MAX
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -202,6 +202,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
 | 
				
			||||||
	.ra_defrtr_metric	= IP6_RT_PRIO_USER,
 | 
						.ra_defrtr_metric	= IP6_RT_PRIO_USER,
 | 
				
			||||||
	.accept_ra_from_local	= 0,
 | 
						.accept_ra_from_local	= 0,
 | 
				
			||||||
	.accept_ra_min_hop_limit= 1,
 | 
						.accept_ra_min_hop_limit= 1,
 | 
				
			||||||
 | 
						.accept_ra_min_rtr_lft	= 0,
 | 
				
			||||||
	.accept_ra_pinfo	= 1,
 | 
						.accept_ra_pinfo	= 1,
 | 
				
			||||||
#ifdef CONFIG_IPV6_ROUTER_PREF
 | 
					#ifdef CONFIG_IPV6_ROUTER_PREF
 | 
				
			||||||
	.accept_ra_rtr_pref	= 1,
 | 
						.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,
 | 
						.ra_defrtr_metric	= IP6_RT_PRIO_USER,
 | 
				
			||||||
	.accept_ra_from_local	= 0,
 | 
						.accept_ra_from_local	= 0,
 | 
				
			||||||
	.accept_ra_min_hop_limit= 1,
 | 
						.accept_ra_min_hop_limit= 1,
 | 
				
			||||||
 | 
						.accept_ra_min_rtr_lft	= 0,
 | 
				
			||||||
	.accept_ra_pinfo	= 1,
 | 
						.accept_ra_pinfo	= 1,
 | 
				
			||||||
#ifdef CONFIG_IPV6_ROUTER_PREF
 | 
					#ifdef CONFIG_IPV6_ROUTER_PREF
 | 
				
			||||||
	.accept_ra_rtr_pref	= 1,
 | 
						.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_IOAM6_ID_WIDE] = cnf->ioam6_id_wide;
 | 
				
			||||||
	array[DEVCONF_NDISC_EVICT_NOCARRIER] = cnf->ndisc_evict_nocarrier;
 | 
						array[DEVCONF_NDISC_EVICT_NOCARRIER] = cnf->ndisc_evict_nocarrier;
 | 
				
			||||||
	array[DEVCONF_ACCEPT_UNTRACKED_NA] = cnf->accept_untracked_na;
 | 
						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)
 | 
					static inline size_t inet6_ifla6_size(void)
 | 
				
			||||||
| 
						 | 
					@ -6789,6 +6792,13 @@ static const struct ctl_table addrconf_sysctl[] = {
 | 
				
			||||||
		.mode		= 0644,
 | 
							.mode		= 0644,
 | 
				
			||||||
		.proc_handler	= proc_dointvec,
 | 
							.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",
 | 
							.procname	= "accept_ra_pinfo",
 | 
				
			||||||
		.data		= &ipv6_devconf.accept_ra_pinfo,
 | 
							.data		= &ipv6_devconf.accept_ra_pinfo,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1280,6 +1280,8 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
 | 
				
			||||||
	if (!ndisc_parse_options(skb->dev, opt, optlen, &ndopts))
 | 
						if (!ndisc_parse_options(skb->dev, opt, optlen, &ndopts))
 | 
				
			||||||
		return SKB_DROP_REASON_IPV6_NDISC_BAD_OPTIONS;
 | 
							return SKB_DROP_REASON_IPV6_NDISC_BAD_OPTIONS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ipv6_accept_ra(in6_dev)) {
 | 
						if (!ipv6_accept_ra(in6_dev)) {
 | 
				
			||||||
		ND_PRINTK(2, info,
 | 
							ND_PRINTK(2, info,
 | 
				
			||||||
			  "RA: %s, did not accept ra for dev: %s\n",
 | 
								  "RA: %s, did not accept ra for dev: %s\n",
 | 
				
			||||||
| 
						 | 
					@ -1287,6 +1289,13 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
 | 
				
			||||||
		goto skip_linkparms;
 | 
							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
 | 
					#ifdef CONFIG_IPV6_NDISC_NODETYPE
 | 
				
			||||||
	/* skip link-specific parameters from interior routers */
 | 
						/* skip link-specific parameters from interior routers */
 | 
				
			||||||
	if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) {
 | 
						if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) {
 | 
				
			||||||
| 
						 | 
					@ -1339,8 +1348,6 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
 | 
				
			||||||
		goto skip_defrtr;
 | 
							goto skip_defrtr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef CONFIG_IPV6_ROUTER_PREF
 | 
					#ifdef CONFIG_IPV6_ROUTER_PREF
 | 
				
			||||||
	pref = ra_msg->icmph.icmp6_router_pref;
 | 
						pref = ra_msg->icmph.icmp6_router_pref;
 | 
				
			||||||
	/* 10b is handled as if it were 00b (medium) */
 | 
						/* 10b is handled as if it were 00b (medium) */
 | 
				
			||||||
| 
						 | 
					@ -1492,6 +1499,13 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
 | 
				
			||||||
		goto out;
 | 
							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
 | 
					#ifdef CONFIG_IPV6_ROUTE_INFO
 | 
				
			||||||
	if (!in6_dev->cnf.accept_ra_from_local &&
 | 
						if (!in6_dev->cnf.accept_ra_from_local &&
 | 
				
			||||||
	    ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr,
 | 
						    ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue