bonding: options handling cleanup
[cascardo/linux.git] / drivers / net / bonding / bond_main.c
index 1c6104d..324389b 100644 (file)
@@ -673,12 +673,12 @@ static void bond_do_fail_over_mac(struct bonding *bond,
                write_unlock_bh(&bond->curr_slave_lock);
 
                if (old_active) {
-                       memcpy(tmp_mac, new_active->dev->dev_addr, ETH_ALEN);
-                       memcpy(saddr.sa_data, old_active->dev->dev_addr,
-                              ETH_ALEN);
+                       ether_addr_copy(tmp_mac, new_active->dev->dev_addr);
+                       ether_addr_copy(saddr.sa_data,
+                                       old_active->dev->dev_addr);
                        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 @@ static void bond_do_fail_over_mac(struct bonding *bond,
                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 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
                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 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
                                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);
                        }
                }
@@ -829,21 +829,25 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
        if (bond_is_lb(bond)) {
                bond_alb_handle_active_change(bond, new_active);
                if (old_active)
-                       bond_set_slave_inactive_flags(old_active);
+                       bond_set_slave_inactive_flags(old_active,
+                                                     BOND_SLAVE_NOTIFY_NOW);
                if (new_active)
-                       bond_set_slave_active_flags(new_active);
+                       bond_set_slave_active_flags(new_active,
+                                                   BOND_SLAVE_NOTIFY_NOW);
        } else {
                rcu_assign_pointer(bond->curr_active_slave, new_active);
        }
 
        if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
                if (old_active)
-                       bond_set_slave_inactive_flags(old_active);
+                       bond_set_slave_inactive_flags(old_active,
+                                                     BOND_SLAVE_NOTIFY_NOW);
 
                if (new_active) {
                        bool should_notify_peers = false;
 
-                       bond_set_slave_active_flags(new_active);
+                       bond_set_slave_active_flags(new_active,
+                                                   BOND_SLAVE_NOTIFY_NOW);
 
                        if (bond->params.fail_over_mac)
                                bond_do_fail_over_mac(bond, new_active,
@@ -906,7 +910,7 @@ void bond_select_active_slave(struct bonding *bond)
                        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);
                }
        }
@@ -942,14 +946,6 @@ static inline void slave_disable_netpoll(struct slave *slave)
        slave->np = NULL;
        __netpoll_free_async(np);
 }
-static inline bool slave_dev_support_netpoll(struct net_device *slave_dev)
-{
-       if (slave_dev->priv_flags & IFF_DISABLE_NETPOLL)
-               return false;
-       if (!slave_dev->netdev_ops->ndo_poll_controller)
-               return false;
-       return true;
-}
 
 static void bond_poll_controller(struct net_device *bond_dev)
 {
@@ -1115,9 +1111,6 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
        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);
@@ -1142,7 +1135,7 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
                        kfree_skb(skb);
                        return RX_HANDLER_CONSUMED;
                }
-               memcpy(eth_hdr(skb)->h_dest, bond->dev->dev_addr, ETH_ALEN);
+               ether_addr_copy(eth_hdr(skb)->h_dest, bond->dev->dev_addr);
        }
 
        return ret;
@@ -1183,16 +1176,21 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
        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;
        }
 
+       if (bond_dev == slave_dev) {
+               pr_err("%s: cannot enslave bond to itself.\n", bond_dev->name);
+               return -EPERM;
+       }
+
        /* vlan challenged mutual exclusion */
        /* no need to lock since we're protected by rtnl_lock */
        if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) {
@@ -1202,9 +1200,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                               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 +1215,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
         * 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 +1259,23 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                                                 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 +1314,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
         * 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 +1398,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        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 +1416,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                         * 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 +1445,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
        }
 
        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 */
