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.c33
-rw-r--r--drivers/net/bonding/bond_sysfs.c79
-rw-r--r--drivers/net/bonding/bonding.h30
3 files changed, 128 insertions, 14 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index d3a70c0d0edd..142d55dc526e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -104,6 +104,7 @@ static char *xmit_hash_policy;
104static int arp_interval = BOND_LINK_ARP_INTERV; 104static int arp_interval = BOND_LINK_ARP_INTERV;
105static char *arp_ip_target[BOND_MAX_ARP_TARGETS]; 105static char *arp_ip_target[BOND_MAX_ARP_TARGETS];
106static char *arp_validate; 106static char *arp_validate;
107static char *arp_all_targets;
107static char *fail_over_mac; 108static char *fail_over_mac;
108static int all_slaves_active = 0; 109static int all_slaves_active = 0;
109static struct bond_params bonding_defaults; 110static struct bond_params bonding_defaults;
@@ -166,6 +167,8 @@ module_param(arp_validate, charp, 0);
166MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes; " 167MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes; "
167 "0 for none (default), 1 for active, " 168 "0 for none (default), 1 for active, "
168 "2 for backup, 3 for all"); 169 "2 for backup, 3 for all");
170module_param(arp_all_targets, charp, 0);
171MODULE_PARM_DESC(arp_all_targets, "fail on any/all arp targets timeout; 0 for any (default), 1 for all");
169module_param(fail_over_mac, charp, 0); 172module_param(fail_over_mac, charp, 0);
170MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to " 173MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to "
171 "the same MAC; 0 for none (default), " 174 "the same MAC; 0 for none (default), "
@@ -216,6 +219,12 @@ const struct bond_parm_tbl xmit_hashtype_tbl[] = {
216{ NULL, -1}, 219{ NULL, -1},
217}; 220};
218 221
222const struct bond_parm_tbl arp_all_targets_tbl[] = {
223{ "any", BOND_ARP_TARGETS_ANY},
224{ "all", BOND_ARP_TARGETS_ALL},
225{ NULL, -1},
226};
227
219const struct bond_parm_tbl arp_validate_tbl[] = { 228const struct bond_parm_tbl arp_validate_tbl[] = {
220{ "none", BOND_ARP_VALIDATE_NONE}, 229{ "none", BOND_ARP_VALIDATE_NONE},
221{ "active", BOND_ARP_VALIDATE_ACTIVE}, 230{ "active", BOND_ARP_VALIDATE_ACTIVE},
@@ -1483,7 +1492,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1483 struct slave *new_slave = NULL; 1492 struct slave *new_slave = NULL;
1484 struct sockaddr addr; 1493 struct sockaddr addr;
1485 int link_reporting; 1494 int link_reporting;
1486 int res = 0; 1495 int res = 0, i;
1487 1496
1488 if (!bond->params.use_carrier && 1497 if (!bond->params.use_carrier &&
1489 slave_dev->ethtool_ops->get_link == NULL && 1498 slave_dev->ethtool_ops->get_link == NULL &&
@@ -1712,6 +1721,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1712 1721
1713 new_slave->last_arp_rx = jiffies - 1722 new_slave->last_arp_rx = jiffies -
1714 (msecs_to_jiffies(bond->params.arp_interval) + 1); 1723 (msecs_to_jiffies(bond->params.arp_interval) + 1);
1724 for (i = 0; i < BOND_MAX_ARP_TARGETS; i++)
1725 new_slave->target_last_arp_rx[i] = new_slave->last_arp_rx;
1715 1726
1716 if (bond->params.miimon && !bond->params.use_carrier) { 1727 if (bond->params.miimon && !bond->params.use_carrier) {
1717 link_reporting = bond_check_dev_link(bond, slave_dev, 1); 1728 link_reporting = bond_check_dev_link(bond, slave_dev, 1);
@@ -2610,16 +2621,20 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
2610 2621
2611static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 sip, __be32 tip) 2622static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 sip, __be32 tip)
2612{ 2623{
2624 int i;
2625
2613 if (!sip || !bond_has_this_ip(bond, tip)) { 2626 if (!sip || !bond_has_this_ip(bond, tip)) {
2614 pr_debug("bva: sip %pI4 tip %pI4 not found\n", &sip, &tip); 2627 pr_debug("bva: sip %pI4 tip %pI4 not found\n", &sip, &tip);
2615 return; 2628 return;
2616 } 2629 }
2617 2630
2618 if (bond_get_targets_ip(bond->params.arp_targets, sip) == -1) { 2631 i = bond_get_targets_ip(bond->params.arp_targets, sip);
2632 if (i == -1) {
2619 pr_debug("bva: sip %pI4 not found in targets\n", &sip); 2633 pr_debug("bva: sip %pI4 not found in targets\n", &sip);
2620 return; 2634 return;
2621 } 2635 }
2622 slave->last_arp_rx = jiffies; 2636 slave->last_arp_rx = jiffies;
2637 slave->target_last_arp_rx[i] = jiffies;
2623} 2638}
2624 2639
2625static int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, 2640static int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
@@ -4409,6 +4424,7 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
4409static int bond_check_params(struct bond_params *params) 4424static int bond_check_params(struct bond_params *params)
4410{ 4425{
4411 int arp_validate_value, fail_over_mac_value, primary_reselect_value, i; 4426 int arp_validate_value, fail_over_mac_value, primary_reselect_value, i;
4427 int arp_all_targets_value;
4412 4428
4413 /* 4429 /*
4414 * Convert string parameters. 4430 * Convert string parameters.
@@ -4634,6 +4650,18 @@ static int bond_check_params(struct bond_params *params)
4634 } else 4650 } else
4635 arp_validate_value = 0; 4651 arp_validate_value = 0;
4636 4652
4653 arp_all_targets_value = 0;
4654 if (arp_all_targets) {
4655 arp_all_targets_value = bond_parse_parm(arp_all_targets,
4656 arp_all_targets_tbl);
4657
4658 if (arp_all_targets_value == -1) {
4659 pr_err("Error: invalid arp_all_targets_value \"%s\"\n",
4660 arp_all_targets);
4661 arp_all_targets_value = 0;
4662 }
4663 }
4664
4637 if (miimon) { 4665 if (miimon) {
4638 pr_info("MII link monitoring set to %d ms\n", miimon); 4666 pr_info("MII link monitoring set to %d ms\n", miimon);
4639 } else if (arp_interval) { 4667 } else if (arp_interval) {
@@ -4698,6 +4726,7 @@ static int bond_check_params(struct bond_params *params)
4698 params->num_peer_notif = num_peer_notif; 4726 params->num_peer_notif = num_peer_notif;
4699 params->arp_interval = arp_interval; 4727 params->arp_interval = arp_interval;
4700 params->arp_validate = arp_validate_value; 4728 params->arp_validate = arp_validate_value;
4729 params->arp_all_targets = arp_all_targets_value;
4701 params->updelay = updelay; 4730 params->updelay = updelay;
4702 params->downdelay = downdelay; 4731 params->downdelay = downdelay;
4703 params->use_carrier = use_carrier; 4732 params->use_carrier = use_carrier;
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index ece57f146a60..dc36a3d7d9e9 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -443,6 +443,44 @@ static ssize_t bonding_store_arp_validate(struct device *d,
443 443
444static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, 444static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate,
445 bonding_store_arp_validate); 445 bonding_store_arp_validate);
446/*
447 * Show and set arp_all_targets.
448 */
449static ssize_t bonding_show_arp_all_targets(struct device *d,
450 struct device_attribute *attr,
451 char *buf)
452{
453 struct bonding *bond = to_bond(d);
454 int value = bond->params.arp_all_targets;
455
456 return sprintf(buf, "%s %d\n", arp_all_targets_tbl[value].modename,
457 value);
458}
459
460static ssize_t bonding_store_arp_all_targets(struct device *d,
461 struct device_attribute *attr,
462 const char *buf, size_t count)
463{
464 struct bonding *bond = to_bond(d);
465 int new_value;
466
467 new_value = bond_parse_parm(buf, arp_all_targets_tbl);
468 if (new_value < 0) {
469 pr_err("%s: Ignoring invalid arp_all_targets value %s\n",
470 bond->dev->name, buf);
471 return -EINVAL;
472 }
473 pr_info("%s: setting arp_all_targets to %s (%d).\n",
474 bond->dev->name, arp_all_targets_tbl[new_value].modename,
475 new_value);
476
477 bond->params.arp_all_targets = new_value;
478
479 return count;
480}
481
482static DEVICE_ATTR(arp_all_targets, S_IRUGO | S_IWUSR,
483 bonding_show_arp_all_targets, bonding_store_arp_all_targets);
446 484
447/* 485/*
448 * Show and store fail_over_mac. User only allowed to change the 486 * Show and store fail_over_mac. User only allowed to change the
@@ -590,10 +628,11 @@ static ssize_t bonding_store_arp_targets(struct device *d,
590 struct device_attribute *attr, 628 struct device_attribute *attr,
591 const char *buf, size_t count) 629 const char *buf, size_t count)
592{ 630{
593 __be32 newtarget;
594 int i = 0, ret = -EINVAL;
595 struct bonding *bond = to_bond(d); 631 struct bonding *bond = to_bond(d);
596 __be32 *targets; 632 struct slave *slave;
633 __be32 newtarget, *targets;
634 unsigned long *targets_rx;
635 int ind, i, j, ret = -EINVAL;
597 636
598 targets = bond->params.arp_targets; 637 targets = bond->params.arp_targets;
599 newtarget = in_aton(buf + 1); 638 newtarget = in_aton(buf + 1);
@@ -611,8 +650,8 @@ static ssize_t bonding_store_arp_targets(struct device *d,
611 goto out; 650 goto out;
612 } 651 }
613 652
614 i = bond_get_targets_ip(targets, 0); /* first free slot */ 653 ind = bond_get_targets_ip(targets, 0); /* first free slot */
615 if (i == -1) { 654 if (ind == -1) {
616 pr_err("%s: ARP target table is full!\n", 655 pr_err("%s: ARP target table is full!\n",
617 bond->dev->name); 656 bond->dev->name);
618 goto out; 657 goto out;
@@ -620,7 +659,12 @@ static ssize_t bonding_store_arp_targets(struct device *d,
620 659
621 pr_info("%s: adding ARP target %pI4.\n", bond->dev->name, 660 pr_info("%s: adding ARP target %pI4.\n", bond->dev->name,
622 &newtarget); 661 &newtarget);
623 targets[i] = newtarget; 662 /* not to race with bond_arp_rcv */
663 write_lock_bh(&bond->lock);
664 bond_for_each_slave(bond, slave, i)
665 slave->target_last_arp_rx[ind] = jiffies;
666 targets[ind] = newtarget;
667 write_unlock_bh(&bond->lock);
624 } else if (buf[0] == '-') { 668 } else if (buf[0] == '-') {
625 if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) { 669 if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
626 pr_err("%s: invalid ARP target %pI4 specified for removal\n", 670 pr_err("%s: invalid ARP target %pI4 specified for removal\n",
@@ -628,18 +672,32 @@ static ssize_t bonding_store_arp_targets(struct device *d,
628 goto out; 672 goto out;
629 } 673 }
630 674
631 i = bond_get_targets_ip(targets, newtarget); 675 ind = bond_get_targets_ip(targets, newtarget);
632 if (i == -1) { 676 if (ind == -1) {
633 pr_info("%s: unable to remove nonexistent ARP target %pI4.\n", 677 pr_err("%s: unable to remove nonexistent ARP target %pI4.\n",
634 bond->dev->name, &newtarget); 678 bond->dev->name, &newtarget);
635 goto out; 679 goto out;
636 } 680 }
637 681
682 if (ind == 0 && !targets[1] && bond->params.arp_interval)
683 pr_warn("%s: removing last arp target with arp_interval on\n",
684 bond->dev->name);
685
638 pr_info("%s: removing ARP target %pI4.\n", bond->dev->name, 686 pr_info("%s: removing ARP target %pI4.\n", bond->dev->name,
639 &newtarget); 687 &newtarget);
640 for (; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++) 688
689 write_lock_bh(&bond->lock);
690 bond_for_each_slave(bond, slave, i) {
691 targets_rx = slave->target_last_arp_rx;
692 j = ind;
693 for (; (j < BOND_MAX_ARP_TARGETS-1) && targets[j+1]; j++)
694 targets_rx[j] = targets_rx[j+1];
695 targets_rx[j] = 0;
696 }
697 for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++)
641 targets[i] = targets[i+1]; 698 targets[i] = targets[i+1];
642 targets[i] = 0; 699 targets[i] = 0;
700 write_unlock_bh(&bond->lock);
643 } else { 701 } else {
644 pr_err("no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n", 702 pr_err("no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
645 bond->dev->name); 703 bond->dev->name);
@@ -1623,6 +1681,7 @@ static struct attribute *per_bond_attrs[] = {
1623 &dev_attr_mode.attr, 1681 &dev_attr_mode.attr,
1624 &dev_attr_fail_over_mac.attr, 1682 &dev_attr_fail_over_mac.attr,
1625 &dev_attr_arp_validate.attr, 1683 &dev_attr_arp_validate.attr,
1684 &dev_attr_arp_all_targets.attr,
1626 &dev_attr_arp_interval.attr, 1685 &dev_attr_arp_interval.attr,
1627 &dev_attr_arp_ip_target.attr, 1686 &dev_attr_arp_ip_target.attr,
1628 &dev_attr_downdelay.attr, 1687 &dev_attr_downdelay.attr,
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 486e532f77e4..3fb73cc8c34a 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -144,6 +144,7 @@ struct bond_params {
144 u8 num_peer_notif; 144 u8 num_peer_notif;
145 int arp_interval; 145 int arp_interval;
146 int arp_validate; 146 int arp_validate;
147 int arp_all_targets;
147 int use_carrier; 148 int use_carrier;
148 int fail_over_mac; 149 int fail_over_mac;
149 int updelay; 150 int updelay;
@@ -179,6 +180,7 @@ struct slave {
179 int delay; 180 int delay;
180 unsigned long jiffies; 181 unsigned long jiffies;
181 unsigned long last_arp_rx; 182 unsigned long last_arp_rx;
183 unsigned long target_last_arp_rx[BOND_MAX_ARP_TARGETS];
182 s8 link; /* one of BOND_LINK_XXXX */ 184 s8 link; /* one of BOND_LINK_XXXX */
183 s8 new_link; 185 s8 new_link;
184 u8 backup:1, /* indicates backup slave. Value corresponds with 186 u8 backup:1, /* indicates backup slave. Value corresponds with
@@ -322,6 +324,9 @@ static inline bool bond_is_active_slave(struct slave *slave)
322#define BOND_FOM_ACTIVE 1 324#define BOND_FOM_ACTIVE 1
323#define BOND_FOM_FOLLOW 2 325#define BOND_FOM_FOLLOW 2
324 326
327#define BOND_ARP_TARGETS_ANY 0
328#define BOND_ARP_TARGETS_ALL 1
329
325#define BOND_ARP_VALIDATE_NONE 0 330#define BOND_ARP_VALIDATE_NONE 0
326#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE) 331#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE)
327#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP) 332#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP)
@@ -334,11 +339,31 @@ static inline int slave_do_arp_validate(struct bonding *bond,
334 return bond->params.arp_validate & (1 << bond_slave_state(slave)); 339 return bond->params.arp_validate & (1 << bond_slave_state(slave));
335} 340}
336 341
342/* Get the oldest arp which we've received on this slave for bond's
343 * arp_targets.
344 */
345static inline unsigned long slave_oldest_target_arp_rx(struct bonding *bond,
346 struct slave *slave)
347{
348 int i = 1;
349 unsigned long ret = slave->target_last_arp_rx[0];
350
351 for (; (i < BOND_MAX_ARP_TARGETS) && bond->params.arp_targets[i]; i++)
352 if (time_before(slave->target_last_arp_rx[i], ret))
353 ret = slave->target_last_arp_rx[i];
354
355 return ret;
356}
357
337static inline unsigned long slave_last_rx(struct bonding *bond, 358static inline unsigned long slave_last_rx(struct bonding *bond,
338 struct slave *slave) 359 struct slave *slave)
339{ 360{
340 if (slave_do_arp_validate(bond, slave)) 361 if (slave_do_arp_validate(bond, slave)) {
341 return slave->last_arp_rx; 362 if (bond->params.arp_all_targets == BOND_ARP_TARGETS_ALL)
363 return slave_oldest_target_arp_rx(bond, slave);
364 else
365 return slave->last_arp_rx;
366 }
342 367
343 return slave->dev->last_rx; 368 return slave->dev->last_rx;
344} 369}
@@ -486,6 +511,7 @@ extern const struct bond_parm_tbl bond_lacp_tbl[];
486extern const struct bond_parm_tbl bond_mode_tbl[]; 511extern const struct bond_parm_tbl bond_mode_tbl[];
487extern const struct bond_parm_tbl xmit_hashtype_tbl[]; 512extern const struct bond_parm_tbl xmit_hashtype_tbl[];
488extern const struct bond_parm_tbl arp_validate_tbl[]; 513extern const struct bond_parm_tbl arp_validate_tbl[];
514extern const struct bond_parm_tbl arp_all_targets_tbl[];
489extern const struct bond_parm_tbl fail_over_mac_tbl[]; 515extern const struct bond_parm_tbl fail_over_mac_tbl[];
490extern const struct bond_parm_tbl pri_reselect_tbl[]; 516extern const struct bond_parm_tbl pri_reselect_tbl[];
491extern struct bond_parm_tbl ad_select_tbl[]; 517extern struct bond_parm_tbl ad_select_tbl[];