netpoll: disable netpoll when enslave a device
[pandora-kernel.git] / drivers / net / bonding / bond_main.c
index 16d6fe9..f4960f5 100644 (file)
@@ -89,8 +89,7 @@
 
 static int max_bonds   = BOND_DEFAULT_MAX_BONDS;
 static int tx_queues   = BOND_DEFAULT_TX_QUEUES;
-static int num_grat_arp = 1;
-static int num_unsol_na = 1;
+static int num_peer_notif = 1;
 static int miimon      = BOND_LINK_MON_INTERV;
 static int updelay;
 static int downdelay;
@@ -113,10 +112,10 @@ module_param(max_bonds, int, 0);
 MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
 module_param(tx_queues, int, 0);
 MODULE_PARM_DESC(tx_queues, "Max number of transmit queues (default = 16)");
-module_param(num_grat_arp, int, 0644);
-MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event");
-module_param(num_unsol_na, int, 0644);
-MODULE_PARM_DESC(num_unsol_na, "Number of unsolicited IPv6 Neighbor Advertisements packets to send on failover event");
+module_param_named(num_grat_arp, num_peer_notif, int, 0644);
+MODULE_PARM_DESC(num_grat_arp, "Number of peer notifications to send on failover event (alias of num_unsol_na)");
+module_param_named(num_unsol_na, num_peer_notif, int, 0644);
+MODULE_PARM_DESC(num_unsol_na, "Number of peer notifications to send on failover event (alias of num_grat_arp)");
 module_param(miimon, int, 0);
 MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
 module_param(updelay, int, 0);
@@ -234,7 +233,6 @@ struct bond_parm_tbl ad_select_tbl[] = {
 
 /*-------------------------- Forward declarations ---------------------------*/
 
-static void bond_send_gratuitous_arp(struct bonding *bond);
 static int bond_init(struct net_device *bond_dev);
 static void bond_uninit(struct net_device *bond_dev);
 
@@ -345,32 +343,6 @@ out:
        return res;
 }
 
-/**
- * bond_has_challenged_slaves
- * @bond: the bond we're working on
- *
- * Searches the slave list. Returns 1 if a vlan challenged slave
- * was found, 0 otherwise.
- *
- * Assumes bond->lock is held.
- */
-static int bond_has_challenged_slaves(struct bonding *bond)
-{
-       struct slave *slave;
-       int i;
-
-       bond_for_each_slave(bond, slave, i) {
-               if (slave->dev->features & NETIF_F_VLAN_CHALLENGED) {
-                       pr_debug("found VLAN challenged slave - %s\n",
-                                slave->dev->name);
-                       return 1;
-               }
-       }
-
-       pr_debug("no VLAN challenged slaves found\n");
-       return 0;
-}
-
 /**
  * bond_next_vlan - safely skip to the next item in the vlans list.
  * @bond: the bond we're working on
@@ -631,7 +603,8 @@ down:
 static int bond_update_speed_duplex(struct slave *slave)
 {
        struct net_device *slave_dev = slave->dev;
-       struct ethtool_cmd etool;
+       struct ethtool_cmd etool = { .cmd = ETHTOOL_GSET };
+       u32 slave_speed;
        int res;
 
        /* Fake speed and duplex */
@@ -645,7 +618,8 @@ static int bond_update_speed_duplex(struct slave *slave)
        if (res < 0)
                return -1;
 
-       switch (etool.speed) {
+       slave_speed = ethtool_cmd_speed(&etool);
+       switch (slave_speed) {
        case SPEED_10:
        case SPEED_100:
        case SPEED_1000:
@@ -663,7 +637,7 @@ static int bond_update_speed_duplex(struct slave *slave)
                return -1;
        }
 
-       slave->speed = etool.speed;
+       slave->speed = slave_speed;
        slave->duplex = etool.duplex;
 
        return 0;
@@ -1087,6 +1061,21 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
        return bestslave;
 }
 
