2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  originally  based  on  the  dummy  device . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  1999 ,  Thomas  Davis ,  tadavis @ lbl . gov . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Licensed  under  the  GPL .  Based  on  dummy . c ,  and  eql . c  devices . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bonding . c :  an  Ethernet  Bonding  driver 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  is  useful  to  talk  to  a  Cisco  EtherChannel  compatible  equipment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	Cisco  5500 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	Sun  Trunking  ( Solaris ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	Alteon  AceDirector  Trunks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	Linux  Bonding 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	and  probably  many  L2  switches  . . . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  How  it  works : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     ifconfig  bond0  ipaddress  netmask  up 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *       will  setup  a  network  device ,  with  an  ip  address .   No  mac  address 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	will  be  assigned  at  this  time .   The  hw  mac  address  will  come  from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	the  first  slave  bonded  to  the  channel .   All  slaves  will  then  use 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	this  hw  mac  address . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     ifconfig  bond0  down 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *          will  release  all  slaves ,  marking  them  as  down . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     ifenslave  bond0  eth0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	will  attach  eth0  to  bond0  as  a  slave .   eth0  hw  mac  address  will  either 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	a :  be  used  as  initial  mac  address 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	b :  if  a  hw  mac  address  already  is  there ,  eth0 ' s  hw  mac  address 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	   will  then  be  set  from  bond0 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <linux/kernel.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/module.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/types.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/fcntl.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/interrupt.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/ptrace.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/ioport.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/in.h> 
  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <net/ip.h> 
  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <linux/ip.h> 
  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <linux/tcp.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/udp.h> 
  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <linux/slab.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/string.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/init.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/timer.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/socket.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/ctype.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/inet.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/bitops.h> 
  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <linux/io.h> 
  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <asm/system.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <asm/dma.h> 
  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <linux/uaccess.h> 
  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <linux/errno.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/netdevice.h> 
  
						 
					
						
							
								
									
										
										
										
											2010-05-06 00:48:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <linux/netpoll.h> 
  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <linux/inetdevice.h> 
  
						 
					
						
							
								
									
										
											 
										
											
												bonding: Improve IGMP join processing
	In active-backup mode, the current bonding code duplicates IGMP
traffic to all slaves, so that switches are up to date in case of a
failover from an active to a backup interface.  If bonding then fails
back to the original active interface, it is likely that the "active
slave" switch's IGMP forwarding for the port will be out of date until
some event occurs to refresh the switch (e.g., a membership query).
	This patch alters the behavior of bonding to no longer flood
IGMP to all ports, and to issue IGMP JOINs to the newly active port at
the time of a failover.  This insures that switches are kept up to date
for all cases.
	"GOELLESCH Niels" <niels.goellesch@eurocontrol.int> originally
reported this problem, and included a patch.  His original patch was
modified by Jay Vosburgh to additionally remove the existing IGMP flood
behavior, use RCU, streamline code paths, fix trailing white space, and
adjust for style.
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
											 
										 
										
											2007-02-28 17:03:37 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <linux/igmp.h> 
  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <linux/etherdevice.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/skbuff.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <net/sock.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/rtnetlink.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/proc_fs.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/seq_file.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/smp.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/if_ether.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <net/arp.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/mii.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/ethtool.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/if_vlan.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/if_bonding.h> 
  
						 
					
						
							
								
									
										
										
										
											2007-12-06 23:40:33 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <linux/jiffies.h> 
  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <net/route.h> 
  
						 
					
						
							
								
									
										
										
										
											2007-09-12 12:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <net/net_namespace.h> 
  
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <net/netns/generic.h> 
  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "bonding.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "bond_3ad.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "bond_alb.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*---------------------------- Module parameters ----------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* monitor all links that often (in milliseconds). <=0 disables monitoring */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define BOND_LINK_MON_INTERV	0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define BOND_LINK_ARP_INTERV	0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  max_bonds 	=  BOND_DEFAULT_MAX_BONDS ;  
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  tx_queues 	=  BOND_DEFAULT_TX_QUEUES ;  
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  num_grat_arp  =  1 ;  
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  num_unsol_na  =  1 ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  miimon 	=  BOND_LINK_MON_INTERV ;  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  updelay ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  downdelay ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  use_carrier 	=  1 ;  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * mode ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * primary ;  
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * primary_reselect ;  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * lacp_rate ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * ad_select ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * xmit_hash_policy ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  arp_interval  =  BOND_LINK_ARP_INTERV ;  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * arp_ip_target [ BOND_MAX_ARP_TARGETS ] ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * arp_validate ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * fail_over_mac ;  
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:39:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  all_slaves_active  =  0 ;  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  bond_params  bonding_defaults ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								module_param ( max_bonds ,  int ,  0 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( max_bonds ,  " Max number of bonded devices " ) ;  
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								module_param ( tx_queues ,  int ,  0 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( tx_queues ,  " Max number of transmit queues (default = 16) " ) ;  
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								module_param ( num_grat_arp ,  int ,  0644 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( num_grat_arp ,  " Number of gratuitous ARP packets to send on failover event " ) ;  
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								module_param ( num_unsol_na ,  int ,  0644 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( num_unsol_na ,  " Number of unsolicited IPv6 Neighbor Advertisements packets to send on failover event " ) ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								module_param ( miimon ,  int ,  0 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( miimon ,  " Link check interval in milliseconds " ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								module_param ( updelay ,  int ,  0 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( updelay ,  " Delay before considering link up, in milliseconds " ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								module_param ( downdelay ,  int ,  0 ) ;  
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:35:03 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( downdelay ,  " Delay before considering link down,  "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    " in milliseconds " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								module_param ( use_carrier ,  int ,  0 ) ;  
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:35:03 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( use_carrier ,  " Use netif_carrier_ok (vs MII ioctls) in miimon;  "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											      " 0 for off, 1 for on (default) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								module_param ( mode ,  charp ,  0 ) ;  
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:35:03 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( mode ,  " Mode of operation : 0 for balance-rr,  "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       " 1 for active-backup, 2 for balance-xor,  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       " 3 for broadcast, 4 for 802.3ad, 5 for balance-tlb,  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       " 6 for balance-alb " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								module_param ( primary ,  charp ,  0 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( primary ,  " Primary network device to use " ) ;  
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								module_param ( primary_reselect ,  charp ,  0 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( primary_reselect ,  " Reselect primary slave  "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   " once it comes up;  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   " 0 for always (default),  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   " 1 for only if speed of primary is  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   " better,  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   " 2 for only on active slave  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   " failure " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								module_param ( lacp_rate ,  charp ,  0 ) ;  
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:35:03 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( lacp_rate ,  " LACPDU tx rate to request from 802.3ad partner  "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    " (slow/fast) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-04 17:51:16 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								module_param ( ad_select ,  charp ,  0 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( ad_select ,  " 803.ad aggregation selection logic: stable (0, default), bandwidth (1), count (2) " ) ;  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								module_param ( xmit_hash_policy ,  charp ,  0 ) ;  
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:35:03 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( xmit_hash_policy ,  " XOR hashing method: 0 for layer 2 (default) "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   " , 1 for layer 3+4 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								module_param ( arp_interval ,  int ,  0 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( arp_interval ,  " arp interval in milliseconds " ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								module_param_array ( arp_ip_target ,  charp ,  NULL ,  0 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( arp_ip_target ,  " arp targets in n.n.n.n form " ) ;  
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								module_param ( arp_validate ,  charp ,  0 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( arp_validate ,  " validate src/dst of ARP probes: none (default), active, backup or all " ) ;  
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								module_param ( fail_over_mac ,  charp ,  0 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( fail_over_mac ,  " For active-backup, do not set all slaves to the same MAC.  none (default), active or follow " ) ;  
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:39:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								module_param ( all_slaves_active ,  int ,  0 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_PARM_DESC ( all_slaves_active ,  " Keep all frames received on an interface "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												     " by setting active flag for all slaves.   " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												     " 0 for never (default), 1 for always. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*----------------------------- Global variables ----------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-03 21:33:57 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  char  *  const  version  =  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									DRV_DESCRIPTION  " : v "  DRV_VERSION  "  ( "  DRV_RELDATE  " ) \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-17 10:42:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  bond_net_id  __read_mostly ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  __be32  arp_target [ BOND_MAX_ARP_TARGETS ] ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  arp_ip_count ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  bond_mode 	=  BOND_MODE_ROUNDROBIN ;  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  xmit_hashtype  =  BOND_XMIT_POLICY_LAYER2 ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  lacp_fast ;  
						 
					
						
							
								
									
										
										
										
											2010-07-19 06:52:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_NET_POLL_CONTROLLER 
  
						 
					
						
							
								
									
										
										
										
											2010-06-25 09:50:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  disable_netpoll  =  1 ;  
						 
					
						
							
								
									
										
										
										
											2010-07-19 06:52:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:10:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  struct  bond_parm_tbl  bond_lacp_tbl [ ]  =  {  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{ 	" slow " , 		AD_LACP_SLOW } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" fast " , 		AD_LACP_FAST } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	NULL , 		- 1 } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:10:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  struct  bond_parm_tbl  bond_mode_tbl [ ]  =  {  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{ 	" balance-rr " , 		BOND_MODE_ROUNDROBIN } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" active-backup " , 	BOND_MODE_ACTIVEBACKUP } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" balance-xor " , 		BOND_MODE_XOR } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" broadcast " , 		BOND_MODE_BROADCAST } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" 802.3ad " , 		BOND_MODE_8023AD } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" balance-tlb " , 		BOND_MODE_TLB } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" balance-alb " , 		BOND_MODE_ALB } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	NULL , 			- 1 } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:10:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  struct  bond_parm_tbl  xmit_hashtype_tbl [ ]  =  {  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{ 	" layer2 " , 		BOND_XMIT_POLICY_LAYER2 } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" layer3+4 " , 		BOND_XMIT_POLICY_LAYER34 } ,  
						 
					
						
							
								
									
										
										
										
											2007-12-06 23:40:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{ 	" layer2+3 " , 		BOND_XMIT_POLICY_LAYER23 } ,  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{ 	NULL , 			- 1 } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:10:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  struct  bond_parm_tbl  arp_validate_tbl [ ]  =  {  
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{ 	" none " , 			BOND_ARP_VALIDATE_NONE } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" active " , 		BOND_ARP_VALIDATE_ACTIVE } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" backup " , 		BOND_ARP_VALIDATE_BACKUP } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" all " , 			BOND_ARP_VALIDATE_ALL } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	NULL , 			- 1 } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:10:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  struct  bond_parm_tbl  fail_over_mac_tbl [ ]  =  {  
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{ 	" none " , 			BOND_FOM_NONE } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" active " , 		BOND_FOM_ACTIVE } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" follow " , 		BOND_FOM_FOLLOW } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	NULL , 			- 1 } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  struct  bond_parm_tbl  pri_reselect_tbl [ ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" always " , 		BOND_PRI_RESELECT_ALWAYS } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" better " , 		BOND_PRI_RESELECT_BETTER } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" failure " , 		BOND_PRI_RESELECT_FAILURE } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	NULL , 			- 1 } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-04 17:51:16 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								struct  bond_parm_tbl  ad_select_tbl [ ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" stable " , 	BOND_AD_STABLE } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" bandwidth " , 	BOND_AD_BANDWIDTH } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	" count " , 	BOND_AD_COUNT } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ 	NULL , 		- 1 } ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*-------------------------- Forward declarations ---------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_send_gratuitous_arp ( struct  bonding  * bond ) ;  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_init ( struct  net_device  * bond_dev ) ;  
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_uninit ( struct  net_device  * bond_dev ) ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*---------------------------- General routines -----------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-09 11:51:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  char  * bond_mode_name ( int  mode )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:08:09 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  const  char  * names [ ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										[ BOND_MODE_ROUNDROBIN ]  =  " load balancing (round-robin) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										[ BOND_MODE_ACTIVEBACKUP ]  =  " fault-tolerance (active-backup) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										[ BOND_MODE_XOR ]  =  " load balancing (xor) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										[ BOND_MODE_BROADCAST ]  =  " fault-tolerance (broadcast) " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										[ BOND_MODE_8023AD ]  =  " IEEE 802.3ad Dynamic link aggregation " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:08:09 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										[ BOND_MODE_TLB ]  =  " transmit load balancing " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										[ BOND_MODE_ALB ]  =  " adaptive load balancing " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( mode  <  0  | |  mode  >  BOND_MODE_ALB ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  " unknown " ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:08:09 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  names [ mode ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*---------------------------------- VLAN -----------------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_add_vlan  -  add  a  new  vlan  id  on  bond 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ bond :  bond  that  got  the  notification 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ vlan_id :  the  vlan  id  to  add 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  - ENOMEM  if  allocation  failed . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_add_vlan ( struct  bonding  * bond ,  unsigned  short  vlan_id )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  vlan_entry  * vlan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " bond: %s, vlan id %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 ( bond  ?  bond - > dev - > name  :  " None " ) ,  vlan_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									vlan  =  kzalloc ( sizeof ( struct  vlan_entry ) ,  GFP_KERNEL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! vlan ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INIT_LIST_HEAD ( & vlan - > vlan_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									vlan - > vlan_id  =  vlan_id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									write_lock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list_add_tail ( & vlan - > vlan_list ,  & bond - > vlan_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									write_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " added VLAN ID %d on bond %s \n " ,  vlan_id ,  bond - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_del_vlan  -  delete  a  vlan  id  from  bond 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ bond :  bond  that  got  the  notification 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ vlan_id :  the  vlan  id  to  delete 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  returns  - ENODEV  if  @ vlan_id  was  not  found  in  @ bond . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_del_vlan ( struct  bonding  * bond ,  unsigned  short  vlan_id )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  vlan_entry  * vlan ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  res  =  - ENODEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " bond: %s, vlan id %d \n " ,  bond - > dev - > name ,  vlan_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									write_lock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									list_for_each_entry ( vlan ,  & bond - > vlan_list ,  vlan_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( vlan - > vlan_id  = =  vlan_id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											list_del ( & vlan - > vlan_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:07:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( bond_is_lb ( bond ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												bond_alb_clear_vlan ( bond ,  vlan_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_debug ( " removed VLAN ID %d from bond %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 vlan_id ,  bond - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											kfree ( vlan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( list_empty ( & bond - > vlan_list )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ( bond - > slave_cnt  = =  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Last VLAN removed and no slaves, so
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  restore  block  on  adding  VLANs .  This  will 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  be  removed  once  new  slaves  that  are  not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  VLAN  challenged  will  be  added . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond - > dev - > features  | =  NETIF_F_VLAN_CHALLENGED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " couldn't find VLAN ID %d in bond %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 vlan_id ,  bond - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									write_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_has_challenged_slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ bond :  the  bond  we ' re  working  on 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Searches  the  slave  list .  Returns  1  if  a  vlan  challenged  slave 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  was  found ,  0  otherwise . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Assumes  bond - > lock  is  held . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_has_challenged_slaves ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( slave - > dev - > features  &  NETIF_F_VLAN_CHALLENGED )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_debug ( " found VLAN challenged slave - %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " no VLAN challenged slaves found \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_next_vlan  -  safely  skip  to  the  next  item  in  the  vlans  list . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ bond :  the  bond  we ' re  working  on 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ curr :  item  we ' re  advancing  from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  % NULL  if  list  is  empty ,  bond - > next_vlan  if  @ curr  is  % NULL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  or  @ curr - > next  otherwise  ( even  if  it  is  @ curr  itself  again ) . 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  Caller  must  hold  bond - > lock 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  vlan_entry  * bond_next_vlan ( struct  bonding  * bond ,  struct  vlan_entry  * curr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  vlan_entry  * next ,  * last ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( list_empty ( & bond - > vlan_list ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! curr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										next  =  list_entry ( bond - > vlan_list . next , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  struct  vlan_entry ,  vlan_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										last  =  list_entry ( bond - > vlan_list . prev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  struct  vlan_entry ,  vlan_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( last  = =  curr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											next  =  list_entry ( bond - > vlan_list . next , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													  struct  vlan_entry ,  vlan_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											next  =  list_entry ( curr - > vlan_list . next , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													  struct  vlan_entry ,  vlan_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_dev_queue_xmit  -  Prepare  skb  for  xmit . 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  @ bond :  bond  device  that  got  this  skb  for  tx . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ skb :  hw  accel  VLAN  tagged  skb  to  transmit 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ slave_dev :  slave  that  is  supposed  to  xmit  this  skbuff 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  When  the  bond  gets  an  skb  to  transmit  that  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  already  hardware  accelerated  VLAN  tagged ,  and  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  needs  to  relay  this  skb  to  a  slave  that  is  not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  hw  accel  capable ,  the  skb  needs  to  be  " unaccelerated " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  i . e .  strip  the  hwaccel  tag  and  re - insert  it  as  part 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  of  the  payload . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  bond_dev_queue_xmit ( struct  bonding  * bond ,  struct  sk_buff  * skb ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  net_device  * slave_dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-03-21 22:29:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  short  uninitialized_var ( vlan_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Test vlan_list not vlgrp to catch and handle 802.1p tags */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( ! list_empty ( & bond - > vlan_list )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ! ( slave_dev - > features  &  NETIF_F_HW_VLAN_TX )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    vlan_get_tag ( skb ,  & vlan_id )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										skb - > dev  =  slave_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										skb  =  vlan_put_tag ( skb ,  vlan_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! skb )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* vlan_put_tag() frees the skb in case of error,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  so  return  success  here  so  the  calling  functions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  won ' t  attempt  to  free  is  again . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										skb - > dev  =  slave_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									skb - > priority  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-06 00:48:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_NET_POLL_CONTROLLER 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( unlikely ( bond - > dev - > priv_flags  &  IFF_IN_NETPOLL ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  netpoll  * np  =  bond - > dev - > npinfo - > netpoll ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_dev - > npinfo  =  bond - > dev - > npinfo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										np - > real_dev  =  np - > dev  =  skb - > dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_dev - > priv_flags  | =  IFF_IN_NETPOLL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										netpoll_send_skb ( np ,  skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_dev - > priv_flags  & =  ~ IFF_IN_NETPOLL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										np - > dev  =  bond - > dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_queue_xmit ( skb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  In  the  following  3  functions ,  bond_vlan_rx_register ( ) ,  bond_vlan_rx_add_vid 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  and  bond_vlan_rx_kill_vid ,  We  don ' t  protect  the  slave  list  iteration  with  a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  lock  because : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  a .  This  operation  is  performed  in  IOCTL  context , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  b .  The  operation  is  protected  by  the  RTNL  semaphore  in  the  8021 q  code , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  c .  Holding  a  lock  with  BH  disabled  while  directly  calling  a  base  driver 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     entry  point  is  generally  a  BAD  idea . 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  The  design  of  synchronization / protection  for  this  operation  in  the  8021 q 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  module  is  good  for  one  or  more  VLAN  devices  over  a  single  physical  device 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  and  cannot  be  extended  for  a  teaming  solution  like  bonding ,  so  there  is  a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  potential  race  condition  here  where  a  net  device  from  the  vlan  group  might 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  be  referenced  ( either  by  a  base  driver  or  the  8021 q  code )  while  it  is  being 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  removed  from  the  system .  However ,  it  turns  out  we ' re  not  making  matters 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  worse ,  and  if  it  works  for  regular  VLAN  usage  it  will  work  here  too . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_vlan_rx_register  -  Propagates  registration  to  slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ bond_dev :  bonding  net  device  that  got  called 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ grp :  vlan  group  being  registered 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_vlan_rx_register ( struct  net_device  * bond_dev ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  struct  vlan_group  * grp ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									write_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									bond - > vlgrp  =  grp ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									write_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  net_device  * slave_dev  =  slave - > dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  struct  net_device_ops  * slave_ops  =  slave_dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( slave_dev - > features  &  NETIF_F_HW_VLAN_RX )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    slave_ops - > ndo_vlan_rx_register )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave_ops - > ndo_vlan_rx_register ( slave_dev ,  grp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_vlan_rx_add_vid  -  Propagates  adding  an  id  to  slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ bond_dev :  bonding  net  device  that  got  called 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ vid :  vlan  id  being  added 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_vlan_rx_add_vid ( struct  net_device  * bond_dev ,  uint16_t  vid )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ,  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  net_device  * slave_dev  =  slave - > dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  struct  net_device_ops  * slave_ops  =  slave_dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( slave_dev - > features  &  NETIF_F_HW_VLAN_FILTER )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    slave_ops - > ndo_vlan_rx_add_vid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave_ops - > ndo_vlan_rx_add_vid ( slave_dev ,  vid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  bond_add_vlan ( bond ,  vid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_err ( " %s: Error: Failed to add vlan id %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										       bond_dev - > name ,  vid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_vlan_rx_kill_vid  -  Propagates  deleting  an  id  to  slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ bond_dev :  bonding  net  device  that  got  called 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ vid :  vlan  id  being  removed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_vlan_rx_kill_vid ( struct  net_device  * bond_dev ,  uint16_t  vid )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * vlan_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ,  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  net_device  * slave_dev  =  slave - > dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  struct  net_device_ops  * slave_ops  =  slave_dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( slave_dev - > features  &  NETIF_F_HW_VLAN_FILTER )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    slave_ops - > ndo_vlan_rx_kill_vid )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											/* Save and then restore vlan_dev in the grp array,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  since  the  slave ' s  driver  might  clear  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-02 20:44:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											vlan_dev  =  vlan_group_get_device ( bond - > vlgrp ,  vid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											slave_ops - > ndo_vlan_rx_kill_vid ( slave_dev ,  vid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-02 20:44:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											vlan_group_set_device ( bond - > vlgrp ,  vid ,  vlan_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  bond_del_vlan ( bond ,  vid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_err ( " %s: Error: Failed to remove vlan id %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										       bond_dev - > name ,  vid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_add_vlans_on_slave ( struct  bonding  * bond ,  struct  net_device  * slave_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  vlan_entry  * vlan ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  net_device_ops  * slave_ops  =  slave_dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! bond - > vlgrp ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( slave_dev - > features  &  NETIF_F_HW_VLAN_RX )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    slave_ops - > ndo_vlan_rx_register ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_ops - > ndo_vlan_rx_register ( slave_dev ,  bond - > vlgrp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( slave_dev - > features  &  NETIF_F_HW_VLAN_FILTER )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    ! ( slave_ops - > ndo_vlan_rx_add_vid ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									list_for_each_entry ( vlan ,  & bond - > vlan_list ,  vlan_list ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_ops - > ndo_vlan_rx_add_vid ( slave_dev ,  vlan - > vlan_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_del_vlans_from_slave ( struct  bonding  * bond ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												      struct  net_device  * slave_dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  net_device_ops  * slave_ops  =  slave_dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  vlan_entry  * vlan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * vlan_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! bond - > vlgrp ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( slave_dev - > features  &  NETIF_F_HW_VLAN_FILTER )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    ! ( slave_ops - > ndo_vlan_rx_kill_vid ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  unreg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list_for_each_entry ( vlan ,  & bond - > vlan_list ,  vlan_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! vlan - > vlan_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Save and then restore vlan_dev in the grp array,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  since  the  slave ' s  driver  might  clear  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-02 20:44:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										vlan_dev  =  vlan_group_get_device ( bond - > vlgrp ,  vlan - > vlan_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										slave_ops - > ndo_vlan_rx_kill_vid ( slave_dev ,  vlan - > vlan_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-02 20:44:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										vlan_group_set_device ( bond - > vlgrp ,  vlan - > vlan_id ,  vlan_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								unreg :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( slave_dev - > features  &  NETIF_F_HW_VLAN_RX )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    slave_ops - > ndo_vlan_rx_register ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_ops - > ndo_vlan_rx_register ( slave_dev ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*------------------------------- Link status -------------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-27 13:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Set  the  carrier  state  for  the  master  according  to  the  state  of  its 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  slaves .   If  any  slaves  are  up ,  the  master  is  up .   In  802.3 ad  mode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  do  special  802.3 ad  magic . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  zero  if  carrier  state  does  not  change ,  nonzero  if  it  does . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_set_carrier ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > slave_cnt  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  down ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_8023AD ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  bond_3ad_set_carrier ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( slave - > link  = =  BOND_LINK_UP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! netif_carrier_ok ( bond - > dev ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												netif_carrier_on ( bond - > dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								down :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( netif_carrier_ok ( bond - > dev ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										netif_carrier_off ( bond - > dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Get  link  speed  and  duplex  from  the  slave ' s  base  driver 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  using  ethtool .  If  for  some  reason  the  call  fails  or  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  values  are  invalid ,  fake  speed  and  duplex  to  100 / Full 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  and  return  error . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_update_speed_duplex ( struct  slave  * slave )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * slave_dev  =  slave - > dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ethtool_cmd  etool ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-31 14:00:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Fake speed and duplex */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									slave - > speed  =  SPEED_100 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									slave - > duplex  =  DUPLEX_FULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-31 14:00:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! slave_dev - > ethtool_ops  | |  ! slave_dev - > ethtool_ops - > get_settings ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-31 14:00:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  slave_dev - > ethtool_ops - > get_settings ( slave_dev ,  & etool ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( etool . speed )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SPEED_10 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SPEED_100 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SPEED_1000 : 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:52:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  SPEED_10000 : 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( etool . duplex )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  DUPLEX_FULL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  DUPLEX_HALF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									slave - > speed  =  etool . speed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									slave - > duplex  =  etool . duplex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  if  < dev >  supports  MII  link  status  reporting ,  check  its  link  status . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  We  either  do  MII / ETHTOOL  ioctls ,  or  check  netif_carrier_ok ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  depending  upon  the  setting  of  the  use_carrier  parameter . 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Return  either  BMSR_LSTATUS ,  meaning  that  the  link  is  up  ( or  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  can ' t  tell  and  just  pretend  it  is ) ,  or  0 ,  meaning  that  the  link  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  down . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  If  reporting  is  non - zero ,  instead  of  faking  link  up ,  return  - 1  if 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  both  ETHTOOL  and  MII  ioctls  fail  ( meaning  the  device  does  not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  support  them ) .   If  use_carrier  is  set ,  return  whatever  it  says . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  It ' d  be  nice  if  there  was  a  good  way  to  tell  if  a  driver  supports 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  netif_carrier ,  but  there  really  isn ' t . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_check_dev_link ( struct  bonding  * bond ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       struct  net_device  * slave_dev ,  int  reporting ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  net_device_ops  * slave_ops  =  slave_dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-28 22:23:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  ( * ioctl ) ( struct  net_device  * ,  struct  ifreq  * ,  int ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  ifreq  ifr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mii_ioctl_data  * mii ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-28 12:05:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! reporting  & &  ! netif_running ( slave_dev ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > params . use_carrier ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  netif_carrier_ok ( slave_dev )  ?  BMSR_LSTATUS  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-24 01:58:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Try to get link status using Ethtool first. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( slave_dev - > ethtool_ops )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( slave_dev - > ethtool_ops - > get_link )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											u32  link ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											link  =  slave_dev - > ethtool_ops - > get_link ( slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  link  ?  BMSR_LSTATUS  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Ethtool can't be used, fallback to MII ioctls. */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ioctl  =  slave_ops - > ndo_do_ioctl ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( ioctl )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* TODO: set pointer to correct ioctl on a per team member */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*       bases to make this more efficient. that is, once  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*       we determine the correct ioctl, we will always    */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*       call it and not the others for that team          */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*       member.                                           */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  We  cannot  assume  that  SIOCGMIIPHY  will  also  read  a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  register ;  not  all  network  drivers  ( e . g . ,  e100 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  support  that . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Yes, the mii is overlaid on the ifreq.ifr_ifru */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										strncpy ( ifr . ifr_name ,  slave_dev - > name ,  IFNAMSIZ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mii  =  if_mii ( & ifr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( IOCTL ( slave_dev ,  & ifr ,  SIOCGMIIPHY )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mii - > reg_num  =  MII_BMSR ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( IOCTL ( slave_dev ,  & ifr ,  SIOCGMIIREG )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  mii - > val_out  &  BMSR_LSTATUS ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  If  reporting ,  report  that  either  there ' s  no  dev - > do_ioctl , 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-31 14:00:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 *  or  both  SIOCGMIIREG  and  get_link  failed  ( meaning  that  we 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 *  cannot  report  link  status ) .   If  not  reporting ,  pretend 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  we ' re  ok . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  reporting  ?  - 1  :  BMSR_LSTATUS ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*----------------------------- Multicast list ------------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Push  the  promiscuity  flag  down  to  appropriate  slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_set_promiscuity ( struct  bonding  * bond ,  int  inc )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  err  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( USES_PRIMARY ( bond - > params . mode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* write lock already acquired */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond - > curr_active_slave )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  dev_set_promiscuity ( bond - > curr_active_slave - > dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														  inc ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  dev_set_promiscuity ( slave - > dev ,  inc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Push  the  allmulti  flag  down  to  all  slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_set_allmulti ( struct  bonding  * bond ,  int  inc )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  err  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( USES_PRIMARY ( bond - > params . mode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* write lock already acquired */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond - > curr_active_slave )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  dev_set_allmulti ( bond - > curr_active_slave - > dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													       inc ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  dev_set_allmulti ( slave - > dev ,  inc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Add  a  Multicast  address  to  slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  according  to  mode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_mc_add ( struct  bonding  * bond ,  void  * addr )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( USES_PRIMARY ( bond - > params . mode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* write lock already acquired */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > curr_active_slave ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dev_mc_add ( bond - > curr_active_slave - > dev ,  addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_for_each_slave ( bond ,  slave ,  i ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dev_mc_add ( slave - > dev ,  addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Remove  a  multicast  address  from  slave 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  according  to  mode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_mc_del ( struct  bonding  * bond ,  void  * addr )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( USES_PRIMARY ( bond - > params . mode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* write lock already acquired */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > curr_active_slave ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dev_mc_del ( bond - > curr_active_slave - > dev ,  addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dev_mc_del ( slave - > dev ,  addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												bonding: Improve IGMP join processing
	In active-backup mode, the current bonding code duplicates IGMP
traffic to all slaves, so that switches are up to date in case of a
failover from an active to a backup interface.  If bonding then fails
back to the original active interface, it is likely that the "active
slave" switch's IGMP forwarding for the port will be out of date until
some event occurs to refresh the switch (e.g., a membership query).
	This patch alters the behavior of bonding to no longer flood
IGMP to all ports, and to issue IGMP JOINs to the newly active port at
the time of a failover.  This insures that switches are kept up to date
for all cases.
	"GOELLESCH Niels" <niels.goellesch@eurocontrol.int> originally
reported this problem, and included a patch.  His original patch was
modified by Jay Vosburgh to additionally remove the existing IGMP flood
behavior, use RCU, streamline code paths, fix trailing white space, and
adjust for style.
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
											 
										 
										
											2007-02-28 17:03:37 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Retrieve  the  list  of  registered  multicast  addresses  for  the  bonding 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  device  and  retransmit  an  IGMP  JOIN  request  to  the  current  active 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  slave . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_resend_igmp_join_requests ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  in_device  * in_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ip_mc_list  * im ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rcu_read_lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									in_dev  =  __in_dev_get_rcu ( bond - > dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( in_dev )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( im  =  in_dev - > mc_list ;  im ;  im  =  im - > next ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												bonding: Improve IGMP join processing
	In active-backup mode, the current bonding code duplicates IGMP
traffic to all slaves, so that switches are up to date in case of a
failover from an active to a backup interface.  If bonding then fails
back to the original active interface, it is likely that the "active
slave" switch's IGMP forwarding for the port will be out of date until
some event occurs to refresh the switch (e.g., a membership query).
	This patch alters the behavior of bonding to no longer flood
IGMP to all ports, and to issue IGMP JOINs to the newly active port at
the time of a failover.  This insures that switches are kept up to date
for all cases.
	"GOELLESCH Niels" <niels.goellesch@eurocontrol.int> originally
reported this problem, and included a patch.  His original patch was
modified by Jay Vosburgh to additionally remove the existing IGMP flood
behavior, use RCU, streamline code paths, fix trailing white space, and
adjust for style.
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
											 
										 
										
											2007-02-28 17:03:37 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ip_mc_rejoin_group ( im ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rcu_read_unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  flush  all  members  of  flush - > mc_list  from  device  dev - > mc_list 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_mc_list_flush ( struct  net_device  * bond_dev ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       struct  net_device  * slave_dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  netdev_hw_addr  * ha ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									netdev_for_each_mc_addr ( ha ,  bond_dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_mc_del ( slave_dev ,  ha - > addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* del lacpdu mc addr from mc list */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										u8  lacpdu_multicast [ ETH_ALEN ]  =  MULTICAST_LACPDU_ADDR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dev_mc_del ( slave_dev ,  lacpdu_multicast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*--------------------------- Active slave change ---------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Update  the  mc  list  and  multicast - related  flags  for  the  new  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  old  active  slaves  ( if  any )  according  to  the  multicast  mode ,  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  promiscuous  flags  unconditionally . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_mc_swap ( struct  bonding  * bond ,  struct  slave  * new_active ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 struct  slave  * old_active ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  netdev_hw_addr  * ha ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! USES_PRIMARY ( bond - > params . mode ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* nothing to do -  mc list is already up-to-date on
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  all  slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( old_active )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > dev - > flags  &  IFF_PROMISC ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											dev_set_promiscuity ( old_active - > dev ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > dev - > flags  &  IFF_ALLMULTI ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											dev_set_allmulti ( old_active - > dev ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										netdev_for_each_mc_addr ( ha ,  bond - > dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dev_mc_del ( old_active - > dev ,  ha - > addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( new_active )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* FIXME: Signal errors upstream. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > dev - > flags  &  IFF_PROMISC ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											dev_set_promiscuity ( new_active - > dev ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > dev - > flags  &  IFF_ALLMULTI ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											dev_set_allmulti ( new_active - > dev ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										netdev_for_each_mc_addr ( ha ,  bond - > dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dev_mc_add ( new_active - > dev ,  ha - > addr ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												bonding: Improve IGMP join processing
	In active-backup mode, the current bonding code duplicates IGMP
traffic to all slaves, so that switches are up to date in case of a
failover from an active to a backup interface.  If bonding then fails
back to the original active interface, it is likely that the "active
slave" switch's IGMP forwarding for the port will be out of date until
some event occurs to refresh the switch (e.g., a membership query).
	This patch alters the behavior of bonding to no longer flood
IGMP to all ports, and to issue IGMP JOINs to the newly active port at
the time of a failover.  This insures that switches are kept up to date
for all cases.
	"GOELLESCH Niels" <niels.goellesch@eurocontrol.int> originally
reported this problem, and included a patch.  His original patch was
modified by Jay Vosburgh to additionally remove the existing IGMP flood
behavior, use RCU, streamline code paths, fix trailing white space, and
adjust for style.
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
											 
										 
										
											2007-02-28 17:03:37 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_resend_igmp_join_requests ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_do_fail_over_mac 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Perform  special  MAC  address  swapping  for  fail_over_mac  settings 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Called  with  RTNL ,  bond - > lock  for  read ,  curr_slave_lock  for  write_bh . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_do_fail_over_mac ( struct  bonding  * bond ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  struct  slave  * new_active , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  struct  slave  * old_active ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-14 11:15:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__releases ( & bond - > curr_slave_lock ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									__releases ( & bond - > lock ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									__acquires ( & bond - > lock ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									__acquires ( & bond - > curr_slave_lock ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u8  tmp_mac [ ETH_ALEN ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr  saddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  rv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( bond - > params . fail_over_mac )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_FOM_ACTIVE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( new_active ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memcpy ( bond - > dev - > dev_addr ,   new_active - > dev - > dev_addr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       new_active - > dev - > addr_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_FOM_FOLLOW : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  if  new_active  & &  old_active ,  swap  them 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  if  just  old_active ,  do  nothing  ( going  to  no  active  slave ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  if  just  new_active ,  set  new_active  to  bond ' s  MAC 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! new_active ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										write_unlock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( old_active )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memcpy ( tmp_mac ,  new_active - > dev - > dev_addr ,  ETH_ALEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memcpy ( saddr . sa_data ,  old_active - > dev - > dev_addr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       ETH_ALEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											saddr . sa_family  =  new_active - > dev - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memcpy ( saddr . sa_data ,  bond - > dev - > dev_addr ,  ETH_ALEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											saddr . sa_family  =  bond - > dev - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rv  =  dev_set_mac_address ( new_active - > dev ,  & saddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rv )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " %s: Error %d setting MAC of slave %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       bond - > dev - > name ,  - rv ,  new_active - > dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! old_active ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memcpy ( saddr . sa_data ,  tmp_mac ,  ETH_ALEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										saddr . sa_family  =  old_active - > dev - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rv  =  dev_set_mac_address ( old_active - > dev ,  & saddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rv ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " %s: Error %d setting MAC of slave %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       bond - > dev - > name ,  - rv ,  new_active - > dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										write_lock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_err ( " %s: bond_do_fail_over_mac impossible: bad policy %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       bond - > dev - > name ,  bond - > params . fail_over_mac ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  bond_should_change_active ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * prim  =  bond - > primary_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * curr  =  bond - > curr_active_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! prim  | |  ! curr  | |  curr - > link  ! =  BOND_LINK_UP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > force_primary )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond - > force_primary  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . primary_reselect  = =  BOND_PRI_RESELECT_BETTER  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( prim - > speed  <  curr - > speed  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     ( prim - > speed  = =  curr - > speed  & &  prim - > duplex  < =  curr - > duplex ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . primary_reselect  = =  BOND_PRI_RESELECT_FAILURE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  find_best_interface  -  select  the  best  available  slave  to  be  the  active  one 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ bond :  our  bonding  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Warning :  Caller  must  hold  curr_slave_lock  for  writing . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  slave  * bond_find_best_slave ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * new_active ,  * old_active ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * bestslave  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  mintime  =  bond - > params . updelay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 14:11:00 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									new_active  =  bond - > curr_active_slave ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! new_active )  {  /* there were no active slaves left */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > slave_cnt  >  0 )    /* found one slave */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											new_active  =  bond - > first_slave ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  NULL ;  /* still no slave, return NULL */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( bond - > primary_slave )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    bond - > primary_slave - > link  = =  BOND_LINK_UP  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    bond_should_change_active ( bond ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										new_active  =  bond - > primary_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* remember where to stop iterating over the slaves */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									old_active  =  new_active ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave_from ( bond ,  new_active ,  i ,  old_active )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( new_active - > link  = =  BOND_LINK_UP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  new_active ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( new_active - > link  = =  BOND_LINK_BACK  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   IS_UP ( new_active - > dev ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* link up, but waiting for stabilization */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( new_active - > delay  <  mintime )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mintime  =  new_active - > delay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bestslave  =  new_active ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  bestslave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  change_active_interface  -  change  the  active  slave  into  the  specified  one 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ bond :  our  bonding  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ new :  the  new  slave  to  make  the  active  one 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Set  the  new  slave  to  the  bond ' s  settings  and  unset  them  on  the  old 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  curr_active_slave . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Setting  include  flags ,  mc - list ,  promiscuity ,  allmulti ,  etc . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  If  @ new ' s  link  state  is  % BOND_LINK_BACK  we ' ll  set  it  to  % BOND_LINK_UP , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  because  it  is  apparently  the  best  available  slave  we  have ,  even  though  its 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  updelay  hasn ' t  timed  out  yet . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  If  new_active  is  not  NULL ,  caller  must  hold  bond - > lock  for  read  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  curr_slave_lock  for  write_bh . 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:35:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  bond_change_active_slave ( struct  bonding  * bond ,  struct  slave  * new_active )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * old_active  =  bond - > curr_active_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( old_active  = =  new_active ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( new_active )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										new_active - > jiffies  =  jiffies ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( new_active - > link  = =  BOND_LINK_BACK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( USES_PRIMARY ( bond - > params . mode ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pr_info ( " %s: making interface %s the new active one %d ms earlier. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond - > dev - > name ,  new_active - > dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													( bond - > params . updelay  -  new_active - > delay )  *  bond - > params . miimon ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											new_active - > delay  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											new_active - > link  =  BOND_LINK_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( bond - > params . mode  = =  BOND_MODE_8023AD ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												bond_3ad_handle_link_change ( new_active ,  BOND_LINK_UP ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:07:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( bond_is_lb ( bond ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												bond_alb_handle_link_change ( bond ,  new_active ,  BOND_LINK_UP ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( USES_PRIMARY ( bond - > params . mode ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pr_info ( " %s: making interface %s the new active one. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond - > dev - > name ,  new_active - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( USES_PRIMARY ( bond - > params . mode ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_mc_swap ( bond ,  new_active ,  old_active ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:07:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond_is_lb ( bond ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_alb_handle_active_change ( bond ,  new_active ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-21 16:36:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( old_active ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_set_slave_inactive_flags ( old_active ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( new_active ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_set_slave_active_flags ( new_active ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond - > curr_active_slave  =  new_active ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_ACTIVEBACKUP )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( old_active ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bond_set_slave_inactive_flags ( old_active ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( new_active )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_set_slave_active_flags ( new_active ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( bond - > params . fail_over_mac ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond_do_fail_over_mac ( bond ,  new_active , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														      old_active ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bond - > send_grat_arp  =  bond - > params . num_grat_arp ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:03 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bond_send_gratuitous_arp ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:02 -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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bond - > send_unsol_na  =  bond - > params . num_unsol_na ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_send_unsolicited_na ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											write_unlock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-15 02:37:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											netdev_bonding_change ( bond - > dev ,  NETDEV_BONDING_FAILOVER ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											write_lock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-25 14:49:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* resend IGMP joins since all were sent on curr_active_slave */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_ROUNDROBIN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_resend_igmp_join_requests ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_select_active_slave  -  select  a  new  active  slave ,  if  needed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ bond :  our  bonding  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  This  functions  should  be  called  when  one  of  the  following  occurs : 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  -  The  old  curr_active_slave  has  been  released  or  lost  its  link . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  -  The  primary_slave  has  got  its  link  back . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  -  A  slave  has  got  its  link  back  and  there ' s  no  old  curr_active_slave . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Caller  must  hold  bond - > lock  for  read  and  curr_slave_lock  for  write_bh . 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:35:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  bond_select_active_slave ( struct  bonding  * bond )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * best_slave ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-27 13:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  rv ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									best_slave  =  bond_find_best_slave ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( best_slave  ! =  bond - > curr_active_slave )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_change_active_slave ( bond ,  best_slave ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-27 13:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rv  =  bond_set_carrier ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! rv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( netif_carrier_ok ( bond - > dev ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_info ( " %s: first active interface up! \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-27 13:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_info ( " %s: now running without any active interface ! \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-27 13:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*--------------------------- slave list handling ---------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  function  attaches  the  slave  to  the  end  of  list . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond - > lock  held  for  writing  by  caller . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_attach_slave ( struct  bonding  * bond ,  struct  slave  * new_slave )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > first_slave  = =  NULL )  {  /* attaching the first slave */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_slave - > next  =  new_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_slave - > prev  =  new_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond - > first_slave  =  new_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_slave - > next  =  bond - > first_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_slave - > prev  =  bond - > first_slave - > prev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_slave - > next - > prev  =  new_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_slave - > prev - > next  =  new_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond - > slave_cnt + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  function  detaches  the  slave  from  the  list . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  WARNING :  no  check  is  made  to  verify  if  the  slave  effectively 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  belongs  to  < bond > . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Nothing  is  freed  on  return ,  structures  are  just  unchained . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  If  any  slave  pointer  in  bond  was  pointing  to  < slave > , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  it  should  be  changed  by  the  calling  function . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond - > lock  held  for  writing  by  caller . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_detach_slave ( struct  bonding  * bond ,  struct  slave  * slave )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( slave - > next ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										slave - > next - > prev  =  slave - > prev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( slave - > prev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										slave - > prev - > next  =  slave - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > first_slave  = =  slave )  {  /* slave is the first slave */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond - > slave_cnt  >  1 )  {  /* there are more slave */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond - > first_slave  =  slave - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond - > first_slave  =  NULL ;  /* slave was the last one */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									slave - > next  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									slave - > prev  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond - > slave_cnt - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-06 00:48:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_NET_POLL_CONTROLLER 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  You  must  hold  read  lock  on  bond - > lock  before  calling  this . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  slaves_support_netpoll ( struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  ret  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( slave - > dev - > priv_flags  &  IFF_DISABLE_NETPOLL )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ! slave - > dev - > netdev_ops - > ndo_poll_controller ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ret  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  i  ! =  0  & &  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_poll_controller ( struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev  =  bond_dev - > npinfo - > netpoll - > real_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dev  ! =  bond_dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										netpoll_poll_dev ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_netpoll_cleanup ( struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  struct  net_device_ops  * ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_dev - > npinfo  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( slave - > dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ops  =  slave - > dev - > netdev_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ops - > ndo_netpoll_cleanup ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ops - > ndo_netpoll_cleanup ( slave - > dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > dev - > npinfo  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_netpoll_cleanup ( struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*---------------------------------- IOCTL ----------------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-09 11:51:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_sethwaddr ( struct  net_device  * bond_dev ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											  struct  net_device  * slave_dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " bond_dev=%p \n " ,  bond_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pr_debug ( " slave_dev=%p \n " ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pr_debug ( " slave_dev->addr_len=%d \n " ,  slave_dev - > addr_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									memcpy ( bond_dev - > dev_addr ,  slave_dev - > dev_addr ,  slave_dev - > addr_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-10 15:47:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define BOND_VLAN_FEATURES \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									( NETIF_F_VLAN_CHALLENGED  |  NETIF_F_HW_VLAN_RX  |  NETIF_F_HW_VLAN_TX  |  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 NETIF_F_HW_VLAN_FILTER ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 01:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2005-11-04 18:45:45 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Compute  the  common  dev - > feature  set  available  to  all  slaves .   Some 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-10 15:47:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  feature  bits  are  managed  elsewhere ,  so  preserve  those  feature  bits 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  on  the  master  device . 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 01:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_compute_features ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * bond_dev  =  bond - > dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-10 15:47:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  long  features  =  bond_dev - > features ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-28 12:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  long  vlan_features  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:41 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  short  max_hard_header_len  =  max ( ( u16 ) ETH_HLEN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														bond_dev - > hard_header_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-04 18:45:45 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 01:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-10 15:47:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									features  & =  ~ ( NETIF_F_ALL_CSUM  |  BOND_VLAN_FEATURES ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-23 01:11:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									features  | =   NETIF_F_GSO_MASK  |  NETIF_F_NO_CSUM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! bond - > first_slave ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  done ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									features  & =  ~ NETIF_F_ONE_FOR_ALL ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-10 15:47:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-28 12:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									vlan_features  =  bond - > first_slave - > dev - > vlan_features ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:53:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-23 01:11:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										features  =  netdev_increment_features ( features , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														     slave - > dev - > features , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														     NETIF_F_ONE_FOR_ALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-28 12:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										vlan_features  =  netdev_increment_features ( vlan_features , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															slave - > dev - > vlan_features , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															NETIF_F_ONE_FOR_ALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:53:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( slave - > dev - > hard_header_len  >  max_hard_header_len ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											max_hard_header_len  =  slave - > dev - > hard_header_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 01:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-10-23 01:11:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								done :  
						 
					
						
							
								
									
										
										
										
											2007-08-10 15:47:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									features  | =  ( bond_dev - > features  &  BOND_VLAN_FEATURES ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-23 01:11:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_dev - > features  =  netdev_fix_features ( features ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-28 12:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_dev - > vlan_features  =  netdev_fix_features ( vlan_features ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:53:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_dev - > hard_header_len  =  max_hard_header_len ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 01:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_setup_by_slave ( struct  net_device  * bond_dev ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												struct  net_device  * slave_dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-20 20:14:53 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_dev - > header_ops 	    =  slave_dev - > header_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_dev - > type 		    =  slave_dev - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_dev - > hard_header_len    =  slave_dev - > hard_header_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_dev - > addr_len 	    =  slave_dev - > addr_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memcpy ( bond_dev - > broadcast ,  slave_dev - > broadcast , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_dev - > addr_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond - > setup_by_slave  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/* enslave device <slave> to bond device <master> */  
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:35:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  bond_enslave ( struct  net_device  * bond_dev ,  struct  net_device  * slave_dev )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  net_device_ops  * slave_ops  =  slave_dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * new_slave  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  netdev_hw_addr  * ha ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  sockaddr  addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  link_reporting ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  old_features  =  bond_dev - > features ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-21 14:18:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! bond - > params . use_carrier  & &  slave_dev - > ethtool_ops  = =  NULL  & & 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										slave_ops - > ndo_do_ioctl  = =  NULL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " %s: Warning: no link monitoring support for %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   bond_dev - > name ,  slave_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* bond must be initialized by bond_open() before enslaving */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( bond_dev - > flags  &  IFF_UP ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " %s: master_dev is not up in bond_enslave \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* already enslaved */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( slave_dev - > flags  &  IFF_SLAVE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " Error, Device was already enslaved \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - EBUSY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* vlan challenged mutual exclusion */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* no need to lock since we're protected by rtnl_lock */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( slave_dev - > features  &  NETIF_F_VLAN_CHALLENGED )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " %s: NETIF_F_VLAN_CHALLENGED \n " ,  slave_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > vlgrp )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " %s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       bond_dev - > name ,  slave_dev - > name ,  bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  - EPERM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " %s: Warning: enslaved VLAN challenged slave %s. Adding VLANs will be blocked as long as %s is part of bond %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   bond_dev - > name ,  slave_dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   slave_dev - > name ,  bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											bond_dev - > features  | =  NETIF_F_VLAN_CHALLENGED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " %s: ! NETIF_F_VLAN_CHALLENGED \n " ,  slave_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( bond - > slave_cnt  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* First slave, and it is not VLAN challenged,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  so  remove  the  block  of  adding  VLANs  over  the  bond . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_dev - > features  & =  ~ NETIF_F_VLAN_CHALLENGED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-26 16:11:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Old  ifenslave  binaries  are  no  longer  supported .   These  can 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 *  be  identified  with  moderate  accuracy  by  the  state  of  the  slave : 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-26 16:11:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 *  the  current  ifenslave  will  set  the  interface  down  prior  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  enslaving  it ;  the  old  ifenslave  will  not . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( slave_dev - > flags  &  IFF_UP ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_err ( " %s is up. This may be due to an out of date ifenslave. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-26 16:11:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       slave_dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  - EPERM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  err_undo_flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* set bonding device ether type by slave - bonding netdevices are
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  created  with  ether_setup ,  so  when  the  slave  type  is  not  ARPHRD_ETHER 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  there  is  a  need  to  override  some  of  the  type  dependent  attribs / funcs . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  bond  ether  type  mutual  exclusion  -  don ' t  allow  slaves  of  dissimilar 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  ether  type  ( eg  ARPHRD_ETHER  and  ARPHRD_INFINIBAND )  share  the  same  bond 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > slave_cnt  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 04:56:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond_dev - > type  ! =  slave_dev - > type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pr_debug ( " %s: change device type from %d to %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 bond_dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 bond_dev - > type ,  slave_dev - > type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-15 02:37:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-10 10:29:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  netdev_bonding_change ( bond_dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														    NETDEV_PRE_TYPE_CHANGE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  notifier_to_errno ( res ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pr_err ( " %s: refused to change device type \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       bond_dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  - EBUSY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  err_undo_flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-15 02:37:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-19 04:00:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Flush unicast and multicast addresses */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dev_uc_flush ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dev_mc_flush ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-19 04:00:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 04:56:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( slave_dev - > type  ! =  ARPHRD_ETHER ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond_setup_by_slave ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ether_setup ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-15 02:37:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-10 10:28:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											netdev_bonding_change ( bond_dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      NETDEV_POST_TYPE_CHANGE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 04:56:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( bond_dev - > type  ! =  slave_dev - > type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_err ( " %s ether type (%d) is different from other slaves (%d), can not enslave it. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       slave_dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       slave_dev - > type ,  bond_dev - > type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  err_undo_flags ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( slave_ops - > ndo_set_mac_address  = =  NULL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > slave_cnt  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " %s: Warning: The first slave device specified does not support setting the MAC address. Setting fail_over_mac to active. " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bond - > params . fail_over_mac  =  BOND_FOM_ACTIVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( bond - > params . fail_over_mac  ! =  BOND_FOM_ACTIVE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " %s: Error: The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  err_undo_flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-19 01:14:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* If this is the first slave, then we need to set the master's hardware
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  address  to  be  the  same  as  the  slave ' s .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > slave_cnt  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memcpy ( bond - > dev - > dev_addr ,  slave_dev - > dev_addr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       slave_dev - > addr_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-06 14:16:40 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									new_slave  =  kzalloc ( sizeof ( struct  slave ) ,  GFP_KERNEL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( ! new_slave )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  err_undo_flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Set  the  new_slave ' s  queue_id  to  be  zero .   Queue  ID  mapping 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  is  set  via  sysfs  or  module  option  if  desired . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									new_slave - > queue_id  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-18 05:42:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Save slave's original mtu and then set it to match the bond */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									new_slave - > original_mtu  =  slave_dev - > mtu ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  dev_set_mtu ( slave_dev ,  bond - > dev - > mtu ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_debug ( " Error %d calling dev_set_mtu \n " ,  res ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  err_free ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-26 16:11:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Save  slave ' s  original  ( " permanent " )  mac  address  for  modes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  that  need  it ,  and  for  restoring  it  upon  release ,  and  then 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  set  it  to  the  master ' s  address 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memcpy ( new_slave - > perm_hwaddr ,  slave_dev - > dev_addr ,  ETH_ALEN ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:57:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! bond - > params . fail_over_mac )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  Set  slave  to  master ' s  mac  address .   The  application  already 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  set  the  master ' s  mac  address  to  that  of  the  first  slave 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memcpy ( addr . sa_data ,  bond_dev - > dev_addr ,  bond_dev - > addr_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										addr . sa_family  =  slave_dev - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  dev_set_mac_address ( slave_dev ,  & addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_debug ( " Error %d calling set_mac_address \n " ,  res ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-18 05:42:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  err_restore_mtu ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-26 16:11:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												bonding / ipv6: no addrconf for slaves separately from master
	At present, when a device is enslaved to bonding, if ipv6 is
active then addrconf will be initated on the slave (because it is closed
then opened during the enslavement processing).  This causes DAD and RS
packets to be sent from the slave.  These packets in turn can confuse
switches that perform ipv6 snooping, causing them to incorrectly update
their forwarding tables (if, e.g., the slave being added is an inactve
backup that won't be used right away) and direct traffic away from the
active slave to a backup slave (where the incoming packets will be
dropped).
	This patch alters the behavior so that addrconf will only run on
the master device itself.  I believe this is logically correct, as it
prevents slaves from having an IPv6 identity independent from the
master.  This is consistent with the IPv4 behavior for bonding.
	This is accomplished by (a) having bonding set IFF_SLAVE sooner
in the enslavement processing than currently occurs (before open, not
after), and (b) having ipv6 addrconf ignore UP and CHANGE events on
slave devices.
	The eql driver also uses the IFF_SLAVE flag.  I inspected eql,
and I believe this change is reasonable for its usage of IFF_SLAVE, but
I did not test it.
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
											 
										 
										
											2007-07-09 10:42:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  netdev_set_master ( slave_dev ,  bond_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " Error %d calling netdev_set_master \n " ,  res ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-02 18:06:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										goto  err_restore_mac ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												bonding / ipv6: no addrconf for slaves separately from master
	At present, when a device is enslaved to bonding, if ipv6 is
active then addrconf will be initated on the slave (because it is closed
then opened during the enslavement processing).  This causes DAD and RS
packets to be sent from the slave.  These packets in turn can confuse
switches that perform ipv6 snooping, causing them to incorrectly update
their forwarding tables (if, e.g., the slave being added is an inactve
backup that won't be used right away) and direct traffic away from the
active slave to a backup slave (where the incoming packets will be
dropped).
	This patch alters the behavior so that addrconf will only run on
the master device itself.  I believe this is logically correct, as it
prevents slaves from having an IPv6 identity independent from the
master.  This is consistent with the IPv4 behavior for bonding.
	This is accomplished by (a) having bonding set IFF_SLAVE sooner
in the enslavement processing than currently occurs (before open, not
after), and (b) having ipv6 addrconf ignore UP and CHANGE events on
slave devices.
	The eql driver also uses the IFF_SLAVE flag.  I inspected eql,
and I believe this change is reasonable for its usage of IFF_SLAVE, but
I did not test it.
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
											 
										 
										
											2007-07-09 10:42:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-26 16:11:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* open the slave since the application closed it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  dev_open ( slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " Opening slave %s failed \n " ,  slave_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-02 18:06:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										goto  err_unset_master ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									new_slave - > dev  =  slave_dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									slave_dev - > priv_flags  | =  IFF_BONDING ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:07:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond_is_lb ( bond ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* bond_alb_init_slave() must be called before all other stages since
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  it  might  fail  and  we  do  not  want  to  have  to  undo  everything 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  bond_alb_init_slave ( bond ,  new_slave ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( res ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-02 18:06:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  err_close ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If the mode USES_PRIMARY, then the new slave gets the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  master ' s  promisc  ( and  mc )  settings  only  if  it  becomes  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  curr_active_slave ,  and  that  is  taken  care  of  later  when  calling 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  bond_change_active ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! USES_PRIMARY ( bond - > params . mode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* set promiscuity level to new slave */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond_dev - > flags  &  IFF_PROMISC )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  dev_set_promiscuity ( slave_dev ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  err_close ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* set allmulti level to new slave */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond_dev - > flags  &  IFF_ALLMULTI )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  dev_set_allmulti ( slave_dev ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  err_close ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-15 00:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										netif_addr_lock_bh ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* upload master's mc_list to new slave */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										netdev_for_each_mc_addr ( ha ,  bond_dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dev_mc_add ( slave_dev ,  ha - > addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-15 00:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										netif_addr_unlock_bh ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* add lacpdu mc addr to mc list */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										u8  lacpdu_multicast [ ETH_ALEN ]  =  MULTICAST_LACPDU_ADDR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dev_mc_add ( slave_dev ,  lacpdu_multicast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_add_vlans_on_slave ( bond ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									write_lock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_attach_slave ( bond ,  new_slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									new_slave - > delay  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									new_slave - > link_failure_count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 01:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_compute_features ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									write_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									new_slave - > last_arp_rx  =  jiffies ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . miimon  & &  ! bond - > params . use_carrier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										link_reporting  =  bond_check_dev_link ( bond ,  slave_dev ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( link_reporting  = =  - 1 )  & &  ! bond - > params . arp_interval )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  miimon  is  set  but  a  bonded  network  driver 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  does  not  support  ETHTOOL / MII  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  arp_interval  is  not  set .   Note :  if 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  use_carrier  is  enabled ,  we  will  never  go 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  here  ( because  netif_carrier  is  always 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  supported ) ;  thus ,  we  don ' t  need  to  change 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  the  messages  for  netif_carrier . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " %s: Warning: MII and ETHTOOL support not available for interface %s, and arp_interval/arp_ip_target module parameters not specified, thus bonding will not detect link failures! see bonding.txt for details. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:34:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       bond_dev - > name ,  slave_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										}  else  if  ( link_reporting  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* unable get link status using mii/ethtool */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " %s: Warning: can't get link status from interface %s; the network driver associated with this interface does not support MII or ETHTOOL link status reporting, thus miimon has no effect on this interface. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   bond_dev - > name ,  slave_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* check for initial state */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! bond - > params . miimon  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( bond_check_dev_link ( bond ,  slave_dev ,  0 )  = =  BMSR_LSTATUS ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond - > params . updelay )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_debug ( " Initial state of slave_dev is BOND_LINK_BACK \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											new_slave - > link   =  BOND_LINK_BACK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											new_slave - > delay  =  bond - > params . updelay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_debug ( " Initial state of slave_dev is BOND_LINK_UP \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											new_slave - > link   =  BOND_LINK_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_slave - > jiffies  =  jiffies ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " Initial state of slave_dev is BOND_LINK_DOWN \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										new_slave - > link   =  BOND_LINK_DOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond_update_speed_duplex ( new_slave )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( new_slave - > link  ! =  BOND_LINK_DOWN ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " %s: Warning: failed to get speed and duplex from %s, assumed to be 100Mb/sec and Full. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   bond_dev - > name ,  new_slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond - > params . mode  = =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " %s: Warning: Operation of 802.3ad mode requires ETHTOOL support in base driver for proper aggregator selection. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( USES_PRIMARY ( bond - > params . mode )  & &  bond - > params . primary [ 0 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* if there is a primary slave, remember it */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( strcmp ( bond - > params . primary ,  new_slave - > dev - > name )  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											bond - > primary_slave  =  new_slave ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bond - > force_primary  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									write_lock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									switch  ( bond - > params . mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_ACTIVEBACKUP : 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:56:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_set_slave_inactive_flags ( new_slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_select_active_slave ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_8023AD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* in 802.3ad mode, the internal mechanism
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  will  activate  the  slaves  in  the  selected 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  aggregator 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_set_slave_inactive_flags ( new_slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* if this is the first slave */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond - > slave_cnt  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											SLAVE_AD_INFO ( new_slave ) . id  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Initialize AD with the number of times that the AD timer is called in 1 second
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  can  be  called  only  after  the  mac  address  of  the  bond  is  set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_3ad_initialize ( bond ,  1000 / AD_TIMER_INTERVAL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    bond - > params . lacp_fast ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											SLAVE_AD_INFO ( new_slave ) . id  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												SLAVE_AD_INFO ( new_slave - > prev ) . id  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_3ad_bind_slave ( new_slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_TLB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_ALB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_slave - > state  =  BOND_STATE_ACTIVE ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_set_slave_inactive_flags ( new_slave ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												bonding: select current active slave when enslaving device for mode tlb and alb
I've hit an issue on my system when I've been using RealTek RTL8139D cards in
bonding interface in mode balancing-alb. When I enslave a card, the current
active slave (bond->curr_active_slave) is not set and the link is therefore
not functional.
----
# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.5.0 (November 4, 2008)
Bonding Mode: adaptive load balancing
Primary Slave: None
Currently Active Slave: None
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0
Slave Interface: eth1
MII Status: up
Link Failure Count: 0
Permanent HW addr: 00:1f:1f:01:2f:22
----
The thing that gets it right is when I unplug the cable and then I put it back
into the NIC. Then the current active slave is set to eth1 and link is working
just fine. Here is dmesg log with bonding DEBUG messages turned on:
----
ADDRCONF(NETDEV_UP): bond0: link is not ready
event_dev: bond0, event: 1
IFF_MASTER
event_dev: bond0, event: 8
IFF_MASTER
bond_ioctl: master=bond0, cmd=35216
slave_dev=cac5d800: 
slave_dev->name=eth1: 
eth1: ! NETIF_F_VLAN_CHALLENGED
event_dev: eth1, event: 8
eth1: link up, 100Mbps, full-duplex, lpa 0xC5E1
event_dev: eth1, event: 1
event_dev: eth1, event: 8
IFF_SLAVE
Initial state of slave_dev is BOND_LINK_UP
bonding: bond0: enslaving eth1 as an active interface with an up link.
ADDRCONF(NETDEV_CHANGE): bond0: link becomes ready
event_dev: bond0, event: 4
IFF_MASTER
bond0: no IPv6 routers present
<<<<cable unplug>>>>
eth1: link down
event_dev: eth1, event: 4
IFF_SLAVE
bonding: bond0: link status definitely down for interface eth1, disabling it
event_dev: bond0, event: 4
IFF_MASTER
<<<<cable plug>>>>
eth1: link up, 100Mbps, full-duplex, lpa 0xC5E1
event_dev: eth1, event: 4
IFF_SLAVE
bonding: bond0: link status definitely up for interface eth1.
bonding: bond0: making interface eth1 the new active one.
event_dev: eth1, event: 8
IFF_SLAVE
event_dev: eth1, event: 8
IFF_SLAVE
bonding: bond0: first active interface up!
event_dev: bond0, event: 4
IFF_MASTER
----
The current active slave is set by calling bond_select_active_slave() function
from bond_miimon_commit() function when the slave (eth1) link goes to state up.
I also tested this on other machine with Broadcom NetXtreme II BCM5708
1000Base-T NIC and there all works fine. The thing is that this adapter is down
and goes up after few seconds after it is enslaved.
This patch calls bond_select_active_slave() in bond_enslave() function for modes
alb and tlb and makes sure that the current active slave is set up properly even
when the slave state is already up. Tested on both systems, works fine.
Notice: The same problem can maybe also occrur in mode 8023AD but I'm unable to
test that.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2009-03-25 17:23:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_select_active_slave ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " This slave is always active in trunk mode \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* always active in trunk mode */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_slave - > state  =  BOND_STATE_ACTIVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* In trunking mode there is little meaning to curr_active_slave
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  anyway  ( it  holds  no  special  properties  of  the  bond  device ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  so  we  can  change  it  without  calling  change_active_interface ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! bond - > curr_active_slave ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											bond - > curr_active_slave  =  new_slave ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  /* switch(bond_mode) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									write_unlock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-27 13:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_set_carrier ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-06 00:48:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_NET_POLL_CONTROLLER 
  
						 
					
						
							
								
									
										
										
										
											2010-06-25 09:50:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Netpoll  and  bonding  is  broken ,  make  sure  it  is  not  initialized 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  until  it  is  fixed . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( disable_netpoll )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-06 00:48:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_dev - > priv_flags  | =  IFF_DISABLE_NETPOLL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-25 09:50:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( slaves_support_netpoll ( bond_dev ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_dev - > priv_flags  & =  ~ IFF_DISABLE_NETPOLL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( bond_dev - > npinfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave_dev - > npinfo  =  bond_dev - > npinfo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! ( bond_dev - > priv_flags  &  IFF_DISABLE_NETPOLL ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_dev - > priv_flags  | =  IFF_DISABLE_NETPOLL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pr_info ( " New slave device %s does not support netpoll \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave_dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pr_info ( " Disabling netpoll support for %s \n " ,  bond_dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-06 00:48:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:41 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  bond_create_slave_symlinks ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-02 18:06:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										goto  err_close ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:41 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_info ( " %s: enslaving %s as a%s interface with a%s link. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_dev - > name ,  slave_dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_slave - > state  = =  BOND_STATE_ACTIVE  ?  " n active "  :  "  backup " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_slave - > link  ! =  BOND_LINK_DOWN  ?  " n up "  :  "  down " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* enslave is successful */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Undo stages on error */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								err_close :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev_close ( slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-02 18:06:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								err_unset_master :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									netdev_set_master ( slave_dev ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								err_restore_mac :  
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:57:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! bond - > params . fail_over_mac )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* XXX TODO - fom follow mode needs to change master's
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  MAC  if  this  slave ' s  MAC  is  in  use  by  the  bond ,  or  at 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  least  print  a  warning . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										memcpy ( addr . sa_data ,  new_slave - > perm_hwaddr ,  ETH_ALEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										addr . sa_family  =  slave_dev - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_set_mac_address ( slave_dev ,  & addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-18 05:42:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								err_restore_mtu :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev_set_mtu ( slave_dev ,  new_slave - > original_mtu ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								err_free :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									kfree ( new_slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								err_undo_flags :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_dev - > features  =  old_features ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Try  to  release  the  slave  device  < slave >  from  the  bond  device  < master > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  It  is  legal  to  access  curr_active_slave  without  a  lock  because  all  the  function 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  is  write - locked . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  The  rules  for  slave  state  should  be : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *    for  Active / Backup : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *      Active  stays  on  all  backups  go  down 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *    for  Bonded  connections : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *      The  first  up  interface  should  be  left  on  and  all  others  downed . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:35:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  bond_release ( struct  net_device  * bond_dev ,  struct  net_device  * slave_dev )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ,  * oldcurrent ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr  addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* slave is not a slave or master is not master of this slave */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( slave_dev - > flags  &  IFF_SLAVE )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( slave_dev - > master  ! =  bond_dev ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_err ( " %s: Error: cannot release %s. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										       bond_dev - > name ,  slave_dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-06 00:48:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									netdev_bonding_change ( bond_dev ,  NETDEV_BONDING_DESLAVE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									write_lock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									slave  =  bond_get_slave_by_dev ( bond ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! slave )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* not a slave of this bond */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_info ( " %s: %s not enslaved \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_dev - > name ,  slave_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-07 21:17:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										write_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! bond - > params . fail_over_mac )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-03 07:58:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! compare_ether_addr ( bond_dev - > dev_addr ,  slave - > perm_hwaddr )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    bond - > slave_cnt  >  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " %s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   bond_dev - > name ,  slave_dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   slave - > perm_hwaddr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   bond_dev - > name ,  slave_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Inform AD package of unbinding of slave. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* must be called before the slave is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  detached  from  the  list 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_3ad_unbind_slave ( slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_info ( " %s: releasing %s interface %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( slave - > state  = =  BOND_STATE_ACTIVE )  ?  " active "  :  " backup " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									oldcurrent  =  bond - > curr_active_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond - > current_arp_slave  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* release the slave from its bond */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_detach_slave ( bond ,  slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 01:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_compute_features ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > primary_slave  = =  slave ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond - > primary_slave  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( oldcurrent  = =  slave ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_change_active_slave ( bond ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:07:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond_is_lb ( bond ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Must be called only after the slave has been
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  detached  from  the  list  and  the  curr_active_slave 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  has  been  cleared  ( if  our_slave  = =  old_current ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  but  before  a  new  active  slave  is  selected . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-17 16:24:59 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										write_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_alb_deinit_slave ( bond ,  slave ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-17 16:24:59 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										write_lock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( oldcurrent  = =  slave )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  Note  that  we  hold  RTNL  over  this  sequence ,  so  there 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  is  no  concern  that  another  slave  add / remove  event 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  will  interfere . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										write_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										write_lock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_select_active_slave ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										write_unlock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										write_lock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( bond - > slave_cnt  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-27 13:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_set_carrier ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* if the last slave was removed, zero the mac address
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  of  the  master  so  it  will  be  set  by  the  application 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  to  the  mac  address  of  the  first  slave 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memset ( bond_dev - > dev_addr ,  0 ,  bond_dev - > addr_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! bond - > vlgrp )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											bond_dev - > features  | =  NETIF_F_VLAN_CHALLENGED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " %s: Warning: clearing HW address of %s while it still has VLANs. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   bond_dev - > name ,  bond_dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pr_warning ( " %s: When re-adding slaves, make sure the bond's HW address matches its VLANs'. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ( bond_dev - > features  &  NETIF_F_VLAN_CHALLENGED )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   ! bond_has_challenged_slaves ( bond ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_info ( " %s: last VLAN challenged slave %s left bond %s. VLAN blocking is removed \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_dev - > name ,  slave_dev - > name ,  bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_dev - > features  & =  ~ NETIF_F_VLAN_CHALLENGED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									write_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:41 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* must do this from outside any spinlocks */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_destroy_slave_symlinks ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									bond_del_vlans_from_slave ( bond ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If the mode USES_PRIMARY, then we should only remove its
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  promisc  and  mc  settings  if  it  was  the  curr_active_slave ,  but  that  was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  already  taken  care  of  above  when  we  detached  the  slave 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! USES_PRIMARY ( bond - > params . mode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* unset promiscuity level from slave */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond_dev - > flags  &  IFF_PROMISC ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											dev_set_promiscuity ( slave_dev ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* unset allmulti level from slave */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond_dev - > flags  &  IFF_ALLMULTI ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											dev_set_allmulti ( slave_dev ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* flush master's mc_list from slave */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-15 00:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										netif_addr_lock_bh ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_mc_list_flush ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-15 00:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										netif_addr_unlock_bh ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									netdev_set_master ( slave_dev ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-06 00:48:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_NET_POLL_CONTROLLER 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-25 09:50:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 /* Make sure netpoll over stays disabled until fixed. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! disable_netpoll ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( slaves_support_netpoll ( bond_dev ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond_dev - > priv_flags  & =  ~ IFF_DISABLE_NETPOLL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-06 00:48:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( slave_dev - > netdev_ops - > ndo_netpoll_cleanup ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_dev - > netdev_ops - > ndo_netpoll_cleanup ( slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_dev - > npinfo  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* close slave before restoring its mac address */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev_close ( slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > params . fail_over_mac  ! =  BOND_FOM_ACTIVE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* restore original ("permanent") mac address */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memcpy ( addr . sa_data ,  slave - > perm_hwaddr ,  ETH_ALEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										addr . sa_family  =  slave_dev - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_set_mac_address ( slave_dev ,  & addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-18 05:42:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dev_set_mtu ( slave_dev ,  slave - > original_mtu ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-21 16:36:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									slave_dev - > priv_flags  & =  ~ ( IFF_MASTER_8023AD  |  IFF_MASTER_ALB  | 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   IFF_SLAVE_INACTIVE  |  IFF_BONDING  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   IFF_SLAVE_NEEDARP ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									kfree ( slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ;   /* deletion OK */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								*  First  release  a  slave  and  than  destroy  the  bond  if  no  more  slaves  are  left .  
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								*  Must  be  under  rtnl_lock  when  this  function  is  called .  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int   bond_release_and_destroy ( struct  net_device  * bond_dev ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											      struct  net_device  * slave_dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ret  =  bond_release ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( ret  = =  0 )  & &  ( bond - > slave_cnt  = =  0 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_info ( " %s: destroying bond %s. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_dev - > name ,  bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										unregister_netdevice ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  function  releases  all  slaves . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_release_all ( struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * slave_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr  addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									write_lock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-27 13:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									netif_carrier_off ( bond_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > slave_cnt  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond - > current_arp_slave  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond - > primary_slave  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_change_active_slave ( bond ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( slave  =  bond - > first_slave )  ! =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Inform AD package of unbinding of slave
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  before  slave  is  detached  from  the  list . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > params . mode  = =  BOND_MODE_8023AD ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											bond_3ad_unbind_slave ( slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_dev  =  slave - > dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_detach_slave ( bond ,  slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-17 16:24:59 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* now that the slave is detached, unlock and perform
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  all  the  undo  steps  that  should  not  be  called  from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  within  a  lock . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										write_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:07:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond_is_lb ( bond ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											/* must be called only after the slave
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  has  been  detached  from  the  list 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_alb_deinit_slave ( bond ,  slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 01:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_compute_features ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:41 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_destroy_slave_symlinks ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_del_vlans_from_slave ( bond ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* If the mode USES_PRIMARY, then we should only remove its
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  promisc  and  mc  settings  if  it  was  the  curr_active_slave ,  but  that  was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  already  taken  care  of  above  when  we  detached  the  slave 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! USES_PRIMARY ( bond - > params . mode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* unset promiscuity level from slave */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( bond_dev - > flags  &  IFF_PROMISC ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												dev_set_promiscuity ( slave_dev ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* unset allmulti level from slave */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( bond_dev - > flags  &  IFF_ALLMULTI ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												dev_set_allmulti ( slave_dev ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* flush master's mc_list from slave */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-15 00:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											netif_addr_lock_bh ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											bond_mc_list_flush ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-15 00:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											netif_addr_unlock_bh ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										netdev_set_master ( slave_dev ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* close slave before restoring its mac address */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_close ( slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:57:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! bond - > params . fail_over_mac )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* restore original ("permanent") mac address*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memcpy ( addr . sa_data ,  slave - > perm_hwaddr ,  ETH_ALEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											addr . sa_family  =  slave_dev - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dev_set_mac_address ( slave_dev ,  & addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-21 16:36:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										slave_dev - > priv_flags  & =  ~ ( IFF_MASTER_8023AD  |  IFF_MASTER_ALB  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   IFF_SLAVE_INACTIVE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										kfree ( slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* re-acquire the lock before getting the next slave */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										write_lock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* zero the mac address of the master so it will be
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  set  by  the  application  to  the  mac  address  of  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  first  slave 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( bond_dev - > dev_addr ,  0 ,  bond_dev - > addr_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! bond - > vlgrp )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_dev - > features  | =  NETIF_F_VLAN_CHALLENGED ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " %s: Warning: clearing HW address of %s while it still has VLANs. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   bond_dev - > name ,  bond_dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_warning ( " %s: When re-adding slaves, make sure the bond's HW address matches its VLANs'. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_info ( " %s: released all slaves \n " ,  bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									write_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  function  changes  the  active  slave  to  slave  < slave_dev > . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  It  returns  - EINVAL  in  the  following  cases . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   -  < slave_dev >  is  not  found  in  the  list . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   -  There  is  not  active  slave  now . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   -  < slave_dev >  is  already  active . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   -  The  link  state  of  < slave_dev >  is  not  BOND_LINK_UP . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   -  < slave_dev >  is  not  running . 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  In  these  cases ,  this  function  does  nothing . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  In  the  other  cases ,  current_slave  pointer  is  changed  and  0  is  returned . 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_ioctl_change_active ( struct  net_device  * bond_dev ,  struct  net_device  * slave_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * old_active  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * new_active  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! USES_PRIMARY ( bond - > params . mode ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Verify that master_dev is indeed the master of slave_dev */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( slave_dev - > flags  &  IFF_SLAVE )  | |  ( slave_dev - > master  ! =  bond_dev ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_lock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									old_active  =  bond - > curr_active_slave ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									new_active  =  bond_get_slave_by_dev ( bond ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Changing  to  the  current  active :  do  nothing ;  return  success . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( new_active  & &  ( new_active  = =  old_active ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( new_active )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( old_active )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( new_active - > link  = =  BOND_LINK_UP )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    IS_UP ( new_active - > dev ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										write_lock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_change_active_slave ( bond ,  new_active ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										write_unlock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										res  =  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_info_query ( struct  net_device  * bond_dev ,  struct  ifbond  * info )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info - > bond_mode  =  bond - > params . mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info - > miimon  =  bond - > params . miimon ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									info - > num_slaves  =  bond - > slave_cnt ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_slave_info_query ( struct  net_device  * bond_dev ,  struct  ifslave  * info )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-23 03:39:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  i ,  res  =  - ENODEV ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( i  = =  ( int ) info - > slave_id )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-23 03:39:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											strcpy ( info - > slave_name ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											info - > link  =  slave - > link ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											info - > state  =  slave - > state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											info - > link_failure_count  =  slave - > link_failure_count ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-23 03:39:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*-------------------------------- Monitoring -------------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_miimon_inspect ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ,  link_state ,  commit  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-24 03:57:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bool  ignore_updelay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ignore_updelay  =  ! bond - > curr_active_slave  ?  true  :  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										slave - > new_link  =  BOND_LINK_NOCHANGE ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										link_state  =  bond_check_dev_link ( bond ,  slave - > dev ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( slave - > link )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  BOND_LINK_UP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( link_state ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											slave - > link  =  BOND_LINK_FAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave - > delay  =  bond - > params . downdelay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( slave - > delay )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pr_info ( " %s: link status down for %sinterface %s, disabling it in %d ms. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond - > dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													( bond - > params . mode  = = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 BOND_MODE_ACTIVEBACKUP )  ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													( ( slave - > state  = =  BOND_STATE_ACTIVE )  ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 " active  "  :  " backup  " )  :  " " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													slave - > dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond - > params . downdelay  *  bond - > params . miimon ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/*FALLTHRU*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  BOND_LINK_FAIL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( link_state )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  recovered  before  downdelay  expired 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > link  =  BOND_LINK_UP ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												slave - > jiffies  =  jiffies ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pr_info ( " %s: link status up again after %d ms for interface %s. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond - > dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													( bond - > params . downdelay  -  slave - > delay )  * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond - > params . miimon , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( slave - > delay  < =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > new_link  =  BOND_LINK_DOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												commit + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											slave - > delay - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  BOND_LINK_DOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! link_state ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave - > link  =  BOND_LINK_BACK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave - > delay  =  bond - > params . updelay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( slave - > delay )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pr_info ( " %s: link status up for interface %s, enabling it in %d ms. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond - > dev - > name ,  slave - > dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ignore_updelay  ?  0  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond - > params . updelay  * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond - > params . miimon ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/*FALLTHRU*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  BOND_LINK_BACK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! link_state )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > link  =  BOND_LINK_DOWN ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pr_info ( " %s: link status down again after %d ms for interface %s. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond - > dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													( bond - > params . updelay  -  slave - > delay )  * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond - > params . miimon , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-24 03:57:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ignore_updelay ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > delay  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( slave - > delay  < =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > new_link  =  BOND_LINK_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												commit + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-24 03:57:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ignore_updelay  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave - > delay - - ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  commit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_miimon_commit ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( slave - > new_link )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  BOND_LINK_NOCHANGE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  BOND_LINK_UP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave - > link  =  BOND_LINK_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave - > jiffies  =  jiffies ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( bond - > params . mode  = =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* prevent it from being the active one */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > state  =  BOND_STATE_BACKUP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( bond - > params . mode  ! =  BOND_MODE_ACTIVEBACKUP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* make it immediately active */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > state  =  BOND_STATE_ACTIVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( slave  ! =  bond - > primary_slave )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* prevent it from being the active one */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > state  =  BOND_STATE_BACKUP ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_info ( " %s: link status definitely up for interface %s. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond - > dev - > name ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* notify ad that the link status has changed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( bond - > params . mode  = =  BOND_MODE_8023AD ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond_3ad_handle_link_change ( slave ,  BOND_LINK_UP ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:07:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( bond_is_lb ( bond ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bond_alb_handle_link_change ( bond ,  slave , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															    BOND_LINK_UP ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! bond - > curr_active_slave  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ( slave  = =  bond - > primary_slave ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  do_failover ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  BOND_LINK_DOWN : 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-30 17:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( slave - > link_failure_count  <  UINT_MAX ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > link_failure_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											slave - > link  =  BOND_LINK_DOWN ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( bond - > params . mode  = =  BOND_MODE_ACTIVEBACKUP  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    bond - > params . mode  = =  BOND_MODE_8023AD ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond_set_slave_inactive_flags ( slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_info ( " %s: link status definitely down for interface %s, disabling it \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond - > dev - > name ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( bond - > params . mode  = =  BOND_MODE_8023AD ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond_3ad_handle_link_change ( slave , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															    BOND_LINK_DOWN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-27 05:42:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( bond_is_lb ( bond ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bond_alb_handle_link_change ( bond ,  slave , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															    BOND_LINK_DOWN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( slave  = =  bond - > curr_active_slave ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  do_failover ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " %s: invalid new link %d on slave %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       bond - > dev - > name ,  slave - > new_link , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       slave - > dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave - > new_link  =  BOND_LINK_NOCHANGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								do_failover :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ASSERT_RTNL ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										write_lock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_select_active_slave ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										write_unlock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_set_carrier ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_mii_monitor 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Really  a  wrapper  that  splits  the  mii  monitor  into  two  phases :  an 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  inspection ,  then  ( if  inspection  indicates  something  needs  to  be  done ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  an  acquisition  of  appropriate  locks  followed  by  a  commit  phase  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  implement  whatever  link  state  changes  are  indicated . 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  bond_mii_monitor ( struct  work_struct  * work )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond  =  container_of ( work ,  struct  bonding , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    mii_work . work ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > kill_timers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > slave_cnt  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  re_arm ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:03 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > send_grat_arp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_lock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_send_gratuitous_arp ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > send_unsol_na )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_lock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_send_unsolicited_na ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond_miimon_inspect ( bond ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtnl_lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_miimon_commit ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-17 16:25:03 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtnl_unlock ( ) ; 	/* might sleep, hold no other locks */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-02 18:21:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								re_arm :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . miimon ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queue_delayed_work ( bond - > wq ,  & bond - > mii_work , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   msecs_to_jiffies ( bond - > params . miimon ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-22 20:06:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  __be32  bond_glean_dev_ip ( struct  net_device  * dev )  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  in_device  * idev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  in_ifaddr  * ifa ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-28 18:00:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__be32  addr  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rcu_read_lock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-03 14:35:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									idev  =  __in_dev_get_rcu ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! idev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifa  =  idev - > ifa_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ifa ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									addr  =  ifa - > ifa_local ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rcu_read_unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-22 20:06:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_has_this_ip ( struct  bonding  * bond ,  __be32  ip )  
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  vlan_entry  * vlan ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ip  = =  bond - > master_ip ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									list_for_each_entry ( vlan ,  & bond - > vlan_list ,  vlan_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ip  = =  vlan - > vlan_ip ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  We  go  to  the  ( large )  trouble  of  VLAN  tagging  ARP  frames  because 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  switches  in  VLAN  mode  ( especially  if  ports  are  configured  as 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  " native "  to  a  VLAN )  might  not  pass  non - tagged  frames . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-22 20:06:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_arp_send ( struct  net_device  * slave_dev ,  int  arp_op ,  __be32  dest_ip ,  __be32  src_ip ,  unsigned  short  vlan_id )  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sk_buff  * skb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " arp %d on slave %s: dst %x src %x vid %d \n " ,  arp_op , 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 slave_dev - > name ,  dest_ip ,  src_ip ,  vlan_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									skb  =  arp_create ( arp_op ,  ETH_P_ARP ,  dest_ip ,  slave_dev ,  src_ip , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 NULL ,  slave_dev - > dev_addr ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! skb )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_err ( " ARP packet allocation failed \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( vlan_id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										skb  =  vlan_put_tag ( skb ,  vlan_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! skb )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " failed to insert VLAN tag \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arp_xmit ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  void  bond_arp_send_all ( struct  bonding  * bond ,  struct  slave  * slave )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  i ,  vlan_id ,  rv ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-22 20:06:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__be32  * targets  =  bond - > params . arp_targets ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  vlan_entry  * vlan ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net_device  * vlan_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  flowi  fl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  rtable  * rt ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:19 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( i  =  0 ;  ( i  <  BOND_MAX_ARP_TARGETS ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! targets [ i ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-13 00:11:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " basa: target %x \n " ,  targets [ i ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! bond - > vlgrp )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_debug ( " basa: empty vlan: arp_send \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bond_arp_send ( slave - > dev ,  ARPOP_REQUEST ,  targets [ i ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												      bond - > master_ip ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  If  VLANs  are  configured ,  we  do  a  route  lookup  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  determine  which  VLAN  interface  would  be  used ,  so  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  can  tag  the  ARP  with  the  proper  VLAN  tag . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memset ( & fl ,  0 ,  sizeof ( fl ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fl . fl4_dst  =  targets [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fl . fl4_tos  =  RTO_ONLINK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rv  =  ip_route_output_key ( dev_net ( bond - > dev ) ,  & rt ,  & fl ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( rv )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( net_ratelimit ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pr_warning ( " %s: no route to arp_ip_target %pI4 \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   bond - > dev - > name ,  & fl . fl4_dst ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  This  target  is  not  on  a  VLAN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-10 23:31:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( rt - > dst . dev  = =  bond - > dev )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-14 14:52:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ip_rt_put ( rt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_debug ( " basa: rtdev == bond->dev: arp_send \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bond_arp_send ( slave - > dev ,  ARPOP_REQUEST ,  targets [ i ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												      bond - > master_ip ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										vlan_id  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										list_for_each_entry ( vlan ,  & bond - > vlan_list ,  vlan_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-02 20:44:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											vlan_dev  =  vlan_group_get_device ( bond - > vlgrp ,  vlan - > vlan_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-10 23:31:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( vlan_dev  = =  rt - > dst . dev )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												vlan_id  =  vlan - > vlan_id ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pr_debug ( " basa: vlan match on %s %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       vlan_dev - > name ,  vlan_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( vlan_id )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-14 14:52:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ip_rt_put ( rt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bond_arp_send ( slave - > dev ,  ARPOP_REQUEST ,  targets [ i ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												      vlan - > vlan_ip ,  vlan_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( net_ratelimit ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " %s: no path to arp_ip_target %pI4 via rt.dev %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   bond - > dev - > name ,  & fl . fl4_dst , 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-10 23:31:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												   rt - > dst . dev  ?  rt - > dst . dev - > name  :  " NULL " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-14 14:52:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ip_rt_put ( rt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Kick  out  a  gratuitous  ARP  for  an  IP  on  the  bonding  master  plus  one 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  for  each  VLAN  above  us . 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:03 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Caller  must  hold  curr_slave_lock  for  read  or  better 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_send_gratuitous_arp ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave  =  bond - > curr_active_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  vlan_entry  * vlan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * vlan_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " bond_send_grat_arp: bond %s slave %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 bond - > dev - > name ,  slave  ?  slave - > dev - > name  :  " NULL " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:03 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! slave  | |  ! bond - > send_grat_arp  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    test_bit ( __LINK_STATE_LINKWATCH_PENDING ,  & slave - > dev - > state ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:03 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond - > send_grat_arp - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > master_ip )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_arp_send ( slave - > dev ,  ARPOP_REPLY ,  bond - > master_ip , 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:42 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bond - > master_ip ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! bond - > vlgrp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									list_for_each_entry ( vlan ,  & bond - > vlan_list ,  vlan_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-02 20:44:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										vlan_dev  =  vlan_group_get_device ( bond - > vlgrp ,  vlan - > vlan_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( vlan - > vlan_ip )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_arp_send ( slave - > dev ,  ARPOP_REPLY ,  vlan - > vlan_ip , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												      vlan - > vlan_ip ,  vlan - > vlan_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-22 20:06:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_validate_arp ( struct  bonding  * bond ,  struct  slave  * slave ,  __be32  sip ,  __be32  tip )  
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-22 20:06:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__be32  * targets  =  bond - > params . arp_targets ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  ( i  <  BOND_MAX_ARP_TARGETS )  & &  targets [ i ] ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " bva: sip %pI4 tip %pI4 t[%d] %pI4 bhti(tip) %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 & sip ,  & tip ,  i ,  & targets [ i ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 bond_has_this_ip ( bond ,  tip ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( sip  = =  targets [ i ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( bond_has_this_ip ( bond ,  tip ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > last_arp_rx  =  jiffies ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_arp_rcv ( struct  sk_buff  * skb ,  struct  net_device  * dev ,  struct  packet_type  * pt ,  struct  net_device  * orig_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  arphdr  * arp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  * arp_ptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-22 20:06:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__be32  sip ,  tip ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												bonding: allow arp_ip_targets on separate vlans to use arp validation
This allows a bond device to specify an arp_ip_target as a host that is
not on the same vlan as the base bond device and still use arp
validation.  A configuration like this, now works:
BONDING_OPTS="mode=active-backup arp_interval=1000 arp_ip_target=10.0.100.1 arp_validate=3"
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 qlen 1000
    link/ether 00:13:21:be:33:e9 brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 qlen 1000
    link/ether 00:13:21:be:33:e9 brd ff:ff:ff:ff:ff:ff
8: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue
    link/ether 00:13:21:be:33:e9 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::213:21ff:febe:33e9/64 scope link
       valid_lft forever preferred_lft forever
9: bond0.100@bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue
    link/ether 00:13:21:be:33:e9 brd ff:ff:ff:ff:ff:ff
    inet 10.0.100.2/24 brd 10.0.100.255 scope global bond0.100
    inet6 fe80::213:21ff:febe:33e9/64 scope link
       valid_lft forever preferred_lft forever
Ethernet Channel Bonding Driver: v3.6.0 (September 26, 2009)
Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: eth1
MII Status: up
MII Polling Interval (ms): 0
Up Delay (ms): 0
Down Delay (ms): 0
ARP Polling Interval (ms): 1000
ARP IP target/s (n.n.n.n form): 10.0.100.1
Slave Interface: eth1
MII Status: up
Link Failure Count: 1
Permanent HW addr: 00:40:05:30:ff:30
Slave Interface: eth0
MII Status: up
Link Failure Count: 0
Permanent HW addr: 00:13:21:be:33:e9
Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2009-12-14 10:48:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( dev - > priv_flags  &  IFF_802_1Q_VLAN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  When  using  VLANS  and  bonding ,  dev  and  oriv_dev  may  be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  incorrect  if  the  physical  interface  supports  VLAN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  acceleration .   With  this  change  ARP  validation  now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  works  for  hosts  only  reachable  on  the  VLAN  interface . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev  =  vlan_dev_real_dev ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										orig_dev  =  dev_get_by_index_rcu ( dev_net ( skb - > dev ) , skb - > skb_iif ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( dev - > priv_flags  &  IFF_BONDING )  | |  ! ( dev - > flags  &  IFF_MASTER ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond  =  netdev_priv ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " bond_arp_rcv: bond %s skb->dev %s orig_dev %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 bond - > dev - > name ,  skb - > dev  ?  skb - > dev - > name  :  " NULL " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 orig_dev  ?  orig_dev - > name  :  " NULL " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									slave  =  bond_get_slave_by_dev ( bond ,  orig_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! slave  | |  ! slave_do_arp_validate ( bond ,  slave ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out_unlock ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-03-03 12:20:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! pskb_may_pull ( skb ,  arp_hdr_len ( dev ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										goto  out_unlock ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-12 20:56:31 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									arp  =  arp_hdr ( skb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( arp - > ar_hln  ! =  dev - > addr_len  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    skb - > pkt_type  = =  PACKET_OTHERHOST  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    skb - > pkt_type  = =  PACKET_LOOPBACK  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    arp - > ar_hrd  ! =  htons ( ARPHRD_ETHER )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    arp - > ar_pro  ! =  htons ( ETH_P_IP )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    arp - > ar_pln  ! =  4 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out_unlock ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arp_ptr  =  ( unsigned  char  * ) ( arp  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arp_ptr  + =  dev - > addr_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memcpy ( & sip ,  arp_ptr ,  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arp_ptr  + =  4  +  dev - > addr_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memcpy ( & tip ,  arp_ptr ,  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4 \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 bond - > dev - > name ,  slave - > dev - > name ,  slave - > state , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 bond - > params . arp_validate ,  slave_do_arp_validate ( bond ,  slave ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 & sip ,  & tip ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Backup  slaves  won ' t  see  the  ARP  reply ,  but  do  come  through 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  here  for  each  ARP  probe  ( so  we  swap  the  sip / tip  to  validate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  the  probe ) .   In  a  " redundant switch, common router "  type  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  configuration ,  the  ARP  probe  will  ( hopefully )  travel  from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  the  active ,  through  one  switch ,  the  router ,  then  the  other 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  switch  before  reaching  the  backup . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( slave - > state  = =  BOND_STATE_ACTIVE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_validate_arp ( bond ,  slave ,  sip ,  tip ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_validate_arp ( bond ,  slave ,  tip ,  sip ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out_unlock :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev_kfree_skb ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NET_RX_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  this  function  is  called  regularly  to  monitor  each  slave ' s  link 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  ensuring  that  traffic  is  being  sent  and  received  when  arp  monitoring 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  is  used  in  load - balancing  mode .  if  the  adapter  has  been  dormant ,  then  an 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  arp  is  transmitted  to  generate  traffic .  see  activebackup_arp_monitor  for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  arp  monitoring  in  active  backup  mode . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  bond_loadbalance_arp_mon ( struct  work_struct  * work )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  container_of ( work ,  struct  bonding , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    arp_work . work ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ,  * oldcurrent ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  do_failover  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  delta_in_ticks ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									delta_in_ticks  =  msecs_to_jiffies ( bond - > params . arp_interval ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > kill_timers ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > slave_cnt  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  re_arm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									oldcurrent  =  bond - > curr_active_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* see if any of the previous devices are up now (i.e. they have
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  xmt  and  rcv  traffic ) .  the  curr_active_slave  does  not  come  into 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  the  picture  unless  it  is  null .  also ,  slave - > jiffies  is  not  needed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  here  because  we  send  an  arp  on  each  slave  and  give  a  slave  as 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  long  as  it  needs  to  get  the  tx / rx  within  the  delta . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  TODO :  what  about  up / down  delay  in  arp  mode ?  it  wasn ' t  here  before 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *        so  it  can  wait 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-02 05:45:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										unsigned  long  trans_start  =  dev_trans_start ( slave - > dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( slave - > link  ! =  BOND_LINK_UP )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-02 05:45:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( time_in_range ( jiffies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												trans_start  -  delta_in_ticks , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												trans_start  +  delta_in_ticks )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    time_in_range ( jiffies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > dev - > last_rx  -  delta_in_ticks , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > dev - > last_rx  +  delta_in_ticks ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > link   =  BOND_LINK_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > state  =  BOND_STATE_ACTIVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* primary_slave has no meaning in round-robin
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  mode .  the  window  of  a  slave  being  up  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  curr_active_slave  being  null  after  enslaving 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  is  closed . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! oldcurrent )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													pr_info ( " %s: link status definitely up for interface %s,  " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														bond - > dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													do_failover  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													pr_info ( " %s: interface %s is now up \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														bond - > dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* slave->link == BOND_LINK_UP */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* not all switches will respond to an arp request
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  when  the  source  ip  is  0 ,  so  don ' t  take  the  link  down 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  if  we  don ' t  know  our  ip  yet 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-02 05:45:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! time_in_range ( jiffies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												trans_start  -  delta_in_ticks , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												trans_start  +  2  *  delta_in_ticks )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ! time_in_range ( jiffies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > dev - > last_rx  -  delta_in_ticks , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > dev - > last_rx  +  2  *  delta_in_ticks ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > link   =  BOND_LINK_DOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > state  =  BOND_STATE_BACKUP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( slave - > link_failure_count  <  UINT_MAX ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													slave - > link_failure_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pr_info ( " %s: interface %s is now down. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond - > dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( slave  = =  oldcurrent ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													do_failover  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* note: if switch is in round-robin mode, all links
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  must  tx  arp  to  ensure  all  links  rx  an  arp  -  otherwise 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  links  may  oscillate  or  not  come  up  at  all ;  if  switch  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  in  something  like  xor  mode ,  there  is  nothing  we  can 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  do  -  all  replies  will  be  rx ' ed  on  same  link  causing  slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  to  be  unstable  during  low / no  traffic  periods 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( IS_UP ( slave - > dev ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											bond_arp_send_all ( bond ,  slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( do_failover )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										write_lock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_select_active_slave ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										write_unlock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								re_arm :  
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > params . arp_interval ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queue_delayed_work ( bond - > wq ,  & bond - > arp_work ,  delta_in_ticks ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Called  to  inspect  slaves  for  active - backup  mode  ARP  monitor  link  state 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  changes .   Sets  new_link  in  slaves  to  specify  what  action  should  take 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  place  for  the  slave .   Returns  0  if  no  changes  are  found ,  > 0  if  changes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  to  link  states  must  be  committed . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Called  with  bond - > lock  held  for  read . 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_ab_arp_inspect ( struct  bonding  * bond ,  int  delta_in_ticks )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  i ,  commit  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-02 05:45:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  long  trans_start ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave - > new_link  =  BOND_LINK_NOCHANGE ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( slave - > link  ! =  BOND_LINK_UP )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-02 05:45:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( time_in_range ( jiffies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave_last_rx ( bond ,  slave )  -  delta_in_ticks , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave_last_rx ( bond ,  slave )  +  delta_in_ticks ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												slave - > new_link  =  BOND_LINK_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												commit + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  Give  slaves  2 * delta  after  being  enslaved  or  made 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  active .   This  avoids  bouncing ,  as  the  last  receive 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  times  need  a  full  ARP  monitor  cycle  to  be  updated . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-02 05:45:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( time_in_range ( jiffies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  slave - > jiffies  -  delta_in_ticks , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  slave - > jiffies  +  2  *  delta_in_ticks ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  Backup  slave  is  down  if : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  -  No  current_arp_slave  AND 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  -  more  than  3 * delta  since  last  receive  AND 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  -  the  bond  has  an  IP  address 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  Note :  a  non - null  current_arp_slave  indicates 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  the  curr_active_slave  went  down  and  we  are 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  searching  for  a  new  one ;  under  this  condition 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  we  only  take  the  curr_active_slave  down  -  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  gives  each  slave  a  chance  to  tx / rx  traffic 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  before  being  taken  out 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( slave - > state  = =  BOND_STATE_BACKUP  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ! bond - > current_arp_slave  & & 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-02 05:45:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    ! time_in_range ( jiffies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave_last_rx ( bond ,  slave )  -  delta_in_ticks , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave_last_rx ( bond ,  slave )  +  3  *  delta_in_ticks ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											slave - > new_link  =  BOND_LINK_DOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											commit + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  Active  slave  is  down  if : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  -  more  than  2 * delta  since  transmitting  OR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  -  ( more  than  2 * delta  since  receive  AND 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *     the  bond  has  an  IP  address ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-02 05:45:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										trans_start  =  dev_trans_start ( slave - > dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( slave - > state  = =  BOND_STATE_ACTIVE )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-02 05:45:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    ( ! time_in_range ( jiffies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											trans_start  -  delta_in_ticks , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											trans_start  +  2  *  delta_in_ticks )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     ! time_in_range ( jiffies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave_last_rx ( bond ,  slave )  -  delta_in_ticks , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave_last_rx ( bond ,  slave )  +  2  *  delta_in_ticks ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											slave - > new_link  =  BOND_LINK_DOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											commit + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  commit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Called  to  commit  link  state  changes  noted  by  inspection  step  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  active - backup  mode  ARP  monitor . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Called  with  RTNL  and  bond - > lock  for  read . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_ab_arp_commit ( struct  bonding  * bond ,  int  delta_in_ticks )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-02 05:45:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  long  trans_start ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( slave - > new_link )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  BOND_LINK_NOCHANGE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-27 13:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  BOND_LINK_UP : 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-02 05:45:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											trans_start  =  dev_trans_start ( slave - > dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ( ! bond - > curr_active_slave  & & 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-02 05:45:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											     time_in_range ( jiffies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   trans_start  -  delta_in_ticks , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   trans_start  +  delta_in_ticks ) )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											    bond - > curr_active_slave  ! =  slave )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												slave - > link  =  BOND_LINK_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond - > current_arp_slave  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pr_info ( " %s: link status definitely up for interface %s. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													bond - > dev - > name ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! bond - > curr_active_slave  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    ( slave  = =  bond - > primary_slave ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  do_failover ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  BOND_LINK_DOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( slave - > link_failure_count  <  UINT_MAX ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > link_failure_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave - > link  =  BOND_LINK_DOWN ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bond_set_slave_inactive_flags ( slave ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_info ( " %s: link status definitely down for interface %s, disabling it \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bond - > dev - > name ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( slave  = =  bond - > curr_active_slave )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												bond - > current_arp_slave  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												goto  do_failover ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " %s: impossible: new_link %d on slave %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       bond - > dev - > name ,  slave - > new_link , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								do_failover :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ASSERT_RTNL ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										write_lock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 11:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_select_active_slave ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										write_unlock_bh ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_set_carrier ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Send  ARP  probes  for  active - backup  mode  ARP  monitor . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Called  with  bond - > lock  held  for  read . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_ab_arp_probe ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_lock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > current_arp_slave  & &  bond - > curr_active_slave ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_info ( " PROBE: c_arp %s && cas %s BAD \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond - > current_arp_slave - > dev - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond - > curr_active_slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > curr_active_slave )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_arp_send_all ( bond ,  bond - > curr_active_slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* if we don't have a curr_active_slave, search for the next available
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  backup  slave  from  the  current_arp_slave  and  make  it  the  candidate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  for  becoming  the  curr_active_slave 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! bond - > current_arp_slave )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond - > current_arp_slave  =  bond - > first_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! bond - > current_arp_slave ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_set_slave_inactive_flags ( bond - > current_arp_slave ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* search for next candidate */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave_from ( bond ,  slave ,  i ,  bond - > current_arp_slave - > next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( IS_UP ( slave - > dev ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave - > link  =  BOND_LINK_BACK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_set_slave_active_flags ( slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_arp_send_all ( bond ,  slave ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											slave - > jiffies  =  jiffies ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bond - > current_arp_slave  =  slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* if the link state is up at this point, we
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  mark  it  down  -  this  can  happen  if  we  have 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  simultaneous  link  failures  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  reselect_active_interface  doesn ' t  make  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  one  the  current  slave  so  it  is  still  marked 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  up  when  it  is  actually  down 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( slave - > link  = =  BOND_LINK_UP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave - > link  =  BOND_LINK_DOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( slave - > link_failure_count  <  UINT_MAX ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave - > link_failure_count + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bond_set_slave_inactive_flags ( slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_info ( " %s: backup interface %s is now down. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond - > dev - > name ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  bond_activebackup_arp_mon ( struct  work_struct  * work )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond  =  container_of ( work ,  struct  bonding , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    arp_work . work ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  delta_in_ticks ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > kill_timers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									delta_in_ticks  =  msecs_to_jiffies ( bond - > params . arp_interval ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > slave_cnt  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  re_arm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:03 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > send_grat_arp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_lock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_send_gratuitous_arp ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > send_unsol_na )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_lock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_send_unsolicited_na ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond_ab_arp_inspect ( bond ,  delta_in_ticks ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtnl_lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_ab_arp_commit ( bond ,  delta_in_ticks ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtnl_unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_ab_arp_probe ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								re_arm :  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > params . arp_interval ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										queue_delayed_work ( bond - > wq ,  & bond - > arp_work ,  delta_in_ticks ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*------------------------------ proc/seq_file-------------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef CONFIG_PROC_FS 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  * bond_info_seq_start ( struct  seq_file  * seq ,  loff_t  * pos )  
						 
					
						
							
								
									
										
										
										
											2009-02-14 11:15:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__acquires ( & dev_base_lock ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									__acquires ( & bond - > lock ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond  =  seq - > private ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									loff_t  off  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* make sure the bond won't be taken away */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & dev_base_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( * pos  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  SEQ_START_TOKEN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( + + off  = =  * pos ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  * bond_info_seq_next ( struct  seq_file  * seq ,  void  * v ,  loff_t  * pos )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond  =  seq - > private ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave  =  v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									+ + * pos ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( v  = =  SEQ_START_TOKEN ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  bond - > first_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									slave  =  slave - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ( slave  = =  bond - > first_slave )  ?  NULL  :  slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_info_seq_stop ( struct  seq_file  * seq ,  void  * v )  
						 
					
						
							
								
									
										
										
										
											2009-02-14 11:15:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__releases ( & bond - > lock ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									__releases ( & dev_base_lock ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond  =  seq - > private ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									read_unlock ( & dev_base_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_info_show_master ( struct  seq_file  * seq )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond  =  seq - > private ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * curr ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									curr  =  bond - > curr_active_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:57:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seq_printf ( seq ,  " Bonding Mode: %s " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										   bond_mode_name ( bond - > params . mode ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:57:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_ACTIVEBACKUP  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    bond - > params . fail_over_mac ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										seq_printf ( seq ,  "  (fail_over_mac %s) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   fail_over_mac_tbl [ bond - > params . fail_over_mac ] . modename ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:57:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									seq_printf ( seq ,  " \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:35:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_XOR  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond - > params . mode  = =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										seq_printf ( seq ,  " Transmit Hash Policy: %s (%d) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xmit_hashtype_tbl [ bond - > params . xmit_policy ] . modename , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond - > params . xmit_policy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( USES_PRIMARY ( bond - > params . mode ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										seq_printf ( seq ,  " Primary Slave: %s " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:35:21 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   ( bond - > primary_slave )  ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   bond - > primary_slave - > dev - > name  :  " None " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > primary_slave ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											seq_printf ( seq ,  "  (primary_reselect %s) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   pri_reselect_tbl [ bond - > params . primary_reselect ] . modename ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										seq_printf ( seq ,  " \n Currently Active Slave: %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											   ( curr )  ?  curr - > dev - > name  :  " None " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-27 13:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seq_printf ( seq ,  " MII Status: %s \n " ,  netif_carrier_ok ( bond - > dev )  ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   " up "  :  " down " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									seq_printf ( seq ,  " MII Polling Interval (ms): %d \n " ,  bond - > params . miimon ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									seq_printf ( seq ,  " Up Delay (ms): %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   bond - > params . updelay  *  bond - > params . miimon ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									seq_printf ( seq ,  " Down Delay (ms): %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   bond - > params . downdelay  *  bond - > params . miimon ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* ARP information */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > params . arp_interval  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  printed  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										seq_printf ( seq ,  " ARP Polling Interval (ms): %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond - > params . arp_interval ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										seq_printf ( seq ,  " ARP IP target/s (n.n.n.n form): " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( i  =  0 ;  ( i  <  BOND_MAX_ARP_TARGETS ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! bond - > params . arp_targets [ i ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-13 00:11:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( printed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												seq_printf ( seq ,  " , " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-29 22:43:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											seq_printf ( seq ,  "  %pI4 " ,  & bond - > params . arp_targets [ i ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											printed  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										seq_printf ( seq ,  " \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ad_info  ad_info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										seq_puts ( seq ,  " \n 802.3ad info \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										seq_printf ( seq ,  " LACP rate: %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   ( bond - > params . lacp_fast )  ?  " fast "  :  " slow " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-04 17:51:16 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										seq_printf ( seq ,  " Aggregator selection policy (ad_select): %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   ad_select_tbl [ bond - > params . ad_select ] . modename ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond_3ad_get_active_agg_info ( bond ,  & ad_info ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											seq_printf ( seq ,  " bond %s has no active aggregator \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   bond - > dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											seq_printf ( seq ,  " Active Aggregator Info: \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											seq_printf ( seq ,  " \t Aggregator ID: %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   ad_info . aggregator_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											seq_printf ( seq ,  " \t Number of ports: %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   ad_info . ports ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											seq_printf ( seq ,  " \t Actor Key: %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   ad_info . actor_key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											seq_printf ( seq ,  " \t Partner Key: %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   ad_info . partner_key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-27 15:59:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											seq_printf ( seq ,  " \t Partner Mac Address: %pM \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   ad_info . partner_system ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_info_show_slave ( struct  seq_file  * seq ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 const  struct  slave  * slave ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond  =  seq - > private ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									seq_printf ( seq ,  " \n Slave Interface: %s \n " ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									seq_printf ( seq ,  " MII Status: %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   ( slave - > link  = =  BOND_LINK_UP )  ?   " up "  :  " down " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:53:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seq_printf ( seq ,  " Link Failure Count: %u \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										   slave - > link_failure_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-10-27 15:59:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seq_printf ( seq ,  " Permanent HW addr: %pM \n " ,  slave - > perm_hwaddr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  struct  aggregator  * agg 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											=  SLAVE_AD_INFO ( slave ) . port . aggregator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( agg ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											seq_printf ( seq ,  " Aggregator ID: %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   agg - > aggregator_identifier ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											seq_puts ( seq ,  " Aggregator ID: N/A \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seq_printf ( seq ,  " Slave queue ID: %d \n " ,  slave - > queue_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_info_seq_show ( struct  seq_file  * seq ,  void  * v )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( v  = =  SEQ_START_TOKEN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										seq_printf ( seq ,  " %s \n " ,  version ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_info_show_master ( seq ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_info_show_slave ( seq ,  v ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-14 13:52:18 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  struct  seq_operations  bond_info_seq_ops  =  {  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									. start  =  bond_info_seq_start , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. next   =  bond_info_seq_next , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. stop   =  bond_info_seq_stop , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. show   =  bond_info_seq_show , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_info_open ( struct  inode  * inode ,  struct  file  * file )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  seq_file  * seq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  proc_dir_entry  * proc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  seq_open ( file ,  & bond_info_seq_ops ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* recover the pointer buried in proc_dir_entry data */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										seq  =  file - > private_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										proc  =  PDE ( inode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										seq - > private  =  proc - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-12 00:55:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  struct  file_operations  bond_info_fops  =  {  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									. owner    =  THIS_MODULE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. open     =  bond_info_open , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. read     =  seq_read , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. llseek   =  seq_lseek , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. release  =  seq_release , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-13 00:45:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_create_proc_entry ( struct  bonding  * bond )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * bond_dev  =  bond - > dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bond_net  * bn  =  net_generic ( dev_net ( bond_dev ) ,  bond_net_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bn - > proc_dir )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-29 01:02:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond - > proc_entry  =  proc_create_data ( bond_dev - > name , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														    S_IRUGO ,  bn - > proc_dir , 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-29 01:02:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														    & bond_info_fops ,  bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > proc_entry  = =  NULL ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " Warning: Cannot create /proc/net/%s/%s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   DRV_NAME ,  bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											memcpy ( bond - > proc_file_name ,  bond_dev - > name ,  IFNAMSIZ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_remove_proc_entry ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net_device  * bond_dev  =  bond - > dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bond_net  * bn  =  net_generic ( dev_net ( bond_dev ) ,  bond_net_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bn - > proc_dir  & &  bond - > proc_entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										remove_proc_entry ( bond - > proc_file_name ,  bn - > proc_dir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										memset ( bond - > proc_file_name ,  0 ,  IFNAMSIZ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond - > proc_entry  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Create the bonding directory under /proc/net, if doesn't exist yet.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Caller  must  hold  rtnl_lock . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-17 03:35:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  __net_init  bond_create_proc_dir ( struct  bond_net  * bn )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! bn - > proc_dir )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bn - > proc_dir  =  proc_mkdir ( DRV_NAME ,  bn - > net - > proc_net ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! bn - > proc_dir ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " Warning: cannot create /proc/net/%s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   DRV_NAME ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Destroy the bonding directory under /proc/net, if empty.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Caller  must  hold  rtnl_lock . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-17 03:35:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  __net_exit  bond_destroy_proc_dir ( struct  bond_net  * bn )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bn - > proc_dir )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										remove_proc_entry ( DRV_NAME ,  bn - > net - > proc_net ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bn - > proc_dir  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-05-05 06:20:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else  /* !CONFIG_PROC_FS */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-13 00:45:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_create_proc_entry ( struct  bonding  * bond )  
						 
					
						
							
								
									
										
										
										
											2009-05-05 06:20:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_remove_proc_entry ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-17 03:35:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  void  bond_create_proc_dir ( struct  bond_net  * bn )  
						 
					
						
							
								
									
										
										
										
											2009-05-05 06:20:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-17 03:35:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  void  bond_destroy_proc_dir ( struct  bond_net  * bn )  
						 
					
						
							
								
									
										
										
										
											2009-05-05 06:20:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif  /* CONFIG_PROC_FS */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 06:20:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*-------------------------- netdev event handling --------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Change  device  name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_event_changename ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_remove_proc_entry ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_create_proc_entry ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  NOTIFY_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_master_netdev_event ( unsigned  long  event ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    struct  net_device  * bond_dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * event_bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( event )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  NETDEV_CHANGENAME : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  bond_event_changename ( event_bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NOTIFY_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_slave_netdev_event ( unsigned  long  event ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   struct  net_device  * slave_dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * bond_dev  =  slave_dev - > master ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( event )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  NETDEV_UNREGISTER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond_dev )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-15 16:44:27 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( bond - > setup_by_slave ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond_release_and_destroy ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond_release ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  NETDEV_CHANGE : 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-18 18:38:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > params . mode  = =  BOND_MODE_8023AD  | |  bond_is_lb ( bond ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave  =  bond_get_slave_by_dev ( bond ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( slave )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												u16  old_speed  =  slave - > speed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												u16  old_duplex  =  slave - > duplex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond_update_speed_duplex ( slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( bond_is_lb ( bond ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( old_speed  ! =  slave - > speed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond_3ad_adapter_speed_changed ( slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( old_duplex  ! =  slave - > duplex ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bond_3ad_adapter_duplex_changed ( slave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  NETDEV_DOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  . . .  Or  is  it  this ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  NETDEV_CHANGEMTU : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  TODO :  Should  slaves  be  allowed  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  independently  alter  their  MTU ?   For 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  an  active - backup  bond ,  slaves  need 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  not  be  the  same  type  of  device ,  so 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  MTUs  may  vary .   For  other  modes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  slaves  arguably  should  have  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  same  MTUs .  To  do  this ,  we ' d  need  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  take  over  the  slave ' s  change_mtu 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  function  for  the  duration  of  their 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  servitude . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  NETDEV_CHANGENAME : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  TODO :  handle  changing  the  primary ' s  name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 01:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  NETDEV_FEAT_CHANGE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_compute_features ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NOTIFY_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_netdev_event :  handle  netdev  notifier  chain  events . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  function  receives  events  for  the  netdev  chain .   The  caller  ( an 
							 
						 
					
						
							
								
									
										
											 
										
											
												[PATCH] Notifier chain update: API changes
The kernel's implementation of notifier chains is unsafe.  There is no
protection against entries being added to or removed from a chain while the
chain is in use.  The issues were discussed in this thread:
    http://marc.theaimsgroup.com/?l=linux-kernel&m=113018709002036&w=2
We noticed that notifier chains in the kernel fall into two basic usage
classes:
	"Blocking" chains are always called from a process context
	and the callout routines are allowed to sleep;
	"Atomic" chains can be called from an atomic context and
	the callout routines are not allowed to sleep.
We decided to codify this distinction and make it part of the API.  Therefore
this set of patches introduces three new, parallel APIs: one for blocking
notifiers, one for atomic notifiers, and one for "raw" notifiers (which is
really just the old API under a new name).  New kinds of data structures are
used for the heads of the chains, and new routines are defined for
registration, unregistration, and calling a chain.  The three APIs are
explained in include/linux/notifier.h and their implementation is in
kernel/sys.c.
With atomic and blocking chains, the implementation guarantees that the chain
links will not be corrupted and that chain callers will not get messed up by
entries being added or removed.  For raw chains the implementation provides no
guarantees at all; users of this API must provide their own protections.  (The
idea was that situations may come up where the assumptions of the atomic and
blocking APIs are not appropriate, so it should be possible for users to
handle these things in their own way.)
There are some limitations, which should not be too hard to live with.  For
atomic/blocking chains, registration and unregistration must always be done in
a process context since the chain is protected by a mutex/rwsem.  Also, a
callout routine for a non-raw chain must not try to register or unregister
entries on its own chain.  (This did happen in a couple of places and the code
had to be changed to avoid it.)
Since atomic chains may be called from within an NMI handler, they cannot use
spinlocks for synchronization.  Instead we use RCU.  The overhead falls almost
entirely in the unregister routine, which is okay since unregistration is much
less frequent that calling a chain.
Here is the list of chains that we adjusted and their classifications.  None
of them use the raw API, so for the moment it is only a placeholder.
  ATOMIC CHAINS
  -------------
arch/i386/kernel/traps.c:		i386die_chain
arch/ia64/kernel/traps.c:		ia64die_chain
arch/powerpc/kernel/traps.c:		powerpc_die_chain
arch/sparc64/kernel/traps.c:		sparc64die_chain
arch/x86_64/kernel/traps.c:		die_chain
drivers/char/ipmi/ipmi_si_intf.c:	xaction_notifier_list
kernel/panic.c:				panic_notifier_list
kernel/profile.c:			task_free_notifier
net/bluetooth/hci_core.c:		hci_notifier
net/ipv4/netfilter/ip_conntrack_core.c:	ip_conntrack_chain
net/ipv4/netfilter/ip_conntrack_core.c:	ip_conntrack_expect_chain
net/ipv6/addrconf.c:			inet6addr_chain
net/netfilter/nf_conntrack_core.c:	nf_conntrack_chain
net/netfilter/nf_conntrack_core.c:	nf_conntrack_expect_chain
net/netlink/af_netlink.c:		netlink_chain
  BLOCKING CHAINS
  ---------------
arch/powerpc/platforms/pseries/reconfig.c:	pSeries_reconfig_chain
arch/s390/kernel/process.c:		idle_chain
arch/x86_64/kernel/process.c		idle_notifier
drivers/base/memory.c:			memory_chain
drivers/cpufreq/cpufreq.c		cpufreq_policy_notifier_list
drivers/cpufreq/cpufreq.c		cpufreq_transition_notifier_list
drivers/macintosh/adb.c:		adb_client_list
drivers/macintosh/via-pmu.c		sleep_notifier_list
drivers/macintosh/via-pmu68k.c		sleep_notifier_list
drivers/macintosh/windfarm_core.c	wf_client_list
drivers/usb/core/notify.c		usb_notifier_list
drivers/video/fbmem.c			fb_notifier_list
kernel/cpu.c				cpu_chain
kernel/module.c				module_notify_list
kernel/profile.c			munmap_notifier
kernel/profile.c			task_exit_notifier
kernel/sys.c				reboot_notifier_list
net/core/dev.c				netdev_chain
net/decnet/dn_dev.c:			dnaddr_chain
net/ipv4/devinet.c:			inetaddr_chain
It's possible that some of these classifications are wrong.  If they are,
please let us know or submit a patch to fix them.  Note that any chain that
gets called very frequently should be atomic, because the rwsem read-locking
used for blocking chains is very likely to incur cache misses on SMP systems.
(However, if the chain's callout routines may sleep then the chain cannot be
atomic.)
The patch set was written by Alan Stern and Chandra Seetharaman, incorporating
material written by Keith Owens and suggestions from Paul McKenney and Andrew
Morton.
[jes@sgi.com: restructure the notifier chain initialization macros]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
Signed-off-by: Jes Sorensen <jes@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
											 
										 
										
											2006-03-27 01:16:30 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  ioctl  handler  calling  blocking_notifier_call_chain )  holds  the  necessary 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  locks  for  us  to  safely  manipulate  the  slave  devices  ( RTNL  lock , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  dev_probe_lock ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_netdev_event ( struct  notifier_block  * this ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											     unsigned  long  event ,  void  * ptr ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * event_dev  =  ( struct  net_device  * ) ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " event_dev: %s, event: %lx \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 event_dev  ?  event_dev - > name  :  " None " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 event ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( event_dev - > priv_flags  &  IFF_BONDING ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NOTIFY_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( event_dev - > flags  &  IFF_MASTER )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " IFF_MASTER \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  bond_master_netdev_event ( event ,  event_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( event_dev - > flags  &  IFF_SLAVE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " IFF_SLAVE \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  bond_slave_netdev_event ( event ,  event_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NOTIFY_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bond_inetaddr_event :  handle  inetaddr  notifier  chain  events . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  We  keep  track  of  device  IPs  primarily  to  use  as  source  addresses  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  ARP  monitor  probes  ( rather  than  spewing  out  broadcasts  all  the  time ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  We  track  one  IP  for  the  main  device  ( if  it  has  one ) ,  plus  one  per  VLAN . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_inetaddr_event ( struct  notifier_block  * this ,  unsigned  long  event ,  void  * ptr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  in_ifaddr  * ifa  =  ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * vlan_dev ,  * event_dev  =  ifa - > ifa_dev - > dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bond_net  * bn  =  net_generic ( dev_net ( event_dev ) ,  bond_net_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  vlan_entry  * vlan ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									list_for_each_entry ( bond ,  & bn - > dev_list ,  bond_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > dev  = =  event_dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch  ( event )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  NETDEV_UP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond - > master_ip  =  ifa - > ifa_local ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  NOTIFY_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  NETDEV_DOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond - > master_ip  =  bond_glean_dev_ip ( bond - > dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  NOTIFY_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  NOTIFY_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										list_for_each_entry ( vlan ,  & bond - > vlan_list ,  vlan_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! bond - > vlgrp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-02 20:44:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											vlan_dev  =  vlan_group_get_device ( bond - > vlgrp ,  vlan - > vlan_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( vlan_dev  = =  event_dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												switch  ( event )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  NETDEV_UP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													vlan - > vlan_ip  =  ifa - > ifa_local ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  NOTIFY_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  NETDEV_DOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													vlan - > vlan_ip  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														bond_glean_dev_ip ( vlan_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  NOTIFY_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  NOTIFY_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NOTIFY_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  struct  notifier_block  bond_netdev_notifier  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. notifier_call  =  bond_netdev_event , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  notifier_block  bond_inetaddr_notifier  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. notifier_call  =  bond_inetaddr_event , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*-------------------------- Packet type handling ---------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* register to receive lacpdus on a bond */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_register_lacpdu ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  packet_type  * pk_type  =  & ( BOND_AD_INFO ( bond ) . ad_pkt_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* initialize packet type */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pk_type - > type  =  PKT_TYPE_LACPDU ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pk_type - > dev  =  bond - > dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pk_type - > func  =  bond_3ad_lacpdu_recv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev_add_pack ( pk_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* unregister to receive lacpdus on a bond */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_unregister_lacpdu ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev_remove_pack ( & ( BOND_AD_INFO ( bond ) . ad_pkt_type ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  bond_register_arp ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  packet_type  * pt  =  & bond - > arp_mon_pt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-28 17:03:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( pt - > type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pt - > type  =  htons ( ETH_P_ARP ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-28 17:03:27 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pt - > dev  =  bond - > dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pt - > func  =  bond_arp_rcv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev_add_pack ( pt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  bond_unregister_arp ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-02-28 17:03:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  packet_type  * pt  =  & bond - > arp_mon_pt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev_remove_pack ( pt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pt - > type  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*---------------------------- Hashing Policies -----------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 23:40:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Hash  for  the  output  device  based  upon  layer  2  and  layer  3  data .  If 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  packet  is  not  IP  mimic  bond_xmit_hash_policy_l2 ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-23 04:09:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_xmit_hash_policy_l23 ( struct  sk_buff  * skb ,  int  count )  
						 
					
						
							
								
									
										
										
										
											2007-12-06 23:40:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ethhdr  * data  =  ( struct  ethhdr  * ) skb - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  iphdr  * iph  =  ip_hdr ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-09-02 10:08:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( skb - > protocol  = =  htons ( ETH_P_IP ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 23:40:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  ( ( ntohl ( iph - > saddr  ^  iph - > daddr )  &  0xffff )  ^ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-23 04:08:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											( data - > h_dest [ 5 ]  ^  data - > h_source [ 5 ] ) )  %  count ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 23:40:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-23 04:08:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ( data - > h_dest [ 5 ]  ^  data - > h_source [ 5 ] )  %  count ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 23:40:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2007-05-09 08:57:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Hash  for  the  output  device  based  upon  layer  3  and  layer  4  data .  If 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  the  packet  is  a  frag  or  not  TCP  or  UDP ,  just  use  layer  3  data .   If  it  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  altogether  not  IP ,  mimic  bond_xmit_hash_policy_l2 ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-23 04:09:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_xmit_hash_policy_l34 ( struct  sk_buff  * skb ,  int  count )  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ethhdr  * data  =  ( struct  ethhdr  * ) skb - > data ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-20 22:47:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  iphdr  * iph  =  ip_hdr ( skb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-22 20:06:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__be16  * layer4hdr  =  ( __be16  * ) ( ( u32  * ) iph  +  iph - > ihl ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  layer4_xor  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-09-02 10:08:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( skb - > protocol  = =  htons ( ETH_P_IP ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( iph - > frag_off  &  htons ( IP_MF | IP_OFFSET ) )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    ( iph - > protocol  = =  IPPROTO_TCP  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     iph - > protocol  = =  IPPROTO_UDP ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-22 20:06:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											layer4_xor  =  ntohs ( ( * layer4hdr  ^  * ( layer4hdr  +  1 ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ( layer4_xor  ^ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											( ( ntohl ( iph - > saddr  ^  iph - > daddr ) )  &  0xffff ) )  %  count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-23 04:08:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ( data - > h_dest [ 5 ]  ^  data - > h_source [ 5 ] )  %  count ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Hash  for  the  output  device  based  upon  layer  2  data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-23 04:09:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_xmit_hash_policy_l2 ( struct  sk_buff  * skb ,  int  count )  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ethhdr  * data  =  ( struct  ethhdr  * ) skb - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-23 04:08:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ( data - > h_dest [ 5 ]  ^  data - > h_source [ 5 ] )  %  count ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*-------------------------- Device entry points ----------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_open ( struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond - > kill_timers  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:07:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond_is_lb ( bond ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* bond_alb_initialize must be called before the timer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  is  started . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond_alb_initialize ( bond ,  ( bond - > params . mode  = =  BOND_MODE_ALB ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* something went wrong - fail the open operation */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-25 23:34:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - ENOMEM ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										INIT_DELAYED_WORK ( & bond - > alb_work ,  bond_alb_monitor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queue_delayed_work ( bond - > wq ,  & bond - > alb_work ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . miimon )  {   /* link check interval, in milliseconds. */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										INIT_DELAYED_WORK ( & bond - > mii_work ,  bond_mii_monitor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queue_delayed_work ( bond - > wq ,  & bond - > mii_work ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . arp_interval )  {   /* arp interval, in milliseconds. */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > params . mode  = =  BOND_MODE_ACTIVEBACKUP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											INIT_DELAYED_WORK ( & bond - > arp_work , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													  bond_activebackup_arp_mon ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											INIT_DELAYED_WORK ( & bond - > arp_work , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													  bond_loadbalance_arp_mon ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queue_delayed_work ( bond - > wq ,  & bond - > arp_work ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bond - > params . arp_validate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_register_arp ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-24 18:27:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										INIT_DELAYED_WORK ( & bond - > ad_work ,  bond_3ad_state_machine_handler ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										queue_delayed_work ( bond - > wq ,  & bond - > ad_work ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* register to receive LACPDUs */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_register_lacpdu ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-04 17:51:16 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_3ad_initiate_agg_selection ( bond ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_close ( struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Unregister the receive of LACPDUs */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_unregister_lacpdu ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > params . arp_validate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_unregister_arp ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									write_lock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:03 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond - > send_grat_arp  =  0 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond - > send_unsol_na  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* signal timers not to re-arm */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond - > kill_timers  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									write_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . miimon )  {   /* link check interval, in milliseconds. */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cancel_delayed_work ( & bond - > mii_work ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . arp_interval )  {   /* arp interval, in milliseconds. */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cancel_delayed_work ( & bond - > arp_work ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( bond - > params . mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_8023AD : 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cancel_delayed_work ( & bond - > ad_work ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_TLB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_ALB : 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cancel_delayed_work ( & bond - > alb_work ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:07:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond_is_lb ( bond ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Must be called only after all
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  slaves  have  been  released 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_alb_deinitialize ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-07 14:58:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  rtnl_link_stats64  * bond_get_stats ( struct  net_device  * bond_dev ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														struct  rtnl_link_stats64  * stats ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-07 14:58:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  rtnl_link_stats64  temp ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-07 14:58:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									memset ( stats ,  0 ,  sizeof ( * stats ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-08 07:19:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  struct  rtnl_link_stats64  * sstats  = 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-07 14:58:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dev_get_stats ( slave - > dev ,  & temp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > rx_packets  + =  sstats - > rx_packets ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > rx_bytes  + =  sstats - > rx_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > rx_errors  + =  sstats - > rx_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > rx_dropped  + =  sstats - > rx_dropped ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > tx_packets  + =  sstats - > tx_packets ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > tx_bytes  + =  sstats - > tx_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > tx_errors  + =  sstats - > tx_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > tx_dropped  + =  sstats - > tx_dropped ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > multicast  + =  sstats - > multicast ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > collisions  + =  sstats - > collisions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > rx_length_errors  + =  sstats - > rx_length_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > rx_over_errors  + =  sstats - > rx_over_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > rx_crc_errors  + =  sstats - > rx_crc_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > rx_frame_errors  + =  sstats - > rx_frame_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > rx_fifo_errors  + =  sstats - > rx_fifo_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > rx_missed_errors  + =  sstats - > rx_missed_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > tx_aborted_errors  + =  sstats - > tx_aborted_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > tx_carrier_errors  + =  sstats - > tx_carrier_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > tx_fifo_errors  + =  sstats - > tx_fifo_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > tx_heartbeat_errors  + =  sstats - > tx_heartbeat_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stats - > tx_window_errors  + =  sstats - > tx_window_errors ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-29 18:07:46 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									read_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  stats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_do_ioctl ( struct  net_device  * bond_dev ,  struct  ifreq  * ifr ,  int  cmd )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * slave_dev  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ifbond  k_binfo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ifbond  __user  * u_binfo  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ifslave  k_sinfo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ifslave  __user  * u_sinfo  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mii_ioctl_data  * mii  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " bond_ioctl: master=%s, cmd=%d \n " ,  bond_dev - > name ,  cmd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SIOCGMIIPHY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mii  =  if_mii ( ifr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! mii ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										mii - > phy_id  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Fall Through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SIOCGMIIREG : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  We  do  this  again  just  in  case  we  were  called  by  SIOCGMIIREG 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  instead  of  SIOCGMIIPHY . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mii  =  if_mii ( ifr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! mii ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( mii - > reg_num  = =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											mii - > val_out  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											read_lock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( netif_carrier_ok ( bond - > dev ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												mii - > val_out  =  BMSR_LSTATUS ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_INFO_QUERY_OLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SIOCBONDINFOQUERY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										u_binfo  =  ( struct  ifbond  __user  * ) ifr - > ifr_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( copy_from_user ( & k_binfo ,  u_binfo ,  sizeof ( ifbond ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  - EFAULT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  bond_info_query ( bond_dev ,  & k_binfo ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( res  = =  0  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    copy_to_user ( u_binfo ,  & k_binfo ,  sizeof ( ifbond ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EFAULT ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_SLAVE_INFO_QUERY_OLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SIOCBONDSLAVEINFOQUERY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										u_sinfo  =  ( struct  ifslave  __user  * ) ifr - > ifr_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( copy_from_user ( & k_sinfo ,  u_sinfo ,  sizeof ( ifslave ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  - EFAULT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  bond_slave_info_query ( bond_dev ,  & k_sinfo ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( res  = =  0  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    copy_to_user ( u_sinfo ,  & k_sinfo ,  sizeof ( ifslave ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EFAULT ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Go on */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! capable ( CAP_NET_ADMIN ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - EPERM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									slave_dev  =  dev_get_by_name ( dev_net ( bond_dev ) ,  ifr - > ifr_slave ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " slave_dev=%p: \n " ,  slave_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! slave_dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										res  =  - ENODEV ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " slave_dev->name=%s: \n " ,  slave_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  BOND_ENSLAVE_OLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SIOCBONDENSLAVE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  bond_enslave ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  BOND_RELEASE_OLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SIOCBONDRELEASE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  bond_release ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  BOND_SETHWADDR_OLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SIOCBONDSETHWADDR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  bond_sethwaddr ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  BOND_CHANGE_ACTIVE_OLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SIOCBONDCHANGEACTIVE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  bond_ioctl_change_active ( bond_dev ,  slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_put ( slave_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  bond_addr_in_mc_list ( unsigned  char  * addr ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 struct  netdev_hw_addr_list  * list , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 int  addrlen ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  netdev_hw_addr  * ha ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									netdev_hw_addr_list_for_each ( ha ,  list ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! memcmp ( ha - > addr ,  addr ,  addrlen ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  void  bond_set_multicast_list ( struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  netdev_hw_addr  * ha ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  found ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Do  promisc  before  checking  multicast_mode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( bond_dev - > flags  &  IFF_PROMISC )  & &  ! ( bond - > flags  &  IFF_PROMISC ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  FIXME :  Need  to  handle  the  error  when  one  of  the  multi - slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  encounters  error . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_set_promiscuity ( bond ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( bond_dev - > flags  &  IFF_PROMISC )  & &  ( bond - > flags  &  IFF_PROMISC ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_set_promiscuity ( bond ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* set allmulti flag to slaves */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( bond_dev - > flags  &  IFF_ALLMULTI )  & &  ! ( bond - > flags  &  IFF_ALLMULTI ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-14 20:51:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  FIXME :  Need  to  handle  the  error  when  one  of  the  multi - slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  encounters  error . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_set_allmulti ( bond ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( bond_dev - > flags  &  IFF_ALLMULTI )  & &  ( bond - > flags  &  IFF_ALLMULTI ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										bond_set_allmulti ( bond ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-29 18:07:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									bond - > flags  =  bond_dev - > flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* looking for addresses to add to slaves' mc list */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									netdev_for_each_mc_addr ( ha ,  bond_dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										found  =  bond_addr_in_mc_list ( ha - > addr ,  & bond - > mc_list , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													     bond_dev - > addr_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! found ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_mc_add ( bond ,  ha - > addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* looking for addresses to delete from slaves' list */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									netdev_hw_addr_list_for_each ( ha ,  & bond - > mc_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										found  =  bond_addr_in_mc_list ( ha - > addr ,  & bond_dev - > mc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													     bond_dev - > addr_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! found ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bond_mc_del ( bond ,  ha - > addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* save master's multicast list */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__hw_addr_flush ( & bond - > mc_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									__hw_addr_add_multiple ( & bond - > mc_list ,  & bond_dev - > mc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       bond_dev - > addr_len ,  NETDEV_HW_ADDR_T_MULTICAST ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-29 18:07:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-20 20:14:53 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_neigh_setup ( struct  net_device  * dev ,  struct  neigh_parms  * parms )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave  =  bond - > first_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( slave )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  struct  net_device_ops  * slave_ops 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											=  slave - > dev - > netdev_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( slave_ops - > ndo_neigh_setup ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-05 01:57:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  slave_ops - > ndo_neigh_setup ( slave - > dev ,  parms ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-20 20:14:53 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Change  the  MTU  of  all  of  a  master ' s  slaves  to  match  the  master 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_change_mtu ( struct  net_device  * bond_dev ,  int  new_mtu )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ,  * stop_at ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " bond=%p, name=%s, new_mtu=%d \n " ,  bond , 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 ( bond_dev  ?  bond_dev - > name  :  " None " ) ,  new_mtu ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Can't hold bond->lock with bh disabled here since
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  some  base  drivers  panic .  On  the  other  hand  we  can ' t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  hold  bond - > lock  without  bh  disabled  because  we ' ll 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  deadlock .  The  only  solution  is  to  rely  on  the  fact 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  that  we ' re  under  rtnl_lock  here ,  and  the  slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  list  won ' t  change .  This  doesn ' t  solve  the  problem 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  of  setting  the  slave ' s  MTU  while  it  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  transmitting ,  but  the  assumption  is  that  the  base 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  driver  can  handle  that . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  TODO :  figure  out  a  way  to  safely  iterate  the  slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  list ,  but  without  holding  a  lock  around  the  actual 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  call  to  the  base  driver . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " s %p s->p %p c_m %p \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 slave , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 slave - > prev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 slave - > dev - > netdev_ops - > ndo_change_mtu ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:50 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										res  =  dev_set_mtu ( slave - > dev ,  new_mtu ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* If we failed to set the slave's mtu to the new value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  we  must  abort  the  operation  even  in  ACTIVE_BACKUP 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  mode ,  because  if  we  allow  the  backup  slaves  to  have 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  different  mtu  values  than  the  active  slave  we ' ll 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  need  to  change  their  mtu  when  doing  a  failover .  That 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  means  changing  their  mtu  from  timer  context ,  which 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  is  probably  not  a  good  idea . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_debug ( " err %d %s \n " ,  res ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											goto  unwind ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_dev - > mtu  =  new_mtu ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								unwind :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* unwind from head to the slave that failed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									stop_at  =  slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave_from_to ( bond ,  slave ,  i ,  bond - > first_slave ,  stop_at )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  tmp_res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tmp_res  =  dev_set_mtu ( slave - > dev ,  bond_dev - > mtu ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( tmp_res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_debug ( " unwind err %d dev %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 tmp_res ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Change  HW  address 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Note  that  many  devices  must  be  down  to  change  the  HW  address ,  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  downing  the  master  releases  all  slaves .   We  can  make  bonds  full  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bonding  devices  to  test  this ,  however . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_set_mac_address ( struct  net_device  * bond_dev ,  void  * addr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  sockaddr  * sa  =  addr ,  tmp_sa ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ,  * stop_at ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_ALB ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  bond_alb_set_mac_address ( bond_dev ,  addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_debug ( " bond=%p, name=%s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 bond ,  bond_dev  ?  bond_dev - > name  :  " None " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:57:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 *  If  fail_over_mac  is  set  to  active ,  do  nothing  and  return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  success .   Returning  an  error  causes  ifenslave  to  fail . 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:57:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > params . fail_over_mac  = =  BOND_FOM_ACTIVE ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:57:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:43:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! is_valid_ether_addr ( sa - > sa_data ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - EADDRNOTAVAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Can't hold bond->lock with bh disabled here since
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  some  base  drivers  panic .  On  the  other  hand  we  can ' t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  hold  bond - > lock  without  bh  disabled  because  we ' ll 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  deadlock .  The  only  solution  is  to  rely  on  the  fact 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  that  we ' re  under  rtnl_lock  here ,  and  the  slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  list  won ' t  change .  This  doesn ' t  solve  the  problem 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  of  setting  the  slave ' s  hw  address  while  it  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  transmitting ,  but  the  assumption  is  that  the  base 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  driver  can  handle  that . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  TODO :  figure  out  a  way  to  safely  iterate  the  slaves 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  list ,  but  without  holding  a  lock  around  the  actual 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  call  to  the  base  driver . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  struct  net_device_ops  * slave_ops  =  slave - > dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_debug ( " slave %p %s \n " ,  slave ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( slave_ops - > ndo_set_mac_address  = =  NULL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											res  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_debug ( " EOPNOTSUPP %s \n " ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											goto  unwind ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  dev_set_mac_address ( slave - > dev ,  addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* TODO: consider downing the slave
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  and  retry  ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  User  should  expect  communications 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  breakage  anyway  until  ARP  finish 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  updating ,  so . . . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:09:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_debug ( " err %d %s \n " ,  res ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											goto  unwind ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* success */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memcpy ( bond_dev - > dev_addr ,  sa - > sa_data ,  bond_dev - > addr_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								unwind :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memcpy ( tmp_sa . sa_data ,  bond_dev - > dev_addr ,  bond_dev - > addr_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tmp_sa . sa_family  =  bond_dev - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* unwind from head to the slave that failed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									stop_at  =  slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave_from_to ( bond ,  slave ,  i ,  bond - > first_slave ,  stop_at )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  tmp_res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tmp_res  =  dev_set_mac_address ( slave - > dev ,  & tmp_sa ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( tmp_res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_debug ( " unwind err %d dev %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 tmp_res ,  slave - > dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_xmit_roundrobin ( struct  sk_buff  * skb ,  struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ,  * start_at ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  i ,  slave_no ,  res  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-25 14:49:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  iphdr  * iph  =  ip_hdr ( skb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! BOND_IS_OK ( bond ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-25 14:49:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 *  Start  with  the  curr_active_slave  that  joined  the  bond  as  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  default  for  sending  IGMP  traffic .   For  failover  purposes  one 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  needs  to  maintain  some  consistency  for  the  interface  that  will 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  send  the  join / membership  reports .   The  curr_active_slave  found 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  will  send  all  of  this  type  of  traffic . 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-30 23:08:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( iph - > protocol  = =  IPPROTO_IGMP )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-25 14:49:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    ( skb - > protocol  = =  htons ( ETH_P_IP ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-25 14:49:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										read_lock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave  =  bond - > curr_active_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! slave ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  Concurrent  TX  may  collide  on  rr_tx_counter ;  we  accept 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  that  as  being  rare  enough  not  to  justify  using  an 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  atomic  op  here . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_no  =  bond - > rr_tx_counter + +  %  bond - > slave_cnt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave_no - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( slave_no  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-17 17:37:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									start_at  =  slave ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave_from ( bond ,  slave ,  i ,  start_at )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( IS_UP ( slave - > dev )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ( slave - > link  = =  BOND_LINK_UP )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ( slave - > state  = =  BOND_STATE_ACTIVE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  bond_dev_queue_xmit ( bond ,  skb ,  slave - > dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* no suitable interface, frame not sent */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_kfree_skb ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  NETDEV_TX_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-28 17:50:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  in  active - backup  mode ,  we  know  that  bond - > curr_active_slave  is  always  valid  if 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  bond  has  a  usable  interface . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_xmit_activebackup ( struct  sk_buff  * skb ,  struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  res  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! BOND_IS_OK ( bond ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-28 17:50:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! bond - > curr_active_slave ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  bond_dev_queue_xmit ( bond ,  skb ,  bond - > curr_active_slave - > dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* no suitable interface, frame not sent */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_kfree_skb ( skb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  NETDEV_TX_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  In  bond_xmit_xor ( )  ,  we  determine  the  output  device  by  using  a  pre - 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  determined  xmit_hash_policy ( ) ,  If  the  selected  device  is  not  enabled , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  find  the  next  active  slave . 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_xmit_xor ( struct  sk_buff  * skb ,  struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ,  * start_at ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  slave_no ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! BOND_IS_OK ( bond ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-23 04:09:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									slave_no  =  bond - > xmit_hash_policy ( skb ,  bond - > slave_cnt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_no - - ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( slave_no  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									start_at  =  slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave_from ( bond ,  slave ,  i ,  start_at )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( IS_UP ( slave - > dev )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ( slave - > link  = =  BOND_LINK_UP )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ( slave - > state  = =  BOND_STATE_ACTIVE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  bond_dev_queue_xmit ( bond ,  skb ,  slave - > dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* no suitable interface, frame not sent */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_kfree_skb ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  NETDEV_TX_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  in  broadcast  mode ,  we  send  everything  to  all  usable  interfaces . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_xmit_broadcast ( struct  sk_buff  * skb ,  struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave ,  * start_at ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * tx_dev  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! BOND_IS_OK ( bond ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									start_at  =  bond - > curr_active_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! start_at ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave_from ( bond ,  slave ,  i ,  start_at )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( IS_UP ( slave - > dev )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ( slave - > link  = =  BOND_LINK_UP )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ( slave - > state  = =  BOND_STATE_ACTIVE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( tx_dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												struct  sk_buff  * skb2  =  skb_clone ( skb ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! skb2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													pr_err ( " %s: Error: bond_xmit_broadcast(): skb_clone() failed \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:34:57 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													       bond_dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  bond_dev_queue_xmit ( bond ,  skb2 ,  tx_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													dev_kfree_skb ( skb2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tx_dev  =  slave - > dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tx_dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										res  =  bond_dev_queue_xmit ( bond ,  skb ,  tx_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* no suitable interface, frame not sent */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_kfree_skb ( skb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* frame sent to all suitable interfaces */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  NETDEV_TX_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*------------------------- Device initialization ---------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 23:40:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_set_xmit_hash_policy ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( bond - > params . xmit_policy )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_XMIT_POLICY_LAYER23 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond - > xmit_hash_policy  =  bond_xmit_hash_policy_l23 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_XMIT_POLICY_LAYER34 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond - > xmit_hash_policy  =  bond_xmit_hash_policy_l34 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_XMIT_POLICY_LAYER2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond - > xmit_hash_policy  =  bond_xmit_hash_policy_l2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Lookup  the  slave  that  corresponds  to  a  qid 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  int  bond_slave_override ( struct  bonding  * bond ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												      struct  sk_buff  * skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ,  res  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * slave  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  slave  * check_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_lock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! BOND_IS_OK ( bond )  | |  ! skb - > queue_mapping ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Find out if any slaves have the same mapping as this skb. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_for_each_slave ( bond ,  check_slave ,  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( check_slave - > queue_id  = =  skb - > queue_mapping )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											slave  =  check_slave ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If the slave isn't UP, use default transmit policy. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( slave  & &  slave - > queue_id  & &  IS_UP ( slave - > dev )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( slave - > link  = =  BOND_LINK_UP ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  bond_dev_queue_xmit ( bond ,  skb ,  slave - > dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read_unlock ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  u16  bond_select_queue ( struct  net_device  * dev ,  struct  sk_buff  * skb )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  This  helper  function  exists  to  help  dev_pick_tx  get  the  correct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  destination  queue .   Using  a  helper  function  skips  the  a  call  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  skb_tx_hash  and  will  put  the  skbs  in  the  queue  we  expect  on  their 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  way  down  to  the  bonding  driver . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  skb - > queue_mapping ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-31 19:50:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  netdev_tx_t  bond_start_xmit ( struct  sk_buff  * skb ,  struct  net_device  * dev )  
						 
					
						
							
								
									
										
										
										
											2008-11-20 20:14:53 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( TX_QUEUE_OVERRIDE ( bond - > params . mode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! bond_slave_override ( bond ,  skb ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  NETDEV_TX_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-20 20:14:53 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( bond - > params . mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_ROUNDROBIN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  bond_xmit_roundrobin ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_ACTIVEBACKUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  bond_xmit_activebackup ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_XOR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  bond_xmit_xor ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_BROADCAST : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  bond_xmit_broadcast ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_8023AD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  bond_3ad_xmit_xor ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_ALB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_TLB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  bond_alb_xmit ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Should never happen, mode already checked */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_err ( " %s: Error: Unknown bonding mode %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       dev - > name ,  bond - > params . mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-20 20:14:53 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										WARN_ON_ONCE ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_kfree_skb ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NETDEV_TX_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  set  bond  mode  specific  net  device  operations 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:35:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  bond_set_mode_ops ( struct  bonding  * bond ,  int  mode )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net_device  * bond_dev  =  bond - > dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									switch  ( mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_ROUNDROBIN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_ACTIVEBACKUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_XOR : 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 23:40:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_set_xmit_hash_policy ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_BROADCAST : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_8023AD : 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-21 16:36:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_set_master_3ad_flags ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 23:40:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_set_xmit_hash_policy ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_ALB : 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-21 16:36:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bond_set_master_alb_flags ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* FALLTHRU */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  BOND_MODE_TLB : 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Should never happen, mode already checked */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_err ( " %s: Error: Unknown bonding mode %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       bond_dev - > name ,  mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-26 16:11:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_ethtool_get_drvinfo ( struct  net_device  * bond_dev ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    struct  ethtool_drvinfo  * drvinfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strncpy ( drvinfo - > driver ,  DRV_NAME ,  32 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strncpy ( drvinfo - > version ,  DRV_VERSION ,  32 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( drvinfo - > fw_version ,  32 ,  " %d " ,  BOND_ABI_VERSION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-13 14:30:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  struct  ethtool_ops  bond_ethtool_ops  =  {  
						 
					
						
							
								
									
										
										
										
											2005-09-26 16:11:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. get_drvinfo 		=  bond_ethtool_get_drvinfo , 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-13 21:17:09 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. get_link 		=  ethtool_op_get_link , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. get_tx_csum 		=  ethtool_op_get_tx_csum , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. get_sg 			=  ethtool_op_get_sg , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. get_tso 		=  ethtool_op_get_tso , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. get_ufo 		=  ethtool_op_get_ufo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. get_flags 		=  ethtool_op_get_flags , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 01:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  struct  net_device_ops  bond_netdev_ops  =  {  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. ndo_init 		=  bond_init , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. ndo_uninit 		=  bond_uninit , 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. ndo_open 		=  bond_open , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. ndo_stop 		=  bond_close , 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-20 20:14:53 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. ndo_start_xmit 		=  bond_start_xmit , 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. ndo_select_queue 	=  bond_select_queue , 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-08 07:19:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. ndo_get_stats64 	=  bond_get_stats , 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. ndo_do_ioctl 		=  bond_do_ioctl , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. ndo_set_multicast_list 	=  bond_set_multicast_list , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. ndo_change_mtu 		=  bond_change_mtu , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. ndo_set_mac_address  	=  bond_set_mac_address , 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-20 20:14:53 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. ndo_neigh_setup 	=  bond_neigh_setup , 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. ndo_vlan_rx_register 	=  bond_vlan_rx_register , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. ndo_vlan_rx_add_vid  	=  bond_vlan_rx_add_vid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. ndo_vlan_rx_kill_vid 	=  bond_vlan_rx_kill_vid , 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-06 00:48:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_NET_POLL_CONTROLLER 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. ndo_netpoll_cleanup 	=  bond_netpoll_cleanup , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. ndo_poll_controller 	=  bond_poll_controller , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-31 21:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_destructor ( struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > wq ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										destroy_workqueue ( bond - > wq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									free_netdev ( bond_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_setup ( struct  net_device  * bond_dev )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* initialize rwlocks */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rwlock_init ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rwlock_init ( & bond - > curr_slave_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond - > params  =  bonding_defaults ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Initialize pointers */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond - > dev  =  bond_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INIT_LIST_HEAD ( & bond - > vlan_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Initialize the device entry points */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ether_setup ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:56:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_dev - > netdev_ops  =  & bond_netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 01:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_dev - > ethtool_ops  =  & bond_ethtool_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_set_mode_ops ( bond ,  bond - > params . mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-31 21:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_dev - > destructor  =  bond_destructor ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Initialize the device options */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_dev - > tx_queue_len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_dev - > flags  | =  IFF_MASTER | IFF_MULTICAST ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_dev - > priv_flags  | =  IFF_BONDING ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_dev - > priv_flags  & =  ~ IFF_XMIT_DST_RELEASE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-03 18:16:50 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bond - > params . arp_interval ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_dev - > priv_flags  | =  IFF_MASTER_ARPMON ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* At first, we block adding VLANs. That's the only way to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  prevent  problems  that  occur  when  adding  VLANs  over  an 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  empty  bond .  The  block  will  be  removed  once  non - challenged 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  slaves  are  enslaved . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_dev - > features  | =  NETIF_F_VLAN_CHALLENGED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-09 12:20:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* don't acquire bond device's netif_tx_lock when
 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 *  transmitting  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_dev - > features  | =  NETIF_F_LLTX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* By default, we declare the bond to be fully
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  VLAN  hardware  accelerated  capable .  Special 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  care  is  taken  in  the  various  xmit  functions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  when  there  are  slaves  that  are  not  hw  accel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  capable 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_dev - > features  | =  ( NETIF_F_HW_VLAN_TX  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       NETIF_F_HW_VLAN_RX  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       NETIF_F_HW_VLAN_FILTER ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 23:40:35 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_work_cancel_all ( struct  bonding  * bond )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									write_lock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond - > kill_timers  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									write_unlock_bh ( & bond - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . miimon  & &  delayed_work_pending ( & bond - > mii_work ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cancel_delayed_work ( & bond - > mii_work ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . arp_interval  & &  delayed_work_pending ( & bond - > arp_work ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cancel_delayed_work ( & bond - > arp_work ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_ALB  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    delayed_work_pending ( & bond - > alb_work ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cancel_delayed_work ( & bond - > alb_work ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond - > params . mode  = =  BOND_MODE_8023AD  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    delayed_work_pending ( & bond - > ad_work ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cancel_delayed_work ( & bond - > ad_work ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  Destroy  a  bonding  device .  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  Must  be  under  rtnl_lock  when  this  function  is  called .  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_uninit ( struct  net_device  * bond_dev )  
						 
					
						
							
								
									
										
										
										
											2008-10-30 17:41:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-12 23:37:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  vlan_entry  * vlan ,  * tmp ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-30 17:41:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-06 00:48:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_netpoll_cleanup ( bond_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Release the bonded slaves */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_release_all ( bond_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-10-30 17:41:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									list_del ( & bond - > bond_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_work_cancel_all ( bond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_remove_proc_entry ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__hw_addr_flush ( & bond - > mc_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 12:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list_for_each_entry_safe ( vlan ,  tmp ,  & bond - > vlan_list ,  vlan_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										list_del ( & vlan - > vlan_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										kfree ( vlan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-30 17:41:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*------------------------- Module initialization ---------------------------*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Convert  string  input  module  parms .   Accept  either  the 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-17 16:25:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  number  of  the  mode  or  its  string  name .   A  bit  complicated  because 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  some  mode  names  are  substrings  of  other  names ,  and  calls  from  sysfs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  may  have  whitespace  in  the  name  ( trailing  newlines ,  for  example ) . 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-09 23:10:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  bond_parse_parm ( const  char  * buf ,  const  struct  bond_parm_tbl  * tbl )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-02-14 11:15:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  modeint  =  - 1 ,  i ,  rv ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-29 18:07:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * p ,  modestr [ BOND_MAX_MODENAME_LEN  +  1 ]  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-17 16:25:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-29 18:07:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( p  =  ( char  * ) buf ;  * p ;  p + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( isdigit ( * p )  | |  isspace ( * p ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( * p ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-17 16:25:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rv  =  sscanf ( buf ,  " %20s " ,  modestr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-29 18:07:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-14 11:15:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rv  =  sscanf ( buf ,  " %d " ,  & modeint ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-29 18:07:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! rv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  tbl [ i ] . modename ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-14 11:15:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( modeint  = =  tbl [ i ] . mode ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-17 16:25:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  tbl [ i ] . mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( strcmp ( modestr ,  tbl [ i ] . modename )  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  tbl [ i ] . mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_check_params ( struct  bond_params  * params )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  arp_validate_value ,  fail_over_mac_value ,  primary_reselect_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Convert  string  parameters . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_mode  =  bond_parse_parm ( mode ,  bond_mode_tbl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond_mode  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " Error: Invalid bonding mode  \" %s \" \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											       mode  = =  NULL  ?  " NULL "  :  mode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( xmit_hash_policy )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( bond_mode  ! =  BOND_MODE_XOR )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ( bond_mode  ! =  BOND_MODE_8023AD ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_info ( " xmit_hash_policy param is irrelevant in mode %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       bond_mode_name ( bond_mode ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xmit_hashtype  =  bond_parse_parm ( xmit_hash_policy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															xmit_hashtype_tbl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( xmit_hashtype  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pr_err ( " Error: Invalid xmit_hash_policy  \" %s \" \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       xmit_hash_policy  = =  NULL  ?  " NULL "  : 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												       xmit_hash_policy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( lacp_rate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond_mode  ! =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_info ( " lacp_rate param is irrelevant in mode %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond_mode_name ( bond_mode ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lacp_fast  =  bond_parse_parm ( lacp_rate ,  bond_lacp_tbl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( lacp_fast  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pr_err ( " Error: Invalid lacp rate  \" %s \" \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												       lacp_rate  = =  NULL  ?  " NULL "  :  lacp_rate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-04 17:51:16 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ad_select )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										params - > ad_select  =  bond_parse_parm ( ad_select ,  ad_select_tbl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( params - > ad_select  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " Error: Invalid ad_select  \" %s \" \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-04 17:51:16 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       ad_select  = =  NULL  ?  " NULL "  :  ad_select ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond_mode  ! =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " ad_select param only affects 802.3ad mode \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-04 17:51:16 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										params - > ad_select  =  BOND_AD_STABLE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-28 13:18:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( max_bonds  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " Warning: max_bonds (%d) not in range %d-%d, so it was reset to BOND_DEFAULT_MAX_BONDS (%d) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   max_bonds ,  0 ,  INT_MAX ,  BOND_DEFAULT_MAX_BONDS ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										max_bonds  =  BOND_DEFAULT_MAX_BONDS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( miimon  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " Warning: miimon module parameter (%d), not in range 0-%d, so it was reset to %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   miimon ,  INT_MAX ,  BOND_LINK_MON_INTERV ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										miimon  =  BOND_LINK_MON_INTERV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( updelay  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " Warning: updelay module parameter (%d), not in range 0-%d, so it was reset to 0 \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   updelay ,  INT_MAX ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										updelay  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( downdelay  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " Warning: downdelay module parameter (%d), not in range 0-%d, so it was reset to 0 \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   downdelay ,  INT_MAX ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										downdelay  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( use_carrier  ! =  0 )  & &  ( use_carrier  ! =  1 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " Warning: use_carrier module parameter (%d), not of valid value (0/1), so it was set to 1 \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   use_carrier ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										use_carrier  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( num_grat_arp  <  0  | |  num_grat_arp  >  255 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-24 07:57:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " Warning: num_grat_arp (%d) not in range 0-255 so it was reset to 1 \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   num_grat_arp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										num_grat_arp  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( num_unsol_na  <  0  | |  num_unsol_na  >  255 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-24 07:57:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " Warning: num_unsol_na (%d) not in range 0-255 so it was reset to 1 \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											   num_unsol_na ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										num_unsol_na  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* reset values for 802.3ad */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond_mode  = =  BOND_MODE_8023AD )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! miimon )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " Warning: miimon must be specified, otherwise bonding will not detect link failure, speed and duplex which are essential for 802.3ad operation \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " Forcing miimon to 100msec \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											miimon  =  100 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tx_queues  <  1  | |  tx_queues  >  255 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_warning ( " Warning: tx_queues (%d) should be between  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   " 1 and 255, resetting to %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   tx_queues ,  BOND_DEFAULT_TX_QUEUES ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tx_queues  =  BOND_DEFAULT_TX_QUEUES ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:39:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( all_slaves_active  ! =  0 )  & &  ( all_slaves_active  ! =  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_warning ( " Warning: all_slaves_active module parameter (%d),  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   " not of valid value (0/1), so it was set to  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   " 0 \n " ,  all_slaves_active ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										all_slaves_active  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* reset values for TLB/ALB */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( bond_mode  = =  BOND_MODE_TLB )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( bond_mode  = =  BOND_MODE_ALB ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! miimon )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " Warning: miimon must be specified, otherwise bonding will not detect link failure and link speed which are essential for TLB/ALB load balancing \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " Forcing miimon to 100msec \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											miimon  =  100 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bond_mode  = =  BOND_MODE_ALB )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_notice ( " In ALB mode you might experience client disconnections upon reconnection of a link if the bonding module updelay parameter (%d msec) is incompatible with the forwarding delay time of the switch \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											  updelay ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! miimon )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( updelay  | |  downdelay )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* just warn the user the up/down delay will have
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  no  effect  since  miimon  is  zero . . . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " Warning: miimon module parameter not set and updelay (%d) or downdelay (%d) module parameter is set; updelay and downdelay have no effect unless miimon is set \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   updelay ,  downdelay ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* don't allow arp monitoring */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( arp_interval )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " Warning: miimon (%d) and arp_interval (%d) can't be used simultaneously, disabling ARP monitoring \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   miimon ,  arp_interval ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											arp_interval  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( updelay  %  miimon )  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " Warning: updelay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   updelay ,  miimon , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   ( updelay  /  miimon )  *  miimon ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										updelay  / =  miimon ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( downdelay  %  miimon )  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " Warning: downdelay (%d) is not a multiple of miimon (%d), downdelay rounded to %d ms \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   downdelay ,  miimon , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   ( downdelay  /  miimon )  *  miimon ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										downdelay  / =  miimon ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( arp_interval  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " Warning: arp_interval module parameter (%d) , not in range 0-%d, so it was reset to %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   arp_interval ,  INT_MAX ,  BOND_LINK_ARP_INTERV ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										arp_interval  =  BOND_LINK_ARP_INTERV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( arp_ip_count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     ( arp_ip_count  <  BOND_MAX_ARP_TARGETS )  & &  arp_ip_target [ arp_ip_count ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     arp_ip_count + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* not complete check, but should be good enough to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   catch  mistakes  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! isdigit ( arp_ip_target [ arp_ip_count ] [ 0 ] ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   arp_ip_target [ arp_ip_count ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											arp_interval  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-22 20:06:58 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											__be32  ip  =  in_aton ( arp_ip_target [ arp_ip_count ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											arp_target [ arp_ip_count ]  =  ip ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( arp_interval  & &  ! arp_ip_count )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* don't allow arping if no arp_ip_target given... */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " Warning: arp_interval module parameter (%d) specified without providing an arp_ip_target parameter, arp_interval was reset to 0 \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   arp_interval ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										arp_interval  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( arp_validate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond_mode  ! =  BOND_MODE_ACTIVEBACKUP )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " arp_validate only supported in active-backup mode \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! arp_interval )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " arp_validate requires arp_interval \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arp_validate_value  =  bond_parse_parm ( arp_validate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														     arp_validate_tbl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( arp_validate_value  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " Error: invalid arp_validate  \" %s \" \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       arp_validate  = =  NULL  ?  " NULL "  :  arp_validate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arp_validate_value  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( miimon )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_info ( " MII link monitoring set to %d ms \n " ,  miimon ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  if  ( arp_interval )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_info ( " ARP monitoring set to %d ms, validate %s, with %d target(s): " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arp_interval , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arp_validate_tbl [ arp_validate_value ] . modename , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											arp_ip_count ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( i  =  0 ;  i  <  arp_ip_count ;  i + + ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-13 04:11:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_info ( "  %s " ,  arp_ip_target [ i ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-13 04:11:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_info ( " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 18:12:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( max_bonds )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* miimon and arp_interval not set, we need one so things
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  work  as  expected ,  see  bonding . txt  for  details 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " Warning: either miimon or arp_interval and arp_ip_target module parameters must be specified, otherwise bonding will not detect link failures! see bonding.txt for details. \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( primary  & &  ! USES_PRIMARY ( bond_mode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* currently, using a primary only makes sense
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  in  active  backup ,  TLB  or  ALB  modes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_warning ( " Warning: %s primary device specified but has no effect in %s mode \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   primary ,  bond_mode_name ( bond_mode ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										primary  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( primary  & &  primary_reselect )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										primary_reselect_value  =  bond_parse_parm ( primary_reselect , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 pri_reselect_tbl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( primary_reselect_value  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " Error: Invalid primary_reselect  \" %s \" \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       primary_reselect  = = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													NULL  ?  " NULL "  :  primary_reselect ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										primary_reselect_value  =  BOND_PRI_RESELECT_ALWAYS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( fail_over_mac )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fail_over_mac_value  =  bond_parse_parm ( fail_over_mac , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														      fail_over_mac_tbl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( fail_over_mac_value  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_err ( " Error: invalid fail_over_mac  \" %s \" \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       arp_validate  = =  NULL  ?  " NULL "  :  arp_validate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bond_mode  ! =  BOND_MODE_ACTIVEBACKUP ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pr_warning ( " Warning: fail_over_mac only affects active-backup mode. \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fail_over_mac_value  =  BOND_FOM_NONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 19:57:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* fill params struct with the proper values */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									params - > mode  =  bond_mode ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:54:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									params - > xmit_policy  =  xmit_hashtype ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									params - > miimon  =  miimon ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									params - > num_grat_arp  =  num_grat_arp ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									params - > num_unsol_na  =  num_unsol_na ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									params - > arp_interval  =  arp_interval ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-22 21:54:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									params - > arp_validate  =  arp_validate_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									params - > updelay  =  updelay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									params - > downdelay  =  downdelay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									params - > use_carrier  =  use_carrier ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									params - > lacp_fast  =  lacp_fast ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									params - > primary [ 0 ]  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 03:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									params - > primary_reselect  =  primary_reselect_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-17 21:10:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									params - > fail_over_mac  =  fail_over_mac_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									params - > tx_queues  =  tx_queues ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:39:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									params - > all_slaves_active  =  all_slaves_active ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( primary )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										strncpy ( params - > primary ,  primary ,  IFNAMSIZ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										params - > primary [ IFNAMSIZ  -  1 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memcpy ( params - > arp_targets ,  arp_target ,  sizeof ( arp_target ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-11-08 19:51:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  lock_class_key  bonding_netdev_xmit_lock_key ;  
						 
					
						
							
								
									
										
										
										
											2008-07-22 14:16:42 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  lock_class_key  bonding_netdev_addr_lock_key ;  
						 
					
						
							
								
									
										
										
										
											2006-11-08 19:51:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-17 00:34:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  bond_set_lockdep_class_one ( struct  net_device  * dev ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       struct  netdev_queue  * txq , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       void  * _unused ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-08 23:13:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lockdep_set_class ( & txq - > _xmit_lock , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											  & bonding_netdev_xmit_lock_key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  bond_set_lockdep_class ( struct  net_device  * dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-07-22 14:16:42 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									lockdep_set_class ( & dev - > addr_list_lock , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											  & bonding_netdev_addr_lock_key ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-17 00:34:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									netdev_for_each_tx_queue ( dev ,  bond_set_lockdep_class_one ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-08 23:13:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Called  from  registration  process 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bond_init ( struct  net_device  * bond_dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  bonding  * bond  =  netdev_priv ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bond_net  * bn  =  net_generic ( dev_net ( bond_dev ) ,  bond_net_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pr_debug ( " Begin bond_init for %s \n " ,  bond_dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond - > wq  =  create_singlethread_workqueue ( bond_dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! bond - > wq ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_set_lockdep_class ( bond_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									netif_carrier_off ( bond_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_create_proc_entry ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									list_add_tail ( & bond - > bond_list ,  & bn - > dev_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_prepare_sysfs_group ( bond ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-01 21:22:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									__hw_addr_init ( & bond - > mc_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bond_validate ( struct  nlattr  * tb [ ] ,  struct  nlattr  * data [ ] )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tb [ IFLA_ADDRESS ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( nla_len ( tb [ IFLA_ADDRESS ] )  ! =  ETH_ALEN ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! is_valid_ether_addr ( nla_data ( tb [ IFLA_ADDRESS ] ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EADDRNOTAVAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  rtnl_link_ops  bond_link_ops  __read_mostly  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. kind 		=  " bond " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 23:58:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. priv_size 	=  sizeof ( struct  bonding ) , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. setup 		=  bond_setup , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. validate 	=  bond_validate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Create a new bond based on the specified name and bonding parameters.
  
						 
					
						
							
								
									
										
										
										
											2007-01-19 18:15:31 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  If  name  is  NULL ,  obtain  a  suitable  " bond%d "  name  for  us . 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Caller  must  NOT  hold  rtnl_lock ;  we  need  to  release  it  here  before  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  set  up  our  sysfs  entries . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  bond_create ( struct  net  * net ,  const  char  * name )  
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * bond_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_lock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-17 16:25:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-02 08:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_dev  =  alloc_netdev_mq ( sizeof ( struct  bonding ) ,  name  ?  name  :  " " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bond_setup ,  tx_queues ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! bond_dev )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-13 20:06:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_err ( " %s: eek! can't alloc netdev! \n " ,  name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-31 21:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtnl_unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENOMEM ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dev_net_set ( bond_dev ,  net ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_dev - > rtnl_link_ops  =  & bond_link_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-01-19 18:15:31 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  dev_alloc_name ( bond_dev ,  " bond%d " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-31 21:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-19 18:15:31 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  register_netdevice ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-08 19:51:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_unlock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-31 21:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bond_destructor ( bond_dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-17 03:35:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  __net_init  bond_net_init ( struct  net  * net )  
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-11-29 15:46:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bond_net  * bn  =  net_generic ( net ,  bond_net_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bn - > net  =  net ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INIT_LIST_HEAD ( & bn - > dev_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_create_proc_dir ( bn ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-29 15:46:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-17 03:35:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  __net_exit  bond_net_exit ( struct  net  * net )  
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-11-29 15:46:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  bond_net  * bn  =  net_generic ( net ,  bond_net_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bond_destroy_proc_dir ( bn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  pernet_operations  bond_net_ops  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. init  =  bond_net_init , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. exit  =  bond_net_exit , 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-29 15:46:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. id    =  & bond_net_id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. size  =  sizeof ( struct  bond_net ) , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  __init  bonding_init ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pr_info ( " %s " ,  version ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  bond_check_params ( & bonding_defaults ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:02:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-29 15:46:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  register_pernet_subsys ( & bond_net_ops ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-17 16:25:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  rtnl_link_register ( & bond_link_ops ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 23:58:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										goto  err_link ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  max_bonds ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										res  =  bond_create ( & init_net ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:41 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  bond_create_sysfs ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									register_netdevice_notifier ( & bond_netdev_notifier ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									register_inetaddr_notifier ( & bond_inetaddr_notifier ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_register_ipv6_notifier ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								err :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_link_unregister ( & bond_link_ops ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 23:58:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								err_link :  
						 
					
						
							
								
									
										
										
										
											2009-11-29 15:46:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unregister_pernet_subsys ( & bond_net_ops ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									goto  out ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 10:36:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  __exit  bonding_exit ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unregister_netdevice_notifier ( & bond_netdev_notifier ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-26 17:52:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unregister_inetaddr_notifier ( & bond_inetaddr_notifier ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_unregister_ipv6_notifier ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-02 17:49:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bond_destroy_sysfs ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_link_unregister ( & bond_link_ops ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-29 15:46:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unregister_pernet_subsys ( & bond_net_ops ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								module_init ( bonding_init ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								module_exit ( bonding_exit ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_LICENSE ( " GPL " ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_VERSION ( DRV_VERSION ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_DESCRIPTION ( DRV_DESCRIPTION  " , v "  DRV_VERSION ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MODULE_AUTHOR ( " Thomas Davis, tadavis@lbl.gov and many others " ) ;  
						 
					
						
							
								
									
										
										
										
											2009-10-29 14:18:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								MODULE_ALIAS_RTNL_LINK ( " bond " ) ;