diff options
-rw-r--r-- | Documentation/networking/ip-sysctl.txt | 12 | ||||
-rw-r--r-- | include/linux/ipv6.h | 1 | ||||
-rw-r--r-- | include/uapi/linux/ipv6.h | 1 | ||||
-rw-r--r-- | include/uapi/linux/sysctl.h | 1 | ||||
-rw-r--r-- | kernel/sysctl_binary.c | 1 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 10 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 21 |
7 files changed, 39 insertions, 8 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index ab42c95f9985..10e216c6e05e 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -1210,6 +1210,18 @@ accept_ra_defrtr - BOOLEAN | |||
1210 | Functional default: enabled if accept_ra is enabled. | 1210 | Functional default: enabled if accept_ra is enabled. |
1211 | disabled if accept_ra is disabled. | 1211 | disabled if accept_ra is disabled. |
1212 | 1212 | ||
1213 | accept_ra_from_local - BOOLEAN | ||
1214 | Accept RA with source-address that is found on local machine | ||
1215 | if the RA is otherwise proper and able to be accepted. | ||
1216 | Default is to NOT accept these as it may be an un-intended | ||
1217 | network loop. | ||
1218 | |||
1219 | Functional default: | ||
1220 | enabled if accept_ra_from_local is enabled | ||
1221 | on a specific interface. | ||
1222 | disabled if accept_ra_from_local is disabled | ||
1223 | on a specific interface. | ||
1224 | |||
1213 | accept_ra_pinfo - BOOLEAN | 1225 | accept_ra_pinfo - BOOLEAN |
1214 | Learn Prefix Information in Router Advertisement. | 1226 | Learn Prefix Information in Router Advertisement. |
1215 | 1227 | ||
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index c811300b0b0c..b0f2452f1d58 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -39,6 +39,7 @@ struct ipv6_devconf { | |||
39 | #endif | 39 | #endif |
40 | __s32 proxy_ndp; | 40 | __s32 proxy_ndp; |
41 | __s32 accept_source_route; | 41 | __s32 accept_source_route; |
42 | __s32 accept_ra_from_local; | ||
42 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | 43 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD |
43 | __s32 optimistic_dad; | 44 | __s32 optimistic_dad; |
44 | #endif | 45 | #endif |
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h index 593b0e32d956..efa2666f4b8a 100644 --- a/include/uapi/linux/ipv6.h +++ b/include/uapi/linux/ipv6.h | |||
@@ -163,6 +163,7 @@ enum { | |||
163 | DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL, | 163 | DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL, |
164 | DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL, | 164 | DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL, |
165 | DEVCONF_SUPPRESS_FRAG_NDISC, | 165 | DEVCONF_SUPPRESS_FRAG_NDISC, |
166 | DEVCONF_ACCEPT_RA_FROM_LOCAL, | ||
166 | DEVCONF_MAX | 167 | DEVCONF_MAX |
167 | }; | 168 | }; |
168 | 169 | ||
diff --git a/include/uapi/linux/sysctl.h b/include/uapi/linux/sysctl.h index 6d6721341f49..43aaba1cc037 100644 --- a/include/uapi/linux/sysctl.h +++ b/include/uapi/linux/sysctl.h | |||
@@ -568,6 +568,7 @@ enum { | |||
568 | NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, | 568 | NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, |
569 | NET_IPV6_PROXY_NDP=23, | 569 | NET_IPV6_PROXY_NDP=23, |
570 | NET_IPV6_ACCEPT_SOURCE_ROUTE=25, | 570 | NET_IPV6_ACCEPT_SOURCE_ROUTE=25, |
571 | NET_IPV6_ACCEPT_RA_FROM_LOCAL=26, | ||
571 | __NET_IPV6_MAX | 572 | __NET_IPV6_MAX |
572 | }; | 573 | }; |
573 | 574 | ||
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index 653cbbd9e7ad..e4ba9a5a5ccb 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c | |||
@@ -522,6 +522,7 @@ static const struct bin_table bin_net_ipv6_conf_var_table[] = { | |||
522 | { CTL_INT, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN, "accept_ra_rt_info_max_plen" }, | 522 | { CTL_INT, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN, "accept_ra_rt_info_max_plen" }, |
523 | { CTL_INT, NET_IPV6_PROXY_NDP, "proxy_ndp" }, | 523 | { CTL_INT, NET_IPV6_PROXY_NDP, "proxy_ndp" }, |
524 | { CTL_INT, NET_IPV6_ACCEPT_SOURCE_ROUTE, "accept_source_route" }, | 524 | { CTL_INT, NET_IPV6_ACCEPT_SOURCE_ROUTE, "accept_source_route" }, |
525 | { CTL_INT, NET_IPV6_ACCEPT_RA_FROM_LOCAL, "accept_ra_from_local" }, | ||
525 | {} | 526 | {} |
526 | }; | 527 | }; |
527 | 528 | ||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 5667b3003af9..358edd2272ac 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -186,6 +186,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { | |||
186 | .max_desync_factor = MAX_DESYNC_FACTOR, | 186 | .max_desync_factor = MAX_DESYNC_FACTOR, |
187 | .max_addresses = IPV6_MAX_ADDRESSES, | 187 | .max_addresses = IPV6_MAX_ADDRESSES, |
188 | .accept_ra_defrtr = 1, | 188 | .accept_ra_defrtr = 1, |
189 | .accept_ra_from_local = 0, | ||
189 | .accept_ra_pinfo = 1, | 190 | .accept_ra_pinfo = 1, |
190 | #ifdef CONFIG_IPV6_ROUTER_PREF | 191 | #ifdef CONFIG_IPV6_ROUTER_PREF |
191 | .accept_ra_rtr_pref = 1, | 192 | .accept_ra_rtr_pref = 1, |
@@ -222,6 +223,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { | |||
222 | .max_desync_factor = MAX_DESYNC_FACTOR, | 223 | .max_desync_factor = MAX_DESYNC_FACTOR, |
223 | .max_addresses = IPV6_MAX_ADDRESSES, | 224 | .max_addresses = IPV6_MAX_ADDRESSES, |
224 | .accept_ra_defrtr = 1, | 225 | .accept_ra_defrtr = 1, |
226 | .accept_ra_from_local = 0, | ||
225 | .accept_ra_pinfo = 1, | 227 | .accept_ra_pinfo = 1, |
226 | #ifdef CONFIG_IPV6_ROUTER_PREF | 228 | #ifdef CONFIG_IPV6_ROUTER_PREF |
227 | .accept_ra_rtr_pref = 1, | 229 | .accept_ra_rtr_pref = 1, |
@@ -4321,6 +4323,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, | |||
4321 | array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; | 4323 | array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; |
4322 | array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify; | 4324 | array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify; |
4323 | array[DEVCONF_SUPPRESS_FRAG_NDISC] = cnf->suppress_frag_ndisc; | 4325 | array[DEVCONF_SUPPRESS_FRAG_NDISC] = cnf->suppress_frag_ndisc; |
4326 | array[DEVCONF_ACCEPT_RA_FROM_LOCAL] = cnf->accept_ra_from_local; | ||
4324 | } | 4327 | } |
4325 | 4328 | ||
4326 | static inline size_t inet6_ifla6_size(void) | 4329 | static inline size_t inet6_ifla6_size(void) |
@@ -5168,6 +5171,13 @@ static struct addrconf_sysctl_table | |||
5168 | .proc_handler = proc_dointvec | 5171 | .proc_handler = proc_dointvec |
5169 | }, | 5172 | }, |
5170 | { | 5173 | { |
5174 | .procname = "accept_ra_from_local", | ||
5175 | .data = &ipv6_devconf.accept_ra_from_local, | ||
5176 | .maxlen = sizeof(int), | ||
5177 | .mode = 0644, | ||
5178 | .proc_handler = proc_dointvec, | ||
5179 | }, | ||
5180 | { | ||
5171 | /* sentinel */ | 5181 | /* sentinel */ |
5172 | } | 5182 | } |
5173 | }, | 5183 | }, |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 736c11c6d266..a845e3d2057e 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -1148,11 +1148,15 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1148 | goto skip_defrtr; | 1148 | goto skip_defrtr; |
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | if (ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, | 1151 | /* Do not accept RA with source-addr found on local machine unless |
1152 | NULL, 0)) { | 1152 | * accept_ra_from_local is set to true. |
1153 | */ | ||
1154 | if (!(in6_dev->cnf.accept_ra_from_local || | ||
1155 | ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, | ||
1156 | NULL, 0))) { | ||
1153 | ND_PRINTK(2, info, | 1157 | ND_PRINTK(2, info, |
1154 | "RA: %s, chk_addr failed for dev: %s\n", | 1158 | "RA from local address detected on dev: %s: default router ignored\n", |
1155 | __func__, skb->dev->name); | 1159 | skb->dev->name); |
1156 | goto skip_defrtr; | 1160 | goto skip_defrtr; |
1157 | } | 1161 | } |
1158 | 1162 | ||
@@ -1290,11 +1294,12 @@ skip_linkparms: | |||
1290 | } | 1294 | } |
1291 | 1295 | ||
1292 | #ifdef CONFIG_IPV6_ROUTE_INFO | 1296 | #ifdef CONFIG_IPV6_ROUTE_INFO |
1293 | if (ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, | 1297 | if (!(in6_dev->cnf.accept_ra_from_local || |
1294 | NULL, 0)) { | 1298 | ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, |
1299 | NULL, 0))) { | ||
1295 | ND_PRINTK(2, info, | 1300 | ND_PRINTK(2, info, |
1296 | "RA: %s, chk-addr (route info) is false for dev: %s\n", | 1301 | "RA from local address detected on dev: %s: router info ignored.\n", |
1297 | __func__, skb->dev->name); | 1302 | skb->dev->name); |
1298 | goto skip_routeinfo; | 1303 | goto skip_routeinfo; |
1299 | } | 1304 | } |
1300 | 1305 | ||