+static bool bond_should_notify_peers(struct bonding *bond)
+{
+       struct slave *slave = bond->curr_active_slave;
+
+       pr_debug("bond_should_notify_peers: bond %s slave %s\n",
+                bond->dev->name, slave ? slave->dev->name : "NULL");
+
+       if (!slave || !bond->send_peer_notif ||
+           test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
+               return false;
+
+       bond->send_peer_notif--;
+       return true;
+}
+
 /**
  * change_active_interface - change the active slave into the specified one
  * @bond: our bonding struct
@@ -1154,6 +1143,8 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
                        bond_set_slave_inactive_flags(old_active);
 
                if (new_active) {
+                       bool should_notify_peers = false;
+
                        bond_set_slave_active_flags(new_active);
 
                        if (bond->params.fail_over_mac)
@@ -1161,17 +1152,19 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
                                                      old_active);
 
                        if (netif_running(bond->dev)) {
-                               bond->send_grat_arp = bond->params.num_grat_arp;
-                               bond_send_gratuitous_arp(bond);
-
-                               bond->send_unsol_na = bond->params.num_unsol_na;
-                               bond_send_unsolicited_na(bond);
+                               bond->send_peer_notif =
+                                       bond->params.num_peer_notif;
+                               should_notify_peers =
+                                       bond_should_notify_peers(bond);
                        }
 
                        write_unlock_bh(&bond->curr_slave_lock);
                        read_unlock(&bond->lock);
 
                        netdev_bonding_change(bond->dev, NETDEV_BONDING_FAILOVER);
+                       if (should_notify_peers)
+                               netdev_bonding_change(bond->dev,
+                                                     NETDEV_NOTIFY_PEERS);
 
                        read_lock(&bond->lock);
                        write_lock_bh(&bond->curr_slave_lock);
@@ -1387,52 +1380,68 @@ static int bond_sethwaddr(struct net_device *bond_dev,
        return 0;
 }
 
-#define BOND_VLAN_FEATURES \
-       (NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | \
-        NETIF_F_HW_VLAN_FILTER)
-
-/*
- * Compute the common dev->feature set available to all slaves.  Some
- * feature bits are managed elsewhere, so preserve those feature bits
- * on the master device.
- */
-static int bond_compute_features(struct bonding *bond)
+static u32 bond_fix_features(struct net_device *dev, u32 features)
 {
        struct slave *slave;
-       struct net_device *bond_dev = bond->dev;
-       u32 features = bond_dev->features;
-       u32 vlan_features = 0;
-       unsigned short max_hard_header_len = max((u16)ETH_HLEN,
-                                               bond_dev->hard_header_len);
+       struct bonding *bond = netdev_priv(dev);
+       u32 mask;
        int i;
 
-       features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);
-       features |=  NETIF_F_GSO_MASK | NETIF_F_NO_CSUM;
+       read_lock(&bond->lock);
 
-       if (!bond->first_slave)
-               goto done;
+       if (!bond->first_slave) {
+               /* Disable adding VLANs to empty bond. But why? --mq */
+               features |= NETIF_F_VLAN_CHALLENGED;
+               goto out;
+       }
 
+       mask = features;
        features &= ~NETIF_F_ONE_FOR_ALL;
+       features |= NETIF_F_ALL_FOR_ALL;
 
-       vlan_features = bond->first_slave->dev->vlan_features;
        bond_for_each_slave(bond, slave, i) {
                features = netdev_increment_features(features,
                                                     slave->dev->features,
-                                                    NETIF_F_ONE_FOR_ALL);
+                                                    mask);
+       }
+
+out:
+       read_unlock(&bond->lock);
+       return features;
+}
+
+#define BOND_VLAN_FEATURES     (NETIF_F_ALL_TX_OFFLOADS | \
+                                NETIF_F_SOFT_FEATURES | \
+                                NETIF_F_LRO)
+
+static void bond_compute_features(struct bonding *bond)
+{
+       struct slave *slave;
+       struct net_device *bond_dev = bond->dev;
+       u32 vlan_features = BOND_VLAN_FEATURES;
+       unsigned short max_hard_header_len = ETH_HLEN;
+       int i;
+
+       read_lock(&bond->lock);
+
+       if (!bond->first_slave)
+               goto done;
+
+       bond_for_each_slave(bond, slave, i) {
                vlan_features = netdev_increment_features(vlan_features,
-                                                       slave->dev->vlan_features,
-                                                       NETIF_F_ONE_FOR_ALL);
+                       slave->dev->vlan_features, BOND_VLAN_FEATURES);
+
                if (slave->dev->hard_header_len > max_hard_header_len)
                        max_hard_header_len = slave->dev->hard_header_len;
        }
 
 done:
