net: ipv6: Add sysctl for minimum prefix len acceptable in RIOs.

This commit adds a new sysctl accept_ra_rt_info_min_plen that
defines the minimum acceptable prefix length of Route Information
Options. The new sysctl is intended to be used together with
accept_ra_rt_info_max_plen to configure a range of acceptable
prefix lengths. It is useful to prevent misconfigurations from
unintentionally blackholing too much of the IPv6 address space
(e.g., home routers announcing RIOs for fc00::/7, which is
incorrect).

Signed-off-by: Joel Scherpelz <jscherpelz@google.com>
Acked-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Joel Scherpelz 2017-03-22 18:19:04 +09:00 committed by David S. Miller
parent 0e4c9f13da
commit bbea124bc9
6 changed files with 26 additions and 2 deletions

View File

@ -1461,11 +1461,20 @@ accept_ra_pinfo - BOOLEAN
Functional default: enabled if accept_ra is enabled. Functional default: enabled if accept_ra is enabled.
disabled if accept_ra is disabled. disabled if accept_ra is disabled.
accept_ra_rt_info_min_plen - INTEGER
Minimum prefix length of Route Information in RA.
Route Information w/ prefix smaller than this variable shall
be ignored.
Functional default: 0 if accept_ra_rtr_pref is enabled.
-1 if accept_ra_rtr_pref is disabled.
accept_ra_rt_info_max_plen - INTEGER accept_ra_rt_info_max_plen - INTEGER
Maximum prefix length of Route Information in RA. Maximum prefix length of Route Information in RA.
Route Information w/ prefix larger than or equal to this Route Information w/ prefix larger than this variable shall
variable shall be ignored. be ignored.
Functional default: 0 if accept_ra_rtr_pref is enabled. Functional default: 0 if accept_ra_rtr_pref is enabled.
-1 if accept_ra_rtr_pref is disabled. -1 if accept_ra_rtr_pref is disabled.

View File

@ -37,6 +37,7 @@ struct ipv6_devconf {
__s32 accept_ra_rtr_pref; __s32 accept_ra_rtr_pref;
__s32 rtr_probe_interval; __s32 rtr_probe_interval;
#ifdef CONFIG_IPV6_ROUTE_INFO #ifdef CONFIG_IPV6_ROUTE_INFO
__s32 accept_ra_rt_info_min_plen;
__s32 accept_ra_rt_info_max_plen; __s32 accept_ra_rt_info_max_plen;
#endif #endif
#endif #endif

View File

@ -184,6 +184,7 @@ enum {
DEVCONF_ENHANCED_DAD, DEVCONF_ENHANCED_DAD,
DEVCONF_ADDR_GEN_MODE, DEVCONF_ADDR_GEN_MODE,
DEVCONF_DISABLE_POLICY, DEVCONF_DISABLE_POLICY,
DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN,
DEVCONF_MAX DEVCONF_MAX
}; };

View File

@ -568,6 +568,7 @@ enum {
NET_IPV6_PROXY_NDP=23, NET_IPV6_PROXY_NDP=23,
NET_IPV6_ACCEPT_SOURCE_ROUTE=25, NET_IPV6_ACCEPT_SOURCE_ROUTE=25,
NET_IPV6_ACCEPT_RA_FROM_LOCAL=26, NET_IPV6_ACCEPT_RA_FROM_LOCAL=26,
NET_IPV6_ACCEPT_RA_RT_INFO_MIN_PLEN=27,
__NET_IPV6_MAX __NET_IPV6_MAX
}; };

View File

@ -224,6 +224,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
.accept_ra_rtr_pref = 1, .accept_ra_rtr_pref = 1,
.rtr_probe_interval = 60 * HZ, .rtr_probe_interval = 60 * HZ,
#ifdef CONFIG_IPV6_ROUTE_INFO #ifdef CONFIG_IPV6_ROUTE_INFO
.accept_ra_rt_info_min_plen = 0,
.accept_ra_rt_info_max_plen = 0, .accept_ra_rt_info_max_plen = 0,
#endif #endif
#endif #endif
@ -277,6 +278,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
.accept_ra_rtr_pref = 1, .accept_ra_rtr_pref = 1,
.rtr_probe_interval = 60 * HZ, .rtr_probe_interval = 60 * HZ,
#ifdef CONFIG_IPV6_ROUTE_INFO #ifdef CONFIG_IPV6_ROUTE_INFO
.accept_ra_rt_info_min_plen = 0,
.accept_ra_rt_info_max_plen = 0, .accept_ra_rt_info_max_plen = 0,
#endif #endif
#endif #endif
@ -4979,6 +4981,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_RTR_PROBE_INTERVAL] = array[DEVCONF_RTR_PROBE_INTERVAL] =
jiffies_to_msecs(cnf->rtr_probe_interval); jiffies_to_msecs(cnf->rtr_probe_interval);
#ifdef CONFIG_IPV6_ROUTE_INFO #ifdef CONFIG_IPV6_ROUTE_INFO
array[DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN] = cnf->accept_ra_rt_info_min_plen;
array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen; array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
#endif #endif
#endif #endif
@ -6121,6 +6124,13 @@ static const struct ctl_table addrconf_sysctl[] = {
.proc_handler = proc_dointvec_jiffies, .proc_handler = proc_dointvec_jiffies,
}, },
#ifdef CONFIG_IPV6_ROUTE_INFO #ifdef CONFIG_IPV6_ROUTE_INFO
{
.procname = "accept_ra_rt_info_min_plen",
.data = &ipv6_devconf.accept_ra_rt_info_min_plen,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{ {
.procname = "accept_ra_rt_info_max_plen", .procname = "accept_ra_rt_info_max_plen",
.data = &ipv6_devconf.accept_ra_rt_info_max_plen, .data = &ipv6_devconf.accept_ra_rt_info_max_plen,

View File

@ -1418,6 +1418,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
if (ri->prefix_len == 0 && if (ri->prefix_len == 0 &&
!in6_dev->cnf.accept_ra_defrtr) !in6_dev->cnf.accept_ra_defrtr)
continue; continue;
if (ri->prefix_len < in6_dev->cnf.accept_ra_rt_info_min_plen)
continue;
if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
continue; continue;
rt6_route_rcv(skb->dev, (u8 *)p, (p->nd_opt_len) << 3, rt6_route_rcv(skb->dev, (u8 *)p, (p->nd_opt_len) << 3,