Commit 8169d10c authored by David S. Miller's avatar David S. Miller

Merge branch 'bonding'

Ding Tianhong says:

====================
bonding: slight optimization for bonding

This serious of patches will slight optimize the mac address compare
and xmit path for bonding, also make some cleanups.

Julia was using ether_addr_equal_64bits to instead of ether_addr_equal,
it is really a hard work and she may did not make patch for bonding yet,
so I have do it in this patchset and that she could miss the bonding drivers.

resend and add cc for Julia.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 4b903e30 844223ab
...@@ -90,8 +90,9 @@ ...@@ -90,8 +90,9 @@
#define AD_LINK_SPEED_BITMASK_10000MBPS 0x10 #define AD_LINK_SPEED_BITMASK_10000MBPS 0x10
//endalloun //endalloun
// compare MAC addresses /* compare MAC addresses */
#define MAC_ADDRESS_COMPARE(A, B) memcmp(A, B, ETH_ALEN) #define MAC_ADDRESS_EQUAL(A, B) \
ether_addr_equal_64bits((const u8 *)A, (const u8 *)B)
static struct mac_addr null_mac_addr = { { 0, 0, 0, 0, 0, 0 } }; static struct mac_addr null_mac_addr = { { 0, 0, 0, 0, 0, 0 } };
static u16 ad_ticks_per_sec; static u16 ad_ticks_per_sec;
...@@ -417,17 +418,18 @@ static u16 __ad_timer_to_ticks(u16 timer_type, u16 par) ...@@ -417,17 +418,18 @@ static u16 __ad_timer_to_ticks(u16 timer_type, u16 par)
*/ */
static void __choose_matched(struct lacpdu *lacpdu, struct port *port) static void __choose_matched(struct lacpdu *lacpdu, struct port *port)
{ {
// check if all parameters are alike /* check if all parameters are alike
* or this is individual link(aggregation == FALSE)
* then update the state machine Matched variable.
*/
if (((ntohs(lacpdu->partner_port) == port->actor_port_number) && if (((ntohs(lacpdu->partner_port) == port->actor_port_number) &&
(ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) && (ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) &&
!MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) && MAC_ADDRESS_EQUAL(&(lacpdu->partner_system), &(port->actor_system)) &&
(ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) && (ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) &&
(ntohs(lacpdu->partner_key) == port->actor_oper_port_key) && (ntohs(lacpdu->partner_key) == port->actor_oper_port_key) &&
((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) || ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) ||
// or this is individual link(aggregation == FALSE)
((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0) ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0)
) { ) {
// update the state machine Matched variable
port->sm_vars |= AD_PORT_MATCHED; port->sm_vars |= AD_PORT_MATCHED;
} else { } else {
port->sm_vars &= ~AD_PORT_MATCHED; port->sm_vars &= ~AD_PORT_MATCHED;
...@@ -507,14 +509,15 @@ static void __update_selected(struct lacpdu *lacpdu, struct port *port) ...@@ -507,14 +509,15 @@ static void __update_selected(struct lacpdu *lacpdu, struct port *port)
if (lacpdu && port) { if (lacpdu && port) {
const struct port_params *partner = &port->partner_oper; const struct port_params *partner = &port->partner_oper;
// check if any parameter is different /* check if any parameter is different then
* update the state machine selected variable.
*/
if (ntohs(lacpdu->actor_port) != partner->port_number || if (ntohs(lacpdu->actor_port) != partner->port_number ||
ntohs(lacpdu->actor_port_priority) != partner->port_priority || ntohs(lacpdu->actor_port_priority) != partner->port_priority ||
MAC_ADDRESS_COMPARE(&lacpdu->actor_system, &partner->system) || !MAC_ADDRESS_EQUAL(&lacpdu->actor_system, &partner->system) ||
ntohs(lacpdu->actor_system_priority) != partner->system_priority || ntohs(lacpdu->actor_system_priority) != partner->system_priority ||
ntohs(lacpdu->actor_key) != partner->key || ntohs(lacpdu->actor_key) != partner->key ||
(lacpdu->actor_state & AD_STATE_AGGREGATION) != (partner->port_state & AD_STATE_AGGREGATION)) { (lacpdu->actor_state & AD_STATE_AGGREGATION) != (partner->port_state & AD_STATE_AGGREGATION)) {
// update the state machine Selected variable
port->sm_vars &= ~AD_PORT_SELECTED; port->sm_vars &= ~AD_PORT_SELECTED;
} }
} }
...@@ -538,15 +541,16 @@ static void __update_default_selected(struct port *port) ...@@ -538,15 +541,16 @@ static void __update_default_selected(struct port *port)
const struct port_params *admin = &port->partner_admin; const struct port_params *admin = &port->partner_admin;
const struct port_params *oper = &port->partner_oper; const struct port_params *oper = &port->partner_oper;
// check if any parameter is different /* check if any parameter is different then
* update the state machine selected variable.
*/
if (admin->port_number != oper->port_number || if (admin->port_number != oper->port_number ||
admin->port_priority != oper->port_priority || admin->port_priority != oper->port_priority ||
MAC_ADDRESS_COMPARE(&admin->system, &oper->system) || !MAC_ADDRESS_EQUAL(&admin->system, &oper->system) ||
admin->system_priority != oper->system_priority || admin->system_priority != oper->system_priority ||
admin->key != oper->key || admin->key != oper->key ||
(admin->port_state & AD_STATE_AGGREGATION) (admin->port_state & AD_STATE_AGGREGATION)
!= (oper->port_state & AD_STATE_AGGREGATION)) { != (oper->port_state & AD_STATE_AGGREGATION)) {
// update the state machine Selected variable
port->sm_vars &= ~AD_PORT_SELECTED; port->sm_vars &= ~AD_PORT_SELECTED;
} }
} }
...@@ -566,12 +570,14 @@ static void __update_default_selected(struct port *port) ...@@ -566,12 +570,14 @@ static void __update_default_selected(struct port *port)
*/ */
static void __update_ntt(struct lacpdu *lacpdu, struct port *port) static void __update_ntt(struct lacpdu *lacpdu, struct port *port)
{ {
// validate lacpdu and port /* validate lacpdu and port */
if (lacpdu && port) { if (lacpdu && port) {
// check if any parameter is different /* check if any parameter is different then
* update the port->ntt.
*/
if ((ntohs(lacpdu->partner_port) != port->actor_port_number) || if ((ntohs(lacpdu->partner_port) != port->actor_port_number) ||
(ntohs(lacpdu->partner_port_priority) != port->actor_port_priority) || (ntohs(lacpdu->partner_port_priority) != port->actor_port_priority) ||
MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) || !MAC_ADDRESS_EQUAL(&(lacpdu->partner_system), &(port->actor_system)) ||
(ntohs(lacpdu->partner_system_priority) != port->actor_system_priority) || (ntohs(lacpdu->partner_system_priority) != port->actor_system_priority) ||
(ntohs(lacpdu->partner_key) != port->actor_oper_port_key) || (ntohs(lacpdu->partner_key) != port->actor_oper_port_key) ||
((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) || ((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) ||
...@@ -579,7 +585,6 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port) ...@@ -579,7 +585,6 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port)
((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) || ((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) ||
((lacpdu->partner_state & AD_STATE_AGGREGATION) != (port->actor_oper_port_state & AD_STATE_AGGREGATION)) ((lacpdu->partner_state & AD_STATE_AGGREGATION) != (port->actor_oper_port_state & AD_STATE_AGGREGATION))
) { ) {
port->ntt = true; port->ntt = true;
} }
} }
...@@ -1076,9 +1081,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) ...@@ -1076,9 +1081,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
port->actor_oper_port_state &= ~AD_STATE_EXPIRED; port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
break; break;
case AD_RX_CURRENT: case AD_RX_CURRENT:
// detect loopback situation /* detect loopback situation */
if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) { if (MAC_ADDRESS_EQUAL(&(lacpdu->actor_system), &(port->actor_system))) {
// INFO_RECEIVED_LOOPBACK_FRAMES
pr_err("%s: An illegal loopback occurred on adapter (%s).\n" pr_err("%s: An illegal loopback occurred on adapter (%s).\n"
"Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n",
port->slave->bond->dev->name, port->slave->dev->name); port->slave->bond->dev->name, port->slave->dev->name);
...@@ -1090,7 +1094,7 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) ...@@ -1090,7 +1094,7 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)); port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT));
port->actor_oper_port_state &= ~AD_STATE_EXPIRED; port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
break; break;
default: //to silence the compiler default: /* to silence the compiler */
break; break;
} }
} }
...@@ -1281,17 +1285,17 @@ static void ad_port_selection_logic(struct port *port) ...@@ -1281,17 +1285,17 @@ static void ad_port_selection_logic(struct port *port)
free_aggregator = aggregator; free_aggregator = aggregator;
continue; continue;
} }
// check if current aggregator suits us /* check if current aggregator suits us */
if (((aggregator->actor_oper_aggregator_key == port->actor_oper_port_key) && // if all parameters match AND if (((aggregator->actor_oper_aggregator_key == port->actor_oper_port_key) && /* if all parameters match AND */
!MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(port->partner_oper.system)) && MAC_ADDRESS_EQUAL(&(aggregator->partner_system), &(port->partner_oper.system)) &&
(aggregator->partner_system_priority == port->partner_oper.system_priority) && (aggregator->partner_system_priority == port->partner_oper.system_priority) &&
(aggregator->partner_oper_aggregator_key == port->partner_oper.key) (aggregator->partner_oper_aggregator_key == port->partner_oper.key)
) && ) &&
((MAC_ADDRESS_COMPARE(&(port->partner_oper.system), &(null_mac_addr)) && // partner answers ((!MAC_ADDRESS_EQUAL(&(port->partner_oper.system), &(null_mac_addr)) && /* partner answers */
!aggregator->is_individual) // but is not individual OR !aggregator->is_individual) /* but is not individual OR */
) )
) { ) {
// attach to the founded aggregator /* attach to the founded aggregator */
port->aggregator = aggregator; port->aggregator = aggregator;
port->actor_port_aggregator_identifier = port->actor_port_aggregator_identifier =
port->aggregator->aggregator_identifier; port->aggregator->aggregator_identifier;
...@@ -1705,7 +1709,7 @@ static void ad_enable_collecting_distributing(struct port *port) ...@@ -1705,7 +1709,7 @@ static void ad_enable_collecting_distributing(struct port *port)
*/ */
static void ad_disable_collecting_distributing(struct port *port) static void ad_disable_collecting_distributing(struct port *port)
{ {
if (port->aggregator && MAC_ADDRESS_COMPARE(&(port->aggregator->partner_system), &(null_mac_addr))) { if (port->aggregator && !MAC_ADDRESS_EQUAL(&(port->aggregator->partner_system), &(null_mac_addr))) {
pr_debug("Disabling port %d(LAG %d)\n", pr_debug("Disabling port %d(LAG %d)\n",
port->actor_port_number, port->actor_port_number,
port->aggregator->aggregator_identifier); port->aggregator->aggregator_identifier);
...@@ -1826,8 +1830,8 @@ static u16 aggregator_identifier; ...@@ -1826,8 +1830,8 @@ static u16 aggregator_identifier;
*/ */
void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
{ {
// check that the bond is not initialized yet /* check that the bond is not initialized yet */
if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr),
bond->dev->dev_addr)) { bond->dev->dev_addr)) {
aggregator_identifier = 0; aggregator_identifier = 0;
...@@ -1851,22 +1855,16 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) ...@@ -1851,22 +1855,16 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
* Returns: 0 on success * Returns: 0 on success
* < 0 on error * < 0 on error
*/ */
int bond_3ad_bind_slave(struct slave *slave) void bond_3ad_bind_slave(struct slave *slave)
{ {
struct bonding *bond = bond_get_bond_by_slave(slave); struct bonding *bond = bond_get_bond_by_slave(slave);
struct port *port; struct port *port;
struct aggregator *aggregator; struct aggregator *aggregator;
if (bond == NULL) { /* check that the slave has not been initialized yet. */
pr_err("%s: The slave %s is not attached to its bond\n",
slave->bond->dev->name, slave->dev->name);
return -1;
}
//check that the slave has not been initialized yet.
if (SLAVE_AD_INFO(slave).port.slave != slave) { if (SLAVE_AD_INFO(slave).port.slave != slave) {
// port initialization /* port initialization */
port = &(SLAVE_AD_INFO(slave).port); port = &(SLAVE_AD_INFO(slave).port);
ad_initialize_port(port, bond->params.lacp_fast); ad_initialize_port(port, bond->params.lacp_fast);
...@@ -1874,28 +1872,30 @@ int bond_3ad_bind_slave(struct slave *slave) ...@@ -1874,28 +1872,30 @@ int bond_3ad_bind_slave(struct slave *slave)
__initialize_port_locks(slave); __initialize_port_locks(slave);
port->slave = slave; port->slave = slave;
port->actor_port_number = SLAVE_AD_INFO(slave).id; port->actor_port_number = SLAVE_AD_INFO(slave).id;
// key is determined according to the link speed, duplex and user key(which is yet not supported) /* key is determined according to the link speed, duplex and user key(which
// ------------------------------------------------------------ * is yet not supported)
// Port key : | User key | Speed |Duplex| * ------------------------------------------------------------
// ------------------------------------------------------------ * Port key : | User key | Speed |Duplex|
// 16 6 1 0 * ------------------------------------------------------------
port->actor_admin_port_key = 0; // initialize this parameter * 16 6 1 0
*/
port->actor_admin_port_key = 0; /* initialize this parameter */
port->actor_admin_port_key |= __get_duplex(port); port->actor_admin_port_key |= __get_duplex(port);
port->actor_admin_port_key |= (__get_link_speed(port) << 1); port->actor_admin_port_key |= (__get_link_speed(port) << 1);
port->actor_oper_port_key = port->actor_admin_port_key; port->actor_oper_port_key = port->actor_admin_port_key;
// if the port is not full duplex, then the port should be not lacp Enabled /* if the port is not full duplex, then the port should be not lacp Enabled */
if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS))
port->sm_vars &= ~AD_PORT_LACP_ENABLED; port->sm_vars &= ~AD_PORT_LACP_ENABLED;
// actor system is the bond's system /* actor system is the bond's system */
port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr; port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr;
// tx timer(to verify that no more than MAX_TX_IN_SECOND lacpdu's are sent in one second) /* tx timer(to verify that no more than MAX_TX_IN_SECOND lacpdu's are sent in one second) */
port->sm_tx_timer_counter = ad_ticks_per_sec/AD_MAX_TX_IN_SECOND; port->sm_tx_timer_counter = ad_ticks_per_sec/AD_MAX_TX_IN_SECOND;
port->aggregator = NULL; port->aggregator = NULL;
port->next_port_in_aggregator = NULL; port->next_port_in_aggregator = NULL;
__disable_port(port); __disable_port(port);
// aggregator initialization /* aggregator initialization */
aggregator = &(SLAVE_AD_INFO(slave).aggregator); aggregator = &(SLAVE_AD_INFO(slave).aggregator);
ad_initialize_agg(aggregator); ad_initialize_agg(aggregator);
...@@ -1906,8 +1906,6 @@ int bond_3ad_bind_slave(struct slave *slave) ...@@ -1906,8 +1906,6 @@ int bond_3ad_bind_slave(struct slave *slave)
aggregator->is_active = 0; aggregator->is_active = 0;
aggregator->num_of_ports = 0; aggregator->num_of_ports = 0;
} }
return 0;
} }
/** /**
...@@ -2397,13 +2395,12 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) ...@@ -2397,13 +2395,12 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
struct list_head *iter; struct list_head *iter;
int slaves_in_agg; int slaves_in_agg;
int slave_agg_no; int slave_agg_no;
int res = 1;
int agg_id; int agg_id;
if (__bond_3ad_get_active_agg_info(bond, &ad_info)) { if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n", pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n",
dev->name); dev->name);
goto out; goto err_free;
} }
slaves_in_agg = ad_info.ports; slaves_in_agg = ad_info.ports;
...@@ -2411,7 +2408,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) ...@@ -2411,7 +2408,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
if (slaves_in_agg == 0) { if (slaves_in_agg == 0) {
pr_debug("%s: Error: active aggregator is empty\n", dev->name); pr_debug("%s: Error: active aggregator is empty\n", dev->name);
goto out; goto err_free;
} }
slave_agg_no = bond_xmit_hash(bond, skb, slaves_in_agg); slave_agg_no = bond_xmit_hash(bond, skb, slaves_in_agg);
...@@ -2430,7 +2427,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) ...@@ -2430,7 +2427,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
} }
if (SLAVE_IS_OK(slave)) { if (SLAVE_IS_OK(slave)) {
res = bond_dev_queue_xmit(bond, skb, slave->dev); bond_dev_queue_xmit(bond, skb, slave->dev);
goto out; goto out;
} }
} }
...@@ -2438,21 +2435,22 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) ...@@ -2438,21 +2435,22 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
if (slave_agg_no >= 0) { if (slave_agg_no >= 0) {
pr_err("%s: Error: Couldn't find a slave to tx on for aggregator ID %d\n", pr_err("%s: Error: Couldn't find a slave to tx on for aggregator ID %d\n",
dev->name, agg_id); dev->name, agg_id);
goto out; goto err_free;
} }
/* we couldn't find any suitable slave after the agg_no, so use the /* we couldn't find any suitable slave after the agg_no, so use the
* first suitable found, if found. */ * first suitable found, if found. */
if (first_ok_slave) if (first_ok_slave)
res = bond_dev_queue_xmit(bond, skb, first_ok_slave->dev); bond_dev_queue_xmit(bond, skb, first_ok_slave->dev);
else
goto err_free;
out: out:
if (res) {
/* no suitable interface, frame not sent */
kfree_skb(skb);
}
return NETDEV_TX_OK; return NETDEV_TX_OK;
err_free:
/* no suitable interface, frame not sent */
kfree_skb(skb);
goto out;
} }
int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
......
...@@ -265,7 +265,7 @@ struct ad_slave_info { ...@@ -265,7 +265,7 @@ struct ad_slave_info {
// ================= AD Exported functions to the main bonding code ================== // ================= AD Exported functions to the main bonding code ==================
void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution); void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution);
int bond_3ad_bind_slave(struct slave *slave); void bond_3ad_bind_slave(struct slave *slave);
void bond_3ad_unbind_slave(struct slave *slave); void bond_3ad_unbind_slave(struct slave *slave);
void bond_3ad_state_machine_handler(struct work_struct *); void bond_3ad_state_machine_handler(struct work_struct *);
void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout); void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout);
......
...@@ -1371,7 +1371,6 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) ...@@ -1371,7 +1371,6 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
int do_tx_balance = 1; int do_tx_balance = 1;
u32 hash_index = 0; u32 hash_index = 0;
const u8 *hash_start = NULL; const u8 *hash_start = NULL;
int res = 1;
struct ipv6hdr *ip6hdr; struct ipv6hdr *ip6hdr;
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
...@@ -1469,7 +1468,8 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) ...@@ -1469,7 +1468,8 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
ETH_ALEN); ETH_ALEN);
} }
res = bond_dev_queue_xmit(bond, skb, tx_slave->dev); bond_dev_queue_xmit(bond, skb, tx_slave->dev);
goto out;
} else { } else {
if (tx_slave) { if (tx_slave) {
_lock_tx_hashtbl(bond); _lock_tx_hashtbl(bond);
...@@ -1478,11 +1478,9 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) ...@@ -1478,11 +1478,9 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
} }
} }
if (res) { /* no suitable interface, frame not sent */
/* no suitable interface, frame not sent */ kfree_skb(skb);
kfree_skb(skb); out:
}
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
......
...@@ -304,7 +304,7 @@ const char *bond_mode_name(int mode) ...@@ -304,7 +304,7 @@ const char *bond_mode_name(int mode)
* @skb: hw accel VLAN tagged skb to transmit * @skb: hw accel VLAN tagged skb to transmit
* @slave_dev: slave that is supposed to xmit this skbuff * @slave_dev: slave that is supposed to xmit this skbuff
*/ */
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
struct net_device *slave_dev) struct net_device *slave_dev)
{ {
skb->dev = slave_dev; skb->dev = slave_dev;
...@@ -317,8 +317,6 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, ...@@ -317,8 +317,6 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb);
else else
dev_queue_xmit(skb); dev_queue_xmit(skb);
return 0;
} }
/* /*
...@@ -1639,7 +1637,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) ...@@ -1639,7 +1637,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
err_undo_flags: err_undo_flags:
/* Enslave of first slave has failed and we need to fix master's mac */ /* Enslave of first slave has failed and we need to fix master's mac */
if (!bond_has_slaves(bond) && if (!bond_has_slaves(bond) &&
ether_addr_equal(bond_dev->dev_addr, slave_dev->dev_addr)) ether_addr_equal_64bits(bond_dev->dev_addr, slave_dev->dev_addr))
eth_hw_addr_random(bond_dev); eth_hw_addr_random(bond_dev);
return res; return res;
...@@ -1712,7 +1710,7 @@ static int __bond_release_one(struct net_device *bond_dev, ...@@ -1712,7 +1710,7 @@ static int __bond_release_one(struct net_device *bond_dev,
bond->current_arp_slave = NULL; bond->current_arp_slave = NULL;
if (!all && !bond->params.fail_over_mac) { if (!all && !bond->params.fail_over_mac) {
if (ether_addr_equal(bond_dev->dev_addr, slave->perm_hwaddr) && if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) &&
bond_has_slaves(bond)) 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", 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, bond_dev->name, slave_dev->name,
...@@ -3673,28 +3671,24 @@ static inline int bond_slave_override(struct bonding *bond, ...@@ -3673,28 +3671,24 @@ static inline int bond_slave_override(struct bonding *bond,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct slave *slave = NULL; struct slave *slave = NULL;
struct slave *check_slave;
struct list_head *iter; struct list_head *iter;
int res = 1;
if (!skb->queue_mapping) if (!skb->queue_mapping)
return 1; return 1;
/* Find out if any slaves have the same mapping as this skb. */ /* Find out if any slaves have the same mapping as this skb. */
bond_for_each_slave_rcu(bond, check_slave, iter) { bond_for_each_slave_rcu(bond, slave, iter) {
if (check_slave->queue_id == skb->queue_mapping) { if (slave->queue_id == skb->queue_mapping) {
slave = check_slave; if (slave_can_tx(slave)) {
bond_dev_queue_xmit(bond, skb, slave->dev);
return 0;
}
/* If the slave isn't UP, use default transmit policy. */
break; break;
} }
} }
/* If the slave isn't UP, use default transmit policy. */ return 1;
if (slave && slave->queue_id && IS_UP(slave->dev) &&
(slave->link == BOND_LINK_UP)) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
}
return res;
} }
......
...@@ -416,7 +416,7 @@ static inline bool slave_can_tx(struct slave *slave) ...@@ -416,7 +416,7 @@ static inline bool slave_can_tx(struct slave *slave)
struct bond_net; struct bond_net;
int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, struct slave *slave); int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, struct slave *slave);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
int bond_create(struct net *net, const char *name); int bond_create(struct net *net, const char *name);
int bond_create_sysfs(struct bond_net *net); int bond_create_sysfs(struct bond_net *net);
void bond_destroy_sysfs(struct bond_net *net); void bond_destroy_sysfs(struct bond_net *net);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment