aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c70
1 files changed, 18 insertions, 52 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c34cc1e7c6f..7f8756825b8 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -550,7 +550,7 @@ down:
550/* 550/*
551 * Get link speed and duplex from the slave's base driver 551 * Get link speed and duplex from the slave's base driver
552 * using ethtool. If for some reason the call fails or the 552 * using ethtool. If for some reason the call fails or the
553 * values are invalid, fake speed and duplex to 100/Full 553 * values are invalid, set speed and duplex to -1,
554 * and return error. 554 * and return error.
555 */ 555 */
556static int bond_update_speed_duplex(struct slave *slave) 556static int bond_update_speed_duplex(struct slave *slave)
@@ -560,9 +560,8 @@ static int bond_update_speed_duplex(struct slave *slave)
560 u32 slave_speed; 560 u32 slave_speed;
561 int res; 561 int res;
562 562
563 /* Fake speed and duplex */ 563 slave->speed = SPEED_UNKNOWN;
564 slave->speed = SPEED_100; 564 slave->duplex = DUPLEX_UNKNOWN;
565 slave->duplex = DUPLEX_FULL;
566 565
567 res = __ethtool_get_settings(slave_dev, &ecmd); 566 res = __ethtool_get_settings(slave_dev, &ecmd);
568 if (res < 0) 567 if (res < 0)
@@ -1751,16 +1750,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1751 new_slave->link = BOND_LINK_DOWN; 1750 new_slave->link = BOND_LINK_DOWN;
1752 } 1751 }
1753 1752
1754 if (bond_update_speed_duplex(new_slave) && 1753 bond_update_speed_duplex(new_slave);
1755 (new_slave->link != BOND_LINK_DOWN)) {
1756 pr_warning("%s: Warning: failed to get speed and duplex from %s, assumed to be 100Mb/sec and Full.\n",
1757 bond_dev->name, new_slave->dev->name);
1758
1759 if (bond->params.mode == BOND_MODE_8023AD) {
1760 pr_warning("%s: Warning: Operation of 802.3ad mode requires ETHTOOL support in base driver for proper aggregator selection.\n",
1761 bond_dev->name);
1762 }
1763 }
1764 1754
1765 if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) { 1755 if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
1766 /* if there is a primary slave, remember it */ 1756 /* if there is a primary slave, remember it */
@@ -2563,30 +2553,6 @@ re_arm:
2563 } 2553 }
2564} 2554}
2565 2555
2566static __be32 bond_glean_dev_ip(struct net_device *dev)
2567{
2568 struct in_device *idev;
2569 struct in_ifaddr *ifa;
2570 __be32 addr = 0;
2571
2572 if (!dev)
2573 return 0;
2574
2575 rcu_read_lock();
2576 idev = __in_dev_get_rcu(dev);
2577 if (!idev)
2578 goto out;
2579
2580 ifa = idev->ifa_list;
2581 if (!ifa)
2582 goto out;
2583
2584 addr = ifa->ifa_local;
2585out:
2586 rcu_read_unlock();
2587 return addr;
2588}
2589
2590static int bond_has_this_ip(struct bonding *bond, __be32 ip) 2556static int bond_has_this_ip(struct bonding *bond, __be32 ip)
2591{ 2557{
2592 struct vlan_entry *vlan; 2558 struct vlan_entry *vlan;
@@ -3220,6 +3186,7 @@ static int bond_slave_netdev_event(unsigned long event,
3220{ 3186{
3221 struct net_device *bond_dev = slave_dev->master; 3187 struct net_device *bond_dev = slave_dev->master;
3222 struct bonding *bond = netdev_priv(bond_dev); 3188 struct bonding *bond = netdev_priv(bond_dev);
3189 struct slave *slave = NULL;
3223 3190
3224 switch (event) { 3191 switch (event) {
3225 case NETDEV_UNREGISTER: 3192 case NETDEV_UNREGISTER:
@@ -3230,20 +3197,16 @@ static int bond_slave_netdev_event(unsigned long event,
3230 bond_release(bond_dev, slave_dev); 3197 bond_release(bond_dev, slave_dev);
3231 } 3198 }
3232 break; 3199 break;
3200 case NETDEV_UP:
3233 case NETDEV_CHANGE: 3201 case NETDEV_CHANGE:
3234 if (bond->params.mode == BOND_MODE_8023AD || bond_is_lb(bond)) { 3202 slave = bond_get_slave_by_dev(bond, slave_dev);
3235 struct slave *slave; 3203 if (slave) {
3204 u32 old_speed = slave->speed;
3205 u8 old_duplex = slave->duplex;
3236 3206
3237 slave = bond_get_slave_by_dev(bond, slave_dev); 3207 bond_update_speed_duplex(slave);
3238 if (slave) {
3239 u32 old_speed = slave->speed;
3240 u8 old_duplex = slave->duplex;
3241
3242 bond_update_speed_duplex(slave);
3243
3244 if (bond_is_lb(bond))
3245 break;
3246 3208
3209 if (bond->params.mode == BOND_MODE_8023AD) {
3247 if (old_speed != slave->speed) 3210 if (old_speed != slave->speed)
3248 bond_3ad_adapter_speed_changed(slave); 3211 bond_3ad_adapter_speed_changed(slave);
3249 if (old_duplex != slave->duplex) 3212 if (old_duplex != slave->duplex)
@@ -3335,6 +3298,10 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
3335 struct bonding *bond; 3298 struct bonding *bond;
3336 struct vlan_entry *vlan; 3299 struct vlan_entry *vlan;
3337 3300
3301 /* we only care about primary address */
3302 if(ifa->ifa_flags & IFA_F_SECONDARY)
3303 return NOTIFY_DONE;
3304
3338 list_for_each_entry(bond, &bn->dev_list, bond_list) { 3305 list_for_each_entry(bond, &bn->dev_list, bond_list) {
3339 if (bond->dev == event_dev) { 3306 if (bond->dev == event_dev) {
3340 switch (event) { 3307 switch (event) {
@@ -3342,7 +3309,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
3342 bond->master_ip = ifa->ifa_local; 3309 bond->master_ip = ifa->ifa_local;
3343 return NOTIFY_OK; 3310 return NOTIFY_OK;
3344 case NETDEV_DOWN: 3311 case NETDEV_DOWN:
3345 bond->master_ip = bond_glean_dev_ip(bond->dev); 3312 bond->master_ip = 0;
3346 return NOTIFY_OK; 3313 return NOTIFY_OK;
3347 default: 3314 default:
3348 return NOTIFY_DONE; 3315 return NOTIFY_DONE;
@@ -3358,8 +3325,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
3358 vlan->vlan_ip = ifa->ifa_local; 3325 vlan->vlan_ip = ifa->ifa_local;
3359 return NOTIFY_OK; 3326 return NOTIFY_OK;
3360 case NETDEV_DOWN: 3327 case NETDEV_DOWN:
3361 vlan->vlan_ip = 3328 vlan->vlan_ip = 0;
3362 bond_glean_dev_ip(vlan_dev);
3363 return NOTIFY_OK; 3329 return NOTIFY_OK;
3364 default: 3330 default:
3365 return NOTIFY_DONE; 3331 return NOTIFY_DONE;