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.c58
1 files changed, 49 insertions, 9 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index ca8d4ea48a5d..339078f95d1b 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1070,6 +1070,9 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1070 optlen = (skb_tail_pointer(skb) - skb_transport_header(skb)) - 1070 optlen = (skb_tail_pointer(skb) - skb_transport_header(skb)) -
1071 sizeof(struct ra_msg); 1071 sizeof(struct ra_msg);
1072 1072
1073 ND_PRINTK(2, info,
1074 "RA: %s, dev: %s\n",
1075 __func__, skb->dev->name);
1073 if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) { 1076 if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
1074 ND_PRINTK(2, warn, "RA: source address is not link-local\n"); 1077 ND_PRINTK(2, warn, "RA: source address is not link-local\n");
1075 return; 1078 return;
@@ -1102,13 +1105,21 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1102 return; 1105 return;
1103 } 1106 }
1104 1107
1105 if (!ipv6_accept_ra(in6_dev)) 1108 if (!ipv6_accept_ra(in6_dev)) {
1109 ND_PRINTK(2, info,
1110 "RA: %s, did not accept ra for dev: %s\n",
1111 __func__, skb->dev->name);
1106 goto skip_linkparms; 1112 goto skip_linkparms;
1113 }
1107 1114
1108#ifdef CONFIG_IPV6_NDISC_NODETYPE 1115#ifdef CONFIG_IPV6_NDISC_NODETYPE
1109 /* skip link-specific parameters from interior routers */ 1116 /* skip link-specific parameters from interior routers */
1110 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) 1117 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) {
1118 ND_PRINTK(2, info,
1119 "RA: %s, nodetype is NODEFAULT, dev: %s\n",
1120 __func__, skb->dev->name);
1111 goto skip_linkparms; 1121 goto skip_linkparms;
1122 }
1112#endif 1123#endif
1113 1124
1114 if (in6_dev->if_flags & IF_RS_SENT) { 1125 if (in6_dev->if_flags & IF_RS_SENT) {
@@ -1130,11 +1141,24 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1130 (ra_msg->icmph.icmp6_addrconf_other ? 1141 (ra_msg->icmph.icmp6_addrconf_other ?
1131 IF_RA_OTHERCONF : 0); 1142 IF_RA_OTHERCONF : 0);
1132 1143
1133 if (!in6_dev->cnf.accept_ra_defrtr) 1144 if (!in6_dev->cnf.accept_ra_defrtr) {
1145 ND_PRINTK(2, info,
1146 "RA: %s, defrtr is false for dev: %s\n",
1147 __func__, skb->dev->name);
1134 goto skip_defrtr; 1148 goto skip_defrtr;
1149 }
1135 1150
1136 if (ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, NULL, 0)) 1151 /* Do not accept RA with source-addr found on local machine unless
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)) {
1157 ND_PRINTK(2, info,
1158 "RA from local address detected on dev: %s: default router ignored\n",
1159 skb->dev->name);
1137 goto skip_defrtr; 1160 goto skip_defrtr;
1161 }
1138 1162
1139 lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime); 1163 lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
1140 1164
@@ -1163,8 +1187,10 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1163 rt = NULL; 1187 rt = NULL;
1164 } 1188 }
1165 1189
1190 ND_PRINTK(3, info, "RA: rt: %p lifetime: %d, for dev: %s\n",
1191 rt, lifetime, skb->dev->name);
1166 if (rt == NULL && lifetime) { 1192 if (rt == NULL && lifetime) {
1167 ND_PRINTK(3, dbg, "RA: adding default router\n"); 1193 ND_PRINTK(3, info, "RA: adding default router\n");
1168 1194
1169 rt = rt6_add_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev, pref); 1195 rt = rt6_add_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev, pref);
1170 if (rt == NULL) { 1196 if (rt == NULL) {
@@ -1260,12 +1286,22 @@ skip_linkparms:
1260 NEIGH_UPDATE_F_ISROUTER); 1286 NEIGH_UPDATE_F_ISROUTER);
1261 } 1287 }
1262 1288
1263 if (!ipv6_accept_ra(in6_dev)) 1289 if (!ipv6_accept_ra(in6_dev)) {
1290 ND_PRINTK(2, info,
1291 "RA: %s, accept_ra is false for dev: %s\n",
1292 __func__, skb->dev->name);
1264 goto out; 1293 goto out;
1294 }
1265 1295
1266#ifdef CONFIG_IPV6_ROUTE_INFO 1296#ifdef CONFIG_IPV6_ROUTE_INFO
1267 if (ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, NULL, 0)) 1297 if (!in6_dev->cnf.accept_ra_from_local &&
1298 ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr,
1299 NULL, 0)) {
1300 ND_PRINTK(2, info,
1301 "RA from local address detected on dev: %s: router info ignored.\n",
1302 skb->dev->name);
1268 goto skip_routeinfo; 1303 goto skip_routeinfo;
1304 }
1269 1305
1270 if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) { 1306 if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
1271 struct nd_opt_hdr *p; 1307 struct nd_opt_hdr *p;
@@ -1293,8 +1329,12 @@ skip_routeinfo:
1293 1329
1294#ifdef CONFIG_IPV6_NDISC_NODETYPE 1330#ifdef CONFIG_IPV6_NDISC_NODETYPE
1295 /* skip link-specific ndopts from interior routers */ 1331 /* skip link-specific ndopts from interior routers */
1296 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) 1332 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) {
1333 ND_PRINTK(2, info,
1334 "RA: %s, nodetype is NODEFAULT (interior routes), dev: %s\n",
1335 __func__, skb->dev->name);
1297 goto out; 1336 goto out;
1337 }
1298#endif 1338#endif
1299 1339
1300 if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) { 1340 if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
@@ -1728,7 +1768,7 @@ int __init ndisc_init(void)
1728 1768
1729#ifdef CONFIG_SYSCTL 1769#ifdef CONFIG_SYSCTL
1730 err = neigh_sysctl_register(NULL, &nd_tbl.parms, 1770 err = neigh_sysctl_register(NULL, &nd_tbl.parms,
1731 &ndisc_ifinfo_sysctl_change); 1771 ndisc_ifinfo_sysctl_change);
1732 if (err) 1772 if (err)
1733 goto out_unregister_pernet; 1773 goto out_unregister_pernet;
1734out: 1774out: