}
/* no suitable interface, frame not sent */
- bond_tx_drop(bond->dev, skb);
-out:
- return NETDEV_TX_OK;
+ return bond_tx_drop(bond->dev, skb);
}
- netdev_tx_t bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
+ struct slave *bond_xmit_tlb_slave_get(struct bonding *bond,
+ struct sk_buff *skb)
{
- struct bonding *bond = netdev_priv(bond_dev);
- struct ethhdr *eth_data;
struct slave *tx_slave = NULL;
+ struct ethhdr *eth_data;
u32 hash_index;
skb_reset_mac_header(skb);
if (--i < 0)
break;
if (bond_slave_can_tx(slave))
- return bond_dev_queue_xmit(bond, skb, slave->dev);
+ return slave;
}
-
+ /* no slave that can tx has been found */
- return bond_tx_drop(bond->dev, skb);
+ return NULL;
}
/**
non_igmp:
slave_cnt = READ_ONCE(bond->slave_cnt);
if (likely(slave_cnt)) {
- slave_id = bond_rr_gen_slave_id(bond);
- return bond_xmit_slave_id(bond, skb, slave_id % slave_cnt);
+ slave_id = bond_rr_gen_slave_id(bond) % slave_cnt;
+ return bond_get_slave_by_id(bond, slave_id);
}
- if (slave)
- bond_dev_queue_xmit(bond, skb, slave->dev);
- else
- bond_tx_drop(bond_dev, skb);
- return NETDEV_TX_OK;
+ return NULL;
+ }
+
+ static netdev_tx_t bond_xmit_roundrobin(struct sk_buff *skb,
+ struct net_device *bond_dev)
+ {
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave;
+
+ slave = bond_xmit_roundrobin_slave_get(bond, skb);
++ if (likely(slave))
++ return bond_dev_queue_xmit(bond, skb, slave->dev);
++
+ return bond_tx_drop(bond_dev, skb);
}
+ static struct slave *bond_xmit_activebackup_slave_get(struct bonding *bond,
+ struct sk_buff *skb)
+ {
+ return rcu_dereference(bond->curr_active_slave);
+ }
+
/* In active-backup mode, we know that bond->curr_active_slave is always valid if
* the bond has a usable interface.
*/
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave;
- slave = rcu_dereference(bond->curr_active_slave);
+ slave = bond_xmit_activebackup_slave_get(bond, skb);
if (slave)
- bond_dev_queue_xmit(bond, skb, slave->dev);
- else
- bond_tx_drop(bond_dev, skb);
+ return bond_dev_queue_xmit(bond, skb, slave->dev);
- return NETDEV_TX_OK;
+ return bond_tx_drop(bond_dev, skb);
}
/* Use this to update slave_array when (a) it's not appropriate to update
struct net_device *dev)
{
struct bonding *bond = netdev_priv(dev);
- struct slave *slave;
struct bond_up_slave *slaves;
- unsigned int count;
+ struct slave *slave;
- slaves = rcu_dereference(bond->slave_arr);
- count = slaves ? READ_ONCE(slaves->count) : 0;
- if (likely(count)) {
- slave = slaves->arr[bond_xmit_hash(bond, skb) % count];
+ slaves = rcu_dereference(bond->usable_slaves);
+ slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves);
+ if (likely(slave))
- bond_dev_queue_xmit(bond, skb, slave->dev);
- else
- bond_tx_drop(dev, skb);
+ return bond_dev_queue_xmit(bond, skb, slave->dev);
- }
+
- return NETDEV_TX_OK;
+ return bond_tx_drop(dev, skb);
}
/* in broadcast mode, we send everything to all usable interfaces. */