diff options
-rw-r--r-- | drivers/net/bonding/bond_main.c | 13 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 52 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 4 |
3 files changed, 68 insertions, 1 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ef6024468d3c..f22f6bf43858 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -106,6 +106,7 @@ static int arp_interval = BOND_LINK_ARP_INTERV; | |||
106 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS]; | 106 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS]; |
107 | static char *arp_validate; | 107 | static char *arp_validate; |
108 | static char *fail_over_mac; | 108 | static char *fail_over_mac; |
109 | static int all_slaves_active = 0; | ||
109 | static struct bond_params bonding_defaults; | 110 | static struct bond_params bonding_defaults; |
110 | 111 | ||
111 | module_param(max_bonds, int, 0); | 112 | module_param(max_bonds, int, 0); |
@@ -155,6 +156,10 @@ module_param(arp_validate, charp, 0); | |||
155 | MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all"); | 156 | MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all"); |
156 | module_param(fail_over_mac, charp, 0); | 157 | module_param(fail_over_mac, charp, 0); |
157 | MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. none (default), active or follow"); | 158 | MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. none (default), active or follow"); |
159 | module_param(all_slaves_active, int, 0); | ||
160 | MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface" | ||
161 | "by setting active flag for all slaves. " | ||
162 | "0 for never (default), 1 for always."); | ||
158 | 163 | ||
159 | /*----------------------------- Global variables ----------------------------*/ | 164 | /*----------------------------- Global variables ----------------------------*/ |
160 | 165 | ||
@@ -4771,6 +4776,13 @@ static int bond_check_params(struct bond_params *params) | |||
4771 | } | 4776 | } |
4772 | } | 4777 | } |
4773 | 4778 | ||
4779 | if ((all_slaves_active != 0) && (all_slaves_active != 1)) { | ||
4780 | pr_warning("Warning: all_slaves_active module parameter (%d), " | ||
4781 | "not of valid value (0/1), so it was set to " | ||
4782 | "0\n", all_slaves_active); | ||
4783 | all_slaves_active = 0; | ||
4784 | } | ||
4785 | |||
4774 | /* reset values for TLB/ALB */ | 4786 | /* reset values for TLB/ALB */ |
4775 | if ((bond_mode == BOND_MODE_TLB) || | 4787 | if ((bond_mode == BOND_MODE_TLB) || |
4776 | (bond_mode == BOND_MODE_ALB)) { | 4788 | (bond_mode == BOND_MODE_ALB)) { |
@@ -4941,6 +4953,7 @@ static int bond_check_params(struct bond_params *params) | |||
4941 | params->primary[0] = 0; | 4953 | params->primary[0] = 0; |
4942 | params->primary_reselect = primary_reselect_value; | 4954 | params->primary_reselect = primary_reselect_value; |
4943 | params->fail_over_mac = fail_over_mac_value; | 4955 | params->fail_over_mac = fail_over_mac_value; |
4956 | params->all_slaves_active = all_slaves_active; | ||
4944 | 4957 | ||
4945 | if (primary) { | 4958 | if (primary) { |
4946 | strncpy(params->primary, primary, IFNAMSIZ); | 4959 | strncpy(params->primary, primary, IFNAMSIZ); |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 496ac1ec614d..066311a5e084 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -1411,7 +1411,58 @@ static ssize_t bonding_show_ad_partner_mac(struct device *d, | |||
1411 | } | 1411 | } |
1412 | static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL); | 1412 | static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL); |
1413 | 1413 | ||
1414 | /* | ||
1415 | * Show and set the all_slaves_active flag. | ||
1416 | */ | ||
1417 | static ssize_t bonding_show_slaves_active(struct device *d, | ||
1418 | struct device_attribute *attr, | ||
1419 | char *buf) | ||
1420 | { | ||
1421 | struct bonding *bond = to_bond(d); | ||
1422 | |||
1423 | return sprintf(buf, "%d\n", bond->params.all_slaves_active); | ||
1424 | } | ||
1425 | |||
1426 | static ssize_t bonding_store_slaves_active(struct device *d, | ||
1427 | struct device_attribute *attr, | ||
1428 | const char *buf, size_t count) | ||
1429 | { | ||
1430 | int i, new_value, ret = count; | ||
1431 | struct bonding *bond = to_bond(d); | ||
1432 | struct slave *slave; | ||
1433 | |||
1434 | if (sscanf(buf, "%d", &new_value) != 1) { | ||
1435 | pr_err("%s: no all_slaves_active value specified.\n", | ||
1436 | bond->dev->name); | ||
1437 | ret = -EINVAL; | ||
1438 | goto out; | ||
1439 | } | ||
1440 | |||
1441 | if (new_value == bond->params.all_slaves_active) | ||
1442 | goto out; | ||
1443 | |||
1444 | if ((new_value == 0) || (new_value == 1)) { | ||
1445 | bond->params.all_slaves_active = new_value; | ||
1446 | } else { | ||
1447 | pr_info("%s: Ignoring invalid all_slaves_active value %d.\n", | ||
1448 | bond->dev->name, new_value); | ||
1449 | ret = -EINVAL; | ||
1450 | goto out; | ||
1451 | } | ||
1414 | 1452 | ||
1453 | bond_for_each_slave(bond, slave, i) { | ||
1454 | if (slave->state == BOND_STATE_BACKUP) { | ||
1455 | if (new_value) | ||
1456 | slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE; | ||
1457 | else | ||
1458 | slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; | ||
1459 | } | ||
1460 | } | ||
1461 | out: | ||
1462 | return count; | ||
1463 | } | ||
1464 | static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR, | ||
1465 | bonding_show_slaves_active, bonding_store_slaves_active); | ||
1415 | 1466 | ||
1416 | static struct attribute *per_bond_attrs[] = { | 1467 | static struct attribute *per_bond_attrs[] = { |
1417 | &dev_attr_slaves.attr, | 1468 | &dev_attr_slaves.attr, |
@@ -1438,6 +1489,7 @@ static struct attribute *per_bond_attrs[] = { | |||
1438 | &dev_attr_ad_actor_key.attr, | 1489 | &dev_attr_ad_actor_key.attr, |
1439 | &dev_attr_ad_partner_key.attr, | 1490 | &dev_attr_ad_partner_key.attr, |
1440 | &dev_attr_ad_partner_mac.attr, | 1491 | &dev_attr_ad_partner_mac.attr, |
1492 | &dev_attr_all_slaves_active.attr, | ||
1441 | NULL, | 1493 | NULL, |
1442 | }; | 1494 | }; |
1443 | 1495 | ||
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index da809645c483..cecdea2a629f 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -131,6 +131,7 @@ struct bond_params { | |||
131 | char primary[IFNAMSIZ]; | 131 | char primary[IFNAMSIZ]; |
132 | int primary_reselect; | 132 | int primary_reselect; |
133 | __be32 arp_targets[BOND_MAX_ARP_TARGETS]; | 133 | __be32 arp_targets[BOND_MAX_ARP_TARGETS]; |
134 | int all_slaves_active; | ||
134 | }; | 135 | }; |
135 | 136 | ||
136 | struct bond_parm_tbl { | 137 | struct bond_parm_tbl { |
@@ -290,7 +291,8 @@ static inline void bond_set_slave_inactive_flags(struct slave *slave) | |||
290 | struct bonding *bond = netdev_priv(slave->dev->master); | 291 | struct bonding *bond = netdev_priv(slave->dev->master); |
291 | if (!bond_is_lb(bond)) | 292 | if (!bond_is_lb(bond)) |
292 | slave->state = BOND_STATE_BACKUP; | 293 | slave->state = BOND_STATE_BACKUP; |
293 | slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; | 294 | if (!bond->params.all_slaves_active) |
295 | slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; | ||
294 | if (slave_do_arp_validate(bond, slave)) | 296 | if (slave_do_arp_validate(bond, slave)) |
295 | slave->dev->priv_flags |= IFF_SLAVE_NEEDARP; | 297 | slave->dev->priv_flags |= IFF_SLAVE_NEEDARP; |
296 | } | 298 | } |