diff options
author | Jay Vosburgh <fubar@us.ibm.com> | 2008-05-18 00:10:14 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-05-22 06:34:29 -0400 |
commit | 3915c1e8634a321d9680e5cd80a53053b642dc0c (patch) | |
tree | 430b2168edbc7f6c4ba3698d261b8573b422658a /drivers/net/bonding/bond_sysfs.c | |
parent | b2220cad583c9b63e085476df448fa2aff5ea906 (diff) |
bonding: Add "follow" option to fail_over_mac
Add a "follow" selection for fail_over_mac. This option
causes the MAC address to move from slave to slave as the active
slave changes. This is in addition to the existing fail_over_mac option
that causes the bond's MAC address to change during failover.
This new option is useful for devices that cannot tolerate
multiple ports using the same MAC address simultaneously, either
because it confuses them or incurs a performance penalty (as is the
case with some LPAR-aware multiport devices). Because the MAC of the
bond itself does not change, the "follow" option is slightly more
reliable during failover and doesn't change the MAC of the bond during
operation.
This patch requires a previous ARP monitor change to properly
handle RTNL during failovers.
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/bonding/bond_sysfs.c')
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 7a61e9a14386..dd265c69b0df 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -50,6 +50,7 @@ extern struct bond_parm_tbl bond_mode_tbl[]; | |||
50 | extern struct bond_parm_tbl bond_lacp_tbl[]; | 50 | extern struct bond_parm_tbl bond_lacp_tbl[]; |
51 | extern struct bond_parm_tbl xmit_hashtype_tbl[]; | 51 | extern struct bond_parm_tbl xmit_hashtype_tbl[]; |
52 | extern struct bond_parm_tbl arp_validate_tbl[]; | 52 | extern struct bond_parm_tbl arp_validate_tbl[]; |
53 | extern struct bond_parm_tbl fail_over_mac_tbl[]; | ||
53 | 54 | ||
54 | static int expected_refcount = -1; | 55 | static int expected_refcount = -1; |
55 | static struct class *netdev_class; | 56 | static struct class *netdev_class; |
@@ -547,42 +548,37 @@ static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attrib | |||
547 | { | 548 | { |
548 | struct bonding *bond = to_bond(d); | 549 | struct bonding *bond = to_bond(d); |
549 | 550 | ||
550 | return sprintf(buf, "%d\n", bond->params.fail_over_mac) + 1; | 551 | return sprintf(buf, "%s %d\n", |
552 | fail_over_mac_tbl[bond->params.fail_over_mac].modename, | ||
553 | bond->params.fail_over_mac); | ||
551 | } | 554 | } |
552 | 555 | ||
553 | static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count) | 556 | static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count) |
554 | { | 557 | { |
555 | int new_value; | 558 | int new_value; |
556 | int ret = count; | ||
557 | struct bonding *bond = to_bond(d); | 559 | struct bonding *bond = to_bond(d); |
558 | 560 | ||
559 | if (bond->slave_cnt != 0) { | 561 | if (bond->slave_cnt != 0) { |
560 | printk(KERN_ERR DRV_NAME | 562 | printk(KERN_ERR DRV_NAME |
561 | ": %s: Can't alter fail_over_mac with slaves in bond.\n", | 563 | ": %s: Can't alter fail_over_mac with slaves in bond.\n", |
562 | bond->dev->name); | 564 | bond->dev->name); |
563 | ret = -EPERM; | 565 | return -EPERM; |
564 | goto out; | ||
565 | } | 566 | } |
566 | 567 | ||
567 | if (sscanf(buf, "%d", &new_value) != 1) { | 568 | new_value = bond_parse_parm(buf, fail_over_mac_tbl); |
569 | if (new_value < 0) { | ||
568 | printk(KERN_ERR DRV_NAME | 570 | printk(KERN_ERR DRV_NAME |
569 | ": %s: no fail_over_mac value specified.\n", | 571 | ": %s: Ignoring invalid fail_over_mac value %s.\n", |
570 | bond->dev->name); | 572 | bond->dev->name, buf); |
571 | ret = -EINVAL; | 573 | return -EINVAL; |
572 | goto out; | ||
573 | } | 574 | } |
574 | 575 | ||
575 | if ((new_value == 0) || (new_value == 1)) { | 576 | bond->params.fail_over_mac = new_value; |
576 | bond->params.fail_over_mac = new_value; | 577 | printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %s (%d).\n", |
577 | printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %d.\n", | 578 | bond->dev->name, fail_over_mac_tbl[new_value].modename, |
578 | bond->dev->name, new_value); | 579 | new_value); |
579 | } else { | 580 | |
580 | printk(KERN_INFO DRV_NAME | 581 | return count; |
581 | ": %s: Ignoring invalid fail_over_mac value %d.\n", | ||
582 | bond->dev->name, new_value); | ||
583 | } | ||
584 | out: | ||
585 | return ret; | ||
586 | } | 582 | } |
587 | 583 | ||
588 | static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac); | 584 | static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac); |