diff options
Diffstat (limited to 'net/ipv6/ndisc.c')
| -rw-r--r-- | net/ipv6/ndisc.c | 58 | 
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)  	optlen = (skb_tail_pointer(skb) - skb_transport_header(skb)) -  		sizeof(struct ra_msg); +	ND_PRINTK(2, info, +		  "RA: %s, dev: %s\n", +		  __func__, skb->dev->name);  	if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {  		ND_PRINTK(2, warn, "RA: source address is not link-local\n");  		return; @@ -1102,13 +1105,21 @@ static void ndisc_router_discovery(struct sk_buff *skb)  		return;  	} -	if (!ipv6_accept_ra(in6_dev)) +	if (!ipv6_accept_ra(in6_dev)) { +		ND_PRINTK(2, info, +			  "RA: %s, did not accept ra for dev: %s\n", +			  __func__, skb->dev->name);  		goto skip_linkparms; +	}  #ifdef CONFIG_IPV6_NDISC_NODETYPE  	/* skip link-specific parameters from interior routers */ -	if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) +	if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) { +		ND_PRINTK(2, info, +			  "RA: %s, nodetype is NODEFAULT, dev: %s\n", +			  __func__, skb->dev->name);  		goto skip_linkparms; +	}  #endif  	if (in6_dev->if_flags & IF_RS_SENT) { @@ -1130,11 +1141,24 @@ static void ndisc_router_discovery(struct sk_buff *skb)  				(ra_msg->icmph.icmp6_addrconf_other ?  					IF_RA_OTHERCONF : 0); -	if (!in6_dev->cnf.accept_ra_defrtr) +	if (!in6_dev->cnf.accept_ra_defrtr) { +		ND_PRINTK(2, info, +			  "RA: %s, defrtr is false for dev: %s\n", +			  __func__, skb->dev->name);  		goto skip_defrtr; +	} -	if (ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, NULL, 0)) +	/* Do not accept RA with source-addr found on local machine unless +	 * accept_ra_from_local is set to true. +	 */ +	if (!in6_dev->cnf.accept_ra_from_local && +	    ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, +			  NULL, 0)) { +		ND_PRINTK(2, info, +			  "RA from local address detected on dev: %s: default router ignored\n", +			  skb->dev->name);  		goto skip_defrtr; +	}  	lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime); @@ -1163,8 +1187,10 @@ static void ndisc_router_discovery(struct sk_buff *skb)  		rt = NULL;  	} +	ND_PRINTK(3, info, "RA: rt: %p  lifetime: %d, for dev: %s\n", +		  rt, lifetime, skb->dev->name);  	if (rt == NULL && lifetime) { -		ND_PRINTK(3, dbg, "RA: adding default router\n"); +		ND_PRINTK(3, info, "RA: adding default router\n");  		rt = rt6_add_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev, pref);  		if (rt == NULL) { @@ -1260,12 +1286,22 @@ skip_linkparms:  			     NEIGH_UPDATE_F_ISROUTER);  	} -	if (!ipv6_accept_ra(in6_dev)) +	if (!ipv6_accept_ra(in6_dev)) { +		ND_PRINTK(2, info, +			  "RA: %s, accept_ra is false for dev: %s\n", +			  __func__, skb->dev->name);  		goto out; +	}  #ifdef CONFIG_IPV6_ROUTE_INFO -	if (ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, NULL, 0)) +	if (!in6_dev->cnf.accept_ra_from_local && +	    ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, +			  NULL, 0)) { +		ND_PRINTK(2, info, +			  "RA from local address detected on dev: %s: router info ignored.\n", +			  skb->dev->name);  		goto skip_routeinfo; +	}  	if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {  		struct nd_opt_hdr *p; @@ -1293,8 +1329,12 @@ skip_routeinfo:  #ifdef CONFIG_IPV6_NDISC_NODETYPE  	/* skip link-specific ndopts from interior routers */ -	if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) +	if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) { +		ND_PRINTK(2, info, +			  "RA: %s, nodetype is NODEFAULT (interior routes), dev: %s\n", +			  __func__, skb->dev->name);  		goto out; +	}  #endif  	if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) { @@ -1728,7 +1768,7 @@ int __init ndisc_init(void)  #ifdef CONFIG_SYSCTL  	err = neigh_sysctl_register(NULL, &nd_tbl.parms, -				    &ndisc_ifinfo_sysctl_change); +				    ndisc_ifinfo_sysctl_change);  	if (err)  		goto out_unregister_pernet;  out:  |