-       features |= (bond_dev->features & BOND_VLAN_FEATURES);
-       bond_dev->features = netdev_fix_features(bond_dev, features);
-       bond_dev->vlan_features = netdev_fix_features(bond_dev, vlan_features);
+       bond_dev->vlan_features = vlan_features;
        bond_dev->hard_header_len = max_hard_header_len;
 
-       return 0;
+       read_unlock(&bond->lock);
+
+       netdev_change_features(bond_dev);
 }
 
 static void bond_setup_by_slave(struct net_device *bond_dev,
@@ -1452,27 +1461,17 @@ static void bond_setup_by_slave(struct net_device *bond_dev,
 }
 
 /* On bonding slaves other than the currently active slave, suppress
- * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
- * ARP on active-backup slaves with arp_validate enabled.
+ * duplicates except for alb non-mcast/bcast.
  */
 static bool bond_should_deliver_exact_match(struct sk_buff *skb,
                                            struct slave *slave,
                                            struct bonding *bond)
 {
        if (bond_is_slave_inactive(slave)) {
-               if (slave_do_arp_validate(bond, slave) &&
-                   skb->protocol == __cpu_to_be16(ETH_P_ARP))
-                       return false;
-
                if (bond->params.mode == BOND_MODE_ALB &&
                    skb->pkt_type != PACKET_BROADCAST &&
                    skb->pkt_type != PACKET_MULTICAST)
-                               return false;
-
-               if (bond->params.mode == BOND_MODE_8023AD &&
-                   skb->protocol == __cpu_to_be16(ETH_P_SLOW))
                        return false;
-
                return true;
        }
        return false;
@@ -1496,6 +1495,15 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
        if (bond->params.arp_interval)
                slave->dev->last_rx = jiffies;
 
+       if (bond->recv_probe) {
+               struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+
+               if (likely(nskb)) {
+                       bond->recv_probe(nskb, bond, slave);
+                       dev_kfree_skb(nskb);
+               }
+       }
+
        if (bond_should_deliver_exact_match(skb, slave, bond)) {
                return RX_HANDLER_EXACT;
        }
@@ -1526,7 +1534,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
        struct netdev_hw_addr *ha;
        struct sockaddr addr;
        int link_reporting;
-       int old_features = bond_dev->features;
        int res = 0;
 
        if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
@@ -1559,16 +1566,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                        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);
-                       bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
                }
        } else {
                pr_debug("%s: ! NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
-               if (bond->slave_cnt == 0) {
-                       /* First slave, and it is not VLAN challenged,
-                        * so remove the block of adding VLANs over the bond.
-                        */
-                       bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
-               }
        }
 
        /*
@@ -1640,6 +1640,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                }
        }
 
+       call_netdevice_notifiers(NETDEV_JOIN, slave_dev);
+
        /* If this is the first slave, then we need to set the master's hardware
         * address to be the same as the slave's. */
        if (is_zero_ether_addr(bond->dev->dev_addr))
@@ -1757,10 +1759,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
        new_slave->delay = 0;
        new_slave->link_failure_count = 0;
 
-       bond_compute_features(bond);
-
        write_unlock_bh(&bond->lock);
 
+       bond_compute_features(bond);
+
        read_lock(&bond->lock);
 
        new_slave->last_arp_rx = jiffies;
@@ -1940,7 +1942,7 @@ err_free:
        kfree(new_slave);
 
 err_undo_flags:
-       bond_dev->features = old_features;
+       bond_compute_features(bond);
 
        return res;
 }
@@ -1961,6 +1963,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
        struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave, *oldcurrent;
        struct sockaddr addr;
+       u32 old_features = bond_dev->features;
 
        /* slave is not a slave or master is not master of this slave */
        if (!(slave_dev->flags & IFF_SLAVE) ||
@@ -2021,8 +2024,6 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
        /* release the slave from its bond */
        bond_detach_slave(bond, slave);
 
-       bond_compute_features(bond);
-
        if (bond->primary_slave == slave)
                bond->primary_slave = NULL;
 
@@ -2066,24 +2067,23 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
                 */
                memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
 
-               if (!bond->vlgrp) {
-                       bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
-               } else {
+               if (bond->vlgrp) {
                        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);
                }
-       } else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
-                  !bond_has_challenged_slaves(bond)) {
-               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);
-               bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
        }
 
        write_unlock_bh(&bond->lock);
        unblock_netpoll_tx();
 
+       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",
+                       bond_dev->name, slave_dev->name, bond_dev->name);
+
        /* must do this from outside any spinlocks */
        bond_destroy_slave_symlinks(bond_dev, slave_dev);
 
@@ -2201,8 +2201,6 @@ static int bond_release_all(struct net_device *bond_dev)
                        bond_alb_deinit_slave(bond, slave);
                }
 
-               bond_compute_features(bond);
-
                bond_destroy_slave_symlinks(bond_dev, slave_dev);
                bond_del_vlans_from_slave(bond, slave_dev);
 
@@ -2251,9 +2249,7 @@ static int bond_release_all(struct net_device *bond_dev)
         */
        memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
 
-       if (!bond->vlgrp) {
-               bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
-       } else {
+       if (bond->vlgrp) {
                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",
@@ -2264,6 +2260,9 @@ static int bond_release_all(struct net_device *bond_dev)
 
 out:
        write_unlock_bh(&bond->lock);
+
+       bond_compute_features(bond);
+
        return 0;
 }
 
@@ -2493,7 +2492,7 @@ static void bond_miimon_commit(struct bonding *bond)
 
                        bond_update_speed_duplex(slave);
 
-                       pr_info("%s: link status definitely up for interface %s, %d 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, slave->duplex ? "full" : "half");
 
@@ -2570,6 +2569,7 @@ void bond_mii_monitor(struct work_struct *work)
 {
        struct bonding *bond = container_of(work, struct bonding,
                                            mii_work.work);
+       bool should_notify_peers = false;
 
        read_lock(&bond->lock);
        if (bond->kill_timers)
@@ -2578,17 +2578,7 @@ void bond_mii_monitor(struct work_struct *work)
        if (bond->slave_cnt == 0)
                goto re_arm;
 
-       if (bond->send_grat_arp) {
-               read_lock(&bond->curr_slave_lock);
-               bond_send_gratuitous_arp(bond);
-               read_unlock(&bond->curr_slave_lock);
-       }
-
-       if (bond->send_unsol_na) {
-               read_lock(&bond->curr_slave_lock);
-               bond_send_unsolicited_na(bond);
-               read_unlock(&bond->curr_slave_lock);
-       }
+       should_notify_peers = bond_should_notify_peers(bond);
 
        if (bond_miimon_inspect(bond)) {
                read_unlock(&bond->lock);
@@ -2608,6 +2598,12 @@ re_arm:
                                   msecs_to_jiffies(bond->params.miimon));
 out:
        read_unlock(&bond->lock);
+
+       if (should_notify_peers) {
+               rtnl_lock();
+               netdev_bonding_change(bond->dev, NETDEV_NOTIFY_PEERS);
+               rtnl_unlock();
+       }
 }
 
 static __be32 bond_glean_dev_ip(struct net_device *dev)
@@ -2751,44 +2747,6 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
        }
 }
 
-/*
- * Kick out a gratuitous ARP for an IP on the bonding master plus one
- * for each VLAN above us.
- *
- * Caller must hold curr_slave_lock for read or better
- */
-static void bond_send_gratuitous_arp(struct bonding *bond)
-{
-       struct slave *slave = bond->curr_active_slave;
-       struct vlan_entry *vlan;
-       struct net_device *vlan_dev;
-
-       pr_debug("bond_send_grat_arp: bond %s slave %s\n",
-                bond->dev->name, slave ? slave->dev->name : "NULL");
-
-       if (!slave || !bond->send_grat_arp ||
-           test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
-               return;
-
-       bond->send_grat_arp--;
-
-       if (bond->master_ip) {
-               bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
-                               bond->master_ip, 0);
-       }
-
-       if (!bond->vlgrp)
-               return;
-
-       list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
-               vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
-               if (vlan->vlan_ip) {
-                       bond_arp_send(slave->dev, ARPOP_REPLY, vlan->vlan_ip,
-                                     vlan->vlan_ip, vlan->vlan_id);
-               }
-       }
-}
-
 static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 sip, __be32 tip)
 {
        int i;
@@ -2806,48 +2764,26 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32
        }
 }
 
