net/bonding: Optionally allow ethernet slaves to keep own MAC
Update the "don't change MAC of slaves" functionality added in previous changes to be a generic option, rather than something tied to IB devices, as it's occasionally useful for regular ethernet devices as well. Adds "fail_over_mac" option (which is automatically enabled for IB slaves), applicable only to active-backup mode. Includes documentation update. Updates bonding driver version to 3.2.0. Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:

committed by
Jeff Garzik

parent
d90a162a4e
commit
dd957c57c5
@@ -98,6 +98,7 @@ static char *xmit_hash_policy = NULL;
|
||||
static int arp_interval = BOND_LINK_ARP_INTERV;
|
||||
static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
|
||||
static char *arp_validate = NULL;
|
||||
static int fail_over_mac = 0;
|
||||
struct bond_params bonding_defaults;
|
||||
|
||||
module_param(max_bonds, int, 0);
|
||||
@@ -131,6 +132,8 @@ module_param_array(arp_ip_target, charp, NULL, 0);
|
||||
MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
|
||||
module_param(arp_validate, charp, 0);
|
||||
MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all");
|
||||
module_param(fail_over_mac, int, 0);
|
||||
MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. 0 of off (default), 1 for on.");
|
||||
|
||||
/*----------------------------- Global variables ----------------------------*/
|
||||
|
||||
@@ -1100,7 +1103,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
|
||||
/* when bonding does not set the slave MAC address, the bond MAC
|
||||
* address is the one of the active slave.
|
||||
*/
|
||||
if (new_active && !bond->do_set_mac_addr)
|
||||
if (new_active && bond->params.fail_over_mac)
|
||||
memcpy(bond->dev->dev_addr, new_active->dev->dev_addr,
|
||||
new_active->dev->addr_len);
|
||||
if (bond->curr_active_slave &&
|
||||
@@ -1367,16 +1370,16 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||
if (slave_dev->set_mac_address == NULL) {
|
||||
if (bond->slave_cnt == 0) {
|
||||
printk(KERN_WARNING DRV_NAME
|
||||
": %s: Warning: The first slave device you "
|
||||
"specified does not support setting the MAC "
|
||||
"address. This bond MAC address would be that "
|
||||
"of the active slave.\n", bond_dev->name);
|
||||
bond->do_set_mac_addr = 0;
|
||||
} else if (bond->do_set_mac_addr) {
|
||||
": %s: Warning: The first slave device "
|
||||
"specified does not support setting the MAC "
|
||||
"address. Enabling the fail_over_mac option.",
|
||||
bond_dev->name);
|
||||
bond->params.fail_over_mac = 1;
|
||||
} else if (!bond->params.fail_over_mac) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
": %s: Error: The slave device you specified "
|
||||
"does not support setting the MAC addres,."
|
||||
"but this bond uses this practice. \n"
|
||||
": %s: Error: The slave device specified "
|
||||
"does not support setting the MAC address, "
|
||||
"but fail_over_mac is not enabled.\n"
|
||||
, bond_dev->name);
|
||||
res = -EOPNOTSUPP;
|
||||
goto err_undo_flags;
|
||||
@@ -1401,7 +1404,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||
*/
|
||||
memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN);
|
||||
|
||||
if (bond->do_set_mac_addr) {
|
||||
if (!bond->params.fail_over_mac) {
|
||||
/*
|
||||
* Set slave to master's mac address. The application already
|
||||
* set the master's mac address to that of the first slave
|
||||
@@ -1637,7 +1640,7 @@ err_close:
|
||||
dev_close(slave_dev);
|
||||
|
||||
err_restore_mac:
|
||||
if (bond->do_set_mac_addr) {
|
||||
if (!bond->params.fail_over_mac) {
|
||||
memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
|
||||
addr.sa_family = slave_dev->type;
|
||||
dev_set_mac_address(slave_dev, &addr);
|
||||
@@ -1814,7 +1817,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||
/* close slave before restoring its mac address */
|
||||
dev_close(slave_dev);
|
||||
|
||||
if (bond->do_set_mac_addr) {
|
||||
if (!bond->params.fail_over_mac) {
|
||||
/* restore original ("permanent") mac address */
|
||||
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
|
||||
addr.sa_family = slave_dev->type;
|
||||
@@ -1935,7 +1938,7 @@ static int bond_release_all(struct net_device *bond_dev)
|
||||
/* close slave before restoring its mac address */
|
||||
dev_close(slave_dev);
|
||||
|
||||
if (bond->do_set_mac_addr) {
|
||||
if (!bond->params.fail_over_mac) {
|
||||
/* restore original ("permanent") mac address*/
|
||||
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
|
||||
addr.sa_family = slave_dev->type;
|
||||
@@ -3060,9 +3063,15 @@ static void bond_info_show_master(struct seq_file *seq)
|
||||
curr = bond->curr_active_slave;
|
||||
read_unlock(&bond->curr_slave_lock);
|
||||
|
||||
seq_printf(seq, "Bonding Mode: %s\n",
|
||||
seq_printf(seq, "Bonding Mode: %s",
|
||||
bond_mode_name(bond->params.mode));
|
||||
|
||||
if (bond->params.mode == BOND_MODE_ACTIVEBACKUP &&
|
||||
bond->params.fail_over_mac)
|
||||
seq_printf(seq, " (fail_over_mac)");
|
||||
|
||||
seq_printf(seq, "\n");
|
||||
|
||||
if (bond->params.mode == BOND_MODE_XOR ||
|
||||
bond->params.mode == BOND_MODE_8023AD) {
|
||||
seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
|
||||
@@ -3994,8 +4003,12 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
|
||||
|
||||
dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None"));
|
||||
|
||||
if (!bond->do_set_mac_addr)
|
||||
return -EOPNOTSUPP;
|
||||
/*
|
||||
* If fail_over_mac is enabled, do nothing and return success.
|
||||
* Returning an error causes ifenslave to fail.
|
||||
*/
|
||||
if (bond->params.fail_over_mac)
|
||||
return 0;
|
||||
|
||||
if (!is_valid_ether_addr(sa->sa_data)) {
|
||||
return -EADDRNOTAVAIL;
|
||||
@@ -4384,10 +4397,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
|
||||
#ifdef CONFIG_PROC_FS
|
||||
bond_create_proc_entry(bond);
|
||||
#endif
|
||||
|
||||
/* set do_set_mac_addr to true on startup */
|
||||
bond->do_set_mac_addr = 1;
|
||||
|
||||
list_add_tail(&bond->bond_list, &bond_dev_list);
|
||||
|
||||
return 0;
|
||||
@@ -4721,6 +4730,11 @@ static int bond_check_params(struct bond_params *params)
|
||||
primary = NULL;
|
||||
}
|
||||
|
||||
if (fail_over_mac && (bond_mode != BOND_MODE_ACTIVEBACKUP))
|
||||
printk(KERN_WARNING DRV_NAME
|
||||
": Warning: fail_over_mac only affects "
|
||||
"active-backup mode.\n");
|
||||
|
||||
/* fill params struct with the proper values */
|
||||
params->mode = bond_mode;
|
||||
params->xmit_policy = xmit_hashtype;
|
||||
@@ -4732,6 +4746,7 @@ static int bond_check_params(struct bond_params *params)
|
||||
params->use_carrier = use_carrier;
|
||||
params->lacp_fast = lacp_fast;
|
||||
params->primary[0] = 0;
|
||||
params->fail_over_mac = fail_over_mac;
|
||||
|
||||
if (primary) {
|
||||
strncpy(params->primary, primary, IFNAMSIZ);
|
||||
|
@@ -567,6 +567,54 @@ static ssize_t bonding_store_arp_validate(struct device *d,
|
||||
|
||||
static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
|
||||
|
||||
/*
|
||||
* Show and store fail_over_mac. User only allowed to change the
|
||||
* value when there are no slaves.
|
||||
*/
|
||||
static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
return sprintf(buf, "%d\n", bond->params.fail_over_mac) + 1;
|
||||
}
|
||||
|
||||
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 ret = count;
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (bond->slave_cnt != 0) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
": %s: Can't alter fail_over_mac with slaves in bond.\n",
|
||||
bond->dev->name);
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sscanf(buf, "%d", &new_value) != 1) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
": %s: no fail_over_mac value specified.\n",
|
||||
bond->dev->name);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((new_value == 0) || (new_value == 1)) {
|
||||
bond->params.fail_over_mac = new_value;
|
||||
printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %d.\n",
|
||||
bond->dev->name, new_value);
|
||||
} else {
|
||||
printk(KERN_INFO DRV_NAME
|
||||
": %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);
|
||||
|
||||
/*
|
||||
* Show and set the arp timer interval. There are two tricky bits
|
||||
* here. First, if ARP monitoring is activated, then we must disable
|
||||
@@ -1388,6 +1436,7 @@ static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
|
||||
static struct attribute *per_bond_attrs[] = {
|
||||
&dev_attr_slaves.attr,
|
||||
&dev_attr_mode.attr,
|
||||
&dev_attr_fail_over_mac.attr,
|
||||
&dev_attr_arp_validate.attr,
|
||||
&dev_attr_arp_interval.attr,
|
||||
&dev_attr_arp_ip_target.attr,
|
||||
|
@@ -22,8 +22,8 @@
|
||||
#include "bond_3ad.h"
|
||||
#include "bond_alb.h"
|
||||
|
||||
#define DRV_VERSION "3.1.3"
|
||||
#define DRV_RELDATE "June 13, 2007"
|
||||
#define DRV_VERSION "3.2.0"
|
||||
#define DRV_RELDATE "September 13, 2007"
|
||||
#define DRV_NAME "bonding"
|
||||
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
|
||||
|
||||
@@ -128,6 +128,7 @@ struct bond_params {
|
||||
int arp_interval;
|
||||
int arp_validate;
|
||||
int use_carrier;
|
||||
int fail_over_mac;
|
||||
int updelay;
|
||||
int downdelay;
|
||||
int lacp_fast;
|
||||
@@ -186,7 +187,6 @@ struct bonding {
|
||||
struct timer_list mii_timer;
|
||||
struct timer_list arp_timer;
|
||||
s8 kill_timers;
|
||||
s8 do_set_mac_addr;
|
||||
s8 send_grat_arp;
|
||||
s8 setup_by_slave;
|
||||
struct net_device_stats stats;
|
||||
|
Reference in New Issue
Block a user