diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 70 |
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 | */ |
556 | static int bond_update_speed_duplex(struct slave *slave) | 556 | static 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 | ||
2566 | static __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; | ||
2585 | out: | ||
2586 | rcu_read_unlock(); | ||
2587 | return addr; | ||
2588 | } | ||
2589 | |||
2590 | static int bond_has_this_ip(struct bonding *bond, __be32 ip) | 2556 | static 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; |