diff options
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_3ad.c | 28 | ||||
-rw-r--r-- | drivers/net/bonding/bond_3ad.h | 1 | ||||
-rw-r--r-- | drivers/net/bonding/bond_main.c | 97 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 4 |
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 | */ | ||
2305 | int 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); | |||
283 | int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); | 283 | int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); |
284 | int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); | 284 | int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); |
285 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev); | 285 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev); |
286 | int 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 | */ | ||
568 | static 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 | |||
589 | down: | ||
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) | |||
1074 | void bond_select_active_slave(struct bonding *bond) | 1110 | void 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 | ||
2200 | re_arm: | 2246 | re_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 | ||