[linux-next] LinuxNextTracking branch, master, updated. next-20140219

batman at open-mesh.org batman at open-mesh.org
Thu Feb 20 00:22:58 CET 2014


The following commit has been merged in the master branch:
commit 2b60fd0dfceede2428913954b9a07ccfd808e8f2
Merge: f1ad7e5861b7b07ae17b77b1cf37db72217d0ee8 f7b12606b5de323a2bb5ca1696558efde8f25441
Author: Stephen Rothwell <sfr at canb.auug.org.au>
Date:   Wed Feb 19 12:46:59 2014 +1100

    Merge remote-tracking branch 'net-next/master'
    
    Conflicts:
    	drivers/net/bonding/bond_3ad.h
    	drivers/net/bonding/bond_main.c

diff --combined MAINTAINERS
index e8ff9eb,5a7b3ec..b499a82
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@@ -1845,6 -1845,12 +1845,12 @@@ L:	netdev at vger.kernel.or
  S:	Supported
  F:	drivers/net/ethernet/broadcom/b44.*
  
+ BROADCOM GENET ETHERNET DRIVER
+ M:	Florian Fainelli <f.fainelli at gmail.com>
+ L:	netdev at vger.kernel.org
+ S:	Supported
+ F:	drivers/net/ethernet/broadcom/genet/
+ 
  BROADCOM BNX2 GIGABIT ETHERNET DRIVER
  M:	Michael Chan <mchan at broadcom.com>
  L:	netdev at vger.kernel.org
@@@ -2367,7 -2373,7 +2373,7 @@@ F:	include/linux/cpufreq.
  
  CPU FREQUENCY DRIVERS - ARM BIG LITTLE
  M:	Viresh Kumar <viresh.kumar at linaro.org>
 -M:	Sudeep KarkadaNagesha <sudeep.karkadanagesha at arm.com>
 +M:	Sudeep Holla <sudeep.holla at arm.com>
  L:	cpufreq at vger.kernel.org
  L:	linux-pm at vger.kernel.org
  W:	http://www.arm.com/products/processors/technologies/biglittleprocessing.php
@@@ -2857,7 -2863,7 +2863,7 @@@ M:	Jani Nikula <jani.nikula at linux.intel
  L:	intel-gfx at lists.freedesktop.org
  L:	dri-devel at lists.freedesktop.org
  Q:	http://patchwork.freedesktop.org/project/intel-gfx/
 -T:	git git://people.freedesktop.org/~danvet/drm-intel
 +T:	git git://anongit.freedesktop.org/drm-intel
  S:	Supported
  F:	drivers/gpu/drm/i915/
  F:	include/drm/i915*
@@@ -3324,17 -3330,6 +3330,17 @@@ S:	Maintaine
  F:	include/linux/netfilter_bridge/
  F:	net/bridge/
  
 +ETHERNET PHY LIBRARY
 +M:	Florian Fainelli <f.fainelli at gmail.com>
 +L:	netdev at vger.kernel.org
 +S:	Maintained
 +F:	include/linux/phy.h
 +F:	include/linux/phy_fixed.h
 +F:	drivers/net/phy/
 +F:	Documentation/networking/phy.txt
 +F:	drivers/of/of_mdio.c
 +F:	drivers/of/of_net.c
 +
  EXT2 FILE SYSTEM
  M:	Jan Kara <jack at suse.cz>
  L:	linux-ext4 at vger.kernel.org
@@@ -3448,8 -3443,6 +3454,8 @@@ F:	include/uapi/scsi/fc
  
  FILE LOCKING (flock() and fcntl()/lockf())
  M:	Matthew Wilcox <matthew at wil.cx>
 +M:	Jeff Layton <jlayton at redhat.com>
 +M:	J. Bruce Fields <bfields at fieldses.org>
  L:	linux-fsdevel at vger.kernel.org
  S:	Maintained
  F:	include/linux/fcntl.h
