diff options
Diffstat (limited to 'net/ipv6/ndisc.c')
| -rw-r--r-- | net/ipv6/ndisc.c | 25 | 
1 files changed, 24 insertions, 1 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index f4462ee3302..1f625690967 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -156,7 +156,11 @@ struct neigh_table nd_tbl = {  /* ND options */  struct ndisc_options { -	struct nd_opt_hdr *nd_opt_array[__ND_OPT_MAX]; +	struct nd_opt_hdr *nd_opt_array[__ND_OPT_ARRAY_MAX]; +#ifdef CONFIG_IPV6_ROUTE_INFO +	struct nd_opt_hdr *nd_opts_ri; +	struct nd_opt_hdr *nd_opts_ri_end; +#endif  };  #define nd_opts_src_lladdr	nd_opt_array[ND_OPT_SOURCE_LL_ADDR] @@ -255,6 +259,13 @@ static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,  			if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0)  				ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;  			break; +#ifdef CONFIG_IPV6_ROUTE_INFO +		case ND_OPT_ROUTE_INFO: +			ndopts->nd_opts_ri_end = nd_opt; +			if (!ndopts->nd_opts_ri) +				ndopts->nd_opts_ri = nd_opt; +			break; +#endif  		default:  			/*  			 * Unknown options must be silently ignored, @@ -1202,6 +1213,18 @@ skip_defrtr:  			     NEIGH_UPDATE_F_ISROUTER);  	} +#ifdef CONFIG_IPV6_ROUTE_INFO +	if (ndopts.nd_opts_ri) { +		struct nd_opt_hdr *p; +		for (p = ndopts.nd_opts_ri; +		     p; +		     p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) { +			rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3, +				      &skb->nh.ipv6h->saddr); +		} +	} +#endif +  	if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {  		struct nd_opt_hdr *p;  		for (p = ndopts.nd_opts_pi;  |