diff options
Diffstat (limited to 'include/net/ndisc.h')
| -rw-r--r-- | include/net/ndisc.h | 50 | 
1 files changed, 50 insertions, 0 deletions
diff --git a/include/net/ndisc.h b/include/net/ndisc.h index c02b6ad3f6c..96a3b5c03e3 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -47,6 +47,8 @@ enum {  #include <linux/icmpv6.h>  #include <linux/in6.h>  #include <linux/types.h> +#include <linux/if_arp.h> +#include <linux/netdevice.h>  #include <net/neighbour.h> @@ -80,6 +82,54 @@ struct nd_opt_hdr {  	__u8		nd_opt_len;  } __packed; +/* ND options */ +struct ndisc_options { +	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 +	struct nd_opt_hdr *nd_useropts; +	struct nd_opt_hdr *nd_useropts_end; +}; + +#define nd_opts_src_lladdr	nd_opt_array[ND_OPT_SOURCE_LL_ADDR] +#define nd_opts_tgt_lladdr	nd_opt_array[ND_OPT_TARGET_LL_ADDR] +#define nd_opts_pi		nd_opt_array[ND_OPT_PREFIX_INFO] +#define nd_opts_pi_end		nd_opt_array[__ND_OPT_PREFIX_INFO_END] +#define nd_opts_rh		nd_opt_array[ND_OPT_REDIRECT_HDR] +#define nd_opts_mtu		nd_opt_array[ND_OPT_MTU] + +#define NDISC_OPT_SPACE(len) (((len)+2+7)&~7) + +extern struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, +						 struct ndisc_options *ndopts); + +/* + * Return the padding between the option length and the start of the + * link addr.  Currently only IP-over-InfiniBand needs this, although + * if RFC 3831 IPv6-over-Fibre Channel is ever implemented it may + * also need a pad of 2. + */ +static int ndisc_addr_option_pad(unsigned short type) +{ +	switch (type) { +	case ARPHRD_INFINIBAND: return 2; +	default:                return 0; +	} +} + +static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p, +				      struct net_device *dev) +{ +	u8 *lladdr = (u8 *)(p + 1); +	int lladdrlen = p->nd_opt_len << 3; +	int prepad = ndisc_addr_option_pad(dev->type); +	if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad)) +		return NULL; +	return lladdr + prepad; +} +  static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, __u32 *hash_rnd)  {  	const u32 *p32 = pkey;  |