aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c70
-rw-r--r--drivers/net/bonding/bond_procfs.c13
-rw-r--r--drivers/net/bonding/bond_sysfs.c7
3 files changed, 36 insertions, 54 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;
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index 95de93b9038..ad284baafe8 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -1,4 +1,5 @@
1#include <linux/proc_fs.h> 1#include <linux/proc_fs.h>
2#include <linux/export.h>
2#include <net/net_namespace.h> 3#include <net/net_namespace.h>
3#include <net/netns/generic.h> 4#include <net/netns/generic.h>
4#include "bonding.h" 5#include "bonding.h"
@@ -157,8 +158,16 @@ static void bond_info_show_slave(struct seq_file *seq,
157 seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); 158 seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
158 seq_printf(seq, "MII Status: %s\n", 159 seq_printf(seq, "MII Status: %s\n",
159 (slave->link == BOND_LINK_UP) ? "up" : "down"); 160 (slave->link == BOND_LINK_UP) ? "up" : "down");
160 seq_printf(seq, "Speed: %d Mbps\n", slave->speed); 161 if (slave->speed == SPEED_UNKNOWN)
161 seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half"); 162 seq_printf(seq, "Speed: %s\n", "Unknown");
163 else
164 seq_printf(seq, "Speed: %d Mbps\n", slave->speed);
165
166 if (slave->duplex == DUPLEX_UNKNOWN)
167 seq_printf(seq, "Duplex: %s\n", "Unknown");
168 else
169 seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");
170
162 seq_printf(seq, "Link Failure Count: %u\n", 171 seq_printf(seq, "Link Failure Count: %u\n",
163 slave->link_failure_count); 172 slave->link_failure_count);
164 173
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 5a20804fdec..4ef7e2fd9fe 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -319,6 +319,13 @@ static ssize_t bonding_store_mode(struct device *d,
319 goto out; 319 goto out;
320 } 320 }
321 321
322 if (bond->slave_cnt > 0) {
323 pr_err("unable to update mode of %s because it has slaves.\n",
324 bond->dev->name);
325 ret = -EPERM;
326 goto out;
327 }
328
322 new_value = bond_parse_parm(buf, bond_mode_tbl); 329 new_value = bond_parse_parm(buf, bond_mode_tbl);
323 if (new_value < 0) { 330 if (new_value < 0) {
324 pr_err("%s: Ignoring invalid mode value %.*s.\n", 331 pr_err("%s: Ignoring invalid mode value %.*s.\n",