Commit 3915c1e8 authored by Jay Vosburgh's avatar Jay Vosburgh Committed by Jeff Garzik

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: default avatarJay Vosburgh <fubar@us.ibm.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent b2220cad
...@@ -289,35 +289,73 @@ downdelay ...@@ -289,35 +289,73 @@ downdelay
fail_over_mac fail_over_mac
Specifies whether active-backup mode should set all slaves to Specifies whether active-backup mode should set all slaves to
the same MAC address (the traditional behavior), or, when the same MAC address at enslavement (the traditional
enabled, change the bond's MAC address when changing the behavior), or, when enabled, perform special handling of the
active interface (i.e., fail over the MAC address itself). bond's MAC address in accordance with the selected policy.
Fail over MAC is useful for devices that cannot ever alter Possible values are:
their MAC address, or for devices that refuse incoming
broadcasts with their own source MAC (which interferes with none or 0
the ARP monitor).
This setting disables fail_over_mac, and causes
The down side of fail over MAC is that every device on the bonding to set all slaves of an active-backup bond to
network must be updated via gratuitous ARP, vs. just updating the same MAC address at enslavement time. This is the
a switch or set of switches (which often takes place for any default.
traffic, not just ARP traffic, if the switch snoops incoming
traffic to update its tables) for the traditional method. If active or 1
the gratuitous ARP is lost, communication may be disrupted.
The "active" fail_over_mac policy indicates that the
When fail over MAC is used in conjuction with the mii monitor, MAC address of the bond should always be the MAC
devices which assert link up prior to being able to actually address of the currently active slave. The MAC
transmit and receive are particularly susecptible to loss of address of the slaves is not changed; instead, the MAC
the gratuitous ARP, and an appropriate updelay setting may be address of the bond changes during a failover.
required.
This policy is useful for devices that cannot ever
A value of 0 disables fail over MAC, and is the default. A alter their MAC address, or for devices that refuse
value of 1 enables fail over MAC. This option is enabled incoming broadcasts with their own source MAC (which
automatically if the first slave added cannot change its MAC interferes with the ARP monitor).
address. This option may be modified via sysfs only when no
slaves are present in the bond. The down side of this policy is that every device on
the network must be updated via gratuitous ARP,
This option was added in bonding version 3.2.0. vs. just updating a switch or set of switches (which
often takes place for any traffic, not just ARP
traffic, if the switch snoops incoming traffic to
update its tables) for the traditional method. If the
gratuitous ARP is lost, communication may be
disrupted.
When this policy is used in conjuction with the mii
monitor, devices which assert link up prior to being
able to actually transmit and receive are particularly
susecptible to loss of the gratuitous ARP, and an
appropriate updelay setting may be required.
follow or 2
The "follow" fail_over_mac policy causes the MAC
address of the bond to be selected normally (normally
the MAC address of the first slave added to the bond).
However, the second and subsequent slaves are not set
to this MAC address while they are in a backup role; a
slave is programmed with the bond's MAC address at
failover time (and the formerly active slave receives
the newly active slave's MAC address).
This policy is useful for multiport devices that
either become confused or incur a performance penalty
when multiple ports are programmed with the same MAC
address.
The default policy is none, unless the first slave cannot
change its MAC address, in which case the active policy is
selected by default.
This option may be modified via sysfs only when no slaves are
present in the bond.
This option was added in bonding version 3.2.0. The "follow"
policy was added in bonding version 3.3.0.
lacp_rate lacp_rate
......
This diff is collapsed.
...@@ -50,6 +50,7 @@ extern struct bond_parm_tbl bond_mode_tbl[]; ...@@ -50,6 +50,7 @@ extern struct bond_parm_tbl bond_mode_tbl[];
extern struct bond_parm_tbl bond_lacp_tbl[]; extern struct bond_parm_tbl bond_lacp_tbl[];
extern struct bond_parm_tbl xmit_hashtype_tbl[]; extern struct bond_parm_tbl xmit_hashtype_tbl[];
extern struct bond_parm_tbl arp_validate_tbl[]; extern struct bond_parm_tbl arp_validate_tbl[];
extern struct bond_parm_tbl fail_over_mac_tbl[];
static int expected_refcount = -1; static int expected_refcount = -1;
static struct class *netdev_class; static struct class *netdev_class;
...@@ -547,42 +548,37 @@ static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attrib ...@@ -547,42 +548,37 @@ static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attrib
{ {
struct bonding *bond = to_bond(d); struct bonding *bond = to_bond(d);
return sprintf(buf, "%d\n", bond->params.fail_over_mac) + 1; return sprintf(buf, "%s %d\n",
fail_over_mac_tbl[bond->params.fail_over_mac].modename,
bond->params.fail_over_mac);
} }
static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count) static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count)
{ {
int new_value; int new_value;
int ret = count;
struct bonding *bond = to_bond(d); struct bonding *bond = to_bond(d);
if (bond->slave_cnt != 0) { if (bond->slave_cnt != 0) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": %s: Can't alter fail_over_mac with slaves in bond.\n", ": %s: Can't alter fail_over_mac with slaves in bond.\n",
bond->dev->name); bond->dev->name);
ret = -EPERM; return -EPERM;
goto out;
} }
if (sscanf(buf, "%d", &new_value) != 1) { new_value = bond_parse_parm(buf, fail_over_mac_tbl);
if (new_value < 0) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": %s: no fail_over_mac value specified.\n", ": %s: Ignoring invalid fail_over_mac value %s.\n",
bond->dev->name); bond->dev->name, buf);
ret = -EINVAL; return -EINVAL;
goto out;
} }
if ((new_value == 0) || (new_value == 1)) { bond->params.fail_over_mac = new_value;
bond->params.fail_over_mac = new_value; printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %s (%d).\n",
printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %d.\n", bond->dev->name, fail_over_mac_tbl[new_value].modename,
bond->dev->name, new_value); new_value);
} else {
printk(KERN_INFO DRV_NAME return count;
": %s: Ignoring invalid fail_over_mac value %d.\n",
bond->dev->name, new_value);
}
out:
return ret;
} }
static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac); static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac);
......
...@@ -248,6 +248,10 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) ...@@ -248,6 +248,10 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
return (struct bonding *)slave->dev->master->priv; return (struct bonding *)slave->dev->master->priv;
} }
#define BOND_FOM_NONE 0
#define BOND_FOM_ACTIVE 1
#define BOND_FOM_FOLLOW 2
#define BOND_ARP_VALIDATE_NONE 0 #define BOND_ARP_VALIDATE_NONE 0
#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE) #define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE)
#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP) #define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment