OSDN Git Service

bonding: allow carrier and link status to determine link state
[uclinux-h8/linux.git] / drivers / net / bonding / bond_main.c
index 718e491..e4c253d 100644 (file)
@@ -132,7 +132,7 @@ MODULE_PARM_DESC(downdelay, "Delay before considering link down, "
                            "in milliseconds");
 module_param(use_carrier, int, 0);
 MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; "
-                             "0 for off, 1 for on (default)");
+                             "0 for off, 1 for on (default), 2 for carrier then legacy checks");
 module_param(mode, charp, 0);
 MODULE_PARM_DESC(mode, "Mode of operation; 0 for balance-rr, "
                       "1 for active-backup, 2 for balance-xor, "
@@ -159,7 +159,7 @@ module_param(min_links, int, 0);
 MODULE_PARM_DESC(min_links, "Minimum number of available links before turning on carrier");
 
 module_param(xmit_hash_policy, charp, 0);
-MODULE_PARM_DESC(xmit_hash_policy, "balance-xor and 802.3ad hashing method; "
+MODULE_PARM_DESC(xmit_hash_policy, "balance-alb, balance-tlb, balance-xor, 802.3ad hashing method; "
                                   "0 for layer 2 (default), 1 for layer 3+4, "
                                   "2 for layer 2+3, 3 for encap layer 2+3, "
                                   "4 for encap layer 3+4");
@@ -247,7 +247,7 @@ void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
 
        BUILD_BUG_ON(sizeof(skb->queue_mapping) !=
                     sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping));
-       skb->queue_mapping = qdisc_skb_cb(skb)->slave_dev_queue_mapping;
+       skb_set_queue_mapping(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping);
 
        if (unlikely(netpoll_tx_running(bond->dev)))
                bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb);
@@ -434,12 +434,16 @@ static int bond_check_dev_link(struct bonding *bond,
        int (*ioctl)(struct net_device *, struct ifreq *, int);
        struct ifreq ifr;
        struct mii_ioctl_data *mii;
+       bool carrier = true;
 
        if (!reporting && !netif_running(slave_dev))
                return 0;
 
        if (bond->params.use_carrier)
-               return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
+               carrier = netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
+
+       if (!carrier)
+               return carrier;
 
        /* Try to get link status using Ethtool first. */
        if (slave_dev->ethtool_ops->get_link)
@@ -1735,9 +1739,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
                unblock_netpoll_tx();
        }
 
-       if (bond_mode_uses_xmit_hash(bond))
+       if (bond_mode_can_use_xmit_hash(bond))
                bond_update_slave_arr(bond, NULL);
 
+       bond->nest_level = dev_get_nest_level(bond_dev);
+
        netdev_info(bond_dev, "Enslaving %s as %s interface with %s link\n",
                    slave_dev->name,
                    bond_is_active_slave(new_slave) ? "an active" : "a backup",
@@ -1868,7 +1874,7 @@ static int __bond_release_one(struct net_device *bond_dev,
        if (BOND_MODE(bond) == BOND_MODE_8023AD)
                bond_3ad_unbind_slave(slave);
 
-       if (bond_mode_uses_xmit_hash(bond))
+       if (bond_mode_can_use_xmit_hash(bond))
                bond_update_slave_arr(bond, slave);
 
        netdev_info(bond_dev, "Releasing %s interface %s\n",
@@ -3100,7 +3106,7 @@ static int bond_slave_netdev_event(unsigned long event,
                 * events. If these (miimon/arpmon) parameters are configured
                 * then array gets refreshed twice and that should be fine!
                 */
-               if (bond_mode_uses_xmit_hash(bond))
+               if (bond_mode_can_use_xmit_hash(bond))
                        bond_update_slave_arr(bond, NULL);
                break;
        case NETDEV_CHANGEMTU:
@@ -3320,7 +3326,7 @@ static int bond_open(struct net_device *bond_dev)
                 */
                if (bond_alb_initialize(bond, (BOND_MODE(bond) == BOND_MODE_ALB)))
                        return -ENOMEM;
-               if (bond->params.tlb_dynamic_lb)
+               if (bond->params.tlb_dynamic_lb || BOND_MODE(bond) == BOND_MODE_ALB)
                        queue_delayed_work(bond->wq, &bond->alb_work, 0);
        }
 
@@ -3339,7 +3345,7 @@ static int bond_open(struct net_device *bond_dev)
                bond_3ad_initiate_agg_selection(bond, 1);
        }
 
-       if (bond_mode_uses_xmit_hash(bond))
+       if (bond_mode_can_use_xmit_hash(bond))
                bond_update_slave_arr(bond, NULL);
 
        return 0;
@@ -3805,7 +3811,8 @@ static u32 bond_rr_gen_slave_id(struct bonding *bond)
        return slave_id;
 }
 
-static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
+static netdev_tx_t bond_xmit_roundrobin(struct sk_buff *skb,
+                                       struct net_device *bond_dev)
 {
        struct bonding *bond = netdev_priv(bond_dev);
        struct iphdr *iph = ip_hdr(skb);
@@ -3841,7 +3848,8 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
 /* In active-backup mode, we know that bond->curr_active_slave is always valid if
  * the bond has a usable interface.
  */
-static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_dev)
+static netdev_tx_t bond_xmit_activebackup(struct sk_buff *skb,
+                                         struct net_device *bond_dev)
 {
        struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave;
@@ -3890,7 +3898,7 @@ err:
  * to determine the slave interface -
  * (a) BOND_MODE_8023AD
  * (b) BOND_MODE_XOR
- * (c) BOND_MODE_TLB && tlb_dynamic_lb == 0
+ * (c) (BOND_MODE_TLB || BOND_MODE_ALB) && tlb_dynamic_lb == 0
  *
  * The caller is expected to hold RTNL only and NO other lock!
  */
@@ -3943,6 +3951,11 @@ int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave)
                        continue;
                if (skipslave == slave)
                        continue;
+
+               netdev_dbg(bond->dev,
+                          "Adding slave dev %s to tx hash array[%d]\n",
+                          slave->dev->name, new_arr->count);
+
                new_arr->arr[new_arr->count++] = slave;
        }
 
@@ -3979,7 +3992,8 @@ out:
  * usable slave array is formed in the control path. The xmit function
  * just calculates hash and sends the packet out.
  */
-static int bond_3ad_xor_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t bond_3ad_xor_xmit(struct sk_buff *skb,
+                                    struct net_device *dev)
 {
        struct bonding *bond = netdev_priv(dev);
        struct slave *slave;
@@ -3999,7 +4013,8 @@ static int bond_3ad_xor_xmit(struct sk_buff *skb, struct net_device *dev)
 }
 
 /* in broadcast mode, we send everything to all usable interfaces. */
-static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
+static netdev_tx_t bond_xmit_broadcast(struct sk_buff *skb,
+                                      struct net_device *bond_dev)
 {
        struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave = NULL;
@@ -4036,12 +4051,12 @@ static inline int bond_slave_override(struct bonding *bond,
        struct slave *slave = NULL;
        struct list_head *iter;
 
-       if (!skb->queue_mapping)
+       if (!skb_rx_queue_recorded(skb))
                return 1;
 
        /* Find out if any slaves have the same mapping as this skb. */
        bond_for_each_slave_rcu(bond, slave, iter) {
-               if (slave->queue_id == skb->queue_mapping) {
+               if (slave->queue_id == skb_get_queue_mapping(skb)) {
                        if (bond_slave_is_up(slave) &&
                            slave->link == BOND_LINK_UP) {
                                bond_dev_queue_xmit(bond, skb, slave->dev);
@@ -4067,7 +4082,7 @@ 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;
 
        /* Save the original txq to restore before passing to the driver */
-       qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
+       qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb_get_queue_mapping(skb);
 
        if (unlikely(txq >= dev->real_num_tx_queues)) {
                do {
@@ -4318,9 +4333,9 @@ static int bond_check_params(struct bond_params *params)
        }
 
        if (xmit_hash_policy) {
-               if ((bond_mode != BOND_MODE_XOR) &&
-                   (bond_mode != BOND_MODE_8023AD) &&
-                   (bond_mode != BOND_MODE_TLB)) {
+               if (bond_mode == BOND_MODE_ROUNDROBIN ||
+                   bond_mode == BOND_MODE_ACTIVEBACKUP ||
+                   bond_mode == BOND_MODE_BROADCAST) {
                        pr_info("xmit_hash_policy param is irrelevant in mode %s\n",
                                bond_mode_name(bond_mode));
                } else {
@@ -4392,8 +4407,8 @@ static int bond_check_params(struct bond_params *params)
                downdelay = 0;
        }
 
-       if ((use_carrier != 0) && (use_carrier != 1)) {
-               pr_warn("Warning: use_carrier module parameter (%d), not of valid value (0/1), so it was set to 1\n",
+       if (use_carrier < 0 || use_carrier > 2) {
+               pr_warn("Warning: use_carrier module parameter (%d), not of valid value (0-2), so it was set to 1\n",
                        use_carrier);
                use_carrier = 1;
        }