patch-2.4.26 linux-2.4.26/drivers/net/bonding/bond_3ad.c
Next file: linux-2.4.26/drivers/net/bonding/bond_3ad.h
Previous file: linux-2.4.26/drivers/net/Makefile
Back to the patch index
Back to the overall index
- Lines: 648
- Date:
2004-04-14 06:05:30.000000000 -0700
- Orig file:
linux-2.4.25/drivers/net/bonding/bond_3ad.c
- Orig date:
2003-08-25 04:44:42.000000000 -0700
diff -urN linux-2.4.25/drivers/net/bonding/bond_3ad.c linux-2.4.26/drivers/net/bonding/bond_3ad.c
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+ * Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -47,8 +47,13 @@
* - Send LACPDU as highest priority packet to further fix the above
* problem on very high Tx traffic load where packets may get dropped
* by the slave.
+ *
+ * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
+ * - Code cleanup and style changes
*/
+//#define BONDING_DEBUG 1
+
#include <linux/skbuff.h>
#include <linux/if_ether.h>
#include <linux/netdevice.h>
@@ -119,6 +124,7 @@
static struct mac_addr null_mac_addr = {{0, 0, 0, 0, 0, 0}};
static u16 ad_ticks_per_sec;
+static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
// ================= 3AD api to bonding and kernel code ==================
static u16 __get_link_speed(struct port *port);
@@ -196,13 +202,11 @@
*/
static inline struct port *__get_first_port(struct bonding *bond)
{
- struct slave *slave = bond->next;
-
- if (slave == (struct slave *)bond) {
+ if (bond->slave_cnt == 0) {
return NULL;
}
- return &(SLAVE_AD_INFO(slave).port);
+ return &(SLAVE_AD_INFO(bond->first_slave).port);
}
/**
@@ -218,7 +222,7 @@
struct slave *slave = port->slave;
// If there's no bond for this port, or this is the last slave
- if ((bond == NULL) || (slave->next == bond->next)) {
+ if ((bond == NULL) || (slave->next == bond->first_slave)) {
return NULL;
}
@@ -236,12 +240,12 @@
{
struct bonding *bond = __get_bond_by_port(port);
- // If there's no bond for this port, or this is the last slave
- if ((bond == NULL) || (bond->next == (struct slave *)bond)) {
+ // If there's no bond for this port, or bond has no slaves
+ if ((bond == NULL) || (bond->slave_cnt == 0)) {
return NULL;
}
- return &(SLAVE_AD_INFO(bond->next).aggregator);
+ return &(SLAVE_AD_INFO(bond->first_slave).aggregator);
}
/**
@@ -257,7 +261,7 @@
struct bonding *bond = bond_get_bond_by_slave(slave);
// If there's no bond for this aggregator, or this is the last slave
- if ((bond == NULL) || (slave->next == bond->next)) {
+ if ((bond == NULL) || (slave->next == bond->first_slave)) {
return NULL;
}
@@ -392,7 +396,7 @@
}
}
- BOND_PRINT_DBG(("Port %d Received link speed %d update from adapter", port->actor_port_number, speed));
+ dprintk("Port %d Received link speed %d update from adapter\n", port->actor_port_number, speed);
return speed;
}
@@ -418,12 +422,12 @@
switch (slave->duplex) {
case DUPLEX_FULL:
retval=0x1;
- BOND_PRINT_DBG(("Port %d Received status full duplex update from adapter", port->actor_port_number));
+ dprintk("Port %d Received status full duplex update from adapter\n", port->actor_port_number);
break;
case DUPLEX_HALF:
default:
retval=0x0;
- BOND_PRINT_DBG(("Port %d Received status NOT full duplex update from adapter", port->actor_port_number));
+ dprintk("Port %d Received status NOT full duplex update from adapter\n", port->actor_port_number);
break;
}
}
@@ -1059,7 +1063,7 @@
// check if the state machine was changed
if (port->sm_mux_state != last_state) {
- BOND_PRINT_DBG(("Mux Machine: Port=%d, Last State=%d, Curr State=%d", port->actor_port_number, last_state, port->sm_mux_state));
+ dprintk("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_mux_state);
switch (port->sm_mux_state) {
case AD_MUX_DETACHED:
__detach_bond_from_agg(port);
@@ -1158,7 +1162,7 @@
// check if the State machine was changed or new lacpdu arrived
if ((port->sm_rx_state != last_state) || (lacpdu)) {
- BOND_PRINT_DBG(("Rx Machine: Port=%d, Last State=%d, Curr State=%d", port->actor_port_number, last_state, port->sm_rx_state));
+ dprintk("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_rx_state);
switch (port->sm_rx_state) {
case AD_RX_INITIALIZE:
if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) {
@@ -1204,7 +1208,7 @@
// detect loopback situation
if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
// INFO_RECEIVED_LOOPBACK_FRAMES
- printk(KERN_ERR "bonding: An illegal loopback occurred on adapter (%s)\n",
+ printk(KERN_ERR DRV_NAME ": An illegal loopback occurred on adapter (%s)\n",
port->slave->dev->name);
printk(KERN_ERR "Check the configuration to verify that all Adapters "
"are connected to 802.3ad compliant switch ports\n");
@@ -1245,7 +1249,7 @@
__update_lacpdu_from_port(port);
// send the lacpdu
if (ad_lacpdu_send(port) >= 0) {
- BOND_PRINT_DBG(("Sent LACPDU on port %d", port->actor_port_number));
+ dprintk("Sent LACPDU on port %d\n", port->actor_port_number);
// mark ntt as false, so it will not be sent again until demanded
port->ntt = 0;
}
@@ -1318,7 +1322,7 @@
// check if the state machine was changed
if (port->sm_periodic_state != last_state) {
- BOND_PRINT_DBG(("Periodic Machine: Port=%d, Last State=%d, Curr State=%d", port->actor_port_number, last_state, port->sm_periodic_state));
+ dprintk("Periodic Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_periodic_state);
switch (port->sm_periodic_state) {
case AD_NO_PERIODIC:
port->sm_periodic_timer_counter = 0; // zero timer
@@ -1375,7 +1379,7 @@
port->next_port_in_aggregator=NULL;
port->actor_port_aggregator_identifier=0;
- BOND_PRINT_DBG(("Port %d left LAG %d", port->actor_port_number, temp_aggregator->aggregator_identifier));
+ dprintk("Port %d left LAG %d\n", port->actor_port_number, temp_aggregator->aggregator_identifier);
// if the aggregator is empty, clear its parameters, and set it ready to be attached
if (!temp_aggregator->lag_ports) {
ad_clear_agg(temp_aggregator);
@@ -1384,7 +1388,7 @@
}
}
if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
- printk(KERN_WARNING "bonding: Warning: Port %d (on %s) was "
+ printk(KERN_WARNING DRV_NAME ": Warning: Port %d (on %s) was "
"related to aggregator %d but was not on its port list\n",
port->actor_port_number, port->slave->dev->name,
port->aggregator->aggregator_identifier);
@@ -1417,7 +1421,7 @@
port->next_port_in_aggregator=aggregator->lag_ports;
port->aggregator->num_of_ports++;
aggregator->lag_ports=port;
- BOND_PRINT_DBG(("Port %d joined LAG %d(existing LAG)", port->actor_port_number, port->aggregator->aggregator_identifier));
+ dprintk("Port %d joined LAG %d(existing LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
// mark this port as selected
port->sm_vars |= AD_PORT_SELECTED;
@@ -1454,9 +1458,9 @@
// mark this port as selected
port->sm_vars |= AD_PORT_SELECTED;
- BOND_PRINT_DBG(("Port %d joined LAG %d(new LAG)", port->actor_port_number, port->aggregator->aggregator_identifier));
+ dprintk("Port %d joined LAG %d(new LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
} else {
- printk(KERN_ERR "bonding: Port %d (on %s) did not find a suitable aggregator\n",
+ printk(KERN_ERR DRV_NAME ": Port %d (on %s) did not find a suitable aggregator\n",
port->actor_port_number, port->slave->dev->name);
}
}
@@ -1580,30 +1584,30 @@
aggregator;
aggregator = __get_next_agg(aggregator)) {
- BOND_PRINT_DBG(("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d",
+ dprintk("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d\n",
aggregator->aggregator_identifier, aggregator->num_of_ports,
aggregator->actor_oper_aggregator_key, aggregator->partner_oper_aggregator_key,
- aggregator->is_individual, aggregator->is_active));
+ aggregator->is_individual, aggregator->is_active);
}
// check if any partner replys
if (best_aggregator->is_individual) {
- printk(KERN_WARNING "bonding: Warning: No 802.3ad response from the link partner "
+ printk(KERN_WARNING DRV_NAME ": Warning: No 802.3ad response from the link partner "
"for any adapters in the bond\n");
}
// check if there are more than one aggregator
if (num_of_aggs > 1) {
- BOND_PRINT_DBG(("Warning: More than one Link Aggregation Group was "
- "found in the bond. Only one group will function in the bond"));
+ dprintk("Warning: More than one Link Aggregation Group was "
+ "found in the bond. Only one group will function in the bond\n");
}
best_aggregator->is_active = 1;
- BOND_PRINT_DBG(("LAG %d choosed as the active LAG", best_aggregator->aggregator_identifier));
- BOND_PRINT_DBG(("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d",
+ dprintk("LAG %d choosed as the active LAG\n", best_aggregator->aggregator_identifier);
+ dprintk("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d\n",
best_aggregator->aggregator_identifier, best_aggregator->num_of_ports,
best_aggregator->actor_oper_aggregator_key, best_aggregator->partner_oper_aggregator_key,
- best_aggregator->is_individual, best_aggregator->is_active));
+ best_aggregator->is_individual, best_aggregator->is_active);
// disable the ports that were related to the former active_aggregator
if (last_active_aggregator) {
@@ -1644,7 +1648,7 @@
aggregator->lag_ports = NULL;
aggregator->is_active = 0;
aggregator->num_of_ports = 0;
- BOND_PRINT_DBG(("LAG %d was cleared", aggregator->aggregator_identifier));
+ dprintk("LAG %d was cleared\n", aggregator->aggregator_identifier);
}
}
@@ -1729,7 +1733,7 @@
static void ad_enable_collecting_distributing(struct port *port)
{
if (port->aggregator->is_active) {
- BOND_PRINT_DBG(("Enabling port %d(LAG %d)", port->actor_port_number, port->aggregator->aggregator_identifier));
+ dprintk("Enabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
__enable_port(port);
}
}
@@ -1742,7 +1746,7 @@
static void ad_disable_collecting_distributing(struct port *port)
{
if (port->aggregator && MAC_ADDRESS_COMPARE(&(port->aggregator->partner_system), &(null_mac_addr))) {
- BOND_PRINT_DBG(("Disabling port %d(LAG %d)", port->actor_port_number, port->aggregator->aggregator_identifier));
+ dprintk("Disabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
__disable_port(port);
}
}
@@ -1780,7 +1784,7 @@
// send the marker information
if (ad_marker_send(port, &marker) >= 0) {
- BOND_PRINT_DBG(("Sent Marker Information on port %d", port->actor_port_number));
+ dprintk("Sent Marker Information on port %d\n", port->actor_port_number);
}
}
#endif
@@ -1803,7 +1807,7 @@
// send the marker response
if (ad_marker_send(port, &marker) >= 0) {
- BOND_PRINT_DBG(("Sent Marker Response on port %d", port->actor_port_number));
+ dprintk("Sent Marker Response on port %d\n", port->actor_port_number);
}
}
@@ -1890,13 +1894,13 @@
void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast)
{
// check that the bond is not initialized yet
- if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->device->dev_addr))) {
+ if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->dev->dev_addr))) {
aggregator_identifier = 0;
BOND_AD_INFO(bond).lacp_fast = lacp_fast;
BOND_AD_INFO(bond).system.sys_priority = 0xFFFF;
- BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->device->dev_addr);
+ BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
// initialize how many times this module is called in one second(should be about every 100ms)
ad_ticks_per_sec = tick_resolution;
@@ -1921,7 +1925,7 @@
struct aggregator *aggregator;
if (bond == NULL) {
- printk(KERN_CRIT "The slave %s is not attached to its bond\n", slave->dev->name);
+ printk(KERN_ERR "The slave %s is not attached to its bond\n", slave->dev->name);
return -1;
}
@@ -1964,7 +1968,7 @@
ad_initialize_agg(aggregator);
- aggregator->aggregator_mac_address = *((struct mac_addr *)bond->device->dev_addr);
+ aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr);
aggregator->aggregator_identifier = (++aggregator_identifier);
aggregator->slave = slave;
aggregator->is_active = 0;
@@ -1996,11 +2000,11 @@
// if slave is null, the whole port is not initialized
if (!port->slave) {
- printk(KERN_WARNING "bonding: Trying to unbind an uninitialized port on %s\n", slave->dev->name);
+ printk(KERN_WARNING DRV_NAME ": Trying to unbind an uninitialized port on %s\n", slave->dev->name);
return;
}
- BOND_PRINT_DBG(("Unbinding Link Aggregation Group %d", aggregator->aggregator_identifier));
+ dprintk("Unbinding Link Aggregation Group %d\n", aggregator->aggregator_identifier);
/* Tell the partner that this port is not suitable for aggregation */
port->actor_oper_port_state &= ~AD_STATE_AGGREGATION;
@@ -2024,10 +2028,10 @@
// if new aggregator found, copy the aggregator's parameters
// and connect the related lag_ports to the new aggregator
if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) {
- BOND_PRINT_DBG(("Some port(s) related to LAG %d - replaceing with LAG %d", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier));
+ dprintk("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier);
if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
- printk(KERN_INFO "bonding: Removing an active aggregator\n");
+ printk(KERN_INFO DRV_NAME ": Removing an active aggregator\n");
// select new active aggregator
select_new_active_agg = 1;
}
@@ -2057,7 +2061,7 @@
ad_agg_selection_logic(__get_first_agg(port));
}
} else {
- printk(KERN_WARNING "bonding: Warning: unbinding aggregator, "
+ printk(KERN_WARNING DRV_NAME ": Warning: unbinding aggregator, "
"and could not find a new aggregator for its ports\n");
}
} else { // in case that the only port related to this aggregator is the one we want to remove
@@ -2072,7 +2076,7 @@
}
}
- BOND_PRINT_DBG(("Unbinding port %d", port->actor_port_number));
+ dprintk("Unbinding port %d\n", port->actor_port_number);
// find the aggregator that this port is connected to
temp_aggregator = __get_first_agg(port);
for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) {
@@ -2123,13 +2127,13 @@
read_lock(&bond->lock);
- //check if there are any slaves
- if (bond->next == (struct slave *)bond) {
- goto end;
+ if (bond->kill_timers) {
+ goto out;
}
- if ((bond->device->flags & IFF_UP) != IFF_UP) {
- goto end;
+ //check if there are any slaves
+ if (bond->slave_cnt == 0) {
+ goto re_arm;
}
// check if agg_select_timer timer after initialize is timed out
@@ -2137,8 +2141,8 @@
// select the active aggregator for the bond
if ((port = __get_first_port(bond))) {
if (!port->slave) {
- printk(KERN_WARNING "bonding: Warning: bond's first port is uninitialized\n");
- goto end;
+ printk(KERN_WARNING DRV_NAME ": Warning: bond's first port is uninitialized\n");
+ goto re_arm;
}
aggregator = __get_first_agg(port);
@@ -2149,8 +2153,8 @@
// for each port run the state machines
for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
if (!port->slave) {
- printk(KERN_WARNING "bonding: Warning: Found an uninitialized port\n");
- goto end;
+ printk(KERN_WARNING DRV_NAME ": Warning: Found an uninitialized port\n");
+ goto re_arm;
}
ad_rx_machine(NULL, port);
@@ -2165,14 +2169,10 @@
}
}
-end:
+re_arm:
+ mod_timer(&(BOND_AD_INFO(bond).ad_timer), jiffies + ad_delta_in_ticks);
+out:
read_unlock(&bond->lock);
-
-
- if ((bond->device->flags & IFF_UP) == IFF_UP) {
- /* re-arm the timer */
- mod_timer(&(BOND_AD_INFO(bond).ad_timer), jiffies + (AD_TIMER_INTERVAL * HZ / 1000));
- }
}
/**
@@ -2194,14 +2194,14 @@
port = &(SLAVE_AD_INFO(slave).port);
if (!port->slave) {
- printk(KERN_WARNING "bonding: Warning: port of slave %s is uninitialized\n", slave->dev->name);
+ printk(KERN_WARNING DRV_NAME ": Warning: port of slave %s is uninitialized\n", slave->dev->name);
return;
}
switch (lacpdu->subtype) {
case AD_TYPE_LACPDU:
__ntohs_lacpdu(lacpdu);
- BOND_PRINT_DBG(("Received LACPDU on port %d", port->actor_port_number));
+ dprintk("Received LACPDU on port %d\n", port->actor_port_number);
ad_rx_machine(lacpdu, port);
break;
@@ -2210,17 +2210,17 @@
switch (((struct marker *)lacpdu)->tlv_type) {
case AD_MARKER_INFORMATION_SUBTYPE:
- BOND_PRINT_DBG(("Received Marker Information on port %d", port->actor_port_number));
+ dprintk("Received Marker Information on port %d\n", port->actor_port_number);
ad_marker_info_received((struct marker *)lacpdu, port);
break;
case AD_MARKER_RESPONSE_SUBTYPE:
- BOND_PRINT_DBG(("Received Marker Response on port %d", port->actor_port_number));
+ dprintk("Received Marker Response on port %d\n", port->actor_port_number);
ad_marker_response_received((struct marker *)lacpdu, port);
break;
default:
- BOND_PRINT_DBG(("Received an unknown Marker subtype on slot %d", port->actor_port_number));
+ dprintk("Received an unknown Marker subtype on slot %d\n", port->actor_port_number);
}
}
}
@@ -2240,14 +2240,14 @@
// if slave is null, the whole port is not initialized
if (!port->slave) {
- printk(KERN_WARNING "bonding: Warning: speed changed for uninitialized port on %s\n",
+ printk(KERN_WARNING DRV_NAME ": Warning: speed changed for uninitialized port on %s\n",
slave->dev->name);
return;
}
port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS;
port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1);
- BOND_PRINT_DBG(("Port %d changed speed", port->actor_port_number));
+ dprintk("Port %d changed speed\n", port->actor_port_number);
// there is no need to reselect a new aggregator, just signal the
// state machines to reinitialize
port->sm_vars |= AD_PORT_BEGIN;
@@ -2267,14 +2267,14 @@
// if slave is null, the whole port is not initialized
if (!port->slave) {
- printk(KERN_WARNING "bonding: Warning: duplex changed for uninitialized port on %s\n",
+ printk(KERN_WARNING DRV_NAME ": Warning: duplex changed for uninitialized port on %s\n",
slave->dev->name);
return;
}
port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port);
- BOND_PRINT_DBG(("Port %d changed duplex", port->actor_port_number));
+ dprintk("Port %d changed duplex\n", port->actor_port_number);
// there is no need to reselect a new aggregator, just signal the
// state machines to reinitialize
port->sm_vars |= AD_PORT_BEGIN;
@@ -2295,10 +2295,8 @@
// if slave is null, the whole port is not initialized
if (!port->slave) {
-#ifdef BONDING_DEBUG
- printk(KERN_WARNING "bonding: Warning: link status changed for uninitialized port on %s\n",
- slave->dev->name);
-#endif
+ printk(KERN_WARNING DRV_NAME ": Warning: link status changed for uninitialized port on %s\n",
+ slave->dev->name);
return;
}
@@ -2356,41 +2354,28 @@
int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
{
- slave_t *slave, *start_at;
- struct bonding *bond = (struct bonding *) dev->priv;
+ struct slave *slave, *start_at;
+ struct bonding *bond = dev->priv;
struct ethhdr *data = (struct ethhdr *)skb->data;
int slave_agg_no;
int slaves_in_agg;
int agg_id;
+ int i;
struct ad_info ad_info;
+ int res = 1;
- if (!IS_UP(dev)) { /* bond down */
- dev_kfree_skb(skb);
- return 0;
- }
-
- if (bond == NULL) {
- printk(KERN_CRIT "bonding: Error: bond is NULL on device %s\n", dev->name);
- dev_kfree_skb(skb);
- return 0;
- }
-
+ /* make sure that the slaves list will
+ * not change during tx
+ */
read_lock(&bond->lock);
- slave = bond->prev;
- /* check if bond is empty */
- if ((slave == (struct slave *) bond) || (bond->slave_cnt == 0)) {
- printk(KERN_DEBUG "ERROR: bond is empty\n");
- dev_kfree_skb(skb);
- read_unlock(&bond->lock);
- return 0;
+ if (!BOND_IS_OK(bond)) {
+ goto out;
}
if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
printk(KERN_DEBUG "ERROR: bond_3ad_get_active_agg_info failed\n");
- dev_kfree_skb(skb);
- read_unlock(&bond->lock);
- return 0;
+ goto out;
}
slaves_in_agg = ad_info.ports;
@@ -2399,21 +2384,12 @@
if (slaves_in_agg == 0) {
/*the aggregator is empty*/
printk(KERN_DEBUG "ERROR: active aggregator is empty\n");
- dev_kfree_skb(skb);
- read_unlock(&bond->lock);
- return 0;
+ goto out;
}
- /* we're at the root, get the first slave */
- if ((slave == NULL) || (slave->dev == NULL)) {
- /* no suitable interface, frame not sent */
- dev_kfree_skb(skb);
- read_unlock(&bond->lock);
- return 0;
- }
+ slave_agg_no = (data->h_dest[5]^bond->dev->dev_addr[5]) % slaves_in_agg;
- slave_agg_no = (data->h_dest[5]^slave->dev->dev_addr[5]) % slaves_in_agg;
- while (slave != (slave_t *)bond) {
+ bond_for_each_slave(bond, slave, i) {
struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
if (agg && (agg->aggregator_identifier == agg_id)) {
@@ -2422,61 +2398,41 @@
break;
}
}
-
- slave = slave->prev;
- if (slave == NULL) {
- printk(KERN_ERR "bonding: Error: slave is NULL\n");
- dev_kfree_skb(skb);
- read_unlock(&bond->lock);
- return 0;
- }
}
- if (slave == (slave_t *)bond) {
- printk(KERN_ERR "bonding: Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id);
- dev_kfree_skb(skb);
- read_unlock(&bond->lock);
- return 0;
+ if (slave_agg_no >= 0) {
+ printk(KERN_ERR DRV_NAME ": Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id);
+ goto out;
}
start_at = slave;
- do {
+ bond_for_each_slave_from(bond, slave, i, start_at) {
int slave_agg_id = 0;
- struct aggregator *agg;
-
- if (slave == NULL) {
- printk(KERN_ERR "bonding: Error: slave is NULL\n");
- dev_kfree_skb(skb);
- read_unlock(&bond->lock);
- return 0;
- }
-
- agg = SLAVE_AD_INFO(slave).port.aggregator;
+ struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
if (agg) {
slave_agg_id = agg->aggregator_identifier;
}
- if (SLAVE_IS_OK(slave) &&
- agg && (slave_agg_id == agg_id)) {
- skb->dev = slave->dev;
- skb->priority = 1;
- dev_queue_xmit(skb);
- read_unlock(&bond->lock);
- return 0;
+ if (SLAVE_IS_OK(slave) && agg && (slave_agg_id == agg_id)) {
+ res = bond_dev_queue_xmit(bond, skb, slave->dev);
+ break;
}
- } while ((slave = slave->next) != start_at);
+ }
- /* no suitable interface, frame not sent */
- dev_kfree_skb(skb);
+out:
+ if (res) {
+ /* no suitable interface, frame not sent */
+ dev_kfree_skb(skb);
+ }
read_unlock(&bond->lock);
return 0;
}
int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype)
{
- struct bonding *bond = (struct bonding *)dev->priv;
+ struct bonding *bond = dev->priv;
struct slave *slave = NULL;
int ret = NET_RX_DROP;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)