aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2006-03-27 16:27:43 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-29 17:34:02 -0500
commitff59c4563a8d1b39597aab4917959146c61f09b0 (patch)
tree5be8ad689d944f27a7b4b4bed2942c3ef47d7a98
parente21a2b0cc5849e76434b37aff3a4b502c772f191 (diff)
[PATCH] bonding: support carrier state for master
Add support for the bonding master to specify its carrier state based upon the state of the slaves. For 802.3ad, the bond is up if there is an active, parterned aggregator. For other modes, the bond is up if any slaves are up. Updates driver version to 3.0.3. Based on a patch by jamal <hadi@cyberus.ca>. Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/bonding/bond_3ad.c28
-rw-r--r--drivers/net/bonding/bond_3ad.h1
-rw-r--r--drivers/net/bonding/bond_main.c97
-rw-r--r--drivers/net/bonding/bonding.h4
4 files changed, 102 insertions, 28 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index f3f5825469d6..6a407070c2e8 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2294,6 +2294,34 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
2294 port->sm_vars |= AD_PORT_BEGIN; 2294 port->sm_vars |= AD_PORT_BEGIN;
2295} 2295}
2296 2296
2297/*
2298 * set link state for bonding master: if we have an active partnered
2299 * aggregator, we're up, if not, we're down. Presumes that we cannot
2300 * have an active aggregator if there are no slaves with link up.
2301 *
2302 * Called by bond_set_carrier(). Return zero if carrier state does not
2303 * change, nonzero if it does.
2304 */
2305int bond_3ad_set_carrier(struct bonding *bond)
2306{
2307 struct aggregator *agg;
2308
2309 agg = __get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator));
2310 if (agg && MAC_ADDRESS_COMPARE(&agg->partner_system, &null_mac_addr)) {
2311 if (!netif_carrier_ok(bond->dev)) {
2312 netif_carrier_on(bond->dev);
2313 return 1;
2314 }
2315 return 0;
2316 }
2317
2318 if (netif_carrier_ok(bond->dev)) {
2319 netif_carrier_off(bond->dev);
2320 return 1;
2321 }
2322 return 0;
2323}
2324
2297/** 2325/**
2298 * bond_3ad_get_active_agg_info - get information of the active aggregator 2326 * bond_3ad_get_active_agg_info - get information of the active aggregator
2299 * @bond: bonding struct to work on 2327 * @bond: bonding struct to work on
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index 5ee2cef5b037..6ad5ad6e65d5 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -283,5 +283,6 @@ void bond_3ad_handle_link_change(struct slave *slave, char link);
283int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); 283int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
284int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); 284int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
285int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev); 285int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev);
286int bond_3ad_set_carrier(struct bonding *bond);
286#endif //__BOND_3AD_H__ 287#endif //__BOND_3AD_H__
287 288
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f13a539dc169..55d236726d11 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -559,6 +559,42 @@ out:
559/*------------------------------- Link status -------------------------------*/ 559/*------------------------------- Link status -------------------------------*/
560 560
561/* 561/*
562 * Set the carrier state for the master according to the state of its
563 * slaves. If any slaves are up, the master is up. In 802.3ad mode,
564 * do special 802.3ad magic.
565 *
566 * Returns zero if carrier state does not change, nonzero if it does.
567 */
568static int bond_set_carrier(struct bonding *bond)
569{
570 struct slave *slave;
571 int i;
572
573 if (bond->slave_cnt == 0)
574 goto down;
575
576 if (bond->params.mode == BOND_MODE_8023AD)
577 return bond_3ad_set_carrier(bond);
578
579 bond_for_each_slave(bond, slave, i) {
580 if (slave->link == BOND_LINK_UP) {
581 if (!netif_carrier_ok(bond->dev)) {
582 netif_carrier_on(bond->dev);
583 return 1;
584 }
585 return 0;
586 }
587 }
588
589down:
590 if (netif_carrier_ok(bond->dev)) {
591 netif_carrier_off(bond->dev);
592 return 1;
593 }
594 return 0;
595}
596
597/*
562 * Get link speed and duplex from the slave's base driver 598 * Get link speed and duplex from the slave's base driver
563 * using ethtool. If for some reason the call fails or the 599 * using ethtool. If for some reason the call fails or the
564 * values are invalid, fake speed and duplex to 100/Full 600 * values are invalid, fake speed and duplex to 100/Full
@@ -1074,10 +1110,24 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
1074void bond_select_active_slave(struct bonding *bond) 1110void bond_select_active_slave(struct bonding *bond)
1075{ 1111{
1076 struct slave *best_slave; 1112 struct slave *best_slave;
1113 int rv;
1077 1114
1078 best_slave = bond_find_best_slave(bond); 1115 best_slave = bond_find_best_slave(bond);
1079 if (best_slave != bond->curr_active_slave) { 1116 if (best_slave != bond->curr_active_slave) {
1080 bond_change_active_slave(bond, best_slave); 1117 bond_change_active_slave(bond, best_slave);
1118 rv = bond_set_carrier(bond);
1119 if (!rv)
1120 return;
1121
1122 if (netif_carrier_ok(bond->dev)) {
1123 printk(KERN_INFO DRV_NAME
1124 ": %s: first active interface up!\n",
1125 bond->dev->name);
1126 } else {
1127 printk(KERN_INFO DRV_NAME ": %s: "
1128 "now running without any active interface !\n",
1129 bond->dev->name);
1130 }
1081 } 1131 }
1082} 1132}
1083 1133
@@ -1458,10 +1508,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1458 if (((!bond->curr_active_slave) || 1508 if (((!bond->curr_active_slave) ||
1459 (bond->curr_active_slave->dev->priv_flags & IFF_SLAVE_INACTIVE)) && 1509 (bond->curr_active_slave->dev->priv_flags & IFF_SLAVE_INACTIVE)) &&
1460 (new_slave->link != BOND_LINK_DOWN)) { 1510 (new_slave->link != BOND_LINK_DOWN)) {
1461 dprintk("This is the first active slave\n");
1462 /* first slave or no active slave yet, and this link 1511 /* first slave or no active slave yet, and this link
1463 is OK, so make this interface the active one */ 1512 is OK, so make this interface the active one */
1464 bond_change_active_slave(bond, new_slave); 1513 bond_change_active_slave(bond, new_slave);
1514 printk(KERN_INFO DRV_NAME
1515 ": %s: first active interface up!\n",
1516 bond->dev->name);
1517 netif_carrier_on(bond->dev);
1518
1465 } else { 1519 } else {
1466 dprintk("This is just a backup slave\n"); 1520 dprintk("This is just a backup slave\n");
1467 bond_set_slave_inactive_flags(new_slave); 1521 bond_set_slave_inactive_flags(new_slave);
@@ -1517,6 +1571,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1517 break; 1571 break;
1518 } /* switch(bond_mode) */ 1572 } /* switch(bond_mode) */
1519 1573
1574 bond_set_carrier(bond);
1575
1520 write_unlock_bh(&bond->lock); 1576 write_unlock_bh(&bond->lock);
1521 1577
1522 res = bond_create_slave_symlinks(bond_dev, slave_dev); 1578 res = bond_create_slave_symlinks(bond_dev, slave_dev);
@@ -1656,18 +1712,12 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1656 bond_alb_deinit_slave(bond, slave); 1712 bond_alb_deinit_slave(bond, slave);
1657 } 1713 }
1658 1714
1659 if (oldcurrent == slave) { 1715 if (oldcurrent == slave)
1660 bond_select_active_slave(bond); 1716 bond_select_active_slave(bond);
1661 1717
1662 if (!bond->curr_active_slave) {
1663 printk(KERN_INFO DRV_NAME
1664 ": %s: now running without any active "
1665 "interface !\n",
1666 bond_dev->name);
1667 }
1668 }
1669
1670 if (bond->slave_cnt == 0) { 1718 if (bond->slave_cnt == 0) {
1719 bond_set_carrier(bond);
1720
1671 /* if the last slave was removed, zero the mac address 1721 /* if the last slave was removed, zero the mac address
1672 * of the master so it will be set by the application 1722 * of the master so it will be set by the application
1673 * to the mac address of the first slave 1723 * to the mac address of the first slave
@@ -1751,6 +1801,8 @@ static int bond_release_all(struct net_device *bond_dev)
1751 1801
1752 write_lock_bh(&bond->lock); 1802 write_lock_bh(&bond->lock);
1753 1803
1804 netif_carrier_off(bond_dev);
1805
1754 if (bond->slave_cnt == 0) { 1806 if (bond->slave_cnt == 0) {
1755 goto out; 1807 goto out;
1756 } 1808 }
@@ -2187,15 +2239,9 @@ void bond_mii_monitor(struct net_device *bond_dev)
2187 2239
2188 bond_select_active_slave(bond); 2240 bond_select_active_slave(bond);
2189 2241
2190 if (oldcurrent && !bond->curr_active_slave) {
2191 printk(KERN_INFO DRV_NAME
2192 ": %s: now running without any active "
2193 "interface !\n",
2194 bond_dev->name);
2195 }
2196
2197 write_unlock(&bond->curr_slave_lock); 2242 write_unlock(&bond->curr_slave_lock);
2198 } 2243 } else
2244 bond_set_carrier(bond);
2199 2245
2200re_arm: 2246re_arm:
2201 if (bond->params.miimon) { 2247 if (bond->params.miimon) {
@@ -2499,13 +2545,6 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev)
2499 2545
2500 bond_select_active_slave(bond); 2546 bond_select_active_slave(bond);
2501 2547
2502 if (oldcurrent && !bond->curr_active_slave) {
2503 printk(KERN_INFO DRV_NAME
2504 ": %s: now running without any active "
2505 "interface !\n",
2506 bond_dev->name);
2507 }
2508
2509 write_unlock(&bond->curr_slave_lock); 2548 write_unlock(&bond->curr_slave_lock);
2510 } 2549 }
2511 2550
@@ -2579,12 +2618,15 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2579 bond->current_arp_slave = NULL; 2618 bond->current_arp_slave = NULL;
2580 } 2619 }
2581 2620
2621 bond_set_carrier(bond);
2622
2582 if (slave == bond->curr_active_slave) { 2623 if (slave == bond->curr_active_slave) {
2583 printk(KERN_INFO DRV_NAME 2624 printk(KERN_INFO DRV_NAME
2584 ": %s: %s is up and now the " 2625 ": %s: %s is up and now the "
2585 "active interface\n", 2626 "active interface\n",
2586 bond_dev->name, 2627 bond_dev->name,
2587 slave->dev->name); 2628 slave->dev->name);
2629 netif_carrier_on(bond->dev);
2588 } else { 2630 } else {
2589 printk(KERN_INFO DRV_NAME 2631 printk(KERN_INFO DRV_NAME
2590 ": %s: backup interface %s is " 2632 ": %s: backup interface %s is "
@@ -2844,7 +2886,8 @@ static void bond_info_show_master(struct seq_file *seq)
2844 (curr) ? curr->dev->name : "None"); 2886 (curr) ? curr->dev->name : "None");
2845 } 2887 }
2846 2888
2847 seq_printf(seq, "MII Status: %s\n", (curr) ? "up" : "down"); 2889 seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ?
2890 "up" : "down");
2848 seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon); 2891 seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon);
2849 seq_printf(seq, "Up Delay (ms): %d\n", 2892 seq_printf(seq, "Up Delay (ms): %d\n",
2850 bond->params.updelay * bond->params.miimon); 2893 bond->params.updelay * bond->params.miimon);
@@ -4531,6 +4574,8 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
4531 if (newbond) 4574 if (newbond)
4532 *newbond = bond_dev->priv; 4575 *newbond = bond_dev->priv;
4533 4576
4577 netif_carrier_off(bond_dev);
4578
4534 rtnl_unlock(); /* allows sysfs registration of net device */ 4579 rtnl_unlock(); /* allows sysfs registration of net device */
4535 res = bond_create_sysfs_entry(bond_dev->priv); 4580 res = bond_create_sysfs_entry(bond_dev->priv);
4536 goto done; 4581 goto done;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index ce9dc9b4e2dc..0bdfe2c71453 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -22,8 +22,8 @@
22#include "bond_3ad.h" 22#include "bond_3ad.h"
23#include "bond_alb.h" 23#include "bond_alb.h"
24 24
25#define DRV_VERSION "3.0.2" 25#define DRV_VERSION "3.0.3"
26#define DRV_RELDATE "February 21, 2006" 26#define DRV_RELDATE "March 23, 2006"
27#define DRV_NAME "bonding" 27#define DRV_NAME "bonding"
28#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 28#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
29 29