-static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
+static void bond_arp_rcv(struct sk_buff *skb, struct bonding *bond,
+                        struct slave *slave)
 {
        struct arphdr *arp;
-       struct slave *slave;
-       struct bonding *bond;
        unsigned char *arp_ptr;
        __be32 sip, tip;
 
-       if (dev->priv_flags & IFF_802_1Q_VLAN) {
-               /*
-                * When using VLANS and bonding, dev and oriv_dev may be
-                * incorrect if the physical interface supports VLAN
-                * acceleration.  With this change ARP validation now
-                * works for hosts only reachable on the VLAN interface.
-                */
-               dev = vlan_dev_real_dev(dev);
-               orig_dev = dev_get_by_index_rcu(dev_net(skb->dev),skb->skb_iif);
-       }
-
-       if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
-               goto out;
+       if (skb->protocol != __cpu_to_be16(ETH_P_ARP))
+               return;
 
-       bond = netdev_priv(dev);
        read_lock(&bond->lock);
 
-       pr_debug("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n",
-                bond->dev->name, skb->dev ? skb->dev->name : "NULL",
-                orig_dev ? orig_dev->name : "NULL");
-
-       slave = bond_get_slave_by_dev(bond, orig_dev);
-       if (!slave || !slave_do_arp_validate(bond, slave))
-               goto out_unlock;
-
-       skb = skb_share_check(skb, GFP_ATOMIC);
-       if (!skb)
-               goto out_unlock;
+       pr_debug("bond_arp_rcv: bond %s skb->dev %s\n",
+                bond->dev->name, skb->dev->name);
 
-       if (!pskb_may_pull(skb, arp_hdr_len(dev)))
+       if (!pskb_may_pull(skb, arp_hdr_len(bond->dev)))
                goto out_unlock;
 
        arp = arp_hdr(skb);
-       if (arp->ar_hln != dev->addr_len ||
+       if (arp->ar_hln != bond->dev->addr_len ||
            skb->pkt_type == PACKET_OTHERHOST ||
            skb->pkt_type == PACKET_LOOPBACK ||
            arp->ar_hrd != htons(ARPHRD_ETHER) ||
@@ -2856,9 +2792,9 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
                goto out_unlock;
 
        arp_ptr = (unsigned char *)(arp + 1);
-       arp_ptr += dev->addr_len;
+       arp_ptr += bond->dev->addr_len;
        memcpy(&sip, arp_ptr, 4);
-       arp_ptr += 4 + dev->addr_len;
+       arp_ptr += 4 + bond->dev->addr_len;
        memcpy(&tip, arp_ptr, 4);
 
        pr_debug("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n",
@@ -2881,9 +2817,6 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
 
 out_unlock:
        read_unlock(&bond->lock);
-out:
-       dev_kfree_skb(skb);
-       return NET_RX_SUCCESS;
 }
 
 /*
@@ -3243,6 +3176,7 @@ void bond_activebackup_arp_mon(struct work_struct *work)
 {
        struct bonding *bond = container_of(work, struct bonding,
                                            arp_work.work);
+       bool should_notify_peers = false;
        int delta_in_ticks;
 
        read_lock(&bond->lock);
@@ -3255,17 +3189,7 @@ void bond_activebackup_arp_mon(struct work_struct *work)
        if (bond->slave_cnt == 0)
                goto re_arm;
 
-       if (bond->send_grat_arp) {
-               read_lock(&bond->curr_slave_lock);
-               bond_send_gratuitous_arp(bond);
-               read_unlock(&bond->curr_slave_lock);
-       }
-
-       if (bond->send_unsol_na) {
-               read_lock(&bond->curr_slave_lock);
-               bond_send_unsolicited_na(bond);
-               read_unlock(&bond->curr_slave_lock);
-       }
+       should_notify_peers = bond_should_notify_peers(bond);
 
        if (bond_ab_arp_inspect(bond, delta_in_ticks)) {
                read_unlock(&bond->lock);
@@ -3286,6 +3210,12 @@ re_arm:
                queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
 out:
        read_unlock(&bond->lock);
+
+       if (should_notify_peers) {
+               rtnl_lock();
+               netdev_bonding_change(bond->dev, NETDEV_NOTIFY_PEERS);
+               rtnl_unlock();
+       }
 }
 
 /*-------------------------- netdev event handling --------------------------*/
@@ -3339,8 +3269,8 @@ static int bond_slave_netdev_event(unsigned long event,
 
                        slave = bond_get_slave_by_dev(bond, slave_dev);
                        if (slave) {
-                               u16 old_speed = slave->speed;
-                               u16 old_duplex = slave->duplex;
+                               u32 old_speed = slave->speed;
+                               u old_duplex = slave->duplex;
 
                                bond_update_speed_duplex(slave);
 
@@ -3482,48 +3412,6 @@ static struct notifier_block bond_inetaddr_notifier = {
        .notifier_call = bond_inetaddr_event,
 };
 
-/*-------------------------- Packet type handling ---------------------------*/
-
-/* register to receive lacpdus on a bond */
-static void bond_register_lacpdu(struct bonding *bond)
-{
-       struct packet_type *pk_type = &(BOND_AD_INFO(bond).ad_pkt_type);
-
-       /* initialize packet type */
-       pk_type->type = PKT_TYPE_LACPDU;
-       pk_type->dev = bond->dev;
-       pk_type->func = bond_3ad_lacpdu_recv;
-
-       dev_add_pack(pk_type);
-}
-
-/* unregister to receive lacpdus on a bond */
-static void bond_unregister_lacpdu(struct bonding *bond)
-{
-       dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
-}
-
-void bond_register_arp(struct bonding *bond)
-{
-       struct packet_type *pt = &bond->arp_mon_pt;
-
-       if (pt->type)
-               return;
-
-       pt->type = htons(ETH_P_ARP);
-       pt->dev = bond->dev;
-       pt->func = bond_arp_rcv;
-       dev_add_pack(pt);
-}
-
-void bond_unregister_arp(struct bonding *bond)
-{
-       struct packet_type *pt = &bond->arp_mon_pt;
-
-       dev_remove_pack(pt);
-       pt->type = 0;
-}
-
 /*---------------------------- Hashing Policies -----------------------------*/
 
 /*
@@ -3617,14 +3505,14 @@ static int bond_open(struct net_device *bond_dev)
 
                queue_delayed_work(bond->wq, &bond->arp_work, 0);
                if (bond->params.arp_validate)
-                       bond_register_arp(bond);
+                       bond->recv_probe = bond_arp_rcv;
        }
 
        if (bond->params.mode == BOND_MODE_8023AD) {
                INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
                queue_delayed_work(bond->wq, &bond->ad_work, 0);
                /* register to receive LACPDUs */
-               bond_register_lacpdu(bond);
+               bond->recv_probe = bond_3ad_lacpdu_recv;
                bond_3ad_initiate_agg_selection(bond, 1);
        }
 
@@ -3635,18 +3523,9 @@ static int bond_close(struct net_device *bond_dev)
 {
        struct bonding *bond = netdev_priv(bond_dev);
 
-       if (bond->params.mode == BOND_MODE_8023AD) {
-               /* Unregister the receive of LACPDUs */
-               bond_unregister_lacpdu(bond);
-       }
-
-       if (bond->params.arp_validate)
-               bond_unregister_arp(bond);
-
        write_lock_bh(&bond->lock);
 
-       bond->send_grat_arp = 0;
-       bond->send_unsol_na = 0;
+       bond->send_peer_notif = 0;
 
        /* signal timers not to re-arm */
        bond->kill_timers = 1;
@@ -3682,6 +3561,7 @@ static int bond_close(struct net_device *bond_dev)
                 */
                bond_alb_deinitialize(bond);
        }
+       bond->recv_probe = NULL;
 
        return 0;
 }
@@ -4105,10 +3985,6 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
        int i, slave_no, res = 1;
        struct iphdr *iph = ip_hdr(skb);
 
-       read_lock(&bond->lock);
-
-       if (!BOND_IS_OK(bond))
-               goto out;
        /*
         * Start with the curr_active_slave that joined the bond as the
         * default for sending IGMP traffic.  For failover purposes one
@@ -4155,7 +4031,7 @@ out:
                /* no suitable interface, frame not sent */
                dev_kfree_skb(skb);
        }
-       read_unlock(&bond->lock);
+
        return NETDEV_TX_OK;
 }
 
@@ -4169,24 +4045,18 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
        struct bonding *bond = netdev_priv(bond_dev);
        int res = 1;
 
-       read_lock(&bond->lock);
        read_lock(&bond->curr_slave_lock);
 
-       if (!BOND_IS_OK(bond))
-               goto out;
-
-       if (!bond->curr_active_slave)
-               goto out;
-
-       res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
+       if (bond->curr_active_slave)
+               res = bond_dev_queue_xmit(bond, skb,
+                       bond->curr_active_slave->dev);
 
-out:
        if (res)
                /* no suitable interface, frame not sent */
                dev_kfree_skb(skb);
 
        read_unlock(&bond->curr_slave_lock);
-       read_unlock(&bond->lock);
+
        return NETDEV_TX_OK;
 }
 
