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 | } |