diff --combined drivers/net/bonding/bond_3ad.c
index 6d20fbd,e9edd84..e362ff7
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@@ -768,11 -768,11 +768,11 @@@ static int ad_lacpdu_send(struct port *
  
  	lacpdu_header = (struct lacpdu_header *)skb_put(skb, length);
  
- 	memcpy(lacpdu_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN);
+ 	ether_addr_copy(lacpdu_header->hdr.h_dest, lacpdu_mcast_addr);
  	/* Note: source address is set to be the member's PERMANENT address,
  	 * because we use it to identify loopback lacpdus in receive.
  	 */
- 	memcpy(lacpdu_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN);
+ 	ether_addr_copy(lacpdu_header->hdr.h_source, slave->perm_hwaddr);
  	lacpdu_header->hdr.h_proto = PKT_TYPE_LACPDU;
  
  	lacpdu_header->lacpdu = port->lacpdu;
@@@ -810,11 -810,11 +810,11 @@@ static int ad_marker_send(struct port *
  
  	marker_header = (struct bond_marker_header *)skb_put(skb, length);
  
- 	memcpy(marker_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN);
+ 	ether_addr_copy(marker_header->hdr.h_dest, lacpdu_mcast_addr);
  	/* Note: source address is set to be the member's PERMANENT address,
  	 * because we use it to identify loopback MARKERs in receive.
  	 */
- 	memcpy(marker_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN);
+ 	ether_addr_copy(marker_header->hdr.h_source, slave->perm_hwaddr);
  	marker_header->hdr.h_proto = PKT_TYPE_LACPDU;
  
  	marker_header->marker = *marker;
@@@ -1079,7 -1079,8 +1079,8 @@@ static void ad_rx_machine(struct lacpd
  			/* detect loopback situation */
  			if (MAC_ADDRESS_EQUAL(&(lacpdu->actor_system),
  					      &(port->actor_system))) {
- 				pr_err("%s: An illegal loopback occurred on adapter (%s).\nCheck the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n",
+ 				pr_err("%s: An illegal loopback occurred on adapter (%s)\n"
+ 				       "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n",
  				       port->slave->bond->dev->name,
  				       port->slave->dev->name);
  				return;
@@@ -1796,6 -1797,8 +1797,6 @@@ void bond_3ad_initiate_agg_selection(st
  	BOND_AD_INFO(bond).agg_select_timer = timeout;
  }
  
 -static u16 aggregator_identifier;
 -
  /**
   * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures
   * @bond: bonding struct to work on
@@@ -1809,7 -1812,7 +1810,7 @@@ void bond_3ad_initialize(struct bondin
  	if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr),
  				bond->dev->dev_addr)) {
  
 -		aggregator_identifier = 0;
 +		BOND_AD_INFO(bond).aggregator_identifier = 0;
  
  		BOND_AD_INFO(bond).system.sys_priority = 0xFFFF;
  		BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
@@@ -1878,7 -1881,7 +1879,7 @@@ void bond_3ad_bind_slave(struct slave *
  		ad_initialize_agg(aggregator);
  
  		aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr);
 -		aggregator->aggregator_identifier = (++aggregator_identifier);
 +		aggregator->aggregator_identifier = ++BOND_AD_INFO(bond).aggregator_identifier;
  		aggregator->slave = slave;
  		aggregator->is_active = 0;
  		aggregator->num_of_ports = 0;
@@@ -1948,7 -1951,7 +1949,7 @@@ void bond_3ad_unbind_slave(struct slav
  			 * new aggregator
  			 */
  			if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) {
- 				pr_debug("Some port(s) related to LAG %d - replaceing with LAG %d\n",
+ 				pr_debug("Some port(s) related to LAG %d - replacing with LAG %d\n",
  					 aggregator->aggregator_identifier,
  					 new_aggregator->aggregator_identifier);
  
@@@ -2298,9 -2301,9 +2299,9 @@@ void bond_3ad_handle_link_change(struc
  		port->actor_oper_port_key = (port->actor_admin_port_key &=
  					     ~AD_SPEED_KEY_BITS);
  	}
- 	pr_debug("Port %d changed link status to %s",
- 		port->actor_port_number,
- 		(link == BOND_LINK_UP) ? "UP" : "DOWN");
+ 	pr_debug("Port %d changed link status to %s\n",
+ 		 port->actor_port_number,
+ 		 link == BOND_LINK_UP ? "UP" : "DOWN");
  	/* there is no need to reselect a new aggregator, just signal the
  	 * state machines to reinitialize
  	 */
diff --combined drivers/net/bonding/bond_3ad.h
index f4dd959,3b97fe48..bb03b1d
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@@ -28,7 -28,7 +28,7 @@@
  #include <linux/netdevice.h>
  #include <linux/if_ether.h>
  
- // General definitions
+ /* General definitions */
  #define PKT_TYPE_LACPDU         cpu_to_be16(ETH_P_SLOW)
  #define AD_TIMER_INTERVAL       100 /*msec*/
  
@@@ -47,54 -47,54 +47,54 @@@ enum 
  	BOND_AD_COUNT = 2,
  };
  
- // rx machine states(43.4.11 in the 802.3ad standard)
+ /* rx machine states(43.4.11 in the 802.3ad standard) */
  typedef enum {
  	AD_RX_DUMMY,
- 	AD_RX_INITIALIZE,     // rx Machine
- 	AD_RX_PORT_DISABLED,  // rx Machine
- 	AD_RX_LACP_DISABLED,  // rx Machine
- 	AD_RX_EXPIRED,	      // rx Machine
- 	AD_RX_DEFAULTED,      // rx Machine
- 	AD_RX_CURRENT	      // rx Machine
+ 	AD_RX_INITIALIZE,	/* rx Machine */
+ 	AD_RX_PORT_DISABLED,	/* rx Machine */
+ 	AD_RX_LACP_DISABLED,	/* rx Machine */
+ 	AD_RX_EXPIRED,		/* rx Machine */
+ 	AD_RX_DEFAULTED,	/* rx Machine */
+ 	AD_RX_CURRENT		/* rx Machine */
  } rx_states_t;
  
- // periodic machine states(43.4.12 in the 802.3ad standard)
+ /* periodic machine states(43.4.12 in the 802.3ad standard) */
  typedef enum {
  	AD_PERIODIC_DUMMY,
- 	AD_NO_PERIODIC,	       // periodic machine
- 	AD_FAST_PERIODIC,      // periodic machine
- 	AD_SLOW_PERIODIC,      // periodic machine
- 	AD_PERIODIC_TX	   // periodic machine
+ 	AD_NO_PERIODIC,		/* periodic machine */
+ 	AD_FAST_PERIODIC,	/* periodic machine */
+ 	AD_SLOW_PERIODIC,	/* periodic machine */
+ 	AD_PERIODIC_TX		/* periodic machine */
  } periodic_states_t;
  
- // mux machine states(43.4.13 in the 802.3ad standard)
+ /* mux machine states(43.4.13 in the 802.3ad standard) */
  typedef enum {
  	AD_MUX_DUMMY,
- 	AD_MUX_DETACHED,       // mux machine
- 	AD_MUX_WAITING,	       // mux machine
- 	AD_MUX_ATTACHED,       // mux machine
- 	AD_MUX_COLLECTING_DISTRIBUTING // mux machine
+ 	AD_MUX_DETACHED,	/* mux machine */
+ 	AD_MUX_WAITING,		/* mux machine */
+ 	AD_MUX_ATTACHED,	/* mux machine */
+ 	AD_MUX_COLLECTING_DISTRIBUTING	/* mux machine */
  } mux_states_t;
  
- // tx machine states(43.4.15 in the 802.3ad standard)
+ /* tx machine states(43.4.15 in the 802.3ad standard) */
  typedef enum {
  	AD_TX_DUMMY,
- 	AD_TRANSMIT	   // tx Machine
+ 	AD_TRANSMIT		/* tx Machine */
  } tx_states_t;
  
- // rx indication types
+ /* rx indication types */
  typedef enum {
- 	AD_TYPE_LACPDU = 1,    // type lacpdu
- 	AD_TYPE_MARKER	   // type marker
+ 	AD_TYPE_LACPDU = 1,	/* type lacpdu */
+ 	AD_TYPE_MARKER		/* type marker */
  } pdu_type_t;
  
- // rx marker indication types
+ /* rx marker indication types */
  typedef enum {
- 	AD_MARKER_INFORMATION_SUBTYPE = 1, // marker imformation subtype
- 	AD_MARKER_RESPONSE_SUBTYPE     // marker response subtype
+ 	AD_MARKER_INFORMATION_SUBTYPE = 1,	/* marker imformation subtype */
+ 	AD_MARKER_RESPONSE_SUBTYPE		/* marker response subtype */
  } bond_marker_subtype_t;
  
- // timers types(43.4.9 in the 802.3ad standard)
+ /* timers types(43.4.9 in the 802.3ad standard) */
  typedef enum {
  	AD_CURRENT_WHILE_TIMER,
  	AD_ACTOR_CHURN_TIMER,
@@@ -105,35 -105,35 +105,35 @@@
  
  #pragma pack(1)
  
- // Link Aggregation Control Protocol(LACP) data unit structure(43.4.2.2 in the 802.3ad standard)
+ /* Link Aggregation Control Protocol(LACP) data unit structure(43.4.2.2 in the 802.3ad standard) */
  typedef struct lacpdu {
- 	u8 subtype;		     // = LACP(= 0x01)
+ 	u8 subtype;		/* = LACP(= 0x01) */
  	u8 version_number;
- 	u8 tlv_type_actor_info;	      // = actor information(type/length/value)
- 	u8 actor_information_length; // = 20
+ 	u8 tlv_type_actor_info;	/* = actor information(type/length/value) */
+ 	u8 actor_information_length;	/* = 20 */
  	__be16 actor_system_priority;
  	struct mac_addr actor_system;
  	__be16 actor_key;
  	__be16 actor_port_priority;
  	__be16 actor_port;
  	u8 actor_state;
- 	u8 reserved_3_1[3];	     // = 0
- 	u8 tlv_type_partner_info;     // = partner information
- 	u8 partner_information_length;	 // = 20
+ 	u8 reserved_3_1[3];		/* = 0 */
+ 	u8 tlv_type_partner_info;	/* = partner information */
+ 	u8 partner_information_length;	/* = 20 */
  	__be16 partner_system_priority;
  	struct mac_addr partner_system;
  	__be16 partner_key;
  	__be16 partner_port_priority;
  	__be16 partner_port;
  	u8 partner_state;
- 	u8 reserved_3_2[3];	     // = 0
- 	u8 tlv_type_collector_info;	  // = collector information
- 	u8 collector_information_length; // = 16
+ 	u8 reserved_3_2[3];		/* = 0 */
+ 	u8 tlv_type_collector_info;	/* = collector information */
+ 	u8 collector_information_length;/* = 16 */
  	__be16 collector_max_delay;
  	u8 reserved_12[12];
- 	u8 tlv_type_terminator;	     // = terminator
- 	u8 terminator_length;	     // = 0
- 	u8 reserved_50[50];	     // = 0
+ 	u8 tlv_type_terminator;		/* = terminator */
+ 	u8 terminator_length;		/* = 0 */
+ 	u8 reserved_50[50];		/* = 0 */
  } __packed lacpdu_t;
  
  typedef struct lacpdu_header {
@@@ -141,20 -141,20 +141,20 @@@
  	struct lacpdu lacpdu;
  } __packed lacpdu_header_t;
  
- // Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard)
+ /* Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard) */
  typedef struct bond_marker {
- 	u8 subtype;		 //  = 0x02  (marker PDU)
- 	u8 version_number;	 //  = 0x01
- 	u8 tlv_type;		 //  = 0x01  (marker information)
- 	//  = 0x02  (marker response information)
- 	u8 marker_length;	 //  = 0x16
- 	u16 requester_port;	 //   The number assigned to the port by the requester
- 	struct mac_addr requester_system;      //   The requester's system id
- 	u32 requester_transaction_id;	//   The transaction id allocated by the requester,
- 	u16 pad;		 //  = 0
- 	u8 tlv_type_terminator;	     //  = 0x00
- 	u8 terminator_length;	     //  = 0x00
- 	u8 reserved_90[90];	     //  = 0
+ 	u8 subtype;		/* = 0x02  (marker PDU) */
+ 	u8 version_number;	/* = 0x01 */
+ 	u8 tlv_type;		/* = 0x01  (marker information) */
+ 	/* = 0x02  (marker response information) */
+ 	u8 marker_length;	/* = 0x16 */
+ 	u16 requester_port;	/* The number assigned to the port by the requester */
+ 	struct mac_addr requester_system;	/* The requester's system id */
+ 	u32 requester_transaction_id;		/* The transaction id allocated by the requester, */
+ 	u16 pad;		/* = 0 */
+ 	u8 tlv_type_terminator;	/* = 0x00 */
+ 	u8 terminator_length;	/* = 0x00 */
+ 	u8 reserved_90[90];	/* = 0 */
  } __packed bond_marker_t;
  
  typedef struct bond_marker_header {
@@@ -173,7 -173,7 +173,7 @@@ struct port
  #pragma pack(8)
  #endif
  
- // aggregator structure(43.4.5 in the 802.3ad standard)
+ /* aggregator structure(43.4.5 in the 802.3ad standard) */
  typedef struct aggregator {
  	struct mac_addr aggregator_mac_address;
  	u16 aggregator_identifier;
@@@ -183,12 -183,12 +183,12 @@@
  	struct mac_addr partner_system;
  	u16 partner_system_priority;
  	u16 partner_oper_aggregator_key;
- 	u16 receive_state;		// BOOLEAN
- 	u16 transmit_state;		// BOOLEAN
+ 	u16 receive_state;	/* BOOLEAN */
+ 	u16 transmit_state;	/* BOOLEAN */
  	struct port *lag_ports;
- 	// ****** PRIVATE PARAMETERS ******
- 	struct slave *slave;	    // pointer to the bond slave that this aggregator belongs to
- 	u16 is_active;	    // BOOLEAN. Indicates if this aggregator is active
+ 	/* ****** PRIVATE PARAMETERS ****** */
+ 	struct slave *slave;	/* pointer to the bond slave that this aggregator belongs to */
+ 	u16 is_active;		/* BOOLEAN. Indicates if this aggregator is active */
  	u16 num_of_ports;
  } aggregator_t;
  
@@@ -201,12 -201,12 +201,12 @@@ struct port_params 
  	u16 port_state;
  };
  
- // port structure(43.4.6 in the 802.3ad standard)
+ /* port structure(43.4.6 in the 802.3ad standard) */
  typedef struct port {
  	u16 actor_port_number;
  	u16 actor_port_priority;
- 	struct mac_addr actor_system;	       // This parameter is added here although it is not specified in the standard, just for simplification
- 	u16 actor_system_priority;	 // This parameter is added here although it is not specified in the standard, just for simplification
+ 	struct mac_addr actor_system;	/* This parameter is added here although it is not specified in the standard, just for simplification */
+ 	u16 actor_system_priority;	/* This parameter is added here although it is not specified in the standard, just for simplification */
  	u16 actor_port_aggregator_identifier;
  	bool ntt;
  	u16 actor_admin_port_key;
@@@ -219,24 -219,24 +219,24 @@@
  
  	bool is_enabled;
  
- 	// ****** PRIVATE PARAMETERS ******
- 	u16 sm_vars;	      // all state machines variables for this port
- 	rx_states_t sm_rx_state;	// state machine rx state
- 	u16 sm_rx_timer_counter;    // state machine rx timer counter
- 	periodic_states_t sm_periodic_state;// state machine periodic state
- 	u16 sm_periodic_timer_counter;	// state machine periodic timer counter
- 	mux_states_t sm_mux_state;	// state machine mux state
- 	u16 sm_mux_timer_counter;   // state machine mux timer counter
- 	tx_states_t sm_tx_state;	// state machine tx state
- 	u16 sm_tx_timer_counter;    // state machine tx timer counter(allways on - enter to transmit state 3 time per second)
- 	struct slave *slave;	    // pointer to the bond slave that this port belongs to
- 	struct aggregator *aggregator;	   // pointer to an aggregator that this port related to
- 	struct port *next_port_in_aggregator; // Next port on the linked list of the parent aggregator
- 	u32 transaction_id;	    // continuous number for identification of Marker PDU's;
- 	struct lacpdu lacpdu;	       // the lacpdu that will be sent for this port
+ 	/* ****** PRIVATE PARAMETERS ****** */
+ 	u16 sm_vars;		/* all state machines variables for this port */
+ 	rx_states_t sm_rx_state;	/* state machine rx state */
+ 	u16 sm_rx_timer_counter;	/* state machine rx timer counter */
+ 	periodic_states_t sm_periodic_state;	/* state machine periodic state */
+ 	u16 sm_periodic_timer_counter;	/* state machine periodic timer counter */
+ 	mux_states_t sm_mux_state;	/* state machine mux state */
+ 	u16 sm_mux_timer_counter;	/* state machine mux timer counter */
+ 	tx_states_t sm_tx_state;	/* state machine tx state */
+ 	u16 sm_tx_timer_counter;	/* state machine tx timer counter(allways on - enter to transmit state 3 time per second) */
+ 	struct slave *slave;		/* pointer to the bond slave that this port belongs to */
+ 	struct aggregator *aggregator;	/* pointer to an aggregator that this port related to */
+ 	struct port *next_port_in_aggregator;	/* Next port on the linked list of the parent aggregator */
+ 	u32 transaction_id;		/* continuous number for identification of Marker PDU's; */
+ 	struct lacpdu lacpdu;		/* the lacpdu that will be sent for this port */
  } port_t;
  
- // system structure
+ /* system structure */
  struct ad_system {
  	u16 sys_priority;
  	struct mac_addr sys_mac_addr;
@@@ -246,27 -246,25 +246,26 @@@
  #pragma pack()
  #endif
  
- // ================= AD Exported structures to the main bonding code ==================
+ /* ========== AD Exported structures to the main bonding code ========== */
  #define BOND_AD_INFO(bond)   ((bond)->ad_info)
  #define SLAVE_AD_INFO(slave) ((slave)->ad_info)
  
  struct ad_bond_info {
- 	struct ad_system system;	    /* 802.3ad system structure */
- 	u32 agg_select_timer;	    // Timer to select aggregator after all adapter's hand shakes
+ 	struct ad_system system;	/* 802.3ad system structure */
+ 	u32 agg_select_timer;		/* Timer to select aggregator after all adapter's hand shakes */
 +	u16 aggregator_identifier;
  };
  
  struct ad_slave_info {
- 	struct aggregator aggregator;	    // 802.3ad aggregator structure
- 	struct port port;		    // 802.3ad port structure
- 	spinlock_t state_machine_lock; /* mutex state machines vs.
- 					  incoming LACPDU */
+ 	struct aggregator aggregator;	/* 802.3ad aggregator structure */
+ 	struct port port;		/* 802.3ad port structure */
+ 	spinlock_t state_machine_lock;	/* mutex state machines vs. incoming LACPDU */
  	u16 id;
  };
  
- // ================= AD Exported functions to the main bonding code ==================
+ /* ========== AD Exported functions to the main bonding code ========== */
  void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution);
- void  bond_3ad_bind_slave(struct slave *slave);
+ void bond_3ad_bind_slave(struct slave *slave);
  void bond_3ad_unbind_slave(struct slave *slave);
  void bond_3ad_state_machine_handler(struct work_struct *);
  void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout);
@@@ -281,5 -279,5 +280,5 @@@ int bond_3ad_lacpdu_recv(const struct s
  			 struct slave *slave);
  int bond_3ad_set_carrier(struct bonding *bond);
  void bond_3ad_update_lacp_rate(struct bonding *bond);
- #endif //__BOND_3AD_H__
+ #endif /* __BOND_3AD_H__ */
  
diff --combined drivers/net/bonding/bond_main.c
index 1c6104d,ac4a1b8..afae7ca
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@@ -673,12 -673,12 +673,12 @@@ static void bond_do_fail_over_mac(struc
  		write_unlock_bh(&bond->curr_slave_lock);
  
  		if (old_active) {
- 			memcpy(tmp_mac, new_active->dev->dev_addr, ETH_ALEN);
+ 			ether_addr_copy(tmp_mac, new_active->dev->dev_addr);
  			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);
+ 			ether_addr_copy(saddr.sa_data, bond->dev->dev_addr);
  			saddr.sa_family = bond->dev->type;
  		}
  
@@@ -692,7 -692,7 +692,7 @@@
  		if (!old_active)
  			goto out;
  
- 		memcpy(saddr.sa_data, tmp_mac, ETH_ALEN);
+ 		ether_addr_copy(saddr.sa_data, tmp_mac);
  		saddr.sa_family = old_active->dev->type;
  
  		rv = dev_set_mac_address(old_active->dev, &saddr);
@@@ -798,11 -798,11 +798,11 @@@ void bond_change_active_slave(struct bo
  		return;
  
  	if (new_active) {
- 		new_active->jiffies = jiffies;
+ 		new_active->last_link_up = jiffies;
  
  		if (new_active->link == BOND_LINK_BACK) {
  			if (USES_PRIMARY(bond->params.mode)) {
- 				pr_info("%s: making interface %s the new active one %d ms earlier.\n",
+ 				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);
  			}
@@@ -817,7 -817,7 +817,7 @@@
  				bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP);
  		} else {
  			if (USES_PRIMARY(bond->params.mode)) {
- 				pr_info("%s: making interface %s the new active one.\n",
+ 				pr_info("%s: making interface %s the new active one\n",
  					bond->dev->name, new_active->dev->name);
  			}
  		}
@@@ -906,7 -906,7 +906,7 @@@ void bond_select_active_slave(struct bo
  			pr_info("%s: first active interface up!\n",
  				bond->dev->name);
  		} else {
- 			pr_info("%s: now running without any active interface !\n",
+ 			pr_info("%s: now running without any active interface!\n",
  				bond->dev->name);
  		}
  	}
@@@ -1115,9 -1115,6 +1115,6 @@@ static rx_handler_result_t bond_handle_
  	slave = bond_slave_get_rcu(skb->dev);
  	bond = slave->bond;
  
- 	if (bond->params.arp_interval)
- 		slave->dev->last_rx = jiffies;
- 
  	recv_probe = ACCESS_ONCE(bond->recv_probe);
  	if (recv_probe) {
  		ret = recv_probe(skb, bond, slave);
@@@ -1183,13 -1180,13 +1180,13 @@@ int bond_enslave(struct net_device *bon
  	if (!bond->params.use_carrier &&
  	    slave_dev->ethtool_ops->get_link == NULL &&
  	    slave_ops->ndo_do_ioctl == NULL) {
- 		pr_warning("%s: Warning: no link monitoring support for %s\n",
- 			   bond_dev->name, slave_dev->name);
+ 		pr_warn("%s: Warning: no link monitoring support for %s\n",
+ 			bond_dev->name, slave_dev->name);
  	}
  
  	/* already enslaved */
  	if (slave_dev->flags & IFF_SLAVE) {
- 		pr_debug("Error, Device was already enslaved\n");
+ 		pr_debug("Error: Device was already enslaved\n");
  		return -EBUSY;
  	}
  
@@@ -1202,9 -1199,9 +1199,9 @@@
  			       bond_dev->name, slave_dev->name, bond_dev->name);
  			return -EPERM;
  		} else {
- 			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);
+ 			pr_warn("%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);
  		}
  	} else {
  		pr_debug("%s: ! NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
@@@ -1217,7 -1214,7 +1214,7 @@@
  	 * enslaving it; the old ifenslave will not.
  	 */
  	if ((slave_dev->flags & IFF_UP)) {
- 		pr_err("%s is up. This may be due to an out of date ifenslave.\n",
+ 		pr_err("%s is up - this may be due to an out of date ifenslave\n",
  		       slave_dev->name);
  		res = -EPERM;
  		goto err_undo_flags;
@@@ -1261,24 -1258,23 +1258,23 @@@
  						 bond_dev);
  		}
  	} else if (bond_dev->type != slave_dev->type) {
- 		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);
+ 		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;
  	}
  
  	if (slave_ops->ndo_set_mac_address == NULL) {
  		if (!bond_has_slaves(bond)) {
- 			pr_warn("%s: Warning: The first slave device specified does not support setting the MAC address.\n",
+ 			pr_warn("%s: Warning: The first slave device specified does not support setting the MAC address\n",
  				bond_dev->name);
  			if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
  				bond->params.fail_over_mac = BOND_FOM_ACTIVE;
- 				pr_warn("%s: Setting fail_over_mac to active for active-backup mode.\n",
+ 				pr_warn("%s: Setting fail_over_mac to active for active-backup mode\n",
  					bond_dev->name);
  			}
  		} else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) {
- 			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",
+ 			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);
  			res = -EOPNOTSUPP;
  			goto err_undo_flags;
@@@ -1317,7 -1313,7 +1313,7 @@@
  	 * 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);
+ 	ether_addr_copy(new_slave->perm_hwaddr, slave_dev->dev_addr);
  
  	if (!bond->params.fail_over_mac ||
  	    bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
@@@ -1401,10 -1397,10 +1397,10 @@@
  
  	bond_update_speed_duplex(new_slave);
  
- 	new_slave->last_arp_rx = jiffies -
+ 	new_slave->last_rx = jiffies -
  		(msecs_to_jiffies(bond->params.arp_interval) + 1);
  	for (i = 0; i < BOND_MAX_ARP_TARGETS; i++)
- 		new_slave->target_last_arp_rx[i] = new_slave->last_arp_rx;
+ 		new_slave->target_last_arp_rx[i] = new_slave->last_rx;
  
  	if (bond->params.miimon && !bond->params.use_carrier) {
  		link_reporting = bond_check_dev_link(bond, slave_dev, 1);
@@@ -1419,12 -1415,12 +1415,12 @@@
  			 * supported); thus, we don't need to change
  			 * the messages for netif_carrier.
  			 */
- 			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",
- 			       bond_dev->name, slave_dev->name);
+ 			pr_warn("%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",
+ 				bond_dev->name, slave_dev->name);
  		} else if (link_reporting == -1) {
  			/* unable get link status using mii/ethtool */
- 			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);
+ 			pr_warn("%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);
  		}
  	}
  
@@@ -1448,10 -1444,10 +1444,10 @@@
  	}
  
  	if (new_slave->link != BOND_LINK_DOWN)
- 		new_slave->jiffies = jiffies;
+ 		new_slave->last_link_up = jiffies;
  	pr_debug("Initial state of slave_dev is BOND_LINK_%s\n",
- 		new_slave->link == BOND_LINK_DOWN ? "DOWN" :
- 			(new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
+ 		 new_slave->link == BOND_LINK_DOWN ? "DOWN" :
+ 		 (new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
  
  	if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
  		/* if there is a primary slave, remember it */
@@@ -1510,9 -1506,8 +1506,8 @@@
  	slave_dev->npinfo = bond->dev->npinfo;
  	if (slave_dev->npinfo) {
  		if (slave_enable_netpoll(new_slave)) {
- 			pr_info("Error, %s: master_dev is using netpoll, "
- 				 "but new slave device does not support netpoll.\n",
- 				 bond_dev->name);
+ 			pr_info("Error, %s: master_dev is using netpoll, but new slave device does not support netpoll\n",
+ 				bond_dev->name);
  			res = -EBUSY;
  			goto err_detach;
  		}
@@@ -1543,17 -1538,15 +1538,17 @@@
  	bond_set_carrier(bond);
  
  	if (USES_PRIMARY(bond->params.mode)) {
 +		block_netpoll_tx();
  		write_lock_bh(&bond->curr_slave_lock);
  		bond_select_active_slave(bond);
  		write_unlock_bh(&bond->curr_slave_lock);
 +		unblock_netpoll_tx();
  	}
  
- 	pr_info("%s: enslaving %s as a%s interface with a%s link.\n",
+ 	pr_info("%s: Enslaving %s as %s interface with %s link\n",
  		bond_dev->name, slave_dev->name,
- 		bond_is_active_slave(new_slave) ? "n active" : " backup",
- 		new_slave->link != BOND_LINK_DOWN ? "n up" : " down");
+ 		bond_is_active_slave(new_slave) ? "an active" : "a backup",
+ 		new_slave->link != BOND_LINK_DOWN ? "an up" : "a down");
  
  	/* enslave is successful */
  	return 0;
@@@ -1573,12 -1566,10 +1568,12 @@@ err_detach
  	if (bond->primary_slave == new_slave)
  		bond->primary_slave = NULL;
  	if (bond->curr_active_slave == new_slave) {
 +		block_netpoll_tx();
  		write_lock_bh(&bond->curr_slave_lock);
  		bond_change_active_slave(bond, NULL);
  		bond_select_active_slave(bond);
  		write_unlock_bh(&bond->curr_slave_lock);
 +		unblock_netpoll_tx();
  	}
  	slave_disable_netpoll(new_slave);
  
@@@ -1593,7 -1584,7 +1588,7 @@@ err_restore_mac
  		 * MAC if this slave's MAC is in use by the bond, or at
  		 * least print a warning.
  		 */
- 		memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
+ 		ether_addr_copy(addr.sa_data, new_slave->perm_hwaddr);
  		addr.sa_family = slave_dev->type;
  		dev_set_mac_address(slave_dev, &addr);
  	}
@@@ -1638,7 -1629,7 +1633,7 @@@ static int __bond_release_one(struct ne
  	/* slave is not a slave or master is not master of this slave */
  	if (!(slave_dev->flags & IFF_SLAVE) ||
  	    !netdev_has_upper_dev(slave_dev, bond_dev)) {
- 		pr_err("%s: Error: cannot release %s.\n",
+ 		pr_err("%s: Error: cannot release %s\n",
  		       bond_dev->name, slave_dev->name);
  		return -EINVAL;
  	}
@@@ -1672,7 -1663,7 +1667,7 @@@
  
  	write_unlock_bh(&bond->lock);
  
- 	pr_info("%s: releasing %s interface %s\n",
+ 	pr_info("%s: Releasing %s interface %s\n",
  		bond_dev->name,
  		bond_is_active_slave(slave) ? "active" : "backup",
  		slave_dev->name);
@@@ -1685,10 -1676,10 +1680,10 @@@
  		     bond->params.mode != BOND_MODE_ACTIVEBACKUP)) {
  		if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) &&
  		    bond_has_slaves(bond))
- 			pr_warn("%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);
+ 			pr_warn("%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);
  	}
  
  	if (bond->primary_slave == slave)
@@@ -1729,10 -1720,10 +1724,10 @@@
  		eth_hw_addr_random(bond_dev);
  
  		if (vlan_uses_dev(bond_dev)) {
- 			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);
+ 			pr_warn("%s: Warning: clearing HW address of %s while it still has VLANs\n",
+ 				bond_dev->name, bond_dev->name);
+ 			pr_warn("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs\n",
+ 				bond_dev->name);
  		}
  	}
  
@@@ -1747,7 -1738,7 +1742,7 @@@
  	bond_compute_features(bond);
  	if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
  	    (old_features & NETIF_F_VLAN_CHALLENGED))
- 		pr_info("%s: last VLAN challenged slave %s left bond %s. VLAN blocking is removed\n",
+ 		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);
  
  	/* must do this from outside any spinlocks */
@@@ -1782,7 -1773,7 +1777,7 @@@
  	if (bond->params.fail_over_mac != BOND_FOM_ACTIVE ||
  	    bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
  		/* restore original ("permanent") mac address */
- 		memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
+ 		ether_addr_copy(addr.sa_data, slave->perm_hwaddr);
  		addr.sa_family = slave_dev->type;
  		dev_set_mac_address(slave_dev, &addr);
  	}
@@@ -1815,7 -1806,7 +1810,7 @@@ static int  bond_release_and_destroy(st
  	ret = bond_release(bond_dev, slave_dev);
  	if (ret == 0 && !bond_has_slaves(bond)) {
  		bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
- 		pr_info("%s: destroying bond %s.\n",
+ 		pr_info("%s: Destroying bond %s\n",
  			bond_dev->name, bond_dev->name);
  		unregister_netdevice(bond_dev);
  	}
@@@ -1884,7 -1875,7 +1879,7 @@@ static int bond_miimon_inspect(struct b
  			slave->link = BOND_LINK_FAIL;
  			slave->delay = bond->params.downdelay;
  			if (slave->delay) {
- 				pr_info("%s: link status down for %sinterface %s, disabling it in %d ms.\n",
+ 				pr_info("%s: link status down for %sinterface %s, disabling it in %d ms\n",
  					bond->dev->name,
  					(bond->params.mode ==
  					 BOND_MODE_ACTIVEBACKUP) ?
@@@ -1900,8 -1891,8 +1895,8 @@@
  				 * recovered before downdelay expired
  				 */
  				slave->link = BOND_LINK_UP;
- 				slave->jiffies = jiffies;
- 				pr_info("%s: link status up again after %d ms for interface %s.\n",
+ 				slave->last_link_up = jiffies;
+ 				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,
@@@ -1926,7 -1917,7 +1921,7 @@@
  			slave->delay = bond->params.updelay;
  
  			if (slave->delay) {
- 				pr_info("%s: link status up for interface %s, enabling it in %d ms.\n",
+ 				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 *
@@@ -1936,7 -1927,7 +1931,7 @@@
  		case BOND_LINK_BACK:
  			if (!link_state) {
  				slave->link = BOND_LINK_DOWN;
- 				pr_info("%s: link status down again after %d ms for interface %s.\n",
+ 				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,
@@@ -1975,7 -1966,7 +1970,7 @@@ static void bond_miimon_commit(struct b
  
  		case BOND_LINK_UP:
  			slave->link = BOND_LINK_UP;
- 			slave->jiffies = jiffies;
+ 			slave->last_link_up = jiffies;
  
  			if (bond->params.mode == BOND_MODE_8023AD) {
  				/* prevent it from being the active one */
@@@ -1988,7 -1979,7 +1983,7 @@@
  				bond_set_backup_slave(slave);
  			}
  
- 			pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n",
+ 			pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex\n",
  				bond->dev->name, slave->dev->name,
  				slave->speed == SPEED_UNKNOWN ? 0 : slave->speed,
  				slave->duplex ? "full" : "half");
@@@ -2136,8 -2127,8 +2131,8 @@@ static void bond_arp_send(struct net_de
  {
  	struct sk_buff *skb;
  
- 	pr_debug("arp %d on slave %s: dst %pI4 src %pI4 vid %d\n", arp_op,
- 		 slave_dev->name, &dest_ip, &src_ip, vlan_id);
+ 	pr_debug("arp %d on slave %s: dst %pI4 src %pI4 vid %d\n",
+ 		 arp_op, slave_dev->name, &dest_ip, &src_ip, vlan_id);
  
  	skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip,
  			 NULL, slave_dev->dev_addr, NULL);
@@@ -2251,7 -2242,7 +2246,7 @@@ static void bond_validate_arp(struct bo
  		pr_debug("bva: sip %pI4 not found in targets\n", &sip);
  		return;
  	}
- 	slave->last_arp_rx = jiffies;
+ 	slave->last_rx = jiffies;
  	slave->target_last_arp_rx[i] = jiffies;
  }
  
@@@ -2261,15 -2252,16 +2256,16 @@@ int bond_arp_rcv(const struct sk_buff *
  	struct arphdr *arp = (struct arphdr *)skb->data;
  	unsigned char *arp_ptr;
  	__be32 sip, tip;
- 	int alen;
+ 	int alen, is_arp = skb->protocol == __cpu_to_be16(ETH_P_ARP);
  
- 	if (skb->protocol != __cpu_to_be16(ETH_P_ARP))
+ 	if (!slave_do_arp_validate(bond, slave)) {
+ 		if ((slave_do_arp_validate_only(bond, slave) && is_arp) ||
+ 		    !slave_do_arp_validate_only(bond, slave))
+ 			slave->last_rx = jiffies;
  		return RX_HANDLER_ANOTHER;
- 
- 	read_lock(&bond->lock);
- 
- 	if (!slave_do_arp_validate(bond, slave))
- 		goto out_unlock;
+ 	} else if (!is_arp) {
+ 		return RX_HANDLER_ANOTHER;
+ 	}
  
  	alen = arp_hdr_len(bond->dev);
  
@@@ -2320,11 -2312,10 +2316,10 @@@
  		bond_validate_arp(bond, slave, sip, tip);
  	else if (bond->curr_active_slave &&
  		 time_after(slave_last_rx(bond, bond->curr_active_slave),
- 			    bond->curr_active_slave->jiffies))
+ 			    bond->curr_active_slave->last_link_up))
  		bond_validate_arp(bond, slave, tip, sip);
  
  out_unlock:
- 	read_unlock(&bond->lock);
  	if (arp != (struct arphdr *)skb->data)
  		kfree(arp);
  	return RX_HANDLER_ANOTHER;
@@@ -2367,9 -2358,9 +2362,9 @@@ static void bond_loadbalance_arp_mon(st
  	oldcurrent = ACCESS_ONCE(bond->curr_active_slave);
  	/* 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.
+ 	 * the picture unless it is null. also, slave->last_link_up 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
  	 */
@@@ -2378,7 -2369,7 +2373,7 @@@
  
  		if (slave->link != BOND_LINK_UP) {
  			if (bond_time_in_interval(bond, trans_start, 1) &&
- 			    bond_time_in_interval(bond, slave->dev->last_rx, 1)) {
+ 			    bond_time_in_interval(bond, slave->last_rx, 1)) {
  
  				slave->link  = BOND_LINK_UP;
  				slave_state_changed = 1;
@@@ -2389,7 -2380,7 +2384,7 @@@
  				 * is closed.
  				 */
  				if (!oldcurrent) {
- 					pr_info("%s: link status definitely up for interface %s, ",
+ 					pr_info("%s: link status definitely up for interface %s\n",
  						bond->dev->name,
  						slave->dev->name);
  					do_failover = 1;
@@@ -2407,7 -2398,7 +2402,7 @@@
  			 * if we don't know our ip yet
  			 */
  			if (!bond_time_in_interval(bond, trans_start, 2) ||
- 			    !bond_time_in_interval(bond, slave->dev->last_rx, 2)) {
+ 			    !bond_time_in_interval(bond, slave->last_rx, 2)) {
  
  				slave->link  = BOND_LINK_DOWN;
  				slave_state_changed = 1;
@@@ -2415,9 -2406,8 +2410,8 @@@
  				if (slave->link_failure_count < UINT_MAX)
  					slave->link_failure_count++;
  
- 				pr_info("%s: interface %s is now down.\n",
- 					bond->dev->name,
- 					slave->dev->name);
+ 				pr_info("%s: interface %s is now down\n",
+ 					bond->dev->name, slave->dev->name);
  
  				if (slave == oldcurrent)
  					do_failover = 1;
@@@ -2496,7 -2486,7 +2490,7 @@@ static int bond_ab_arp_inspect(struct b
  		 * active.  This avoids bouncing, as the last receive
  		 * times need a full ARP monitor cycle to be updated.
  		 */
- 		if (bond_time_in_interval(bond, slave->jiffies, 2))
+ 		if (bond_time_in_interval(bond, slave->last_link_up, 2))
  			continue;
  
  		/*
@@@ -2566,7 -2556,7 +2560,7 @@@ static void bond_ab_arp_commit(struct b
  					bond->current_arp_slave = NULL;
  				}
  
- 				pr_info("%s: link status definitely up for interface %s.\n",
+ 				pr_info("%s: link status definitely up for interface %s\n",
  					bond->dev->name, slave->dev->name);
  
  				if (!bond->curr_active_slave ||
@@@ -2679,7 -2669,7 +2673,7 @@@ static bool bond_ab_arp_probe(struct bo
  
  			bond_set_slave_inactive_flags(slave);
  
- 			pr_info("%s: backup interface %s is now down.\n",
+ 			pr_info("%s: backup interface %s is now down\n",
  				bond->dev->name, slave->dev->name);
  		}
  		if (slave == curr_arp_slave)
@@@ -2697,7 -2687,7 +2691,7 @@@
  	new_slave->link = BOND_LINK_BACK;
  	bond_set_slave_active_flags(new_slave);
  	bond_arp_send_all(bond, new_slave);
- 	new_slave->jiffies = jiffies;
+ 	new_slave->last_link_up = jiffies;
  	rcu_assign_pointer(bond->current_arp_slave, new_slave);
  	rtnl_unlock();
  
@@@ -2865,15 -2855,12 +2859,15 @@@ static int bond_slave_netdev_event(unsi
  			break;
  		}
  
- 		pr_info("%s: Primary slave changed to %s, reselecting active slave.\n",
- 			bond->dev->name, bond->primary_slave ? slave_dev->name :
- 							       "none");
+ 		pr_info("%s: Primary slave changed to %s, reselecting active slave\n",
+ 			bond->dev->name,
+ 			bond->primary_slave ? slave_dev->name : "none");
 +
 +		block_netpoll_tx();
  		write_lock_bh(&bond->curr_slave_lock);
  		bond_select_active_slave(bond);
  		write_unlock_bh(&bond->curr_slave_lock);
 +		unblock_netpoll_tx();
  		break;
  	case NETDEV_FEAT_CHANGE:
  		bond_compute_features(bond);
@@@ -2903,8 -2890,7 +2897,7 @@@ static int bond_netdev_event(struct not
  	struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
  
  	pr_debug("event_dev: %s, event: %lx\n",
- 		 event_dev ? event_dev->name : "None",
- 		 event);
+ 		 event_dev ? event_dev->name : "None", event);
  
  	if (!(event_dev->priv_flags & IFF_BONDING))
  		return NOTIFY_DONE;
@@@ -3071,8 -3057,7 +3064,7 @@@ static int bond_open(struct net_device 
  
  	if (bond->params.arp_interval) {  /* arp interval, in milliseconds. */
  		queue_delayed_work(bond->wq, &bond->arp_work, 0);
- 		if (bond->params.arp_validate)
- 			bond->recv_probe = bond_arp_rcv;
+ 		bond->recv_probe = bond_arp_rcv;
  	}
  
  	if (bond->params.mode == BOND_MODE_8023AD) {
@@@ -3359,8 -3344,8 +3351,8 @@@ static int bond_change_mtu(struct net_d
  	struct list_head *iter;
  	int res = 0;
  
- 	pr_debug("bond=%p, name=%s, new_mtu=%d\n", bond,
- 		 (bond_dev ? bond_dev->name : "None"), new_mtu);
+ 	pr_debug("bond=%p, name=%s, new_mtu=%d\n",
+ 		 bond, bond_dev ? bond_dev->name : "None", new_mtu);
  
  	/* Can't hold bond->lock with bh disabled here since
  	 * some base drivers panic. On the other hand we can't
@@@ -3379,8 -3364,7 +3371,7 @@@
  
  	bond_for_each_slave(bond, slave, iter) {
  		pr_debug("s %p c_m %p\n",
- 			 slave,
- 			 slave->dev->netdev_ops->ndo_change_mtu);
+ 			 slave, slave->dev->netdev_ops->ndo_change_mtu);
  
  		res = dev_set_mtu(slave->dev, new_mtu);
  
@@@ -3468,15 -3452,7 +3459,7 @@@ static int bond_set_mac_address(struct 
  	 */
  
  	bond_for_each_slave(bond, slave, iter) {
- 		const struct net_device_ops *slave_ops = slave->dev->netdev_ops;
  		pr_debug("slave %p %s\n", slave, slave->dev->name);
- 
- 		if (slave_ops->ndo_set_mac_address == NULL) {
- 			res = -EOPNOTSUPP;
- 			pr_debug("EOPNOTSUPP %s\n", slave->dev->name);
- 			goto unwind;
- 		}
- 
  		res = dev_set_mac_address(slave->dev, addr);
  		if (res) {
  			/* TODO: consider downing the slave
@@@ -3707,7 -3683,7 +3690,7 @@@ static inline int bond_slave_override(s
  
  
  static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb,
 -			     void *accel_priv)
 +			     void *accel_priv, select_queue_fallback_t fallback)
  {
  	/*
  	 * This helper function exists to help dev_pick_tx get the correct
@@@ -3942,7 -3918,7 +3925,7 @@@ static void bond_uninit(struct net_devi
  	/* Release the bonded slaves */
  	bond_for_each_slave(bond, slave, iter)
  		__bond_release_one(bond_dev, slave->dev, true);
- 	pr_info("%s: released all slaves\n", bond_dev->name);
+ 	pr_info("%s: Released all slaves\n", bond_dev->name);
  
  	list_del(&bond->bond_list);
  
@@@ -4020,7 -3996,7 +4003,7 @@@ static int bond_check_params(struct bon
  		if ((bond_mode != BOND_MODE_XOR) &&
  		    (bond_mode != BOND_MODE_8023AD)) {
  			pr_info("xmit_hash_policy param is irrelevant in mode %s\n",
- 			       bond_mode_name(bond_mode));
+ 				bond_mode_name(bond_mode));
  		} else {
  			bond_opt_initstr(&newval, xmit_hash_policy);
  			valptr = bond_opt_parse(bond_opt_get(BOND_OPT_XMIT_HASH),
@@@ -4061,74 -4037,71 +4044,71 @@@
  		}
  		params->ad_select = valptr->value;
  		if (bond_mode != BOND_MODE_8023AD)
- 			pr_warning("ad_select param only affects 802.3ad mode\n");
+ 			pr_warn("ad_select param only affects 802.3ad mode\n");
  	} else {
  		params->ad_select = BOND_AD_STABLE;
  	}
  
  	if (max_bonds < 0) {
- 		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);
+ 		pr_warn("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);
  		max_bonds = BOND_DEFAULT_MAX_BONDS;
  	}
  
  	if (miimon < 0) {
- 		pr_warning("Warning: miimon module parameter (%d), not in range 0-%d, so it was reset to 0\n",
- 			   miimon, INT_MAX);
+ 		pr_warn("Warning: miimon module parameter (%d), not in range 0-%d, so it was reset to 0\n",
+ 			miimon, INT_MAX);
  		miimon = 0;
  	}
  
  	if (updelay < 0) {
- 		pr_warning("Warning: updelay module parameter (%d), not in range 0-%d, so it was reset to 0\n",
- 			   updelay, INT_MAX);
+ 		pr_warn("Warning: updelay module parameter (%d), not in range 0-%d, so it was reset to 0\n",
+ 			updelay, INT_MAX);
  		updelay = 0;
  	}
  
  	if (downdelay < 0) {
- 		pr_warning("Warning: downdelay module parameter (%d), not in range 0-%d, so it was reset to 0\n",
- 			   downdelay, INT_MAX);
+ 		pr_warn("Warning: downdelay module parameter (%d), not in range 0-%d, so it was reset to 0\n",
+ 			downdelay, INT_MAX);
  		downdelay = 0;
  	}
  
  	if ((use_carrier != 0) && (use_carrier != 1)) {
- 		pr_warning("Warning: use_carrier module parameter (%d), not of valid value (0/1), so it was set to 1\n",
- 			   use_carrier);
+ 		pr_warn("Warning: use_carrier module parameter (%d), not of valid value (0/1), so it was set to 1\n",
+ 			use_carrier);
  		use_carrier = 1;
  	}
  
  	if (num_peer_notif < 0 || num_peer_notif > 255) {
- 		pr_warning("Warning: num_grat_arp/num_unsol_na (%d) not in range 0-255 so it was reset to 1\n",
- 			   num_peer_notif);
+ 		pr_warn("Warning: num_grat_arp/num_unsol_na (%d) not in range 0-255 so it was reset to 1\n",
+ 			num_peer_notif);
  		num_peer_notif = 1;
  	}
  
  	/* reset values for 802.3ad/TLB/ALB */
  	if (BOND_NO_USES_ARP(bond_mode)) {
  		if (!miimon) {
- 			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");
- 			pr_warning("Forcing miimon to 100msec\n");
+ 			pr_warn("Warning: miimon must be specified, otherwise bonding will not detect link failure, speed and duplex which are essential for 802.3ad operation\n");
+ 			pr_warn("Forcing miimon to 100msec\n");
  			miimon = BOND_DEFAULT_MIIMON;
  		}
  	}
  
  	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);
+ 		pr_warn("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;
  	}
  
  	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);
+ 		pr_warn("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;
  	}
  
  	if (resend_igmp < 0 || resend_igmp > 255) {
- 		pr_warning("Warning: resend_igmp (%d) should be between "
- 			   "0 and 255, resetting to %d\n",
- 			   resend_igmp, BOND_DEFAULT_RESEND_IGMP);
+ 		pr_warn("Warning: resend_igmp (%d) should be between 0 and 255, resetting to %d\n",
+ 			resend_igmp, BOND_DEFAULT_RESEND_IGMP);
  		resend_igmp = BOND_DEFAULT_RESEND_IGMP;
  	}
  
@@@ -4149,37 -4122,36 +4129,36 @@@
  			/* just warn the user the up/down delay will have
  			 * no effect since miimon is zero...
  			 */
- 			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);
+ 			pr_warn("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);
  		}
  	} else {
  		/* don't allow arp monitoring */
  		if (arp_interval) {
- 			pr_warning("Warning: miimon (%d) and arp_interval (%d) can't be used simultaneously, disabling ARP monitoring\n",
- 				   miimon, arp_interval);
+ 			pr_warn("Warning: miimon (%d) and arp_interval (%d) can't be used simultaneously, disabling ARP monitoring\n",
+ 				miimon, arp_interval);
  			arp_interval = 0;
  		}
  
  		if ((updelay % miimon) != 0) {
- 			pr_warning("Warning: updelay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n",
- 				   updelay, miimon,
- 				   (updelay / miimon) * miimon);
+ 			pr_warn("Warning: updelay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n",
+ 				updelay, miimon, (updelay / miimon) * miimon);
  		}
  
  		updelay /= miimon;
  
  		if ((downdelay % miimon) != 0) {
- 			pr_warning("Warning: downdelay (%d) is not a multiple of miimon (%d), downdelay rounded to %d ms\n",
- 				   downdelay, miimon,
- 				   (downdelay / miimon) * miimon);
+ 			pr_warn("Warning: downdelay (%d) is not a multiple of miimon (%d), downdelay rounded to %d ms\n",
+ 				downdelay, miimon,
+ 				(downdelay / miimon) * miimon);
  		}
  
  		downdelay /= miimon;
  	}
  
  	if (arp_interval < 0) {
- 		pr_warning("Warning: arp_interval module parameter (%d) , not in range 0-%d, so it was reset to 0\n",
- 			   arp_interval, INT_MAX);
+ 		pr_warn("Warning: arp_interval module parameter (%d), not in range 0-%d, so it was reset to 0\n",
+ 			arp_interval, INT_MAX);
  		arp_interval = 0;
  	}
  
@@@ -4190,30 -4162,26 +4169,26 @@@
  		__be32 ip;
  		if (!in4_pton(arp_ip_target[i], -1, (u8 *)&ip, -1, NULL) ||
  		    IS_IP_TARGET_UNUSABLE_ADDRESS(ip)) {
- 			pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n",
- 				   arp_ip_target[i]);
+ 			pr_warn("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n",
+ 				arp_ip_target[i]);
  			arp_interval = 0;
  		} else {
  			if (bond_get_targets_ip(arp_target, ip) == -1)
  				arp_target[arp_ip_count++] = ip;
  			else
- 				pr_warning("Warning: duplicate address %pI4 in arp_ip_target, skipping\n",
- 					   &ip);
+ 				pr_warn("Warning: duplicate address %pI4 in arp_ip_target, skipping\n",
+ 					&ip);
  		}
  	}
  
  	if (arp_interval && !arp_ip_count) {
  		/* don't allow arping if no arp_ip_target given... */
- 		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);
+ 		pr_warn("Warning: arp_interval module parameter (%d) specified without providing an arp_ip_target parameter, arp_interval was reset to 0\n",
+ 			arp_interval);
  		arp_interval = 0;
  	}
  
  	if (arp_validate) {
- 		if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
- 			pr_err("arp_validate only supported in active-backup mode\n");
- 			return -EINVAL;
- 		}
  		if (!arp_interval) {
  			pr_err("arp_validate requires arp_interval\n");
  			return -EINVAL;
@@@ -4255,23 -4223,23 +4230,23 @@@
  			arp_interval, valptr->string, arp_ip_count);
  
  		for (i = 0; i < arp_ip_count; i++)
- 			pr_info(" %s", arp_ip_target[i]);
+ 			pr_cont(" %s", arp_ip_target[i]);
  
- 		pr_info("\n");
+ 		pr_cont("\n");
  
  	} else if (max_bonds) {
  		/* miimon and arp_interval not set, we need one so things
  		 * work as expected, see bonding.txt for details
  		 */
- 		pr_debug("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");
+ 		pr_debug("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");
  	}
  
  	if (primary && !USES_PRIMARY(bond_mode)) {
  		/* currently, using a primary only makes sense
  		 * in active backup, TLB or ALB modes
  		 */
- 		pr_warning("Warning: %s primary device specified but has no effect in %s mode\n",
- 			   primary, bond_mode_name(bond_mode));
+ 		pr_warn("Warning: %s primary device specified but has no effect in %s mode\n",
+ 			primary, bond_mode_name(bond_mode));
  		primary = NULL;
  	}
  
@@@ -4300,14 -4268,14 +4275,14 @@@
  		}
  		fail_over_mac_value = valptr->value;
  		if (bond_mode != BOND_MODE_ACTIVEBACKUP)
- 			pr_warning("Warning: fail_over_mac only affects active-backup mode.\n");
+ 			pr_warn("Warning: fail_over_mac only affects active-backup mode\n");
  	} else {
  		fail_over_mac_value = BOND_FOM_NONE;
  	}
  
  	if (lp_interval == 0) {
- 		pr_warning("Warning: ip_interval must be between 1 and %d, so it was reset to %d\n",
- 			   INT_MAX, BOND_ALB_DEFAULT_LP_INTERVAL);
+ 		pr_warn("Warning: ip_interval must be between 1 and %d, so it was reset to %d\n",
+ 			INT_MAX, BOND_ALB_DEFAULT_LP_INTERVAL);
  		lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL;
  	}
  
diff --combined drivers/net/bonding/bond_options.c
index c378784,5f997b9..23f3655
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@@ -14,7 -14,7 +14,7 @@@
  #include <linux/errno.h>
  #include <linux/if.h>
  #include <linux/netdevice.h>
 -#include <linux/rwlock.h>
 +#include <linux/spinlock.h>
  #include <linux/rcupdate.h>
  #include <linux/ctype.h>
  #include <linux/inet.h>
@@@ -47,11 -47,14 +47,14 @@@ static struct bond_opt_value bond_xmit_
  };
  
  static struct bond_opt_value bond_arp_validate_tbl[] = {
- 	{ "none",   BOND_ARP_VALIDATE_NONE,   BOND_VALFLAG_DEFAULT},
- 	{ "active", BOND_ARP_VALIDATE_ACTIVE, 0},
- 	{ "backup", BOND_ARP_VALIDATE_BACKUP, 0},
- 	{ "all",    BOND_ARP_VALIDATE_ALL,    0},
- 	{ NULL,     -1,                       0},
+ 	{ "none",		BOND_ARP_VALIDATE_NONE,		BOND_VALFLAG_DEFAULT},
+ 	{ "active",		BOND_ARP_VALIDATE_ACTIVE,	0},
+ 	{ "backup",		BOND_ARP_VALIDATE_BACKUP,	0},
+ 	{ "all",		BOND_ARP_VALIDATE_ALL,		0},
+ 	{ "filter",		BOND_ARP_FILTER,		0},
+ 	{ "filter_active",	BOND_ARP_FILTER_ACTIVE,		0},
+ 	{ "filter_backup",	BOND_ARP_FILTER_BACKUP,		0},
+ 	{ NULL,			-1,				0},
  };
  
  static struct bond_opt_value bond_arp_all_targets_tbl[] = {
@@@ -151,7 -154,8 +154,8 @@@ static struct bond_option bond_opts[] 
  		.id = BOND_OPT_ARP_VALIDATE,
  		.name = "arp_validate",
  		.desc = "validate src/dst of ARP probes",
- 		.unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_ACTIVEBACKUP)),
+ 		.unsuppmodes = BIT(BOND_MODE_8023AD) | BIT(BOND_MODE_TLB) |
+ 			       BIT(BOND_MODE_ALB),
  		.values = bond_arp_validate_tbl,
  		.set = bond_option_arp_validate_set
  	},
@@@ -473,10 -477,10 +477,10 @@@ static void bond_opt_error_interpret(st
  				p = strchr(val->string, '\n');
  				if (p)
  					*p = '\0';
- 				pr_err("%s: option %s: invalid value (%s).\n",
+ 				pr_err("%s: option %s: invalid value (%s)\n",
  				       bond->dev->name, opt->name, val->string);
  			} else {
- 				pr_err("%s: option %s: invalid value (%llu).\n",
+ 				pr_err("%s: option %s: invalid value (%llu)\n",
  				       bond->dev->name, opt->name, val->value);
  			}
  		}
@@@ -484,7 -488,7 +488,7 @@@
  		maxval = bond_opt_get_flags(opt, BOND_VALFLAG_MAX);
  		if (!maxval)
  			break;
- 		pr_err("%s: option %s: allowed values %llu - %llu.\n",
+ 		pr_err("%s: option %s: allowed values %llu - %llu\n",
  		       bond->dev->name, opt->name, minval ? minval->value : 0,
  		       maxval->value);
  		break;
@@@ -492,11 -496,11 +496,11 @@@
  		bond_opt_dep_print(bond, opt);
  		break;
  	case -ENOTEMPTY:
- 		pr_err("%s: option %s: unable to set because the bond device has slaves.\n",
+ 		pr_err("%s: option %s: unable to set because the bond device has slaves\n",
  		       bond->dev->name, opt->name);
  		break;
  	case -EBUSY:
- 		pr_err("%s: option %s: unable to set because the bond device is up.\n",
+ 		pr_err("%s: option %s: unable to set because the bond device is up\n",
  		       bond->dev->name, opt->name);
  		break;
  	default:
@@@ -589,7 -593,7 +593,7 @@@ int bond_option_mode_set(struct bondin
  		bond->params.arp_interval = 0;
  		/* set miimon to default value */
  		bond->params.miimon = BOND_DEFAULT_MIIMON;
- 		pr_info("%s: Setting MII monitoring interval to %d.\n",
+ 		pr_info("%s: Setting MII monitoring interval to %d\n",
  			bond->dev->name, bond->params.miimon);
  	}
  
@@@ -636,13 -640,13 +640,13 @@@ int bond_option_active_slave_set(struc
  
  	if (slave_dev) {
  		if (!netif_is_bond_slave(slave_dev)) {
- 			pr_err("Device %s is not bonding slave.\n",
+ 			pr_err("Device %s is not bonding slave\n",
  			       slave_dev->name);
  			return -EINVAL;
  		}
  
  		if (bond->dev != netdev_master_upper_dev_get(slave_dev)) {
- 			pr_err("%s: Device %s is not our slave.\n",
+ 			pr_err("%s: Device %s is not our slave\n",
  			       bond->dev->name, slave_dev->name);
  			return -EINVAL;
  		}
@@@ -653,8 -657,7 +657,7 @@@
  
  	/* check to see if we are clearing active */
  	if (!slave_dev) {
- 		pr_info("%s: Clearing current active slave.\n",
- 		bond->dev->name);
+ 		pr_info("%s: Clearing current active slave\n", bond->dev->name);
  		rcu_assign_pointer(bond->curr_active_slave, NULL);
  		bond_select_active_slave(bond);
  	} else {
@@@ -665,16 -668,16 +668,16 @@@
  
  		if (new_active == old_active) {
  			/* do nothing */
- 			pr_info("%s: %s is already the current active slave.\n",
+ 			pr_info("%s: %s is already the current active slave\n",
  				bond->dev->name, new_active->dev->name);
  		} else {
  			if (old_active && (new_active->link == BOND_LINK_UP) &&
  			    IS_UP(new_active->dev)) {
- 				pr_info("%s: Setting %s as active slave.\n",
+ 				pr_info("%s: Setting %s as active slave\n",
  					bond->dev->name, new_active->dev->name);
  				bond_change_active_slave(bond, new_active);
  			} else {
- 				pr_err("%s: Could not set %s as active slave; either %s is down or the link is down.\n",
+ 				pr_err("%s: Could not set %s as active slave; either %s is down or the link is down\n",
  				       bond->dev->name, new_active->dev->name,
  				       new_active->dev->name);
  				ret = -EINVAL;
@@@ -690,19 -693,19 +693,19 @@@
  
  int bond_option_miimon_set(struct bonding *bond, struct bond_opt_value *newval)
  {
- 	pr_info("%s: Setting MII monitoring interval to %llu.\n",
+ 	pr_info("%s: Setting MII monitoring interval to %llu\n",
  		bond->dev->name, newval->value);
  	bond->params.miimon = newval->value;
  	if (bond->params.updelay)
- 		pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
+ 		pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value\n",
  			bond->dev->name,
  			bond->params.updelay * bond->params.miimon);
  	if (bond->params.downdelay)
- 		pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
+ 		pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value\n",
  			bond->dev->name,
  			bond->params.downdelay * bond->params.miimon);
  	if (newval->value && bond->params.arp_interval) {
- 		pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
+ 		pr_info("%s: MII monitoring cannot be used with ARP monitoring - disabling ARP monitoring...\n",
  			bond->dev->name);
  		bond->params.arp_interval = 0;
  		if (bond->params.arp_validate)
@@@ -742,9 -745,8 +745,8 @@@ int bond_option_updelay_set(struct bond
  			bond->params.miimon);
  	}
  	bond->params.updelay = value / bond->params.miimon;
- 	pr_info("%s: Setting up delay to %d.\n",
- 		bond->dev->name,
- 		bond->params.updelay * bond->params.miimon);
+ 	pr_info("%s: Setting up delay to %d\n",
+ 		bond->dev->name, bond->params.updelay * bond->params.miimon);
  
  	return 0;
  }
@@@ -767,9 -769,8 +769,8 @@@ int bond_option_downdelay_set(struct bo
  			bond->params.miimon);
  	}
  	bond->params.downdelay = value / bond->params.miimon;
- 	pr_info("%s: Setting down delay to %d.\n",
- 		bond->dev->name,
- 		bond->params.downdelay * bond->params.miimon);
+ 	pr_info("%s: Setting down delay to %d\n",
+ 		bond->dev->name, bond->params.downdelay * bond->params.miimon);
  
  	return 0;
  }
@@@ -777,7 -778,7 +778,7 @@@
  int bond_option_use_carrier_set(struct bonding *bond,
  				struct bond_opt_value *newval)
  {
- 	pr_info("%s: Setting use_carrier to %llu.\n",
+ 	pr_info("%s: Setting use_carrier to %llu\n",
  		bond->dev->name, newval->value);
  	bond->params.use_carrier = newval->value;
  
@@@ -787,17 -788,17 +788,17 @@@
  int bond_option_arp_interval_set(struct bonding *bond,
  				 struct bond_opt_value *newval)
  {
- 	pr_info("%s: Setting ARP monitoring interval to %llu.\n",
+ 	pr_info("%s: Setting ARP monitoring interval to %llu\n",
  		bond->dev->name, newval->value);
  	bond->params.arp_interval = newval->value;
  	if (newval->value) {
  		if (bond->params.miimon) {
- 			pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
+ 			pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring\n",
  				bond->dev->name, bond->dev->name);
  			bond->params.miimon = 0;
  		}
  		if (!bond->params.arp_targets[0])
- 			pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n",
+ 			pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified\n",
  				bond->dev->name);
  	}
  	if (bond->dev->flags & IFF_UP) {
@@@ -812,8 -813,7 +813,7 @@@
  			cancel_delayed_work_sync(&bond->arp_work);
  		} else {
  			/* arp_validate can be set only in active-backup mode */
- 			if (bond->params.arp_validate)
- 				bond->recv_probe = bond_arp_rcv;
+ 			bond->recv_probe = bond_arp_rcv;
  			cancel_delayed_work_sync(&bond->mii_work);
  			queue_delayed_work(bond->wq, &bond->arp_work, 0);
  		}
@@@ -856,12 -856,11 +856,11 @@@ static int _bond_option_arp_ip_target_a
  
  	ind = bond_get_targets_ip(targets, 0); /* first free slot */
  	if (ind == -1) {
- 		pr_err("%s: ARP target table is full!\n",
- 		       bond->dev->name);
+ 		pr_err("%s: ARP target table is full!\n", bond->dev->name);
  		return -EINVAL;
  	}
  
- 	pr_info("%s: adding ARP target %pI4.\n", bond->dev->name, &target);
+ 	pr_info("%s: Adding ARP target %pI4\n", bond->dev->name, &target);
  
  	_bond_options_arp_ip_target_set(bond, ind, target, jiffies);
  
@@@ -896,17 -895,16 +895,16 @@@ int bond_option_arp_ip_target_rem(struc
  
  	ind = bond_get_targets_ip(targets, target);
  	if (ind == -1) {
- 		pr_err("%s: unable to remove nonexistent ARP target %pI4.\n",
+ 		pr_err("%s: unable to remove nonexistent ARP target %pI4\n",
  		       bond->dev->name, &target);
  		return -EINVAL;
  	}
  
  	if (ind == 0 && !targets[1] && bond->params.arp_interval)
- 		pr_warn("%s: removing last arp target with arp_interval on\n",
+ 		pr_warn("%s: Removing last arp target with arp_interval on\n",
  			bond->dev->name);
  
- 	pr_info("%s: removing ARP target %pI4.\n", bond->dev->name,
- 		&target);
+ 	pr_info("%s: Removing ARP target %pI4\n", bond->dev->name, &target);
  
  	/* not to race with bond_arp_rcv */
  	write_lock_bh(&bond->lock);
@@@ -954,7 -952,7 +952,7 @@@ int bond_option_arp_ip_targets_set(stru
  		else if (newval->string[0] == '-')
  			ret = bond_option_arp_ip_target_rem(bond, target);
  		else
- 			pr_err("no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
+ 			pr_err("no command found in arp_ip_targets file for bond %s - use +<addr> or -<addr>\n",
  			       bond->dev->name);
  	} else {
  		target = newval->value;
@@@ -967,7 -965,7 +965,7 @@@
  int bond_option_arp_validate_set(struct bonding *bond,
  				 struct bond_opt_value *newval)
  {
- 	pr_info("%s: setting arp_validate to %s (%llu).\n",
+ 	pr_info("%s: Setting arp_validate to %s (%llu)\n",
  		bond->dev->name, newval->string, newval->value);
  
  	if (bond->dev->flags & IFF_UP) {
@@@ -984,7 -982,7 +982,7 @@@
  int bond_option_arp_all_targets_set(struct bonding *bond,
  				    struct bond_opt_value *newval)
  {
- 	pr_info("%s: setting arp_all_targets to %s (%llu).\n",
+ 	pr_info("%s: Setting arp_all_targets to %s (%llu)\n",
  		bond->dev->name, newval->string, newval->value);
  	bond->params.arp_all_targets = newval->value;
  
@@@ -1006,8 -1004,7 +1004,7 @@@ int bond_option_primary_set(struct bond
  		*p = '\0';
  	/* check to see if we are clearing primary */
  	if (!strlen(primary)) {
- 		pr_info("%s: Setting primary slave to None.\n",
- 			bond->dev->name);
+ 		pr_info("%s: Setting primary slave to None\n", bond->dev->name);
  		bond->primary_slave = NULL;
  		memset(bond->params.primary, 0, sizeof(bond->params.primary));
  		bond_select_active_slave(bond);
@@@ -1016,7 -1013,7 +1013,7 @@@
  
  	bond_for_each_slave(bond, slave, iter) {
  		if (strncmp(slave->dev->name, primary, IFNAMSIZ) == 0) {
- 			pr_info("%s: Setting %s as primary slave.\n",
+ 			pr_info("%s: Setting %s as primary slave\n",
  				bond->dev->name, slave->dev->name);
  			bond->primary_slave = slave;
  			strcpy(bond->params.primary, slave->dev->name);
@@@ -1026,15 -1023,14 +1023,14 @@@
  	}
  
  	if (bond->primary_slave) {
- 		pr_info("%s: Setting primary slave to None.\n",
- 			bond->dev->name);
+ 		pr_info("%s: Setting primary slave to None\n", bond->dev->name);
  		bond->primary_slave = NULL;
  		bond_select_active_slave(bond);
  	}
  	strncpy(bond->params.primary, primary, IFNAMSIZ);
  	bond->params.primary[IFNAMSIZ - 1] = 0;
  
- 	pr_info("%s: Recording %s as primary, but it has not been enslaved to %s yet.\n",
+ 	pr_info("%s: Recording %s as primary, but it has not been enslaved to %s yet\n",
  		bond->dev->name, primary, bond->dev->name);
  
  out:
@@@ -1048,7 -1044,7 +1044,7 @@@
  int bond_option_primary_reselect_set(struct bonding *bond,
  				     struct bond_opt_value *newval)
  {
- 	pr_info("%s: setting primary_reselect to %s (%llu).\n",
+ 	pr_info("%s: Setting primary_reselect to %s (%llu)\n",
  		bond->dev->name, newval->string, newval->value);
  	bond->params.primary_reselect = newval->value;
  
@@@ -1064,7 -1060,7 +1060,7 @@@
  int bond_option_fail_over_mac_set(struct bonding *bond,
  				  struct bond_opt_value *newval)
  {
- 	pr_info("%s: Setting fail_over_mac to %s (%llu).\n",
+ 	pr_info("%s: Setting fail_over_mac to %s (%llu)\n",
  		bond->dev->name, newval->string, newval->value);
  	bond->params.fail_over_mac = newval->value;
  
@@@ -1074,7 -1070,7 +1070,7 @@@
  int bond_option_xmit_hash_policy_set(struct bonding *bond,
  				     struct bond_opt_value *newval)
  {
- 	pr_info("%s: setting xmit hash policy to %s (%llu).\n",
+ 	pr_info("%s: Setting xmit hash policy to %s (%llu)\n",
  		bond->dev->name, newval->string, newval->value);
  	bond->params.xmit_policy = newval->value;
  
@@@ -1084,7 -1080,7 +1080,7 @@@
  int bond_option_resend_igmp_set(struct bonding *bond,
  				struct bond_opt_value *newval)
  {
- 	pr_info("%s: Setting resend_igmp to %llu.\n",
+ 	pr_info("%s: Setting resend_igmp to %llu\n",
  		bond->dev->name, newval->value);
  	bond->params.resend_igmp = newval->value;
  
@@@ -1158,7 -1154,7 +1154,7 @@@ int bond_option_pps_set(struct bonding 
  int bond_option_lacp_rate_set(struct bonding *bond,
  			      struct bond_opt_value *newval)
  {
- 	pr_info("%s: Setting LACP rate to %s (%llu).\n",
+ 	pr_info("%s: Setting LACP rate to %s (%llu)\n",
  		bond->dev->name, newval->string, newval->value);
  	bond->params.lacp_fast = newval->value;
  	bond_3ad_update_lacp_rate(bond);
@@@ -1169,7 -1165,7 +1165,7 @@@
  int bond_option_ad_select_set(struct bonding *bond,
  			      struct bond_opt_value *newval)
  {
- 	pr_info("%s: Setting ad_select to %s (%llu).\n",
+ 	pr_info("%s: Setting ad_select to %s (%llu)\n",
  		bond->dev->name, newval->string, newval->value);
  	bond->params.ad_select = newval->value;
  
@@@ -1199,8 -1195,7 +1195,7 @@@ int bond_option_queue_id_set(struct bon
  		goto err_no_cmd;
  
  	/* Check buffer length, valid ifname and queue id */
- 	if (strlen(newval->string) > IFNAMSIZ ||
- 	    !dev_valid_name(newval->string) ||
+ 	if (!dev_valid_name(newval->string) ||
  	    qid > bond->dev->real_num_tx_queues)
  		goto err_no_cmd;
  
@@@ -1232,8 -1227,7 +1227,7 @@@ out
  	return ret;
  
  err_no_cmd:
- 	pr_info("invalid input for queue_id set for %s.\n",
- 		bond->dev->name);
+ 	pr_info("invalid input for queue_id set for %s\n", bond->dev->name);
  	ret = -EPERM;
  	goto out;
  
@@@ -1254,7 -1248,7 +1248,7 @@@ int bond_option_slaves_set(struct bondi
  
  	dev = __dev_get_by_name(dev_net(bond->dev), ifname);
  	if (!dev) {
- 		pr_info("%s: Interface %s does not exist!\n",
+ 		pr_info("%s: interface %s does not exist!\n",
  			bond->dev->name, ifname);
  		ret = -ENODEV;
  		goto out;
@@@ -1262,12 -1256,12 +1256,12 @@@
  
  	switch (command[0]) {
  	case '+':
- 		pr_info("%s: Adding slave %s.\n", bond->dev->name, dev->name);
+ 		pr_info("%s: Adding slave %s\n", bond->dev->name, dev->name);
  		ret = bond_enslave(bond->dev, dev);
  		break;
  
  	case '-':
- 		pr_info("%s: Removing slave %s.\n", bond->dev->name, dev->name);
+ 		pr_info("%s: Removing slave %s\n", bond->dev->name, dev->name);
  		ret = bond_release(bond->dev, dev);
  		break;
  
@@@ -1279,7 -1273,7 +1273,7 @@@ out
  	return ret;
  
  err_no_cmd:
- 	pr_err("no command found in slaves file for bond %s. Use +ifname or -ifname.\n",
+ 	pr_err("no command found in slaves file for bond %s - use +ifname or -ifname\n",
  	       bond->dev->name);
  	ret = -EPERM;
  	goto out;
diff --combined drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 66c0df7,8363b9d..5ee13af
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@@ -1638,36 -1638,16 +1638,16 @@@ int bnx2x_enable_msix(struct bnx2x *bp
  	DP(BNX2X_MSG_SP, "about to request enable msix with %d vectors\n",
  	   msix_vec);
  
- 	rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], msix_vec);
- 
+ 	rc = pci_enable_msix_range(bp->pdev, &bp->msix_table[0],
+ 				   BNX2X_MIN_MSIX_VEC_CNT(bp), msix_vec);
  	/*
  	 * reconfigure number of tx/rx queues according to available
  	 * MSI-X vectors
  	 */
- 	if (rc >= BNX2X_MIN_MSIX_VEC_CNT(bp)) {
- 		/* how less vectors we will have? */
- 		int diff = msix_vec - rc;
- 
- 		BNX2X_DEV_INFO("Trying to use less MSI-X vectors: %d\n", rc);
- 
- 		rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], rc);
- 
- 		if (rc) {
- 			BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc);
- 			goto no_msix;
- 		}
- 		/*
- 		 * decrease number of queues by number of unallocated entries
- 		 */
- 		bp->num_ethernet_queues -= diff;
- 		bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues;
- 
- 		BNX2X_DEV_INFO("New queue configuration set: %d\n",
- 			       bp->num_queues);
- 	} else if (rc > 0) {
+ 	if (rc == -ENOSPC) {
  		/* Get by with single vector */
- 		rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], 1);
- 		if (rc) {
+ 		rc = pci_enable_msix_range(bp->pdev, &bp->msix_table[0], 1, 1);
+ 		if (rc < 0) {
  			BNX2X_DEV_INFO("Single MSI-X is not attainable rc %d\n",
  				       rc);
  			goto no_msix;
@@@ -1680,8 -1660,22 +1660,22 @@@
  		bp->num_ethernet_queues = 1;
  		bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues;
  	} else if (rc < 0) {
- 		BNX2X_DEV_INFO("MSI-X is not attainable  rc %d\n", rc);
+ 		BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc);
  		goto no_msix;
+ 	} else if (rc < msix_vec) {
+ 		/* how less vectors we will have? */
+ 		int diff = msix_vec - rc;
+ 
+ 		BNX2X_DEV_INFO("Trying to use less MSI-X vectors: %d\n", rc);
+ 
+ 		/*
+ 		 * decrease number of queues by number of unallocated entries
+ 		 */
+ 		bp->num_ethernet_queues -= diff;
+ 		bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues;
+ 
+ 		BNX2X_DEV_INFO("New queue configuration set: %d\n",
+ 			       bp->num_queues);
  	}
  
  	bp->flags |= USING_MSIX_FLAG;
@@@ -1873,7 -1867,7 +1867,7 @@@ void bnx2x_netif_stop(struct bnx2x *bp
  }
  
  u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
 -		       void *accel_priv)
 +		       void *accel_priv, select_queue_fallback_t fallback)
  {
  	struct bnx2x *bp = netdev_priv(dev);
  
@@@ -1895,7 -1889,7 +1889,7 @@@
  	}
  
  	/* select a non-FCoE queue */
 -	return __netdev_pick_tx(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp);
 +	return fallback(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp);
  }
  
  void bnx2x_set_num_queues(struct bnx2x *bp)
@@@ -4773,12 -4767,8 +4767,8 @@@ void bnx2x_tx_timeout(struct net_devic
  		bnx2x_panic();
  #endif
  
- 	smp_mb__before_clear_bit();
- 	set_bit(BNX2X_SP_RTNL_TX_TIMEOUT, &bp->sp_rtnl_state);
- 	smp_mb__after_clear_bit();
- 
  	/* This allows the netif to be shutdown gracefully before resetting */
- 	schedule_delayed_work(&bp->sp_rtnl_task, 0);
+ 	bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_TX_TIMEOUT, 0);
  }
  
  int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
@@@ -4906,3 -4896,15 +4896,15 @@@ void bnx2x_update_coalesce_sb_index(str
  	disable = disable ? 1 : (usec ? 0 : 1);
  	storm_memset_hc_disable(bp, port, fw_sb_id, sb_index, disable);
  }
+ 
+ void bnx2x_schedule_sp_rtnl(struct bnx2x *bp, enum sp_rtnl_flag flag,
+ 			    u32 verbose)
+ {
+ 	smp_mb__before_clear_bit();
+ 	set_bit(flag, &bp->sp_rtnl_state);
+ 	smp_mb__after_clear_bit();
+ 	DP((BNX2X_MSG_SP | verbose), "Scheduling sp_rtnl task [Flag: %d]\n",
+ 	   flag);
+ 	schedule_delayed_work(&bp->sp_rtnl_task, 0);
+ }
+ EXPORT_SYMBOL(bnx2x_schedule_sp_rtnl);
diff --combined drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index a89a40f,5135cc7..ec02b15
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@@ -496,7 -496,7 +496,7 @@@ int bnx2x_set_vf_vlan(struct net_devic
  
  /* select_queue callback */
  u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
 -		       void *accel_priv);
 +		       void *accel_priv, select_queue_fallback_t fallback);
  
  static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
  					struct bnx2x_fastpath *fp,
@@@ -1324,4 -1324,7 +1324,7 @@@ void bnx2x_fill_fw_str(struct bnx2x *bp
  int bnx2x_drain_tx_queues(struct bnx2x *bp);
  void bnx2x_squeeze_objects(struct bnx2x *bp);
  
+ void bnx2x_schedule_sp_rtnl(struct bnx2x*, enum sp_rtnl_flag,
+ 			    u32 verbose);
+ 
  #endif /* BNX2X_CMN_H */
diff --combined drivers/net/ethernet/ti/cpsw.c
index 651087b,39d1253..0b6a280
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@@ -554,7 -554,7 +554,7 @@@ static void cpsw_set_promiscious(struc
  		 * common for both the interface as the interface shares
  		 * the same hardware resource.
  		 */
 -		for (i = 0; i <= priv->data.slaves; i++)
 +		for (i = 0; i < priv->data.slaves; i++)
  			if (priv->slaves[i].ndev->flags & IFF_PROMISC)
  				flag = true;
  
@@@ -578,7 -578,7 +578,7 @@@
  			unsigned long timeout = jiffies + HZ;
  
  			/* Disable Learn for all ports */
 -			for (i = 0; i <= priv->data.slaves; i++) {
 +			for (i = 0; i < priv->data.slaves; i++) {
  				cpsw_ale_control_set(ale, i,
  						     ALE_PORT_NOLEARN, 1);
  				cpsw_ale_control_set(ale, i,
@@@ -606,7 -606,7 +606,7 @@@
  			cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0);
  
  			/* Enable Learn for all ports */
 -			for (i = 0; i <= priv->data.slaves; i++) {
 +			for (i = 0; i < priv->data.slaves; i++) {
  				cpsw_ale_control_set(ale, i,
  						     ALE_PORT_NOLEARN, 0);
  				cpsw_ale_control_set(ale, i,
@@@ -1471,7 -1471,6 +1471,6 @@@ static int cpsw_hwtstamp_get(struct net
  static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
  {
  	struct cpsw_priv *priv = netdev_priv(dev);
- 	struct mii_ioctl_data *data = if_mii(req);
  	int slave_no = cpsw_slave_index(priv);
  
  	if (!netif_running(dev))
@@@ -1484,14 -1483,11 +1483,11 @@@
  	case SIOCGHWTSTAMP:
  		return cpsw_hwtstamp_get(dev, req);
  #endif
- 	case SIOCGMIIPHY:
- 		data->phy_id = priv->slaves[slave_no].phy->addr;
- 		break;
- 	default:
- 		return -ENOTSUPP;
  	}
  
- 	return 0;
+ 	if (!priv->slaves[slave_no].phy)
+ 		return -EOPNOTSUPP;
+ 	return phy_mii_ioctl(priv->slaves[slave_no].phy, req, cmd);
  }
  
  static void cpsw_ndo_tx_timeout(struct net_device *ndev)
@@@ -1896,11 -1892,6 +1892,11 @@@ static int cpsw_probe_dt(struct cpsw_pl
  			memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN);
  
  		slave_data->phy_if = of_get_phy_mode(slave_node);
 +		if (slave_data->phy_if < 0) {
 +			pr_err("Missing or malformed slave[%d] phy-mode property\n",
 +			       i);
 +			return slave_data->phy_if;
 +		}
  
  		if (data->dual_emac) {
  			if (of_property_read_u32(slave_node, "dual_emac_res_vlan",
diff --combined drivers/net/hyperv/netvsc_drv.c
index 7141a19,1eadc13..bcd2df2
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@@ -88,12 -88,8 +88,12 @@@ static int netvsc_open(struct net_devic
  {
  	struct net_device_context *net_device_ctx = netdev_priv(net);
  	struct hv_device *device_obj = net_device_ctx->device_ctx;
 +	struct netvsc_device *nvdev;
 +	struct rndis_device *rdev;
  	int ret = 0;
  
 +	netif_carrier_off(net);
 +
  	/* Open up the device */
  	ret = rndis_filter_open(device_obj);
  	if (ret != 0) {
@@@ -103,11 -99,6 +103,11 @@@
  
  	netif_start_queue(net);
  
 +	nvdev = hv_get_drvdata(device_obj);
 +	rdev = nvdev->extension;
 +	if (!rdev->link_state)
 +		netif_carrier_on(net);
 +
  	return ret;
  }
  
@@@ -155,7 -146,7 +155,7 @@@ static int netvsc_start_xmit(struct sk_
  	/* Allocate a netvsc packet based on # of frags. */
  	packet = kzalloc(sizeof(struct hv_netvsc_packet) +
  			 (num_pages * sizeof(struct hv_page_buffer)) +
- 			 sizeof(struct rndis_filter_packet) +
+ 			 sizeof(struct rndis_message) +
  			 NDIS_VLAN_PPI_SIZE, GFP_ATOMIC);
  	if (!packet) {
  		/* out of memory, drop packet */
@@@ -238,24 -229,23 +238,24 @@@ void netvsc_linkstatus_callback(struct 
  	struct net_device *net;
  	struct net_device_context *ndev_ctx;
  	struct netvsc_device *net_device;
 +	struct rndis_device *rdev;
  
  	net_device = hv_get_drvdata(device_obj);
 +	rdev = net_device->extension;
 +
 +	rdev->link_state = status != 1;
 +
  	net = net_device->ndev;
  
 -	if (!net) {
 -		netdev_err(net, "got link status but net device "
 -				"not initialized yet\n");
 +	if (!net || net->reg_state != NETREG_REGISTERED)
  		return;
 -	}
  
 +	ndev_ctx = netdev_priv(net);
  	if (status == 1) {
  		schedule_delayed_work(&ndev_ctx->dwork, 0);
  		schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20));
  	} else {
 -		netif_carrier_off(net);
 +		schedule_delayed_work(&ndev_ctx->dwork, 0);
  	}
  }
  
@@@ -398,35 -388,17 +398,35 @@@ static const struct net_device_ops devi
   * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add
   * another netif_notify_peers() into a delayed work, otherwise GARP packet
   * will not be sent after quick migration, and cause network disconnection.
 + * Also, we update the carrier status here.
   */
 -static void netvsc_send_garp(struct work_struct *w)
 +static void netvsc_link_change(struct work_struct *w)
  {
  	struct net_device_context *ndev_ctx;
  	struct net_device *net;
  	struct netvsc_device *net_device;
 +	struct rndis_device *rdev;
 +	bool notify;
 +
 +	rtnl_lock();
  
  	ndev_ctx = container_of(w, struct net_device_context, dwork.work);
  	net_device = hv_get_drvdata(ndev_ctx->device_ctx);
 +	rdev = net_device->extension;
  	net = net_device->ndev;
 -	netdev_notify_peers(net);
 +
 +	if (rdev->link_state) {
 +		netif_carrier_off(net);
 +		notify = false;
 +	} else {
 +		netif_carrier_on(net);
 +		notify = true;
 +	}
 +
 +	rtnl_unlock();
 +
 +	if (notify)
 +		netdev_notify_peers(net);
  }
  
  
@@@ -442,10 -414,13 +442,10 @@@ static int netvsc_probe(struct hv_devic
  	if (!net)
  		return -ENOMEM;
  
  	net_device_ctx = netdev_priv(net);
  	net_device_ctx->device_ctx = dev;
  	hv_set_drvdata(dev, net);
 -	INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp);
 +	INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change);
  	INIT_WORK(&net_device_ctx->work, do_set_multicast);
  
  	net->netdev_ops = &device_ops;
@@@ -468,6 -443,8 +468,6 @@@
  	}
  	memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
  
 -	netif_carrier_on(net);
 -
  	ret = register_netdev(net);
  	if (ret != 0) {
  		pr_err("Unable to register netdev.\n");
diff --combined drivers/net/macvlan.c
index a5d2189,25685e3..44227c2
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@@ -534,7 -534,6 +534,6 @@@ static int macvlan_init(struct net_devi
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	const struct net_device *lowerdev = vlan->lowerdev;
- 	int i;
  
  	dev->state		= (dev->state & ~MACVLAN_STATE_MASK) |
  				  (lowerdev->state & MACVLAN_STATE_MASK);
@@@ -546,16 -545,10 +545,10 @@@
  
  	macvlan_set_lockdep_class(dev);
  
- 	vlan->pcpu_stats = alloc_percpu(struct vlan_pcpu_stats);
+ 	vlan->pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
  	if (!vlan->pcpu_stats)
  		return -ENOMEM;
  
- 	for_each_possible_cpu(i) {
- 		struct vlan_pcpu_stats *mvlstats;
- 		mvlstats = per_cpu_ptr(vlan->pcpu_stats, i);
- 		u64_stats_init(&mvlstats->syncp);
- 	}
- 
  	return 0;
  }
  
@@@ -879,15 -872,14 +872,15 @@@ int macvlan_common_newlink(struct net *
  	dev->priv_flags |= IFF_MACVLAN;
  	err = netdev_upper_dev_link(lowerdev, dev);
  	if (err)
 -		goto destroy_port;
 -
 +		goto unregister_netdev;
  
  	list_add_tail_rcu(&vlan->list, &port->vlans);
  	netif_stacked_transfer_operstate(lowerdev, dev);
  
  	return 0;
  
 +unregister_netdev:
 +	unregister_netdevice(dev);
  destroy_port:
  	port->count -= 1;
  	if (!port->count)
diff --combined drivers/net/team/team.c
index c8624a8,adb46de..aea92f0
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@@ -1540,16 -1540,10 +1540,10 @@@ static int team_init(struct net_device 
  	mutex_init(&team->lock);
  	team_set_no_mode(team);
  
- 	team->pcpu_stats = alloc_percpu(struct team_pcpu_stats);
+ 	team->pcpu_stats = netdev_alloc_pcpu_stats(struct team_pcpu_stats);
  	if (!team->pcpu_stats)
  		return -ENOMEM;
  
- 	for_each_possible_cpu(i) {
- 		struct team_pcpu_stats *team_stats;
- 		team_stats = per_cpu_ptr(team->pcpu_stats, i);
- 		u64_stats_init(&team_stats->syncp);
- 	}
- 
  	for (i = 0; i < TEAM_PORT_HASHENTRIES; i++)
  		INIT_HLIST_HEAD(&team->en_port_hlist[i]);
  	INIT_LIST_HEAD(&team->port_list);
@@@ -1648,7 -1642,7 +1642,7 @@@ static netdev_tx_t team_xmit(struct sk_
  }
  
  static u16 team_select_queue(struct net_device *dev, struct sk_buff *skb,
 -			     void *accel_priv)
 +			     void *accel_priv, select_queue_fallback_t fallback)
  {
  	/*
  	 * This helper function exists to help dev_pick_tx get the correct
diff --combined include/linux/netdevice.h
index e8eeebd,891432a..5e47565
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@@ -752,9 -752,6 +752,9 @@@ struct netdev_phys_port_id 
  	unsigned char id_len;
  };
  
 +typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
 +				       struct sk_buff *skb);
 +
  /*
   * This structure defines the management hooks for network devices.
   * The following hooks can be defined; unless noted otherwise, they are
@@@ -786,7 -783,7 +786,7 @@@
   *	Required can not be NULL.
   *
   * u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb,
 - *                         void *accel_priv);
 + *                         void *accel_priv, select_queue_fallback_t fallback);
   *	Called to decide which queue to when device supports multiple
   *	transmit queues.
   *
@@@ -1008,8 -1005,7 +1008,8 @@@ struct net_device_ops 
  						   struct net_device *dev);
  	u16			(*ndo_select_queue)(struct net_device *dev,
  						    struct sk_buff *skb,
 -						    void *accel_priv);
 +						    void *accel_priv,
 +						    select_queue_fallback_t fallback);
  	void			(*ndo_change_rx_flags)(struct net_device *dev,
  						       int flags);
  	void			(*ndo_set_rx_mode)(struct net_device *dev);
@@@ -1316,13 -1312,7 +1316,7 @@@ struct net_device 
  /*
   * Cache lines mostly used on receive path (including eth_type_trans())
   */
- 	unsigned long		last_rx;	/* Time of last Rx
- 						 * This should not be set in
- 						 * drivers, unless really needed,
- 						 * because network stack (bonding)
- 						 * use it if/when necessary, to
- 						 * avoid dirtying this cache line.
- 						 */
+ 	unsigned long		last_rx;	/* Time of last Rx */
  
  	/* Interface address info used in eth_type_trans() */
  	unsigned char		*dev_addr;	/* hw address, (before bcast
@@@ -1555,6 -1545,7 +1549,6 @@@ static inline void netdev_for_each_tx_q
  struct netdev_queue *netdev_pick_tx(struct net_device *dev,
  				    struct sk_buff *skb,
  				    void *accel_priv);
 -u16 __netdev_pick_tx(struct net_device *dev, struct sk_buff *skb);
  
  /*
   * Net namespace inlines
@@@ -1729,6 -1720,20 +1723,20 @@@ struct pcpu_sw_netstats 
  	struct u64_stats_sync   syncp;
  };
  
+ #define netdev_alloc_pcpu_stats(type)				\
+ ({								\
+ 	typeof(type) *pcpu_stats = alloc_percpu(type);		\
+ 	if (pcpu_stats)	{					\
+ 		int i;						\
+ 		for_each_possible_cpu(i) {			\
+ 			typeof(type) *stat;			\
+ 			stat = per_cpu_ptr(pcpu_stats, i);	\
+ 			u64_stats_init(&stat->syncp);		\
+ 		}						\
+ 	}							\
+ 	pcpu_stats;						\
+ })
+ 
  #include <linux/notifier.h>
  
  /* netdevice notifier chain. Please remember to update the rtnetlink
@@@ -2279,26 -2284,6 +2287,26 @@@ static inline void netdev_reset_queue(s
  }
  
  /**
 + * 	netdev_cap_txqueue - check if selected tx queue exceeds device queues
 + * 	@dev: network device
 + * 	@queue_index: given tx queue index
 + *
 + * 	Returns 0 if given tx queue index >= number of device tx queues,
 + * 	otherwise returns the originally passed tx queue index.
 + */
 +static inline u16 netdev_cap_txqueue(struct net_device *dev, u16 queue_index)
 +{
 +	if (unlikely(queue_index >= dev->real_num_tx_queues)) {
 +		net_warn_ratelimited("%s selects TX queue %d, but real number of TX queues is %d\n",
 +				     dev->name, queue_index,
 +				     dev->real_num_tx_queues);
 +		return 0;
 +	}
 +
 +	return queue_index;
 +}
 +
 +/**
   *	netif_running - test if up
   *	@dev: network device
   *
@@@ -3091,12 -3076,7 +3099,12 @@@ void netdev_change_features(struct net_
  void netif_stacked_transfer_operstate(const struct net_device *rootdev,
  					struct net_device *dev);
  
 -netdev_features_t netif_skb_features(struct sk_buff *skb);
 +netdev_features_t netif_skb_dev_features(struct sk_buff *skb,
 +					 const struct net_device *dev);
 +static inline netdev_features_t netif_skb_features(struct sk_buff *skb)
 +{
 +	return netif_skb_dev_features(skb, skb->dev);
 +}
  
  static inline bool net_gso_ok(netdev_features_t features, int gso_type)
  {
diff --combined net/core/rtnetlink.c
index 1a0dac2,7b2ad56..fc122fd
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@@ -1121,56 -1121,7 +1121,7 @@@ nla_put_failure
  	return -EMSGSIZE;
  }
  
- static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
- {
- 	struct net *net = sock_net(skb->sk);
- 	int h, s_h;
- 	int idx = 0, s_idx;
- 	struct net_device *dev;
- 	struct hlist_head *head;
- 	struct nlattr *tb[IFLA_MAX+1];
- 	u32 ext_filter_mask = 0;
- 
- 	s_h = cb->args[0];
- 	s_idx = cb->args[1];
- 
- 	rcu_read_lock();
- 	cb->seq = net->dev_base_seq;
- 
- 	if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
- 			ifla_policy) >= 0) {
- 
- 		if (tb[IFLA_EXT_MASK])
- 			ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
- 	}
- 
- 	for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
- 		idx = 0;
- 		head = &net->dev_index_head[h];
- 		hlist_for_each_entry_rcu(dev, head, index_hlist) {
- 			if (idx < s_idx)
- 				goto cont;
- 			if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
- 					     NETLINK_CB(cb->skb).portid,
- 					     cb->nlh->nlmsg_seq, 0,
- 					     NLM_F_MULTI,
- 					     ext_filter_mask) <= 0)
- 				goto out;
- 
- 			nl_dump_check_consistent(cb, nlmsg_hdr(skb));
- cont:
- 			idx++;
- 		}
- 	}
- out:
- 	rcu_read_unlock();
- 	cb->args[1] = idx;
- 	cb->args[0] = h;
- 
- 	return skb->len;
- }
- 
- const struct nla_policy ifla_policy[IFLA_MAX+1] = {
+ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
  	[IFLA_IFNAME]		= { .type = NLA_STRING, .len = IFNAMSIZ-1 },
  	[IFLA_ADDRESS]		= { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
  	[IFLA_BROADCAST]	= { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
@@@ -1197,7 -1148,6 +1148,6 @@@
  	[IFLA_NUM_RX_QUEUES]	= { .type = NLA_U32 },
  	[IFLA_PHYS_PORT_ID]	= { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
  };
- EXPORT_SYMBOL(ifla_policy);
  
  static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
  	[IFLA_INFO_KIND]	= { .type = NLA_STRING },
@@@ -1235,6 -1185,61 +1185,61 @@@ static const struct nla_policy ifla_por
  	[IFLA_PORT_RESPONSE]	= { .type = NLA_U16, },
  };
  
+ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+ {
+ 	struct net *net = sock_net(skb->sk);
+ 	int h, s_h;
+ 	int idx = 0, s_idx;
+ 	struct net_device *dev;
+ 	struct hlist_head *head;
+ 	struct nlattr *tb[IFLA_MAX+1];
+ 	u32 ext_filter_mask = 0;
+ 
+ 	s_h = cb->args[0];
+ 	s_idx = cb->args[1];
+ 
+ 	rcu_read_lock();
+ 	cb->seq = net->dev_base_seq;
+ 
+ 	if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
+ 			ifla_policy) >= 0) {
+ 
+ 		if (tb[IFLA_EXT_MASK])
+ 			ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
+ 	}
+ 
+ 	for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
+ 		idx = 0;
+ 		head = &net->dev_index_head[h];
+ 		hlist_for_each_entry_rcu(dev, head, index_hlist) {
+ 			if (idx < s_idx)
+ 				goto cont;
+ 			if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
+ 					     NETLINK_CB(cb->skb).portid,
+ 					     cb->nlh->nlmsg_seq, 0,
+ 					     NLM_F_MULTI,
+ 					     ext_filter_mask) <= 0)
+ 				goto out;
+ 
+ 			nl_dump_check_consistent(cb, nlmsg_hdr(skb));
+ cont:
+ 			idx++;
+ 		}
+ 	}
+ out:
+ 	rcu_read_unlock();
+ 	cb->args[1] = idx;
+ 	cb->args[0] = h;
+ 
+ 	return skb->len;
+ }
+ 
+ int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len)
+ {
+ 	return nla_parse(tb, IFLA_MAX, head, len, ifla_policy);
+ }
+ EXPORT_SYMBOL(rtnl_nla_parse_ifla);
+ 
  struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
  {
  	struct net *net;
@@@ -1963,21 -1968,16 +1968,21 @@@ replay
  
  		dev->ifindex = ifm->ifi_index;
  
 -		if (ops->newlink)
 +		if (ops->newlink) {
  			err = ops->newlink(net, dev, tb, data);
 -		else
 +			/* Drivers should call free_netdev() in ->destructor
 +			 * and unregister it on failure so that device could be
 +			 * finally freed in rtnl_unlock.
 +			 */
 +			if (err < 0)
 +				goto out;
 +		} else {
  			err = register_netdevice(dev);
 -
 -		if (err < 0) {
 -			free_netdev(dev);
 -			goto out;
 +			if (err < 0) {
 +				free_netdev(dev);
 +				goto out;
 +			}
  		}
 -
  		err = rtnl_configure_link(dev, ifm);
  		if (err < 0)
  			unregister_netdevice(dev);
diff --combined net/ipv4/ip_forward.c
index f3869c1,d9d9290..be8abe7
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@@ -39,71 -39,6 +39,71 @@@
  #include <net/route.h>
  #include <net/xfrm.h>
  
 +static bool ip_may_fragment(const struct sk_buff *skb)
 +{
 +	return unlikely((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0) ||
 +	       !skb->local_df;
 +}
 +
 +static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
 +{
 +	if (skb->len <= mtu || skb->local_df)
 +		return false;
 +
 +	if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu)
 +		return false;
 +
 +	return true;
 +}
 +
 +static bool ip_gso_exceeds_dst_mtu(const struct sk_buff *skb)
 +{
 +	unsigned int mtu;
 +
 +	if (skb->local_df || !skb_is_gso(skb))
 +		return false;
 +
 +	mtu = ip_dst_mtu_maybe_forward(skb_dst(skb), true);
 +
 +	/* if seglen > mtu, do software segmentation for IP fragmentation on
 +	 * output.  DF bit cannot be set since ip_forward would have sent
 +	 * icmp error.
 +	 */
 +	return skb_gso_network_seglen(skb) > mtu;
 +}
 +
 +/* called if GSO skb needs to be fragmented on forward */
 +static int ip_forward_finish_gso(struct sk_buff *skb)
 +{
 +	struct dst_entry *dst = skb_dst(skb);
 +	netdev_features_t features;
 +	struct sk_buff *segs;
 +	int ret = 0;
 +
 +	features = netif_skb_dev_features(skb, dst->dev);
 +	segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
 +	if (IS_ERR(segs)) {
 +		kfree_skb(skb);
 +		return -ENOMEM;
 +	}
 +
 +	consume_skb(skb);
 +
 +	do {
 +		struct sk_buff *nskb = segs->next;
 +		int err;
 +
 +		segs->next = NULL;
 +		err = dst_output(segs);
 +
 +		if (err && ret == 0)
 +			ret = err;
 +		segs = nskb;
 +	} while (segs);
 +
 +	return ret;
 +}
 +
  static int ip_forward_finish(struct sk_buff *skb)
  {
  	struct ip_options *opt	= &(IPCB(skb)->opt);
@@@ -114,9 -49,6 +114,9 @@@
  	if (unlikely(opt->optlen))
  		ip_forward_options(skb);
  
 +	if (ip_gso_exceeds_dst_mtu(skb))
 +		return ip_forward_finish_gso(skb);
 +
  	return dst_output(skb);
  }
  
@@@ -127,6 -59,10 +127,10 @@@ int ip_forward(struct sk_buff *skb
  	struct rtable *rt;	/* Route we use */
  	struct ip_options *opt	= &(IPCB(skb)->opt);
  
+ 	/* that should never happen */
+ 	if (skb->pkt_type != PACKET_HOST)
+ 		goto drop;
+ 
  	if (skb_warn_if_lro(skb))
  		goto drop;
  
@@@ -136,9 -72,6 +140,6 @@@
  	if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
  		return NET_RX_SUCCESS;
  
- 	if (skb->pkt_type != PACKET_HOST)
- 		goto drop;
- 
  	skb_forward_csum(skb);
  
  	/*
@@@ -159,7 -92,8 +160,7 @@@
  
  	IPCB(skb)->flags |= IPSKB_FORWARDED;
  	mtu = ip_dst_mtu_maybe_forward(&rt->dst, true);
 -	if (unlikely(skb->len > mtu && !skb_is_gso(skb) &&
 -		     (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) {
 +	if (!ip_may_fragment(skb) && ip_exceeds_mtu(skb, mtu)) {
  		IP_INC_STATS(dev_net(rt->dst.dev), IPSTATS_MIB_FRAGFAILS);
  		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
  			  htonl(mtu));
diff --combined net/ipv4/route.c
index 4c011ec,271554c..11e4384
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@@ -697,7 -697,6 +697,6 @@@ static void update_or_create_fnhe(struc
  
  out_unlock:
  	spin_unlock_bh(&fnhe_lock);
- 	return;
  }
  
  static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flowi4 *fl4,
@@@ -1597,7 -1596,6 +1596,7 @@@ static int __mkroute_input(struct sk_bu
  	rth->rt_gateway	= 0;
  	rth->rt_uses_gateway = 0;
  	INIT_LIST_HEAD(&rth->rt_uncached);
 +	RT_CACHE_STAT_INC(in_slow_tot);
  
  	rth->dst.input = ip_forward;
  	rth->dst.output = ip_output;
@@@ -1696,11 -1694,10 +1695,11 @@@ static int ip_route_input_slow(struct s
  	fl4.daddr = daddr;
  	fl4.saddr = saddr;
  	err = fib_lookup(net, &fl4, &res);
 -	if (err != 0)
 +	if (err != 0) {
 +		if (!IN_DEV_FORWARD(in_dev))
 +			err = -EHOSTUNREACH;
  		goto no_route;
 -
 -	RT_CACHE_STAT_INC(in_slow_tot);
 +	}
  
  	if (res.type == RTN_BROADCAST)
  		goto brd_input;
@@@ -1714,10 -1711,8 +1713,10 @@@
  		goto local_input;
  	}
  
 -	if (!IN_DEV_FORWARD(in_dev))
 +	if (!IN_DEV_FORWARD(in_dev)) {
 +		err = -EHOSTUNREACH;
  		goto no_route;
 +	}
  	if (res.type != RTN_UNICAST)
  		goto martian_destination;
  
@@@ -1772,7 -1767,6 +1771,7 @@@ local_input
  	rth->rt_gateway	= 0;
  	rth->rt_uses_gateway = 0;
  	INIT_LIST_HEAD(&rth->rt_uncached);
 +	RT_CACHE_STAT_INC(in_slow_tot);
  	if (res.type == RTN_UNREACHABLE) {
  		rth->dst.input= ip_error;
  		rth->dst.error= -err;
diff --combined net/tipc/link.c
index da6018b,e4f233d..284d638
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@@ -77,19 -77,19 +77,19 @@@ static const char *link_unk_evt = "Unkn
  
  static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
  				       struct sk_buff *buf);
- static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf);
- static int  tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
+ static void tipc_link_proto_rcv(struct tipc_link *l_ptr, struct sk_buff *buf);
+ static int  tipc_link_tunnel_rcv(struct tipc_node *n_ptr,
  				 struct sk_buff **buf);
  static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance);
- static int  link_send_sections_long(struct tipc_port *sender,
- 				    struct iovec const *msg_sect,
- 				    unsigned int len, u32 destnode);
+ static int  tipc_link_iovec_long_xmit(struct tipc_port *sender,
+ 				      struct iovec const *msg_sect,
+ 				      unsigned int len, u32 destnode);
  static void link_state_event(struct tipc_link *l_ptr, u32 event);
  static void link_reset_statistics(struct tipc_link *l_ptr);
  static void link_print(struct tipc_link *l_ptr, const char *str);
- static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf);
- static void tipc_link_send_sync(struct tipc_link *l);
- static void tipc_link_recv_sync(struct tipc_node *n, struct sk_buff *buf);
+ static int tipc_link_frag_xmit(struct tipc_link *l_ptr, struct sk_buff *buf);
+ static void tipc_link_sync_xmit(struct tipc_link *l);
+ static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf);
  
  /*
   *  Simple link routines
@@@ -147,11 -147,6 +147,6 @@@ int tipc_link_is_active(struct tipc_lin
  /**
   * link_timeout - handle expiration of link timer
   * @l_ptr: pointer to link
-  *
-  * This routine must not grab "tipc_net_lock" to avoid a potential deadlock conflict
-  * with tipc_link_delete().  (There is no risk that the node will be deleted by
-  * another thread because tipc_link_delete() always cancels the link timer before
-  * tipc_node_delete() is called.)
   */
  static void link_timeout(struct tipc_link *l_ptr)
  {
@@@ -213,8 -208,8 +208,8 @@@ static void link_set_timer(struct tipc_
   * Returns pointer to link.
   */
  struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
- 			      struct tipc_bearer *b_ptr,
- 			      const struct tipc_media_addr *media_addr)
+ 				   struct tipc_bearer *b_ptr,
+ 				   const struct tipc_media_addr *media_addr)
  {
  	struct tipc_link *l_ptr;
  	struct tipc_msg *msg;
@@@ -279,41 -274,43 +274,43 @@@
  
  	k_init_timer(&l_ptr->timer, (Handler)link_timeout,
  		     (unsigned long)l_ptr);
- 	list_add_tail(&l_ptr->link_list, &b_ptr->links);
  
  	link_state_event(l_ptr, STARTING_EVT);
  
  	return l_ptr;
  }
  
- /**
-  * tipc_link_delete - delete a link
-  * @l_ptr: pointer to link
-  *
-  * Note: 'tipc_net_lock' is write_locked, bearer is locked.
-  * This routine must not grab the node lock until after link timer cancellation
-  * to avoid a potential deadlock situation.
-  */
- void tipc_link_delete(struct tipc_link *l_ptr)
- {
- 	if (!l_ptr) {
- 		pr_err("Attempt to delete non-existent link\n");
- 		return;
- 	}
  
- 	k_cancel_timer(&l_ptr->timer);
+ void tipc_link_delete_list(unsigned int bearer_id, bool shutting_down)
+ {
+ 	struct tipc_link *l_ptr;
+ 	struct tipc_node *n_ptr;
  
- 	tipc_node_lock(l_ptr->owner);
- 	tipc_link_reset(l_ptr);
- 	tipc_node_detach_link(l_ptr->owner, l_ptr);
- 	tipc_link_purge_queues(l_ptr);
- 	list_del_init(&l_ptr->link_list);
- 	tipc_node_unlock(l_ptr->owner);
- 	k_term_timer(&l_ptr->timer);
- 	kfree(l_ptr);
+ 	list_for_each_entry(n_ptr, &tipc_node_list, list) {
+ 		spin_lock_bh(&n_ptr->lock);
+ 		l_ptr = n_ptr->links[bearer_id];
+ 		if (l_ptr) {
+ 			tipc_link_reset(l_ptr);
+ 			if (shutting_down || !tipc_node_is_up(n_ptr)) {
+ 				tipc_node_detach_link(l_ptr->owner, l_ptr);
+ 				tipc_link_reset_fragments(l_ptr);
+ 				spin_unlock_bh(&n_ptr->lock);
+ 
+ 				/* Nobody else can access this link now: */
+ 				del_timer_sync(&l_ptr->timer);
+ 				kfree(l_ptr);
+ 			} else {
+ 				/* Detach/delete when failover is finished: */
+ 				l_ptr->flags |= LINK_STOPPED;
+ 				spin_unlock_bh(&n_ptr->lock);
+ 				del_timer_sync(&l_ptr->timer);
+ 			}
+ 			continue;
+ 		}
+ 		spin_unlock_bh(&n_ptr->lock);
+ 	}
  }
  
- 
  /**
   * link_schedule_port - schedule port for deferred sending
   * @l_ptr: pointer to link
@@@ -461,6 -458,19 +458,19 @@@ void tipc_link_reset(struct tipc_link *
  	link_reset_statistics(l_ptr);
  }
  
+ void tipc_link_reset_list(unsigned int bearer_id)
+ {
+ 	struct tipc_link *l_ptr;
+ 	struct tipc_node *n_ptr;
+ 
+ 	list_for_each_entry(n_ptr, &tipc_node_list, list) {
+ 		spin_lock_bh(&n_ptr->lock);
+ 		l_ptr = n_ptr->links[bearer_id];
+ 		if (l_ptr)
+ 			tipc_link_reset(l_ptr);
+ 		spin_unlock_bh(&n_ptr->lock);
+ 	}
+ }
  
  static void link_activate(struct tipc_link *l_ptr)
  {
@@@ -479,7 -489,10 +489,10 @@@ static void link_state_event(struct tip
  	struct tipc_link *other;
  	u32 cont_intv = l_ptr->continuity_interval;
  
- 	if (!l_ptr->started && (event != STARTING_EVT))
+ 	if (l_ptr->flags & LINK_STOPPED)
+ 		return;
+ 
+ 	if (!(l_ptr->flags & LINK_STARTED) && (event != STARTING_EVT))
  		return;		/* Not yet. */
  
  	/* Check whether changeover is going on */
@@@ -499,12 -512,12 +512,12 @@@
  			if (l_ptr->next_in_no != l_ptr->checkpoint) {
  				l_ptr->checkpoint = l_ptr->next_in_no;
  				if (tipc_bclink_acks_missing(l_ptr->owner)) {
- 					tipc_link_send_proto_msg(l_ptr, STATE_MSG,
- 								 0, 0, 0, 0, 0);
+ 					tipc_link_proto_xmit(l_ptr, STATE_MSG,
+ 							     0, 0, 0, 0, 0);
  					l_ptr->fsm_msg_cnt++;
  				} else if (l_ptr->max_pkt < l_ptr->max_pkt_target) {
- 					tipc_link_send_proto_msg(l_ptr, STATE_MSG,
- 								 1, 0, 0, 0, 0);
+ 					tipc_link_proto_xmit(l_ptr, STATE_MSG,
+ 							     1, 0, 0, 0, 0);
  					l_ptr->fsm_msg_cnt++;
  				}
  				link_set_timer(l_ptr, cont_intv);
@@@ -512,7 -525,7 +525,7 @@@
  			}
  			l_ptr->state = WORKING_UNKNOWN;
  			l_ptr->fsm_msg_cnt = 0;
- 			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
+ 			tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
  			l_ptr->fsm_msg_cnt++;
  			link_set_timer(l_ptr, cont_intv / 4);
  			break;
@@@ -522,7 -535,8 +535,8 @@@
  			tipc_link_reset(l_ptr);
  			l_ptr->state = RESET_RESET;
  			l_ptr->fsm_msg_cnt = 0;
- 			tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
+ 			tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
+ 					     0, 0, 0, 0, 0);
  			l_ptr->fsm_msg_cnt++;
  			link_set_timer(l_ptr, cont_intv);
  			break;
@@@ -544,7 -558,8 +558,8 @@@
  			tipc_link_reset(l_ptr);
  			l_ptr->state = RESET_RESET;
  			l_ptr->fsm_msg_cnt = 0;
- 			tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
+ 			tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
+ 					     0, 0, 0, 0, 0);
  			l_ptr->fsm_msg_cnt++;
  			link_set_timer(l_ptr, cont_intv);
  			break;
@@@ -554,14 -569,14 +569,14 @@@
  				l_ptr->fsm_msg_cnt = 0;
  				l_ptr->checkpoint = l_ptr->next_in_no;
  				if (tipc_bclink_acks_missing(l_ptr->owner)) {
- 					tipc_link_send_proto_msg(l_ptr, STATE_MSG,
- 								 0, 0, 0, 0, 0);
+ 					tipc_link_proto_xmit(l_ptr, STATE_MSG,
+ 							     0, 0, 0, 0, 0);
  					l_ptr->fsm_msg_cnt++;
  				}
  				link_set_timer(l_ptr, cont_intv);
  			} else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) {
- 				tipc_link_send_proto_msg(l_ptr, STATE_MSG,
- 							 1, 0, 0, 0, 0);
+ 				tipc_link_proto_xmit(l_ptr, STATE_MSG,
+ 						     1, 0, 0, 0, 0);
  				l_ptr->fsm_msg_cnt++;
  				link_set_timer(l_ptr, cont_intv / 4);
  			} else {	/* Link has failed */
@@@ -570,8 -585,8 +585,8 @@@
  				tipc_link_reset(l_ptr);
  				l_ptr->state = RESET_UNKNOWN;
  				l_ptr->fsm_msg_cnt = 0;
- 				tipc_link_send_proto_msg(l_ptr, RESET_MSG,
- 							 0, 0, 0, 0, 0);
+ 				tipc_link_proto_xmit(l_ptr, RESET_MSG,
+ 						     0, 0, 0, 0, 0);
  				l_ptr->fsm_msg_cnt++;
  				link_set_timer(l_ptr, cont_intv);
  			}
@@@ -591,24 -606,25 +606,25 @@@
  			l_ptr->state = WORKING_WORKING;
  			l_ptr->fsm_msg_cnt = 0;
  			link_activate(l_ptr);
- 			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
+ 			tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
  			l_ptr->fsm_msg_cnt++;
  			if (l_ptr->owner->working_links == 1)
- 				tipc_link_send_sync(l_ptr);
+ 				tipc_link_sync_xmit(l_ptr);
  			link_set_timer(l_ptr, cont_intv);
  			break;
  		case RESET_MSG:
  			l_ptr->state = RESET_RESET;
  			l_ptr->fsm_msg_cnt = 0;
- 			tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0);
+ 			tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
+ 					     1, 0, 0, 0, 0);
  			l_ptr->fsm_msg_cnt++;
  			link_set_timer(l_ptr, cont_intv);
  			break;
  		case STARTING_EVT:
- 			l_ptr->started = 1;
+ 			l_ptr->flags |= LINK_STARTED;
  			/* fall through */
  		case TIMEOUT_EVT:
- 			tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0);
+ 			tipc_link_proto_xmit(l_ptr, RESET_MSG, 0, 0, 0, 0, 0);
  			l_ptr->fsm_msg_cnt++;
  			link_set_timer(l_ptr, cont_intv);
  			break;
@@@ -626,16 -642,17 +642,17 @@@
  			l_ptr->state = WORKING_WORKING;
  			l_ptr->fsm_msg_cnt = 0;
  			link_activate(l_ptr);
- 			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
+ 			tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
  			l_ptr->fsm_msg_cnt++;
  			if (l_ptr->owner->working_links == 1)
- 				tipc_link_send_sync(l_ptr);
+ 				tipc_link_sync_xmit(l_ptr);
  			link_set_timer(l_ptr, cont_intv);
  			break;
  		case RESET_MSG:
  			break;
  		case TIMEOUT_EVT:
- 			tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
+ 			tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
+ 					     0, 0, 0, 0, 0);
  			l_ptr->fsm_msg_cnt++;
  			link_set_timer(l_ptr, cont_intv);
  			break;
@@@ -721,11 -738,11 +738,11 @@@ static void link_add_chain_to_outqueue(
  }
  
  /*
-  * tipc_link_send_buf() is the 'full path' for messages, called from
-  * inside TIPC when the 'fast path' in tipc_send_buf
+  * tipc_link_xmit() is the 'full path' for messages, called from
+  * inside TIPC when the 'fast path' in tipc_send_xmit
   * has failed, and from link_send()
   */
- int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
+ int __tipc_link_xmit(struct tipc_link *l_ptr, struct sk_buff *buf)
  {
  	struct tipc_msg *msg = buf_msg(buf);
  	u32 size = msg_size(msg);
@@@ -753,7 -770,7 +770,7 @@@
  
  	/* Fragmentation needed ? */
  	if (size > max_packet)
- 		return link_send_long_buf(l_ptr, buf);
+ 		return tipc_link_frag_xmit(l_ptr, buf);
  
  	/* Packet can be queued or sent. */
  	if (likely(!link_congested(l_ptr))) {
@@@ -797,11 -814,11 +814,11 @@@
  }
  
  /*
-  * tipc_link_send(): same as tipc_link_send_buf(), but the link to use has
-  * not been selected yet, and the the owner node is not locked
+  * tipc_link_xmit(): same as __tipc_link_xmit(), but the link to use
+  * has not been selected yet, and the the owner node is not locked
   * Called by TIPC internal users, e.g. the name distributor
   */
- int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
+ int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector)
  {
  	struct tipc_link *l_ptr;
  	struct tipc_node *n_ptr;
@@@ -813,7 -830,7 +830,7 @@@
  		tipc_node_lock(n_ptr);
  		l_ptr = n_ptr->active_links[selector & 1];
  		if (l_ptr)
- 			res = tipc_link_send_buf(l_ptr, buf);
+ 			res = __tipc_link_xmit(l_ptr, buf);
  		else
  			kfree_skb(buf);
  		tipc_node_unlock(n_ptr);
@@@ -825,14 -842,14 +842,14 @@@
  }
  
  /*
-  * tipc_link_send_sync - synchronize broadcast link endpoints.
+  * tipc_link_sync_xmit - synchronize broadcast link endpoints.
   *
   * Give a newly added peer node the sequence number where it should
   * start receiving and acking broadcast packets.
   *
   * Called with node locked
   */
- static void tipc_link_send_sync(struct tipc_link *l)
+ static void tipc_link_sync_xmit(struct tipc_link *l)
  {
  	struct sk_buff *buf;
  	struct tipc_msg *msg;
@@@ -849,14 -866,14 +866,14 @@@
  }
  
  /*
-  * tipc_link_recv_sync - synchronize broadcast link endpoints.
+  * tipc_link_sync_rcv - synchronize broadcast link endpoints.
   * Receive the sequence number where we should start receiving and
   * acking broadcast packets from a newly added peer node, and open
   * up for reception of such packets.
   *
   * Called with node locked
   */
- static void tipc_link_recv_sync(struct tipc_node *n, struct sk_buff *buf)
+ static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf)
  {
  	struct tipc_msg *msg = buf_msg(buf);
  
@@@ -866,7 -883,7 +883,7 @@@
  }
  
  /*
-  * tipc_link_send_names - send name table entries to new neighbor
+  * tipc_link_names_xmit - send name table entries to new neighbor
   *
   * Send routine for bulk delivery of name table messages when contact
   * with a new neighbor occurs. No link congestion checking is performed
@@@ -874,7 -891,7 +891,7 @@@
   * small enough not to require fragmentation.
   * Called without any locks held.
   */
- void tipc_link_send_names(struct list_head *message_list, u32 dest)
+ void tipc_link_names_xmit(struct list_head *message_list, u32 dest)
  {
  	struct tipc_node *n_ptr;
  	struct tipc_link *l_ptr;
@@@ -909,13 -926,13 +926,13 @@@
  }
  
  /*
-  * link_send_buf_fast: Entry for data messages where the
+  * tipc_link_xmit_fast: Entry for data messages where the
   * destination link is known and the header is complete,
   * inclusive total message length. Very time critical.
   * Link is locked. Returns user data length.
   */
- static int link_send_buf_fast(struct tipc_link *l_ptr, struct sk_buff *buf,
- 			      u32 *used_max_pkt)
+ static int tipc_link_xmit_fast(struct tipc_link *l_ptr, struct sk_buff *buf,
+ 			       u32 *used_max_pkt)
  {
  	struct tipc_msg *msg = buf_msg(buf);
  	int res = msg_data_sz(msg);
@@@ -931,18 -948,18 +948,18 @@@
  		else
  			*used_max_pkt = l_ptr->max_pkt;
  	}
- 	return tipc_link_send_buf(l_ptr, buf);  /* All other cases */
+ 	return __tipc_link_xmit(l_ptr, buf);  /* All other cases */
  }
  
  /*
-  * tipc_link_send_sections_fast: Entry for messages where the
+  * tipc_link_iovec_xmit_fast: Entry for messages where the
   * destination processor is known and the header is complete,
   * except for total message length.
   * Returns user data length or errno.
   */
- int tipc_link_send_sections_fast(struct tipc_port *sender,
- 				 struct iovec const *msg_sect,
- 				 unsigned int len, u32 destaddr)
+ int tipc_link_iovec_xmit_fast(struct tipc_port *sender,
+ 			      struct iovec const *msg_sect,
+ 			      unsigned int len, u32 destaddr)
  {
  	struct tipc_msg *hdr = &sender->phdr;
  	struct tipc_link *l_ptr;
@@@ -968,8 -985,8 +985,8 @@@ again
  		l_ptr = node->active_links[selector];
  		if (likely(l_ptr)) {
  			if (likely(buf)) {
- 				res = link_send_buf_fast(l_ptr, buf,
- 							 &sender->max_pkt);
+ 				res = tipc_link_xmit_fast(l_ptr, buf,
+ 							  &sender->max_pkt);
  exit:
  				tipc_node_unlock(node);
  				read_unlock_bh(&tipc_net_lock);
@@@ -995,8 -1012,8 +1012,8 @@@
  			if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
  				goto again;
  
- 			return link_send_sections_long(sender, msg_sect, len,
- 						       destaddr);
+ 			return tipc_link_iovec_long_xmit(sender, msg_sect,
+ 							 len, destaddr);
  		}
  		tipc_node_unlock(node);
  	}
@@@ -1006,13 -1023,13 +1023,13 @@@
  	if (buf)
  		return tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
  	if (res >= 0)
- 		return tipc_port_reject_sections(sender, hdr, msg_sect,
- 						 len, TIPC_ERR_NO_NODE);
+ 		return tipc_port_iovec_reject(sender, hdr, msg_sect, len,
+ 					      TIPC_ERR_NO_NODE);
  	return res;
  }
  
  /*
-  * link_send_sections_long(): Entry for long messages where the
+  * tipc_link_iovec_long_xmit(): Entry for long messages where the
   * destination node is known and the header is complete,
   * inclusive total message length.
   * Link and bearer congestion status have been checked to be ok,
@@@ -1025,9 -1042,9 +1042,9 @@@
   *
   * Returns user data length or errno.
   */
- static int link_send_sections_long(struct tipc_port *sender,
- 				   struct iovec const *msg_sect,
- 				   unsigned int len, u32 destaddr)
+ static int tipc_link_iovec_long_xmit(struct tipc_port *sender,
+ 				     struct iovec const *msg_sect,
+ 				     unsigned int len, u32 destaddr)
  {
  	struct tipc_link *l_ptr;
  	struct tipc_node *node;
@@@ -1146,8 -1163,8 +1163,8 @@@ error
  	} else {
  reject:
  		kfree_skb_list(buf_chain);
- 		return tipc_port_reject_sections(sender, hdr, msg_sect,
- 						 len, TIPC_ERR_NO_NODE);
+ 		return tipc_port_iovec_reject(sender, hdr, msg_sect,
+ 					      len, TIPC_ERR_NO_NODE);
  	}
  
  	/* Append chain of fragments to send queue & send them */
@@@ -1391,12 -1408,6 +1408,12 @@@ static int link_recv_buf_validate(struc
  	u32 hdr_size;
  	u32 min_hdr_size;
  
 +	/* If this packet comes from the defer queue, the skb has already
 +	 * been validated
 +	 */
 +	if (unlikely(TIPC_SKB_CB(buf)->deferred))
 +		return 1;
 +
  	if (unlikely(buf->len < MIN_H_SIZE))
  		return 0;
  
@@@ -1441,7 -1452,6 +1458,6 @@@ void tipc_rcv(struct sk_buff *head, str
  		u32 seq_no;
  		u32 ackd;
  		u32 released = 0;
- 		int type;
  
  		head = head->next;
  		buf->next = NULL;
@@@ -1463,9 -1473,9 +1479,9 @@@
  
  		if (unlikely(msg_non_seq(msg))) {
  			if (msg_user(msg) ==  LINK_CONFIG)
- 				tipc_disc_recv_msg(buf, b_ptr);
+ 				tipc_disc_rcv(buf, b_ptr);
  			else
- 				tipc_bclink_recv_pkt(buf);
+ 				tipc_bclink_rcv(buf);
  			continue;
  		}
  
@@@ -1489,7 -1499,7 +1505,7 @@@
  		if ((n_ptr->block_setup & WAIT_PEER_DOWN) &&
  			msg_user(msg) == LINK_PROTOCOL &&
  			(msg_type(msg) == RESET_MSG ||
- 					msg_type(msg) == ACTIVATE_MSG) &&
+ 			 msg_type(msg) == ACTIVATE_MSG) &&
  			!msg_redundant_link(msg))
  			n_ptr->block_setup &= ~WAIT_PEER_DOWN;
  
@@@ -1508,7 -1518,6 +1524,6 @@@
  		while ((crs != l_ptr->next_out) &&
  		       less_eq(buf_seqno(crs), ackd)) {
  			struct sk_buff *next = crs->next;
- 
  			kfree_skb(crs);
  			crs = next;
  			released++;
@@@ -1521,18 -1530,19 +1536,19 @@@
  		/* Try sending any messages link endpoint has pending */
  		if (unlikely(l_ptr->next_out))
  			tipc_link_push_queue(l_ptr);
+ 
  		if (unlikely(!list_empty(&l_ptr->waiting_ports)))
  			tipc_link_wakeup_ports(l_ptr, 0);
+ 
  		if (unlikely(++l_ptr->unacked_window >= TIPC_MIN_LINK_WIN)) {
  			l_ptr->stats.sent_acks++;
- 			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
+ 			tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
  		}
  
- 		/* Now (finally!) process the incoming message */
- protocol_check:
+ 		/* Process the incoming packet */
  		if (unlikely(!link_working_working(l_ptr))) {
  			if (msg_user(msg) == LINK_PROTOCOL) {
- 				link_recv_proto_msg(l_ptr, buf);
+ 				tipc_link_proto_rcv(l_ptr, buf);
  				head = link_insert_deferred_queue(l_ptr, head);
  				tipc_node_unlock(n_ptr);
  				continue;
@@@ -1561,67 -1571,65 +1577,65 @@@
  		l_ptr->next_in_no++;
  		if (unlikely(l_ptr->oldest_deferred_in))
  			head = link_insert_deferred_queue(l_ptr, head);
- deliver:
- 		if (likely(msg_isdata(msg))) {
- 			tipc_node_unlock(n_ptr);
- 			tipc_port_recv_msg(buf);
- 			continue;
+ 
+ 		/* Deliver packet/message to correct user: */
+ 		if (unlikely(msg_user(msg) ==  CHANGEOVER_PROTOCOL)) {
+ 			if (!tipc_link_tunnel_rcv(n_ptr, &buf)) {
+ 				tipc_node_unlock(n_ptr);
+ 				continue;
+ 			}
+ 			msg = buf_msg(buf);
+ 		} else if (msg_user(msg) == MSG_FRAGMENTER) {
+ 			int rc;
+ 
+ 			l_ptr->stats.recv_fragments++;
+ 			rc = tipc_link_frag_rcv(&l_ptr->reasm_head,
+ 						&l_ptr->reasm_tail,
+ 						&buf);
+ 			if (rc == LINK_REASM_COMPLETE) {
+ 				l_ptr->stats.recv_fragmented++;
+ 				msg = buf_msg(buf);
+ 			} else {
+ 				if (rc == LINK_REASM_ERROR)
+ 					tipc_link_reset(l_ptr);
+ 				tipc_node_unlock(n_ptr);
+ 				continue;
+ 			}
  		}
+ 
  		switch (msg_user(msg)) {
- 			int ret;
+ 		case TIPC_LOW_IMPORTANCE:
+ 		case TIPC_MEDIUM_IMPORTANCE:
+ 		case TIPC_HIGH_IMPORTANCE:
+ 		case TIPC_CRITICAL_IMPORTANCE:
+ 			tipc_node_unlock(n_ptr);
+ 			tipc_port_rcv(buf);
+ 			continue;
  		case MSG_BUNDLER:
  			l_ptr->stats.recv_bundles++;
  			l_ptr->stats.recv_bundled += msg_msgcnt(msg);
  			tipc_node_unlock(n_ptr);
- 			tipc_link_recv_bundle(buf);
+ 			tipc_link_bundle_rcv(buf);
  			continue;
  		case NAME_DISTRIBUTOR:
  			n_ptr->bclink.recv_permitted = true;
  			tipc_node_unlock(n_ptr);
- 			tipc_named_recv(buf);
- 			continue;
- 		case BCAST_PROTOCOL:
- 			tipc_link_recv_sync(n_ptr, buf);
- 			tipc_node_unlock(n_ptr);
+ 			tipc_named_rcv(buf);
  			continue;
  		case CONN_MANAGER:
  			tipc_node_unlock(n_ptr);
- 			tipc_port_recv_proto_msg(buf);
+ 			tipc_port_proto_rcv(buf);
  			continue;
- 		case MSG_FRAGMENTER:
- 			l_ptr->stats.recv_fragments++;
- 			ret = tipc_link_recv_fragment(&l_ptr->reasm_head,
- 						      &l_ptr->reasm_tail,
- 						      &buf);
- 			if (ret == LINK_REASM_COMPLETE) {
- 				l_ptr->stats.recv_fragmented++;
- 				msg = buf_msg(buf);
- 				goto deliver;
- 			}
- 			if (ret == LINK_REASM_ERROR)
- 				tipc_link_reset(l_ptr);
- 			tipc_node_unlock(n_ptr);
- 			continue;
- 		case CHANGEOVER_PROTOCOL:
- 			type = msg_type(msg);
- 			if (tipc_link_tunnel_rcv(&l_ptr, &buf)) {
- 				msg = buf_msg(buf);
- 				seq_no = msg_seqno(msg);
- 				if (type == ORIGINAL_MSG)
- 					goto deliver;
- 				goto protocol_check;
- 			}
+ 		case BCAST_PROTOCOL:
+ 			tipc_link_sync_rcv(n_ptr, buf);
  			break;
  		default:
  			kfree_skb(buf);
  			break;
  		}
  		tipc_node_unlock(n_ptr);
- 		tipc_net_route_msg(buf);
  		continue;
  unlock_discard:
- 
  		tipc_node_unlock(n_ptr);
  discard:
  		kfree_skb(buf);
@@@ -1688,7 -1696,7 +1702,7 @@@ static void link_handle_out_of_seq_msg(
  	u32 seq_no = buf_seqno(buf);
  
  	if (likely(msg_user(buf_msg(buf)) == LINK_PROTOCOL)) {
- 		link_recv_proto_msg(l_ptr, buf);
+ 		tipc_link_proto_rcv(l_ptr, buf);
  		return;
  	}
  
@@@ -1709,9 -1717,8 +1723,9 @@@
  				&l_ptr->newest_deferred_in, buf)) {
  		l_ptr->deferred_inqueue_sz++;
  		l_ptr->stats.deferred_recv++;
 +		TIPC_SKB_CB(buf)->deferred = true;
  		if ((l_ptr->deferred_inqueue_sz % 16) == 1)
- 			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
+ 			tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
  	} else
  		l_ptr->stats.duplicates++;
  }
@@@ -1719,9 -1726,8 +1733,8 @@@
  /*
   * Send protocol message to the other endpoint.
   */
- void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
- 			      int probe_msg, u32 gap, u32 tolerance,
- 			      u32 priority, u32 ack_mtu)
+ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
+ 			  u32 gap, u32 tolerance, u32 priority, u32 ack_mtu)
  {
  	struct sk_buff *buf = NULL;
  	struct tipc_msg *msg = l_ptr->pmsg;
@@@ -1820,7 -1826,7 +1833,7 @@@
   * Note that network plane id propagates through the network, and may
   * change at any time. The node with lowest address rules
   */
- static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf)
+ static void tipc_link_proto_rcv(struct tipc_link *l_ptr, struct sk_buff *buf)
  {
  	u32 rec_gap = 0;
  	u32 max_pkt_info;
@@@ -1939,8 -1945,8 +1952,8 @@@
  						      msg_last_bcast(msg));
  
  		if (rec_gap || (msg_probe(msg))) {
- 			tipc_link_send_proto_msg(l_ptr, STATE_MSG,
- 						 0, rec_gap, 0, 0, max_pkt_ack);
+ 			tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, rec_gap, 0,
+ 					     0, max_pkt_ack);
  		}
  		if (msg_seq_gap(msg)) {
  			l_ptr->stats.recv_nacks++;
@@@ -1979,7 -1985,7 +1992,7 @@@ static void tipc_link_tunnel_xmit(struc
  	}
  	skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE);
  	skb_copy_to_linear_data_offset(buf, INT_H_SIZE, msg, length);
- 	tipc_link_send_buf(tunnel, buf);
+ 	__tipc_link_xmit(tunnel, buf);
  }
  
  
@@@ -2012,7 -2018,7 +2025,7 @@@ void tipc_link_failover_send_queue(stru
  		if (buf) {
  			skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE);
  			msg_set_size(&tunnel_hdr, INT_H_SIZE);
- 			tipc_link_send_buf(tunnel, buf);
+ 			__tipc_link_xmit(tunnel, buf);
  		} else {
  			pr_warn("%sunable to send changeover msg\n",
  				link_co_err);
@@@ -2046,7 -2052,7 +2059,7 @@@
  	}
  }
  
- /* tipc_link_dup_send_queue(): A second link has become active. Tunnel a
+ /* tipc_link_dup_queue_xmit(): A second link has become active. Tunnel a
   * duplicate of the first link's send queue via the new link. This way, we
   * are guaranteed that currently queued packets from a socket are delivered
   * before future traffic from the same socket, even if this is using the
@@@ -2055,7 -2061,7 +2068,7 @@@
   * and sequence order is preserved per sender/receiver socket pair.
   * Owner node is locked.
   */
- void tipc_link_dup_send_queue(struct tipc_link *l_ptr,
+ void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr,
  			      struct tipc_link *tunnel)
  {
  	struct sk_buff *iter;
@@@ -2085,7 -2091,7 +2098,7 @@@
  		skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE);
  		skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data,
  					       length);
- 		tipc_link_send_buf(tunnel, outbuf);
+ 		__tipc_link_xmit(tunnel, outbuf);
  		if (!tipc_link_is_up(l_ptr))
  			return;
  		iter = iter->next;
@@@ -2112,89 -2118,114 +2125,114 @@@ static struct sk_buff *buf_extract(stru
  	return eb;
  }
  
- /*  tipc_link_tunnel_rcv(): Receive a tunneled packet, sent
-  *  via other link as result of a failover (ORIGINAL_MSG) or
-  *  a new active link (DUPLICATE_MSG). Failover packets are
-  *  returned to the active link for delivery upwards.
+ 
+ 
+ /* tipc_link_dup_rcv(): Receive a tunnelled DUPLICATE_MSG packet.
+  * Owner node is locked.
+  */
+ static void tipc_link_dup_rcv(struct tipc_link *l_ptr,
+ 			      struct sk_buff *t_buf)
+ {
+ 	struct sk_buff *buf;
+ 
+ 	if (!tipc_link_is_up(l_ptr))
+ 		return;
+ 
+ 	buf = buf_extract(t_buf, INT_H_SIZE);
+ 	if (buf == NULL) {
+ 		pr_warn("%sfailed to extract inner dup pkt\n", link_co_err);
+ 		return;
+ 	}
+ 
+ 	/* Add buffer to deferred queue, if applicable: */
+ 	link_handle_out_of_seq_msg(l_ptr, buf);
+ }
+ 
+ /*  tipc_link_failover_rcv(): Receive a tunnelled ORIGINAL_MSG packet
   *  Owner node is locked.
   */
- static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
- 				struct sk_buff **buf)
+ static struct sk_buff *tipc_link_failover_rcv(struct tipc_link *l_ptr,
+ 					      struct sk_buff *t_buf)
  {
- 	struct sk_buff *tunnel_buf = *buf;
- 	struct tipc_link *dest_link;
+ 	struct tipc_msg *t_msg = buf_msg(t_buf);
+ 	struct sk_buff *buf = NULL;
  	struct tipc_msg *msg;
- 	struct tipc_msg *tunnel_msg = buf_msg(tunnel_buf);
- 	u32 msg_typ = msg_type(tunnel_msg);
- 	u32 msg_count = msg_msgcnt(tunnel_msg);
- 	u32 bearer_id = msg_bearer_id(tunnel_msg);
  
- 	if (bearer_id >= MAX_BEARERS)
- 		goto exit;
- 	dest_link = (*l_ptr)->owner->links[bearer_id];
- 	if (!dest_link)
- 		goto exit;
- 	if (dest_link == *l_ptr) {
- 		pr_err("Unexpected changeover message on link <%s>\n",
- 		       (*l_ptr)->name);
- 		goto exit;
- 	}
- 	*l_ptr = dest_link;
- 	msg = msg_get_wrapped(tunnel_msg);
+ 	if (tipc_link_is_up(l_ptr))
+ 		tipc_link_reset(l_ptr);
  
- 	if (msg_typ == DUPLICATE_MSG) {
- 		if (less(msg_seqno(msg), mod(dest_link->next_in_no)))
- 			goto exit;
- 		*buf = buf_extract(tunnel_buf, INT_H_SIZE);
- 		if (*buf == NULL) {
- 			pr_warn("%sduplicate msg dropped\n", link_co_err);
+ 	/* First failover packet? */
+ 	if (l_ptr->exp_msg_count == START_CHANGEOVER)
+ 		l_ptr->exp_msg_count = msg_msgcnt(t_msg);
+ 
+ 	/* Should there be an inner packet? */
+ 	if (l_ptr->exp_msg_count) {
+ 		l_ptr->exp_msg_count--;
+ 		buf = buf_extract(t_buf, INT_H_SIZE);
+ 		if (buf == NULL) {
+ 			pr_warn("%sno inner failover pkt\n", link_co_err);
  			goto exit;
  		}
- 		kfree_skb(tunnel_buf);
- 		return 1;
- 	}
+ 		msg = buf_msg(buf);
  
- 	/* First original message ?: */
- 	if (tipc_link_is_up(dest_link)) {
- 		pr_info("%s<%s>, changeover initiated by peer\n", link_rst_msg,
- 			dest_link->name);
- 		tipc_link_reset(dest_link);
- 		dest_link->exp_msg_count = msg_count;
- 		if (!msg_count)
- 			goto exit;
- 	} else if (dest_link->exp_msg_count == START_CHANGEOVER) {
- 		dest_link->exp_msg_count = msg_count;
- 		if (!msg_count)
+ 		if (less(msg_seqno(msg), l_ptr->reset_checkpoint)) {
+ 			kfree_skb(buf);
+ 			buf = NULL;
  			goto exit;
+ 		}
+ 		if (msg_user(msg) == MSG_FRAGMENTER) {
+ 			l_ptr->stats.recv_fragments++;
+ 			tipc_link_frag_rcv(&l_ptr->reasm_head,
+ 					   &l_ptr->reasm_tail,
+ 					   &buf);
+ 		}
  	}
+ exit:
+ 	if ((l_ptr->exp_msg_count == 0) && (l_ptr->flags & LINK_STOPPED)) {
+ 		tipc_node_detach_link(l_ptr->owner, l_ptr);
+ 		kfree(l_ptr);
+ 	}
+ 	return buf;
+ }
+ 
+ /*  tipc_link_tunnel_rcv(): Receive a tunnelled packet, sent
+  *  via other link as result of a failover (ORIGINAL_MSG) or
+  *  a new active link (DUPLICATE_MSG). Failover packets are
+  *  returned to the active link for delivery upwards.
+  *  Owner node is locked.
+  */
+ static int tipc_link_tunnel_rcv(struct tipc_node *n_ptr,
+ 				struct sk_buff **buf)
+ {
+ 	struct sk_buff *t_buf = *buf;
+ 	struct tipc_link *l_ptr;
+ 	struct tipc_msg *t_msg = buf_msg(t_buf);
+ 	u32 bearer_id = msg_bearer_id(t_msg);
  
- 	/* Receive original message */
- 	if (dest_link->exp_msg_count == 0) {
- 		pr_warn("%sgot too many tunnelled messages\n", link_co_err);
+ 	*buf = NULL;
+ 
+ 	if (bearer_id >= MAX_BEARERS)
  		goto exit;
- 	}
- 	dest_link->exp_msg_count--;
- 	if (less(msg_seqno(msg), dest_link->reset_checkpoint)) {
+ 
+ 	l_ptr = n_ptr->links[bearer_id];
+ 	if (!l_ptr)
  		goto exit;
- 	} else {
- 		*buf = buf_extract(tunnel_buf, INT_H_SIZE);
- 		if (*buf != NULL) {
- 			kfree_skb(tunnel_buf);
- 			return 1;
- 		} else {
- 			pr_warn("%soriginal msg dropped\n", link_co_err);
- 		}
- 	}
+ 
+ 	if (msg_type(t_msg) == DUPLICATE_MSG)
+ 		tipc_link_dup_rcv(l_ptr, t_buf);
+ 	else if (msg_type(t_msg) == ORIGINAL_MSG)
+ 		*buf = tipc_link_failover_rcv(l_ptr, t_buf);
+ 	else
+ 		pr_warn("%sunknown tunnel pkt received\n", link_co_err);
  exit:
- 	*buf = NULL;
- 	kfree_skb(tunnel_buf);
- 	return 0;
+ 	kfree_skb(t_buf);
+ 	return *buf != NULL;
  }
  
  /*
   *  Bundler functionality:
   */
- void tipc_link_recv_bundle(struct sk_buff *buf)
+ void tipc_link_bundle_rcv(struct sk_buff *buf)
  {
  	u32 msgcount = msg_msgcnt(buf_msg(buf));
  	u32 pos = INT_H_SIZE;
@@@ -2217,11 -2248,11 +2255,11 @@@
   */
  
  /*
-  * link_send_long_buf: Entry for buffers needing fragmentation.
+  * tipc_link_frag_xmit: Entry for buffers needing fragmentation.
   * The buffer is complete, inclusive total message length.
   * Returns user data length.
   */
- static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
+ static int tipc_link_frag_xmit(struct tipc_link *l_ptr, struct sk_buff *buf)
  {
  	struct sk_buff *buf_chain = NULL;
  	struct sk_buff *buf_chain_tail = (struct sk_buff *)&buf_chain;
@@@ -2284,12 -2315,11 +2322,11 @@@
  	return dsz;
  }
  
- /*
-  * tipc_link_recv_fragment(): Called with node lock on. Returns
+ /* tipc_link_frag_rcv(): Called with node lock on. Returns
   * the reassembled buffer if message is complete.
   */
- int tipc_link_recv_fragment(struct sk_buff **head, struct sk_buff **tail,
- 			    struct sk_buff **fbuf)
+ int tipc_link_frag_rcv(struct sk_buff **head, struct sk_buff **tail,
+ 		       struct sk_buff **fbuf)
  {
  	struct sk_buff *frag = *fbuf;
  	struct tipc_msg *msg = buf_msg(frag);
@@@ -2303,6 -2333,7 +2340,7 @@@
  			goto out_free;
  		*head = frag;
  		skb_frag_list_init(*head);
+ 		*fbuf = NULL;
  		return 0;
  	} else if (*head &&
  		   skb_try_coalesce(*head, frag, &headstolen, &delta)) {
@@@ -2322,10 -2353,12 +2360,12 @@@
  		*tail = *head = NULL;
  		return LINK_REASM_COMPLETE;
  	}
+ 	*fbuf = NULL;
  	return 0;
  out_free:
  	pr_warn_ratelimited("Link unable to reassemble fragmented message\n");
  	kfree_skb(*fbuf);
+ 	*fbuf = NULL;
  	return LINK_REASM_ERROR;
  }
  
@@@ -2359,35 -2392,40 +2399,40 @@@ void tipc_link_set_queue_limits(struct 
  	l_ptr->queue_limit[MSG_FRAGMENTER] = 4000;
  }
  
- /**
-  * link_find_link - locate link by name
-  * @name: ptr to link name string
-  * @node: ptr to area to be filled with ptr to associated node
-  *
+ /* tipc_link_find_owner - locate owner node of link by link's name
+  * @name: pointer to link name string
+  * @bearer_id: pointer to index in 'node->links' array where the link was found.
   * Caller must hold 'tipc_net_lock' to ensure node and bearer are not deleted;
   * this also prevents link deletion.
   *
-  * Returns pointer to link (or 0 if invalid link name).
+  * Returns pointer to node owning the link, or 0 if no matching link is found.
   */
- static struct tipc_link *link_find_link(const char *name,
- 					struct tipc_node **node)
+ static struct tipc_node *tipc_link_find_owner(const char *link_name,
+ 					      unsigned int *bearer_id)
  {
  	struct tipc_link *l_ptr;
  	struct tipc_node *n_ptr;
+ 	struct tipc_node *tmp_n_ptr;
+ 	struct tipc_node *found_node = 0;
+ 
  	int i;
  
- 	list_for_each_entry(n_ptr, &tipc_node_list, list) {
+ 	*bearer_id = 0;
+ 	list_for_each_entry_safe(n_ptr, tmp_n_ptr, &tipc_node_list, list) {
+ 		tipc_node_lock(n_ptr);
  		for (i = 0; i < MAX_BEARERS; i++) {
  			l_ptr = n_ptr->links[i];
- 			if (l_ptr && !strcmp(l_ptr->name, name))
- 				goto found;
+ 			if (l_ptr && !strcmp(l_ptr->name, link_name)) {
+ 				*bearer_id = i;
+ 				found_node = n_ptr;
+ 				break;
+ 			}
  		}
+ 		tipc_node_unlock(n_ptr);
+ 		if (found_node)
+ 			break;
  	}
- 	l_ptr = NULL;
- 	n_ptr = NULL;
- found:
- 	*node = n_ptr;
- 	return l_ptr;
+ 	return found_node;
  }
  
  /**
@@@ -2429,32 -2467,33 +2474,33 @@@ static int link_cmd_set_value(const cha
  	struct tipc_link *l_ptr;
  	struct tipc_bearer *b_ptr;
  	struct tipc_media *m_ptr;
+ 	int bearer_id;
  	int res = 0;
  
- 	l_ptr = link_find_link(name, &node);
- 	if (l_ptr) {
- 		/*
- 		 * acquire node lock for tipc_link_send_proto_msg().
- 		 * see "TIPC locking policy" in net.c.
- 		 */
+ 	node = tipc_link_find_owner(name, &bearer_id);
+ 	if (node) {
  		tipc_node_lock(node);
- 		switch (cmd) {
- 		case TIPC_CMD_SET_LINK_TOL:
- 			link_set_supervision_props(l_ptr, new_value);
- 			tipc_link_send_proto_msg(l_ptr,
- 				STATE_MSG, 0, 0, new_value, 0, 0);
- 			break;
- 		case TIPC_CMD_SET_LINK_PRI:
- 			l_ptr->priority = new_value;
- 			tipc_link_send_proto_msg(l_ptr,
- 				STATE_MSG, 0, 0, 0, new_value, 0);
- 			break;
- 		case TIPC_CMD_SET_LINK_WINDOW:
- 			tipc_link_set_queue_limits(l_ptr, new_value);
- 			break;
- 		default:
- 			res = -EINVAL;
- 			break;
+ 		l_ptr = node->links[bearer_id];
+ 
+ 		if (l_ptr) {
+ 			switch (cmd) {
+ 			case TIPC_CMD_SET_LINK_TOL:
+ 				link_set_supervision_props(l_ptr, new_value);
+ 				tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0,
+ 						     new_value, 0, 0);
+ 				break;
+ 			case TIPC_CMD_SET_LINK_PRI:
+ 				l_ptr->priority = new_value;
+ 				tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0,
+ 						     0, new_value, 0);
+ 				break;
+ 			case TIPC_CMD_SET_LINK_WINDOW:
+ 				tipc_link_set_queue_limits(l_ptr, new_value);
+ 				break;
+ 			default:
+ 				res = -EINVAL;
+ 				break;
+ 			}
  		}
  		tipc_node_unlock(node);
  		return res;
@@@ -2549,6 -2588,7 +2595,7 @@@ struct sk_buff *tipc_link_cmd_reset_sta
  	char *link_name;
  	struct tipc_link *l_ptr;
  	struct tipc_node *node;
+ 	unsigned int bearer_id;
  
  	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME))
  		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@@ -2559,15 -2599,19 +2606,19 @@@
  			return tipc_cfg_reply_error_string("link not found");
  		return tipc_cfg_reply_none();
  	}
- 
  	read_lock_bh(&tipc_net_lock);
- 	l_ptr = link_find_link(link_name, &node);
- 	if (!l_ptr) {
+ 	node = tipc_link_find_owner(link_name, &bearer_id);
+ 	if (!node) {
  		read_unlock_bh(&tipc_net_lock);
  		return tipc_cfg_reply_error_string("link not found");
  	}
- 
  	tipc_node_lock(node);
+ 	l_ptr = node->links[bearer_id];
+ 	if (!l_ptr) {
+ 		tipc_node_unlock(node);
+ 		read_unlock_bh(&tipc_net_lock);
+ 		return tipc_cfg_reply_error_string("link not found");
+ 	}
  	link_reset_statistics(l_ptr);
  	tipc_node_unlock(node);
  	read_unlock_bh(&tipc_net_lock);
@@@ -2597,18 -2641,27 +2648,27 @@@ static int tipc_link_stats(const char *
  	struct tipc_node *node;
  	char *status;
  	u32 profile_total = 0;
+ 	unsigned int bearer_id;
  	int ret;
  
  	if (!strcmp(name, tipc_bclink_name))
  		return tipc_bclink_stats(buf, buf_size);
  
  	read_lock_bh(&tipc_net_lock);
- 	l = link_find_link(name, &node);
- 	if (!l) {
+ 	node = tipc_link_find_owner(name, &bearer_id);
+ 	if (!node) {
  		read_unlock_bh(&tipc_net_lock);
  		return 0;
  	}
  	tipc_node_lock(node);
+ 
+ 	l = node->links[bearer_id];
+ 	if (!l) {
+ 		tipc_node_unlock(node);
+ 		read_unlock_bh(&tipc_net_lock);
+ 		return 0;
+ 	}
+ 
  	s = &l->stats;
  
  	if (tipc_link_is_active(l))

-- 
LinuxNextTracking


More information about the linux-merge mailing list