aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ndisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ndisc.c')
-rw-r--r--net/ipv6/ndisc.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 06d80c6dc5ce..b3295d82fece 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1093,6 +1093,14 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1093 return; 1093 return;
1094 } 1094 }
1095 1095
1096#ifdef CONFIG_IPV6_NDISC_NODETYPE
1097 if (skb->ndisc_nodetype == NDISC_NODETYPE_HOST) {
1098 ND_PRINTK2(KERN_WARNING
1099 "ICMPv6 RA: from host or unauthorized router\n");
1100 return;
1101 }
1102#endif
1103
1096 /* 1104 /*
1097 * set the RA_RECV flag in the interface 1105 * set the RA_RECV flag in the interface
1098 */ 1106 */
@@ -1116,6 +1124,12 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1116 return; 1124 return;
1117 } 1125 }
1118 1126
1127#ifdef CONFIG_IPV6_NDISC_NODETYPE
1128 /* skip link-specific parameters from interior routers */
1129 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT)
1130 goto skip_linkparms;
1131#endif
1132
1119 if (in6_dev->if_flags & IF_RS_SENT) { 1133 if (in6_dev->if_flags & IF_RS_SENT) {
1120 /* 1134 /*
1121 * flag that an RA was received after an RS was sent 1135 * flag that an RA was received after an RS was sent
@@ -1230,6 +1244,10 @@ skip_defrtr:
1230 } 1244 }
1231 } 1245 }
1232 1246
1247#ifdef CONFIG_IPV6_NDISC_NODETYPE
1248skip_linkparms:
1249#endif
1250
1233 /* 1251 /*
1234 * Process options. 1252 * Process options.
1235 */ 1253 */
@@ -1261,7 +1279,13 @@ skip_defrtr:
1261 for (p = ndopts.nd_opts_ri; 1279 for (p = ndopts.nd_opts_ri;
1262 p; 1280 p;
1263 p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) { 1281 p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) {
1264 if (((struct route_info *)p)->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) 1282 struct route_info *ri = (struct route_info *)p;
1283#ifdef CONFIG_IPV6_NDISC_NODETYPE
1284 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT &&
1285 ri->prefix_len == 0)
1286 continue;
1287#endif
1288 if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
1265 continue; 1289 continue;
1266 rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3, 1290 rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3,
1267 &ipv6_hdr(skb)->saddr); 1291 &ipv6_hdr(skb)->saddr);
@@ -1269,6 +1293,12 @@ skip_defrtr:
1269 } 1293 }
1270#endif 1294#endif
1271 1295
1296#ifdef CONFIG_IPV6_NDISC_NODETYPE
1297 /* skip link-specific ndopts from interior routers */
1298 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT)
1299 goto out;
1300#endif
1301
1272 if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) { 1302 if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
1273 struct nd_opt_hdr *p; 1303 struct nd_opt_hdr *p;
1274 for (p = ndopts.nd_opts_pi; 1304 for (p = ndopts.nd_opts_pi;
@@ -1332,6 +1362,16 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
1332 int optlen; 1362 int optlen;
1333 u8 *lladdr = NULL; 1363 u8 *lladdr = NULL;
1334 1364
1365#ifdef CONFIG_IPV6_NDISC_NODETYPE
1366 switch (skb->ndisc_nodetype) {
1367 case NDISC_NODETYPE_HOST:
1368 case NDISC_NODETYPE_NODEFAULT:
1369 ND_PRINTK2(KERN_WARNING
1370 "ICMPv6 Redirect: from host or unauthorized router\n");
1371 return;
1372 }
1373#endif
1374
1335 if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) { 1375 if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
1336 ND_PRINTK2(KERN_WARNING 1376 ND_PRINTK2(KERN_WARNING
1337 "ICMPv6 Redirect: source address is not link-local.\n"); 1377 "ICMPv6 Redirect: source address is not link-local.\n");