@@ -1463,14 +1460,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        switch (bond->params.mode) {
        case BOND_MODE_ACTIVEBACKUP:
-               bond_set_slave_inactive_flags(new_slave);
+               bond_set_slave_inactive_flags(new_slave,
+                                             BOND_SLAVE_NOTIFY_NOW);
                break;
        case BOND_MODE_8023AD:
                /* in 802.3ad mode, the internal mechanism
                 * will activate the slaves in the selected
                 * aggregator
                 */
-               bond_set_slave_inactive_flags(new_slave);
+               bond_set_slave_inactive_flags(new_slave, BOND_SLAVE_NOTIFY_NOW);
                /* if this is the first slave */
                if (!prev_slave) {
                        SLAVE_AD_INFO(new_slave).id = 1;
@@ -1488,7 +1486,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
        case BOND_MODE_TLB:
        case BOND_MODE_ALB:
                bond_set_active_slave(new_slave);
-               bond_set_slave_inactive_flags(new_slave);
+               bond_set_slave_inactive_flags(new_slave, BOND_SLAVE_NOTIFY_NOW);
                break;
        default:
                pr_debug("This slave is always active in trunk mode\n");
@@ -1510,9 +1508,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
        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;
                }
@@ -1550,10 +1547,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                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;
@@ -1593,7 +1590,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 +1635,7 @@ static int __bond_release_one(struct net_device *bond_dev,
        /* 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;
        }
@@ -1654,9 +1651,6 @@ static int __bond_release_one(struct net_device *bond_dev,
                return -EINVAL;
        }
 
-       /* release the slave from its bond */
-       bond->slave_cnt--;
-
        bond_sysfs_slave_del(slave);
 
        bond_upper_dev_unlink(bond_dev, slave_dev);
@@ -1672,7 +1666,7 @@ static int __bond_release_one(struct net_device *bond_dev,
 
        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 +1679,10 @@ static int __bond_release_one(struct net_device *bond_dev,
                     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,15 +1723,16 @@ static int __bond_release_one(struct net_device *bond_dev,
                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);
                }
        }
 
        unblock_netpoll_tx();
        synchronize_rcu();
+       bond->slave_cnt--;
 
        if (!bond_has_slaves(bond)) {
                call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev);
@@ -1747,7 +1742,7 @@ static int __bond_release_one(struct net_device *bond_dev,
        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 +1777,7 @@ static int __bond_release_one(struct net_device *bond_dev,
        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 +1810,7 @@ static int  bond_release_and_destroy(struct net_device *bond_dev,
        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);
        }
@@ -1829,9 +1824,7 @@ static int bond_info_query(struct net_device *bond_dev, struct ifbond *info)
        info->bond_mode = bond->params.mode;
        info->miimon = bond->params.miimon;
 
-       read_lock(&bond->lock);
        info->num_slaves = bond->slave_cnt;
-       read_unlock(&bond->lock);
 
        return 0;
 }
@@ -1843,7 +1836,6 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
        int i = 0, res = -ENODEV;
        struct slave *slave;
 
-       read_lock(&bond->lock);
        bond_for_each_slave(bond, slave, iter) {
                if (i++ == (int)info->slave_id) {
                        res = 0;
@@ -1854,7 +1846,6 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
                        break;
                }
        }
-       read_unlock(&bond->lock);
 
        return res;
 }
@@ -1884,7 +1875,7 @@ static int bond_miimon_inspect(struct bonding *bond)
                        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 @@ static int bond_miimon_inspect(struct bonding *bond)
                                 * 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 @@ static int bond_miimon_inspect(struct bonding *bond)
                        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 @@ static int bond_miimon_inspect(struct bonding *bond)
                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 @@ static void bond_miimon_commit(struct bonding *bond)
 
                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 @@ static void bond_miimon_commit(struct bonding *bond)
                                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");
@@ -2015,7 +2006,8 @@ static void bond_miimon_commit(struct bonding *bond)
 
                        if (bond->params.mode == BOND_MODE_ACTIVEBACKUP ||
                            bond->params.mode == BOND_MODE_8023AD)
-                               bond_set_slave_inactive_flags(slave);
+                               bond_set_slave_inactive_flags(slave,
+                                                             BOND_SLAVE_NOTIFY_NOW);
 
                        pr_info("%s: link status definitely down for interface %s, disabling it\n",
                                bond->dev->name, slave->dev->name);
@@ -2136,8 +2128,8 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_
 {
        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);
@@ -2172,8 +2164,13 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
                rt = ip_route_output(dev_net(bond->dev), targets[i], 0,
                                     RTO_ONLINK, 0);
                if (IS_ERR(rt)) {
-                       pr_debug("%s: no route to arp_ip_target %pI4\n",
-                                bond->dev->name, &targets[i]);
+                       /* there's no route to target - try to send arp
+                        * probe to generate any traffic (arp_validate=0)
+                        */
+                       if (bond->params.arp_validate && net_ratelimit())
+                               pr_warn("%s: no route to arp_ip_target %pI4 and arp_validate is set\n",
+                                       bond->dev->name, &targets[i]);
+                       bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], 0, 0);
                        continue;
                }
 
@@ -2251,7 +2248,7 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32
                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;
 }
 
@@ -2259,17 +2256,19 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
                 struct slave *slave)
 {
        struct arphdr *arp = (struct arphdr *)skb->data;
+       struct slave *curr_active_slave;
        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);
 
@@ -2303,6 +2302,8 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
                 bond->params.arp_validate, slave_do_arp_validate(bond, slave),
                 &sip, &tip);
 
+       curr_active_slave = rcu_dereference(bond->curr_active_slave);
+
        /*
         * Backup slaves won't see the ARP reply, but do come through
         * here for each ARP probe (so we swap the sip/tip to validate
@@ -2316,15 +2317,15 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
         * is done to avoid endless looping when we can't reach the
         * arp_ip_target and fool ourselves with our own arp requests.
         */
+
        if (bond_is_active_slave(slave))
                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))
+       else if (curr_active_slave &&
+                time_after(slave_last_rx(bond, curr_active_slave),
+                           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 +2368,9 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
        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 +2379,7 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
 
                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 +2390,7 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
                                 * 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 +2408,7 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
                         * 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 +2416,8 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
                                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 +2496,7 @@ static int bond_ab_arp_inspect(struct bonding *bond)
                 * 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;
 
                /*
@@ -2562,11 +2562,12 @@ static void bond_ab_arp_commit(struct bonding *bond)
                                slave->link = BOND_LINK_UP;
                                if (bond->current_arp_slave) {
                                        bond_set_slave_inactive_flags(
-                                               bond->current_arp_slave);
+                                               bond->current_arp_slave,
+                                               BOND_SLAVE_NOTIFY_NOW);
                                        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 ||
@@ -2582,7 +2583,8 @@ static void bond_ab_arp_commit(struct bonding *bond)
                                slave->link_failure_count++;
 
                        slave->link = BOND_LINK_DOWN;
-                       bond_set_slave_inactive_flags(slave);
+                       bond_set_slave_inactive_flags(slave,
+                                                     BOND_SLAVE_NOTIFY_NOW);
 
                        pr_info("%s: link status definitely down for interface %s, disabling it\n",
                                bond->dev->name, slave->dev->name);
@@ -2615,17 +2617,17 @@ do_failover:
 
 /*
  * Send ARP probes for active-backup mode ARP monitor.
+ *
+ * Called with rcu_read_lock hold.
  */
 static bool bond_ab_arp_probe(struct bonding *bond)
 {
        struct slave *slave, *before = NULL, *new_slave = NULL,
-                    *curr_arp_slave, *curr_active_slave;
+                    *curr_arp_slave = rcu_dereference(bond->current_arp_slave),
+                    *curr_active_slave = rcu_dereference(bond->curr_active_slave);
        struct list_head *iter;
        bool found = false;
-
-       rcu_read_lock();
-       curr_arp_slave = rcu_dereference(bond->current_arp_slave);
-       curr_active_slave = rcu_dereference(bond->curr_active_slave);
+       bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER;
 
        if (curr_arp_slave && curr_active_slave)
                pr_info("PROBE: c_arp %s && cas %s BAD\n",
@@ -2634,32 +2636,23 @@ static bool bond_ab_arp_probe(struct bonding *bond)
 
        if (curr_active_slave) {
                bond_arp_send_all(bond, curr_active_slave);
-               rcu_read_unlock();
-               return true;
+               return should_notify_rtnl;
        }
-       rcu_read_unlock();
 
        /* if we don't have a curr_active_slave, search for the next available
         * backup slave from the current_arp_slave and make it the candidate
         * for becoming the curr_active_slave
         */
 
-       if (!rtnl_trylock())
-               return false;
-       /* curr_arp_slave might have gone away */
-       curr_arp_slave = ACCESS_ONCE(bond->current_arp_slave);
-
        if (!curr_arp_slave) {
-               curr_arp_slave = bond_first_slave(bond);
-               if (!curr_arp_slave) {
-                       rtnl_unlock();
-                       return true;
-               }
+               curr_arp_slave = bond_first_slave_rcu(bond);
+               if (!curr_arp_slave)
+                       return should_notify_rtnl;
        }
 
-       bond_set_slave_inactive_flags(curr_arp_slave);
+       bond_set_slave_inactive_flags(curr_arp_slave, BOND_SLAVE_NOTIFY_LATER);
 
-       bond_for_each_slave(bond, slave, iter) {
+       bond_for_each_slave_rcu(bond, slave, iter) {
                if (!found && !before && IS_UP(slave->dev))
                        before = slave;
 
@@ -2677,9 +2670,10 @@ static bool bond_ab_arp_probe(struct bonding *bond)
                        if (slave->link_failure_count < UINT_MAX)
                                slave->link_failure_count++;
 
-                       bond_set_slave_inactive_flags(slave);
+                       bond_set_slave_inactive_flags(slave,
+                                                     BOND_SLAVE_NOTIFY_LATER);
 
-                       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)
@@ -2689,26 +2683,31 @@ static bool bond_ab_arp_probe(struct bonding *bond)
        if (!new_slave && before)
                new_slave = before;
 
-       if (!new_slave) {
-               rtnl_unlock();
-               return true;
-       }
+       if (!new_slave)
+               goto check_state;
 
        new_slave->link = BOND_LINK_BACK;
-       bond_set_slave_active_flags(new_slave);
+       bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER);
        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();
 
-       return true;
+check_state:
+       bond_for_each_slave_rcu(bond, slave, iter) {
+               if (slave->should_notify) {
+                       should_notify_rtnl = BOND_SLAVE_NOTIFY_NOW;
+                       break;
+               }
+       }
+       return should_notify_rtnl;
 }
 
 static 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, should_commit = false;
+       bool should_notify_peers = false;
+       bool should_notify_rtnl = false;
        int delta_in_ticks;
 
        delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval);
@@ -2717,11 +2716,12 @@ static void bond_activebackup_arp_mon(struct work_struct *work)
                goto re_arm;
 
        rcu_read_lock();
+
        should_notify_peers = bond_should_notify_peers(bond);
-       should_commit = bond_ab_arp_inspect(bond);
-       rcu_read_unlock();
 
-       if (should_commit) {
+       if (bond_ab_arp_inspect(bond)) {
+               rcu_read_unlock();
+
                /* Race avoidance with bond_close flush of workqueue */
                if (!rtnl_trylock()) {
                        delta_in_ticks = 1;
@@ -2730,23 +2730,28 @@ static void bond_activebackup_arp_mon(struct work_struct *work)
                }
 
                bond_ab_arp_commit(bond);
+
                rtnl_unlock();
+               rcu_read_lock();
        }
 
-       if (!bond_ab_arp_probe(bond)) {
-               /* rtnl locking failed, re-arm */
-               delta_in_ticks = 1;
-               should_notify_peers = false;
-       }
+       should_notify_rtnl = bond_ab_arp_probe(bond);
+       rcu_read_unlock();
 
 re_arm:
        if (bond->params.arp_interval)
                queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
 
-       if (should_notify_peers) {
+       if (should_notify_peers || should_notify_rtnl) {
                if (!rtnl_trylock())
                        return;
-               call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev);
+
+               if (should_notify_peers)
+                       call_netdevice_notifiers(NETDEV_NOTIFY_PEERS,
+                                                bond->dev);
+               if (should_notify_rtnl)
+                       bond_slave_state_notify(bond);
+
                rtnl_unlock();
        }
 }
@@ -2865,9 +2870,9 @@ static int bond_slave_netdev_event(unsigned long event,
                        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);
@@ -2903,8 +2908,7 @@ static int bond_netdev_event(struct notifier_block *this,
        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;
@@ -3046,9 +3050,11 @@ static int bond_open(struct net_device *bond_dev)
                bond_for_each_slave(bond, slave, iter) {
                        if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP)
                                && (slave != bond->curr_active_slave)) {
-                               bond_set_slave_inactive_flags(slave);
+                               bond_set_slave_inactive_flags(slave,
+                                                             BOND_SLAVE_NOTIFY_NOW);
                        } else {
-                               bond_set_slave_active_flags(slave);
+                               bond_set_slave_active_flags(slave,
+                                                           BOND_SLAVE_NOTIFY_NOW);
                        }
                }
                read_unlock(&bond->curr_slave_lock);
@@ -3071,8 +3077,7 @@ static int bond_open(struct net_device *bond_dev)
 
        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 +3364,8 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
        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 +3384,7 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
 
        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 +3472,7 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
         */
 
        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
@@ -3942,7 +3938,7 @@ static void bond_uninit(struct net_device *bond_dev)
        /* 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);
 
@@ -3951,56 +3947,11 @@ static void bond_uninit(struct net_device *bond_dev)
 
 /*------------------------- Module initialization ---------------------------*/
 
-int bond_parm_tbl_lookup(int mode, const struct bond_parm_tbl *tbl)
-{
-       int i;
-
-       for (i = 0; tbl[i].modename; i++)
-               if (mode == tbl[i].mode)
-                       return tbl[i].mode;
-
-       return -1;
-}
-
-static int bond_parm_tbl_lookup_name(const char *modename,
-                                    const struct bond_parm_tbl *tbl)
-{
-       int i;
-
-       for (i = 0; tbl[i].modename; i++)
-               if (strcmp(modename, tbl[i].modename) == 0)
-                       return tbl[i].mode;
-
-       return -1;
-}
-
-/*
- * Convert string input module parms.  Accept either the
- * number of the mode or its string name.  A bit complicated because
- * some mode names are substrings of other names, and calls from sysfs
- * may have whitespace in the name (trailing newlines, for example).
- */
-int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
-{
-       int modeint;
-       char *p, modestr[BOND_MAX_MODENAME_LEN + 1];
-
-       for (p = (char *)buf; *p; p++)
-               if (!(isdigit(*p) || isspace(*p)))
-                       break;
-
-       if (*p && sscanf(buf, "%20s", modestr) != 0)
-               return bond_parm_tbl_lookup_name(modestr, tbl);
-       else if (sscanf(buf, "%d", &modeint) != 0)
-               return bond_parm_tbl_lookup(modeint, tbl);
-
-       return -1;
-}
-
 static int bond_check_params(struct bond_params *params)
 {
        int arp_validate_value, fail_over_mac_value, primary_reselect_value, i;
-       struct bond_opt_value newval, *valptr;
+       struct bond_opt_value newval;
+       const struct bond_opt_value *valptr;
        int arp_all_targets_value;
 
        /*
@@ -4020,7 +3971,7 @@ static int bond_check_params(struct bond_params *params)
                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 +4012,71 @@ static int bond_check_params(struct bond_params *params)
                }
                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 +4097,36 @@ static int bond_check_params(struct bond_params *params)
                        /* 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 +4137,26 @@ static int bond_check_params(struct bond_params *params)
                __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 +4198,23 @@ static int bond_check_params(struct bond_params *params)
                        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 +4243,14 @@ static int bond_check_params(struct bond_params *params)
                }
                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;
        }