| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #ifndef _NDISC_H
 | 
					
						
							|  |  |  | #define _NDISC_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  *	ICMP codes for neighbour discovery messages | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define NDISC_ROUTER_SOLICITATION	133
 | 
					
						
							|  |  |  | #define NDISC_ROUTER_ADVERTISEMENT	134
 | 
					
						
							|  |  |  | #define NDISC_NEIGHBOUR_SOLICITATION	135
 | 
					
						
							|  |  |  | #define NDISC_NEIGHBOUR_ADVERTISEMENT	136
 | 
					
						
							|  |  |  | #define NDISC_REDIRECT			137
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-11 18:35:59 -04:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Router type: cross-layer information from link-layer to | 
					
						
							|  |  |  |  * IPv6 layer reported by certain link types (e.g., RFC4214). | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define NDISC_NODETYPE_UNSPEC		0	/* unspecified (default) */
 | 
					
						
							|  |  |  | #define NDISC_NODETYPE_HOST		1	/* host or unauthorized router */
 | 
					
						
							|  |  |  | #define NDISC_NODETYPE_NODEFAULT	2	/* non-default router */
 | 
					
						
							|  |  |  | #define NDISC_NODETYPE_DEFAULT		3	/* default router */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *	ndisc options | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum { | 
					
						
							|  |  |  | 	__ND_OPT_PREFIX_INFO_END = 0, | 
					
						
							|  |  |  | 	ND_OPT_SOURCE_LL_ADDR = 1,	/* RFC2461 */ | 
					
						
							|  |  |  | 	ND_OPT_TARGET_LL_ADDR = 2,	/* RFC2461 */ | 
					
						
							|  |  |  | 	ND_OPT_PREFIX_INFO = 3,		/* RFC2461 */ | 
					
						
							|  |  |  | 	ND_OPT_REDIRECT_HDR = 4,	/* RFC2461 */ | 
					
						
							|  |  |  | 	ND_OPT_MTU = 5,			/* RFC2461 */ | 
					
						
							| 
									
										
										
										
											2006-03-20 17:06:24 -08:00
										 |  |  | 	__ND_OPT_ARRAY_MAX, | 
					
						
							|  |  |  | 	ND_OPT_ROUTE_INFO = 24,		/* RFC4191 */ | 
					
						
							| 
									
										
										
										
											2007-10-10 21:22:05 -07:00
										 |  |  | 	ND_OPT_RDNSS = 25,		/* RFC5006 */ | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	__ND_OPT_MAX | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define MAX_RTR_SOLICITATION_DELAY	HZ
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define ND_REACHABLE_TIME		(30*HZ)
 | 
					
						
							|  |  |  | #define ND_RETRANS_TIMER		HZ
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-27 02:43:12 -02:00
										 |  |  | #include <linux/compiler.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #include <linux/icmpv6.h>
 | 
					
						
							| 
									
										
										
										
											2005-12-27 02:43:12 -02:00
										 |  |  | #include <linux/in6.h>
 | 
					
						
							|  |  |  | #include <linux/types.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #include <net/neighbour.h>
 | 
					
						
							| 
									
										
										
										
											2005-12-27 02:43:12 -02:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct ctl_table; | 
					
						
							|  |  |  | struct inet6_dev; | 
					
						
							|  |  |  | struct net_device; | 
					
						
							|  |  |  | struct net_proto_family; | 
					
						
							|  |  |  | struct sk_buff; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern struct neigh_table nd_tbl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct nd_msg { | 
					
						
							|  |  |  |         struct icmp6hdr	icmph; | 
					
						
							|  |  |  |         struct in6_addr	target; | 
					
						
							|  |  |  | 	__u8		opt[0]; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct rs_msg { | 
					
						
							|  |  |  | 	struct icmp6hdr	icmph; | 
					
						
							|  |  |  | 	__u8		opt[0]; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ra_msg { | 
					
						
							|  |  |  |         struct icmp6hdr		icmph; | 
					
						
							| 
									
										
										
										
											2006-11-14 20:56:00 -08:00
										 |  |  | 	__be32			reachable_time; | 
					
						
							|  |  |  | 	__be32			retrans_timer; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct nd_opt_hdr { | 
					
						
							|  |  |  | 	__u8		nd_opt_type; | 
					
						
							|  |  |  | 	__u8		nd_opt_len; | 
					
						
							| 
									
										
										
										
											2010-06-03 03:21:52 -07:00
										 |  |  | } __packed; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-28 15:06:58 -05:00
										 |  |  | static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, __u32 *hash_rnd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const u32 *p32 = pkey; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (((p32[0] ^ dev->ifindex) * hash_rnd[0]) + | 
					
						
							|  |  |  | 		(p32[1] * hash_rnd[1]) + | 
					
						
							|  |  |  | 		(p32[2] * hash_rnd[2]) + | 
					
						
							|  |  |  | 		(p32[3] * hash_rnd[3])); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-28 15:41:23 -05:00
										 |  |  | static inline struct neighbour *__ipv6_neigh_lookup(struct neigh_table *tbl, struct net_device *dev, const void *pkey) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct neigh_hash_table *nht; | 
					
						
							|  |  |  | 	const u32 *p32 = pkey; | 
					
						
							|  |  |  | 	struct neighbour *n; | 
					
						
							|  |  |  | 	u32 hash_val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rcu_read_lock_bh(); | 
					
						
							|  |  |  | 	nht = rcu_dereference_bh(tbl->nht); | 
					
						
							|  |  |  | 	hash_val = ndisc_hashfn(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); | 
					
						
							|  |  |  | 	for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); | 
					
						
							|  |  |  | 	     n != NULL; | 
					
						
							|  |  |  | 	     n = rcu_dereference_bh(n->next)) { | 
					
						
							|  |  |  | 		u32 *n32 = (u32 *) n->primary_key; | 
					
						
							|  |  |  | 		if (n->dev == dev && | 
					
						
							|  |  |  | 		    ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) | | 
					
						
							|  |  |  | 		     (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0) { | 
					
						
							|  |  |  | 			if (!atomic_inc_not_zero(&n->refcnt)) | 
					
						
							|  |  |  | 				n = NULL; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	rcu_read_unlock_bh(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-29 11:13:15 -08:00
										 |  |  | extern int			ndisc_init(void); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern void			ndisc_cleanup(void); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern int			ndisc_rcv(struct sk_buff *skb); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern void			ndisc_send_ns(struct net_device *dev, | 
					
						
							|  |  |  | 					      struct neighbour *neigh, | 
					
						
							| 
									
										
										
											
												[IPV6]: Make address arguments const.
- net/ipv6/addrconf.c:
	ipv6_get_ifaddr(), ipv6_dev_get_saddr()
- net/ipv6/mcast.c:
	ipv6_sock_mc_join(), ipv6_sock_mc_drop(),
	inet6_mc_check(),
	ipv6_dev_mc_inc(), __ipv6_dev_mc_dec(), ipv6_dev_mc_dec(),
	ipv6_chk_mcast_addr()
- net/ipv6/route.c:
	rt6_lookup(), icmp6_dst_alloc()
- net/ipv6/ip6_output.c:
	ip6_nd_hdr()
- net/ipv6/ndisc.c:
	ndisc_send_ns(), ndisc_send_rs(), ndisc_send_redirect(),
	ndisc_get_neigh(), __ndisc_send()
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
											
										 
											2008-04-10 15:42:10 +09:00
										 |  |  | 					      const struct in6_addr *solicit, | 
					
						
							|  |  |  | 					      const struct in6_addr *daddr, | 
					
						
							|  |  |  | 					      const struct in6_addr *saddr); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern void			ndisc_send_rs(struct net_device *dev, | 
					
						
							| 
									
										
										
											
												[IPV6]: Make address arguments const.
- net/ipv6/addrconf.c:
	ipv6_get_ifaddr(), ipv6_dev_get_saddr()
- net/ipv6/mcast.c:
	ipv6_sock_mc_join(), ipv6_sock_mc_drop(),
	inet6_mc_check(),
	ipv6_dev_mc_inc(), __ipv6_dev_mc_dec(), ipv6_dev_mc_dec(),
	ipv6_chk_mcast_addr()
- net/ipv6/route.c:
	rt6_lookup(), icmp6_dst_alloc()
- net/ipv6/ip6_output.c:
	ip6_nd_hdr()
- net/ipv6/ndisc.c:
	ndisc_send_ns(), ndisc_send_rs(), ndisc_send_redirect(),
	ndisc_get_neigh(), __ndisc_send()
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
											
										 
											2008-04-10 15:42:10 +09:00
										 |  |  | 					      const struct in6_addr *saddr, | 
					
						
							|  |  |  | 					      const struct in6_addr *daddr); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern void			ndisc_send_redirect(struct sk_buff *skb, | 
					
						
							| 
									
										
										
											
												[IPV6]: Make address arguments const.
- net/ipv6/addrconf.c:
	ipv6_get_ifaddr(), ipv6_dev_get_saddr()
- net/ipv6/mcast.c:
	ipv6_sock_mc_join(), ipv6_sock_mc_drop(),
	inet6_mc_check(),
	ipv6_dev_mc_inc(), __ipv6_dev_mc_dec(), ipv6_dev_mc_dec(),
	ipv6_chk_mcast_addr()
- net/ipv6/route.c:
	rt6_lookup(), icmp6_dst_alloc()
- net/ipv6/ip6_output.c:
	ip6_nd_hdr()
- net/ipv6/ndisc.c:
	ndisc_send_ns(), ndisc_send_rs(), ndisc_send_redirect(),
	ndisc_get_neigh(), __ndisc_send()
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
											
										 
											2008-04-10 15:42:10 +09:00
										 |  |  | 						    const struct in6_addr *target); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-22 04:53:02 +00:00
										 |  |  | extern int			ndisc_mc_map(const struct in6_addr *addr, char *buf, | 
					
						
							|  |  |  | 					     struct net_device *dev, int dir); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												bonding: send IPv6 neighbor advertisement on failover
This patch adds better IPv6 failover support for bonding devices,
especially when in active-backup mode and there are only IPv6 addresses
configured, as reported by Alex Sidorenko.
- Creates a new file, net/drivers/bonding/bond_ipv6.c, for the
   IPv6-specific routines.  Both regular bonds and VLANs over bonds
   are supported.
- Adds a new tunable, num_unsol_na, to limit the number of unsolicited
   IPv6 Neighbor Advertisements that are sent on a failover event.
   Default is 1.
- Creates two new IPv6 neighbor discovery functions:
   ndisc_build_skb()
   ndisc_send_skb()
   These were required to support VLANs since we have to be able to
   add the VLAN id to the skb since ndisc_send_na() and friends
   shouldn't be asked to do this.  These two routines are basically
   __ndisc_send() split into two pieces, in a slightly different order.
- Updates Documentation/networking/bonding.txt and bumps the rev of bond
   support to 3.4.0.
On failover, this new code will generate one packet:
- An unsolicited IPv6 Neighbor Advertisement, which helps the switch
   learn that the address has moved to the new slave.
Testing has shown that sending just the NA results in pretty good
behavior when in active-back mode, I saw no lost ping packets for example.
Signed-off-by: Brian Haley <brian.haley@hp.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
											
										 
											2008-11-04 17:51:14 -08:00
										 |  |  | extern struct sk_buff		*ndisc_build_skb(struct net_device *dev, | 
					
						
							|  |  |  | 						 const struct in6_addr *daddr, | 
					
						
							|  |  |  | 						 const struct in6_addr *saddr, | 
					
						
							|  |  |  | 						 struct icmp6hdr *icmp6h, | 
					
						
							|  |  |  | 						 const struct in6_addr *target, | 
					
						
							|  |  |  | 						 int llinfo); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern void			ndisc_send_skb(struct sk_buff *skb, | 
					
						
							|  |  |  | 					       struct net_device *dev, | 
					
						
							|  |  |  | 					       struct neighbour *neigh, | 
					
						
							|  |  |  | 					       const struct in6_addr *daddr, | 
					
						
							|  |  |  | 					       const struct in6_addr *saddr, | 
					
						
							|  |  |  | 					       struct icmp6hdr *icmp6h); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  *	IGMP | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-02-29 11:13:15 -08:00
										 |  |  | extern int			igmp6_init(void); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern void			igmp6_cleanup(void); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern int			igmp6_event_query(struct sk_buff *skb); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern int			igmp6_event_report(struct sk_buff *skb); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_SYSCTL
 | 
					
						
							| 
									
										
										
										
											2005-12-27 02:43:12 -02:00
										 |  |  | extern int 			ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 							   int write, | 
					
						
							|  |  |  | 							   void __user *buffer, | 
					
						
							|  |  |  | 							   size_t *lenp, | 
					
						
							|  |  |  | 							   loff_t *ppos); | 
					
						
							| 
									
										
										
										
											2008-10-15 22:04:23 -07:00
										 |  |  | int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, | 
					
						
							|  |  |  | 				 void __user *oldval, size_t __user *oldlenp, | 
					
						
							| 
									
										
										
										
											2008-05-19 16:25:42 -07:00
										 |  |  | 				 void __user *newval, size_t newlen); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern void 			inet6_ifinfo_notify(int event, | 
					
						
							|  |  |  | 						    struct inet6_dev *idev); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |