* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
- *
- * Changes:
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- * Amir Noam <amir.noam at intel dot com>
- * - Added support for lacp_rate module param.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- * - Based on discussion on mailing list, changed locking scheme
- * to use lock/unlock or lock_bh/unlock_bh appropriately instead
- * of lock_irqsave/unlock_irqrestore. The new scheme helps exposing
- * hidden bugs and solves system hangs that occurred due to the fact
- * that holding lock_irqsave doesn't prevent softirqs from running.
- * This also increases total throughput since interrupts are not
- * blocked on each transmitted packets or monitor timeout.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- * - Renamed bond_3ad_link_status_changed() to
- * bond_3ad_handle_link_change() for compatibility with TLB.
- *
- * 2003/05/20 - Amir Noam <amir.noam at intel dot com>
- * - Fix long fail over time when releasing last slave of an active
- * aggregator - send LACPDU on unbind of slave to tell partner this
- * port is no longer aggregatable.
- *
- * 2003/06/25 - Tsippy Mendelson <tsippy.mendelson at intel dot com>
- * - 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
// detect loopback situation
if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
// INFO_RECEIVED_LOOPBACK_FRAMES
- 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");
+ printk(KERN_ERR DRV_NAME ": %s: An illegal loopback occurred on "
+ "adapter (%s). Check the configuration to verify that all "
+ "Adapters are connected to 802.3ad compliant switch ports\n",
+ port->slave->dev->master->name, port->slave->dev->name);
__release_rx_machine_lock(port);
return;
}
}
}
if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
- printk(KERN_WARNING DRV_NAME ": Warning: Port %d (on %s) was "
+ printk(KERN_WARNING DRV_NAME ": %s: Warning: Port %d (on %s) was "
"related to aggregator %d but was not on its port list\n",
+ port->slave->dev->master->name,
port->actor_port_number, port->slave->dev->name,
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 DRV_NAME ": Port %d (on %s) did not find a suitable aggregator\n",
+ printk(KERN_ERR DRV_NAME ": %s: Port %d (on %s) did not find a suitable aggregator\n",
+ port->slave->dev->master->name,
port->actor_port_number, port->slave->dev->name);
}
}
// check if any partner replys
if (best_aggregator->is_individual) {
- printk(KERN_WARNING DRV_NAME ": Warning: No 802.3ad response from the link partner "
- "for any adapters in the bond\n");
+ printk(KERN_WARNING DRV_NAME ": %s: Warning: No 802.3ad response from "
+ "the link partner for any adapters in the bond\n",
+ best_aggregator->slave->dev->master->name);
}
// check if there are more than one aggregator
struct aggregator *aggregator;
if (bond == NULL) {
- printk(KERN_ERR "The slave %s is not attached to its bond\n", slave->dev->name);
+ printk(KERN_ERR DRV_NAME ": %s: The slave %s is not attached to its bond\n",
+ slave->dev->master->name, slave->dev->name);
return -1;
}
// if slave is null, the whole port is not initialized
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": Trying to unbind an uninitialized port on %s\n", slave->dev->name);
+ printk(KERN_WARNING DRV_NAME ": Warning: %s: Trying to "
+ "unbind an uninitialized port on %s\n",
+ slave->dev->master->name, slave->dev->name);
return;
}
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 DRV_NAME ": Removing an active aggregator\n");
+ printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
+ aggregator->slave->dev->master->name);
// select new active aggregator
select_new_active_agg = 1;
}
ad_agg_selection_logic(__get_first_agg(port));
}
} else {
- printk(KERN_WARNING DRV_NAME ": Warning: unbinding aggregator, "
- "and could not find a new aggregator for its ports\n");
+ printk(KERN_WARNING DRV_NAME ": %s: Warning: unbinding aggregator, "
+ "and could not find a new aggregator for its ports\n",
+ slave->dev->master->name);
}
} else { // in case that the only port related to this aggregator is the one we want to remove
select_new_active_agg = aggregator->is_active;
// clear the aggregator
ad_clear_agg(aggregator);
if (select_new_active_agg) {
- printk(KERN_INFO "Removing an active aggregator\n");
+ printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
+ slave->dev->master->name);
// select new active aggregator
ad_agg_selection_logic(__get_first_agg(port));
}
// clear the aggregator
ad_clear_agg(temp_aggregator);
if (select_new_active_agg) {
- printk(KERN_INFO "Removing an active aggregator\n");
+ printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
+ slave->dev->master->name);
// select new active aggregator
ad_agg_selection_logic(__get_first_agg(port));
}
// select the active aggregator for the bond
if ((port = __get_first_port(bond))) {
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": Warning: bond's first port is uninitialized\n");
+ printk(KERN_WARNING DRV_NAME ": %s: Warning: bond's first port is "
+ "uninitialized\n", bond->dev->name);
goto re_arm;
}
// 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 DRV_NAME ": Warning: Found an uninitialized port\n");
+ printk(KERN_WARNING DRV_NAME ": %s: Warning: Found an uninitialized "
+ "port\n", bond->dev->name);
goto re_arm;
}
port = &(SLAVE_AD_INFO(slave).port);
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": Warning: port of slave %s is uninitialized\n", slave->dev->name);
+ printk(KERN_WARNING DRV_NAME ": %s: Warning: port of slave %s is "
+ "uninitialized\n", slave->dev->name, slave->dev->master->name);
return;
}
// if slave is null, the whole port is not initialized
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": Warning: speed changed for uninitialized port on %s\n",
- slave->dev->name);
+ printk(KERN_WARNING DRV_NAME ": Warning: %s: speed "
+ "changed for uninitialized port on %s\n",
+ slave->dev->master->name, slave->dev->name);
return;
}
// if slave is null, the whole port is not initialized
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": Warning: duplex changed for uninitialized port on %s\n",
- slave->dev->name);
+ printk(KERN_WARNING DRV_NAME ": %s: Warning: duplex changed "
+ "for uninitialized port on %s\n",
+ slave->dev->master->name, slave->dev->name);
return;
}
// if slave is null, the whole port is not initialized
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": Warning: link status changed for uninitialized port on %s\n",
- slave->dev->name);
+ printk(KERN_WARNING DRV_NAME ": Warning: %s: link status changed for "
+ "uninitialized port on %s\n",
+ slave->dev->master->name, slave->dev->name);
return;
}
port->sm_vars |= AD_PORT_BEGIN;
}
+/*
+ * set link state for bonding master: if we have an active partnered
+ * aggregator, we're up, if not, we're down. Presumes that we cannot
+ * have an active aggregator if there are no slaves with link up.
+ *
+ * Called by bond_set_carrier(). Return zero if carrier state does not
+ * change, nonzero if it does.
+ */
+int bond_3ad_set_carrier(struct bonding *bond)
+{
+ struct aggregator *agg;
+
+ agg = __get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator));
+ if (agg && MAC_ADDRESS_COMPARE(&agg->partner_system, &null_mac_addr)) {
+ if (!netif_carrier_ok(bond->dev)) {
+ netif_carrier_on(bond->dev);
+ return 1;
+ }
+ return 0;
+ }
+
+ if (netif_carrier_ok(bond->dev)) {
+ netif_carrier_off(bond->dev);
+ return 1;
+ }
+ return 0;
+}
+
/**
* bond_3ad_get_active_agg_info - get information of the active aggregator
* @bond: bonding struct to work on
{
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;
}
if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
- printk(KERN_DEBUG "ERROR: bond_3ad_get_active_agg_info failed\n");
+ printk(KERN_DEBUG DRV_NAME ": %s: Error: "
+ "bond_3ad_get_active_agg_info failed\n", dev->name);
goto out;
}
if (slaves_in_agg == 0) {
/*the aggregator is empty*/
- printk(KERN_DEBUG "ERROR: active aggregator is empty\n");
+ printk(KERN_DEBUG DRV_NAME ": %s: Error: active "
+ "aggregator is empty\n",
+ dev->name);
goto out;
}
- slave_agg_no = (data->h_dest[5]^bond->dev->dev_addr[5]) % slaves_in_agg;
+ slave_agg_no = bond->xmit_hash_policy(skb, dev, slaves_in_agg);
bond_for_each_slave(bond, slave, i) {
struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
}
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);
+ printk(KERN_ERR DRV_NAME ": %s: Error: Couldn't find a slave to tx on "
+ "for aggregator ID %d\n", dev->name, agg_id);
goto out;
}
return 0;
}
-int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype)
+int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev)
{
struct bonding *bond = dev->priv;
struct slave *slave = NULL;
int ret = NET_RX_DROP;
- if (!(dev->flags & IFF_MASTER)) {
+ if (!(dev->flags & IFF_MASTER))
goto out;
- }
read_lock(&bond->lock);
- slave = bond_get_slave_by_dev((struct bonding *)dev->priv,
- skb->real_dev);
- if (slave == NULL) {
+ slave = bond_get_slave_by_dev((struct bonding *)dev->priv, orig_dev);
+ if (!slave)
goto out_unlock;
- }
bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);