@@ -4203,11 +4073,6 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
        int i;
        int res = 1;
 
-       read_lock(&bond->lock);
-
-       if (!BOND_IS_OK(bond))
-               goto out;
-
        slave_no = bond->xmit_hash_policy(skb, bond->slave_cnt);
 
        bond_for_each_slave(bond, slave, i) {
@@ -4227,12 +4092,11 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
                }
        }
 
-out:
        if (res) {
                /* no suitable interface, frame not sent */
                dev_kfree_skb(skb);
        }
-       read_unlock(&bond->lock);
+
        return NETDEV_TX_OK;
 }
 
@@ -4247,11 +4111,6 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
        int i;
        int res = 1;
 
-       read_lock(&bond->lock);
-
-       if (!BOND_IS_OK(bond))
-               goto out;
-
        read_lock(&bond->curr_slave_lock);
        start_at = bond->curr_active_slave;
        read_unlock(&bond->curr_slave_lock);
@@ -4290,7 +4149,6 @@ out:
                dev_kfree_skb(skb);
 
        /* frame sent to all suitable interfaces */
-       read_unlock(&bond->lock);
        return NETDEV_TX_OK;
 }
 
@@ -4322,10 +4180,8 @@ static inline int bond_slave_override(struct bonding *bond,
        struct slave *slave = NULL;
        struct slave *check_slave;
 
-       read_lock(&bond->lock);
-
-       if (!BOND_IS_OK(bond) || !skb->queue_mapping)
-               goto out;
+       if (!skb->queue_mapping)
+               return 1;
 
        /* Find out if any slaves have the same mapping as this skb. */
        bond_for_each_slave(bond, check_slave, i) {
@@ -4341,8 +4197,6 @@ static inline int bond_slave_override(struct bonding *bond,
                res = bond_dev_queue_xmit(bond, skb, slave->dev);
        }
 
-out:
-       read_unlock(&bond->lock);
        return res;
 }
 
@@ -4357,24 +4211,17 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
        u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
 
        if (unlikely(txq >= dev->real_num_tx_queues)) {
-               do
+               do {
                        txq -= dev->real_num_tx_queues;
-               while (txq >= dev->real_num_tx_queues);
+               while (txq >= dev->real_num_tx_queues);
        }
        return txq;
 }
 
-static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct bonding *bond = netdev_priv(dev);
 
-       /*
-        * If we risk deadlock from transmitting this in the
-        * netpoll path, tell netpoll to queue the frame for later tx
-        */
-       if (is_netpoll_tx_blocked(dev))
-               return NETDEV_TX_BUSY;
-
        if (TX_QUEUE_OVERRIDE(bond->params.mode)) {
                if (!bond_slave_override(bond, skb))
                        return NETDEV_TX_OK;
@@ -4404,6 +4251,29 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 }
 
+static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct bonding *bond = netdev_priv(dev);
+       netdev_tx_t ret = NETDEV_TX_OK;
+
+       /*
+        * If we risk deadlock from transmitting this in the
+        * netpoll path, tell netpoll to queue the frame for later tx
+        */
+       if (is_netpoll_tx_blocked(dev))
+               return NETDEV_TX_BUSY;
+
+       read_lock(&bond->lock);
+
+       if (bond->slave_cnt)
+               ret = __bond_start_xmit(skb, dev);
+       else
+               dev_kfree_skb(skb);
+
+       read_unlock(&bond->lock);
+
+       return ret;
+}
 
 /*
  * set bond mode specific net device operations
@@ -4448,11 +4318,6 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
 static const struct ethtool_ops bond_ethtool_ops = {
        .get_drvinfo            = bond_ethtool_get_drvinfo,
        .get_link               = ethtool_op_get_link,
-       .get_tx_csum            = ethtool_op_get_tx_csum,
-       .get_sg                 = ethtool_op_get_sg,
-       .get_tso                = ethtool_op_get_tso,
-       .get_ufo                = ethtool_op_get_ufo,
-       .get_flags              = ethtool_op_get_flags,
 };
 
 static const struct net_device_ops bond_netdev_ops = {
@@ -4478,6 +4343,7 @@ static const struct net_device_ops bond_netdev_ops = {
 #endif
        .ndo_add_slave          = bond_enslave,
        .ndo_del_slave          = bond_release,
+       .ndo_fix_features       = bond_fix_features,
 };
 
 static void bond_destructor(struct net_device *bond_dev)
@@ -4533,14 +4399,14 @@ static void bond_setup(struct net_device *bond_dev)
         * when there are slaves that are not hw accel
         * capable
         */
-       bond_dev->features |= (NETIF_F_HW_VLAN_TX |
-                              NETIF_F_HW_VLAN_RX |
-                              NETIF_F_HW_VLAN_FILTER);
 
-       /* By default, we enable GRO on bonding devices.
-        * Actual support requires lowlevel drivers are GRO ready.
-        */
-       bond_dev->features |= NETIF_F_GRO;
+       bond_dev->hw_features = BOND_VLAN_FEATURES |
+                               NETIF_F_HW_VLAN_TX |
+                               NETIF_F_HW_VLAN_RX |
+                               NETIF_F_HW_VLAN_FILTER;
+
+       bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_NO_CSUM);
+       bond_dev->features |= bond_dev->hw_features;
 }
 
 static void bond_work_cancel_all(struct bonding *bond)
@@ -4724,16 +4590,10 @@ static int bond_check_params(struct bond_params *params)
                use_carrier = 1;
        }
 
-       if (num_grat_arp < 0 || num_grat_arp > 255) {
-               pr_warning("Warning: num_grat_arp (%d) not in range 0-255 so it was reset to 1\n",
-                          num_grat_arp);
-               num_grat_arp = 1;
-       }
-
-       if (num_unsol_na < 0 || num_unsol_na > 255) {
-               pr_warning("Warning: num_unsol_na (%d) not in range 0-255 so it was reset to 1\n",
-                          num_unsol_na);
-               num_unsol_na = 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);
+               num_peer_notif = 1;
        }
 
        /* reset values for 802.3ad */
@@ -4925,8 +4785,7 @@ static int bond_check_params(struct bond_params *params)
        params->mode = bond_mode;
        params->xmit_policy = xmit_hashtype;
        params->miimon = miimon;
-       params->num_grat_arp = num_grat_arp;
-       params->num_unsol_na = num_unsol_na;
+       params->num_peer_notif = num_peer_notif;
        params->arp_interval = arp_interval;
        params->arp_validate = arp_validate_value;
        params->updelay = updelay;
@@ -5025,8 +4884,9 @@ int bond_create(struct net *net, const char *name)
 
        rtnl_lock();
 
-       bond_dev = alloc_netdev_mq(sizeof(struct bonding), name ? name : "",
-                               bond_setup, tx_queues);
+       bond_dev = alloc_netdev_mq(sizeof(struct bonding),
+                                  name ? name : "bond%d",
+                                  bond_setup, tx_queues);
        if (!bond_dev) {
                pr_err("%s: eek! can't alloc netdev!\n", name);
                rtnl_unlock();
@@ -5036,26 +4896,10 @@ int bond_create(struct net *net, const char *name)
        dev_net_set(bond_dev, net);
        bond_dev->rtnl_link_ops = &bond_link_ops;
 
-       if (!name) {
-               res = dev_alloc_name(bond_dev, "bond%d");
-               if (res < 0)
-                       goto out;
-       } else {
-               /*
-                * If we're given a name to register
-                * we need to ensure that its not already
-                * registered
-                */
-               res = -EEXIST;
-               if (__dev_get_by_name(net, name) != NULL)
-                       goto out;
-       }
-
        res = register_netdevice(bond_dev);
 
        netif_carrier_off(bond_dev);
 
-out:
        rtnl_unlock();
        if (res < 0)
                bond_destructor(bond_dev);
@@ -5121,7 +4965,6 @@ static int __init bonding_init(void)
 
        register_netdevice_notifier(&bond_netdev_notifier);
        register_inetaddr_notifier(&bond_inetaddr_notifier);
-       bond_register_ipv6_notifier();
 out:
        return res;
 err:
@@ -5136,7 +4979,6 @@ static void __exit bonding_exit(void)
 {
        unregister_netdevice_notifier(&bond_netdev_notifier);
        unregister_inetaddr_notifier(&bond_inetaddr_notifier);
-       bond_unregister_ipv6_notifier();
 
        bond_destroy_sysfs();
        bond_destroy_debugfs();