diff options
| author | Jay Vosburgh <fubar@us.ibm.com> | 2007-10-09 22:57:24 -0400 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2007-10-15 14:20:46 -0400 |
| commit | dd957c57c52a3964b8446a3e868a08186274b628 (patch) | |
| tree | e745b1d3cfe5fbcb4bc6b85084dd90a22e1a1da9 | |
| parent | d90a162a4ee280201e84944a84f86d6728dc0c27 (diff) | |
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>
| -rw-r--r-- | Documentation/networking/bonding.txt | 33 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_main.c | 57 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 49 | ||||
| -rw-r--r-- | drivers/net/bonding/bonding.h | 6 |
4 files changed, 121 insertions, 24 deletions
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index 1da566630831..11340625e363 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt | |||
| @@ -281,6 +281,39 @@ downdelay | |||
| 281 | will be rounded down to the nearest multiple. The default | 281 | will be rounded down to the nearest multiple. The default |
| 282 | value is 0. | 282 | value is 0. |
| 283 | 283 | ||
| 284 | fail_over_mac | ||
| 285 | |||
| 286 | Specifies whether active-backup mode should set all slaves to | ||
| 287 | the same MAC address (the traditional behavior), or, when | ||
| 288 | enabled, change the bond's MAC address when changing the | ||
| 289 | active interface (i.e., fail over the MAC address itself). | ||
| 290 | |||
| 291 | Fail over MAC is useful for devices that cannot ever alter | ||
| 292 | their MAC address, or for devices that refuse incoming | ||
| 293 | broadcasts with their own source MAC (which interferes with | ||
| 294 | the ARP monitor). | ||
| 295 | |||
| 296 | The down side of fail over MAC is that every device on the | ||
| 297 | network must be updated via gratuitous ARP, vs. just updating | ||
| 298 | a switch or set of switches (which often takes place for any | ||
| 299 | traffic, not just ARP traffic, if the switch snoops incoming | ||
| 300 | traffic to update its tables) for the traditional method. If | ||
| 301 | the gratuitous ARP is lost, communication may be disrupted. | ||
| 302 | |||
| 303 | When fail over MAC is used in conjuction with the mii monitor, | ||
| 304 | devices which assert link up prior to being able to actually | ||
| 305 | transmit and receive are particularly susecptible to loss of | ||
| 306 | the gratuitous ARP, and an appropriate updelay setting may be | ||
| 307 | required. | ||
| 308 | |||
| 309 | A value of 0 disables fail over MAC, and is the default. A | ||
| 310 | value of 1 enables fail over MAC. This option is enabled | ||
| 311 | automatically if the first slave added cannot change its MAC | ||
| 312 | address. This option may be modified via sysfs only when no | ||
| 313 | slaves are present in the bond. | ||
| 314 | |||
| 315 | This option was added in bonding version 3.2.0. | ||
| 316 | |||
| 284 | lacp_rate | 317 | lacp_rate |
| 285 | 318 | ||
| 286 | Option specifying the rate in which we'll ask our link partner | 319 | Option specifying the rate in which we'll ask our link partner |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 0e198dd87c20..db80f243dd37 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -98,6 +98,7 @@ static char *xmit_hash_policy = NULL; | |||
| 98 | static int arp_interval = BOND_LINK_ARP_INTERV; | 98 | static int arp_interval = BOND_LINK_ARP_INTERV; |
| 99 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; | 99 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; |
| 100 | static char *arp_validate = NULL; | 100 | static char *arp_validate = NULL; |
| 101 | static int fail_over_mac = 0; | ||
| 101 | struct bond_params bonding_defaults; | 102 | struct bond_params bonding_defaults; |
| 102 | 103 | ||
| 103 | module_param(max_bonds, int, 0); | 104 | module_param(max_bonds, int, 0); |
| @@ -131,6 +132,8 @@ module_param_array(arp_ip_target, charp, NULL, 0); | |||
| 131 | MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); | 132 | MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); |
| 132 | module_param(arp_validate, charp, 0); | 133 | module_param(arp_validate, charp, 0); |
| 133 | MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all"); | 134 | MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all"); |
| 135 | module_param(fail_over_mac, int, 0); | ||
| 136 | 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."); | ||
| 134 | 137 | ||
| 135 | /*----------------------------- Global variables ----------------------------*/ | 138 | /*----------------------------- Global variables ----------------------------*/ |
| 136 | 139 | ||
| @@ -1100,7 +1103,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
| 1100 | /* when bonding does not set the slave MAC address, the bond MAC | 1103 | /* when bonding does not set the slave MAC address, the bond MAC |
| 1101 | * address is the one of the active slave. | 1104 | * address is the one of the active slave. |
| 1102 | */ | 1105 | */ |
| 1103 | if (new_active && !bond->do_set_mac_addr) | 1106 | if (new_active && bond->params.fail_over_mac) |
| 1104 | memcpy(bond->dev->dev_addr, new_active->dev->dev_addr, | 1107 | memcpy(bond->dev->dev_addr, new_active->dev->dev_addr, |
| 1105 | new_active->dev->addr_len); | 1108 | new_active->dev->addr_len); |
| 1106 | if (bond->curr_active_slave && | 1109 | if (bond->curr_active_slave && |
| @@ -1367,16 +1370,16 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1367 | if (slave_dev->set_mac_address == NULL) { | 1370 | if (slave_dev->set_mac_address == NULL) { |
| 1368 | if (bond->slave_cnt == 0) { | 1371 | if (bond->slave_cnt == 0) { |
| 1369 | printk(KERN_WARNING DRV_NAME | 1372 | printk(KERN_WARNING DRV_NAME |
| 1370 | ": %s: Warning: The first slave device you " | 1373 | ": %s: Warning: The first slave device " |
| 1371 | "specified does not support setting the MAC " | 1374 | "specified does not support setting the MAC " |
| 1372 | "address. This bond MAC address would be that " | 1375 | "address. Enabling the fail_over_mac option.", |
| 1373 | "of the active slave.\n", bond_dev->name); | 1376 | bond_dev->name); |
| 1374 | bond->do_set_mac_addr = 0; | 1377 | bond->params.fail_over_mac = 1; |
| 1375 | } else if (bond->do_set_mac_addr) { | 1378 | } else if (!bond->params.fail_over_mac) { |
| 1376 | printk(KERN_ERR DRV_NAME | 1379 | printk(KERN_ERR DRV_NAME |
| 1377 | ": %s: Error: The slave device you specified " | 1380 | ": %s: Error: The slave device specified " |
| 1378 | "does not support setting the MAC addres,." | 1381 | "does not support setting the MAC address, " |
| 1379 | "but this bond uses this practice. \n" | 1382 | "but fail_over_mac is not enabled.\n" |
| 1380 | , bond_dev->name); | 1383 | , bond_dev->name); |
| 1381 | res = -EOPNOTSUPP; | 1384 | res = -EOPNOTSUPP; |
| 1382 | goto err_undo_flags; | 1385 | goto err_undo_flags; |
| @@ -1401,7 +1404,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1401 | */ | 1404 | */ |
| 1402 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); | 1405 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); |
| 1403 | 1406 | ||
| 1404 | if (bond->do_set_mac_addr) { | 1407 | if (!bond->params.fail_over_mac) { |
| 1405 | /* | 1408 | /* |
| 1406 | * Set slave to master's mac address. The application already | 1409 | * Set slave to master's mac address. The application already |
| 1407 | * set the master's mac address to that of the first slave | 1410 | * set the master's mac address to that of the first slave |
| @@ -1637,7 +1640,7 @@ err_close: | |||
| 1637 | dev_close(slave_dev); | 1640 | dev_close(slave_dev); |
| 1638 | 1641 | ||
| 1639 | err_restore_mac: | 1642 | err_restore_mac: |
| 1640 | if (bond->do_set_mac_addr) { | 1643 | if (!bond->params.fail_over_mac) { |
| 1641 | memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); | 1644 | memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); |
| 1642 | addr.sa_family = slave_dev->type; | 1645 | addr.sa_family = slave_dev->type; |
| 1643 | dev_set_mac_address(slave_dev, &addr); | 1646 | dev_set_mac_address(slave_dev, &addr); |
| @@ -1814,7 +1817,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1814 | /* close slave before restoring its mac address */ | 1817 | /* close slave before restoring its mac address */ |
| 1815 | dev_close(slave_dev); | 1818 | dev_close(slave_dev); |
| 1816 | 1819 | ||
| 1817 | if (bond->do_set_mac_addr) { | 1820 | if (!bond->params.fail_over_mac) { |
| 1818 | /* restore original ("permanent") mac address */ | 1821 | /* restore original ("permanent") mac address */ |
| 1819 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 1822 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
| 1820 | addr.sa_family = slave_dev->type; | 1823 | addr.sa_family = slave_dev->type; |
| @@ -1935,7 +1938,7 @@ static int bond_release_all(struct net_device *bond_dev) | |||
| 1935 | /* close slave before restoring its mac address */ | 1938 | /* close slave before restoring its mac address */ |
| 1936 | dev_close(slave_dev); | 1939 | dev_close(slave_dev); |
| 1937 | 1940 | ||
| 1938 | if (bond->do_set_mac_addr) { | 1941 | if (!bond->params.fail_over_mac) { |
| 1939 | /* restore original ("permanent") mac address*/ | 1942 | /* restore original ("permanent") mac address*/ |
| 1940 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 1943 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
| 1941 | addr.sa_family = slave_dev->type; | 1944 | addr.sa_family = slave_dev->type; |
| @@ -3060,9 +3063,15 @@ static void bond_info_show_master(struct seq_file *seq) | |||
| 3060 | curr = bond->curr_active_slave; | 3063 | curr = bond->curr_active_slave; |
| 3061 | read_unlock(&bond->curr_slave_lock); | 3064 | read_unlock(&bond->curr_slave_lock); |
| 3062 | 3065 | ||
| 3063 | seq_printf(seq, "Bonding Mode: %s\n", | 3066 | seq_printf(seq, "Bonding Mode: %s", |
| 3064 | bond_mode_name(bond->params.mode)); | 3067 | bond_mode_name(bond->params.mode)); |
| 3065 | 3068 | ||
| 3069 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP && | ||
| 3070 | bond->params.fail_over_mac) | ||
| 3071 | seq_printf(seq, " (fail_over_mac)"); | ||
| 3072 | |||
| 3073 | seq_printf(seq, "\n"); | ||
| 3074 | |||
| 3066 | if (bond->params.mode == BOND_MODE_XOR || | 3075 | if (bond->params.mode == BOND_MODE_XOR || |
| 3067 | bond->params.mode == BOND_MODE_8023AD) { | 3076 | bond->params.mode == BOND_MODE_8023AD) { |
| 3068 | seq_printf(seq, "Transmit Hash Policy: %s (%d)\n", | 3077 | 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) | |||
| 3994 | 4003 | ||
| 3995 | dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None")); | 4004 | dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None")); |
| 3996 | 4005 | ||
| 3997 | if (!bond->do_set_mac_addr) | 4006 | /* |
| 3998 | return -EOPNOTSUPP; | 4007 | * If fail_over_mac is enabled, do nothing and return success. |
| 4008 | * Returning an error causes ifenslave to fail. | ||
| 4009 | */ | ||
| 4010 | if (bond->params.fail_over_mac) | ||
| 4011 | return 0; | ||
| 3999 | 4012 | ||
| 4000 | if (!is_valid_ether_addr(sa->sa_data)) { | 4013 | if (!is_valid_ether_addr(sa->sa_data)) { |
| 4001 | return -EADDRNOTAVAIL; | 4014 | return -EADDRNOTAVAIL; |
| @@ -4384,10 +4397,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) | |||
| 4384 | #ifdef CONFIG_PROC_FS | 4397 | #ifdef CONFIG_PROC_FS |
| 4385 | bond_create_proc_entry(bond); | 4398 | bond_create_proc_entry(bond); |
| 4386 | #endif | 4399 | #endif |
| 4387 | |||
| 4388 | /* set do_set_mac_addr to true on startup */ | ||
| 4389 | bond->do_set_mac_addr = 1; | ||
| 4390 | |||
| 4391 | list_add_tail(&bond->bond_list, &bond_dev_list); | 4400 | list_add_tail(&bond->bond_list, &bond_dev_list); |
| 4392 | 4401 | ||
| 4393 | return 0; | 4402 | return 0; |
| @@ -4721,6 +4730,11 @@ static int bond_check_params(struct bond_params *params) | |||
| 4721 | primary = NULL; | 4730 | primary = NULL; |
| 4722 | } | 4731 | } |
| 4723 | 4732 | ||
| 4733 | if (fail_over_mac && (bond_mode != BOND_MODE_ACTIVEBACKUP)) | ||
| 4734 | printk(KERN_WARNING DRV_NAME | ||
| 4735 | ": Warning: fail_over_mac only affects " | ||
| 4736 | "active-backup mode.\n"); | ||
| 4737 | |||
| 4724 | /* fill params struct with the proper values */ | 4738 | /* fill params struct with the proper values */ |
| 4725 | params->mode = bond_mode; | 4739 | params->mode = bond_mode; |
| 4726 | params->xmit_policy = xmit_hashtype; | 4740 | params->xmit_policy = xmit_hashtype; |
| @@ -4732,6 +4746,7 @@ static int bond_check_params(struct bond_params *params) | |||
| 4732 | params->use_carrier = use_carrier; | 4746 | params->use_carrier = use_carrier; |
| 4733 | params->lacp_fast = lacp_fast; | 4747 | params->lacp_fast = lacp_fast; |
| 4734 | params->primary[0] = 0; | 4748 | params->primary[0] = 0; |
| 4749 | params->fail_over_mac = fail_over_mac; | ||
| 4735 | 4750 | ||
| 4736 | if (primary) { | 4751 | if (primary) { |
| 4737 | strncpy(params->primary, primary, IFNAMSIZ); | 4752 | strncpy(params->primary, primary, IFNAMSIZ); |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index b5d2a13fe627..80c0c8c415ed 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
| @@ -568,6 +568,54 @@ static ssize_t bonding_store_arp_validate(struct device *d, | |||
| 568 | static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate); | 568 | static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate); |
| 569 | 569 | ||
| 570 | /* | 570 | /* |
| 571 | * Show and store fail_over_mac. User only allowed to change the | ||
| 572 | * value when there are no slaves. | ||
| 573 | */ | ||
| 574 | static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attribute *attr, char *buf) | ||
| 575 | { | ||
| 576 | struct bonding *bond = to_bond(d); | ||
| 577 | |||
| 578 | return sprintf(buf, "%d\n", bond->params.fail_over_mac) + 1; | ||
| 579 | } | ||
| 580 | |||
| 581 | static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count) | ||
| 582 | { | ||
| 583 | int new_value; | ||
| 584 | int ret = count; | ||
| 585 | struct bonding *bond = to_bond(d); | ||
| 586 | |||
| 587 | if (bond->slave_cnt != 0) { | ||
| 588 | printk(KERN_ERR DRV_NAME | ||
| 589 | ": %s: Can't alter fail_over_mac with slaves in bond.\n", | ||
| 590 | bond->dev->name); | ||
| 591 | ret = -EPERM; | ||
| 592 | goto out; | ||
| 593 | } | ||
| 594 | |||
| 595 | if (sscanf(buf, "%d", &new_value) != 1) { | ||
| 596 | printk(KERN_ERR DRV_NAME | ||
| 597 | ": %s: no fail_over_mac value specified.\n", | ||
| 598 | bond->dev->name); | ||
| 599 | ret = -EINVAL; | ||
| 600 | goto out; | ||
| 601 | } | ||
| 602 | |||
| 603 | if ((new_value == 0) || (new_value == 1)) { | ||
| 604 | bond->params.fail_over_mac = new_value; | ||
| 605 | printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %d.\n", | ||
| 606 | bond->dev->name, new_value); | ||
| 607 | } else { | ||
| 608 | printk(KERN_INFO DRV_NAME | ||
| 609 | ": %s: Ignoring invalid fail_over_mac value %d.\n", | ||
| 610 | bond->dev->name, new_value); | ||
| 611 | } | ||
| 612 | out: | ||
| 613 | return ret; | ||
| 614 | } | ||
| 615 | |||
| 616 | static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac); | ||
| 617 | |||
| 618 | /* | ||
| 571 | * Show and set the arp timer interval. There are two tricky bits | 619 | * Show and set the arp timer interval. There are two tricky bits |
| 572 | * here. First, if ARP monitoring is activated, then we must disable | 620 | * here. First, if ARP monitoring is activated, then we must disable |
| 573 | * MII monitoring. Second, if the ARP timer isn't running, we must | 621 | * MII monitoring. Second, if the ARP timer isn't running, we must |
| @@ -1388,6 +1436,7 @@ static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL); | |||
| 1388 | static struct attribute *per_bond_attrs[] = { | 1436 | static struct attribute *per_bond_attrs[] = { |
| 1389 | &dev_attr_slaves.attr, | 1437 | &dev_attr_slaves.attr, |
| 1390 | &dev_attr_mode.attr, | 1438 | &dev_attr_mode.attr, |
| 1439 | &dev_attr_fail_over_mac.attr, | ||
| 1391 | &dev_attr_arp_validate.attr, | 1440 | &dev_attr_arp_validate.attr, |
| 1392 | &dev_attr_arp_interval.attr, | 1441 | &dev_attr_arp_interval.attr, |
| 1393 | &dev_attr_arp_ip_target.attr, | 1442 | &dev_attr_arp_ip_target.attr, |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 85e579b0d6f4..a8bbd563265c 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
| @@ -22,8 +22,8 @@ | |||
| 22 | #include "bond_3ad.h" | 22 | #include "bond_3ad.h" |
| 23 | #include "bond_alb.h" | 23 | #include "bond_alb.h" |
| 24 | 24 | ||
| 25 | #define DRV_VERSION "3.1.3" | 25 | #define DRV_VERSION "3.2.0" |
| 26 | #define DRV_RELDATE "June 13, 2007" | 26 | #define DRV_RELDATE "September 13, 2007" |
| 27 | #define DRV_NAME "bonding" | 27 | #define DRV_NAME "bonding" |
| 28 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" | 28 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" |
| 29 | 29 | ||
| @@ -128,6 +128,7 @@ struct bond_params { | |||
| 128 | int arp_interval; | 128 | int arp_interval; |
| 129 | int arp_validate; | 129 | int arp_validate; |
| 130 | int use_carrier; | 130 | int use_carrier; |
| 131 | int fail_over_mac; | ||
| 131 | int updelay; | 132 | int updelay; |
| 132 | int downdelay; | 133 | int downdelay; |
| 133 | int lacp_fast; | 134 | int lacp_fast; |
| @@ -186,7 +187,6 @@ struct bonding { | |||
| 186 | struct timer_list mii_timer; | 187 | struct timer_list mii_timer; |
| 187 | struct timer_list arp_timer; | 188 | struct timer_list arp_timer; |
| 188 | s8 kill_timers; | 189 | s8 kill_timers; |
| 189 | s8 do_set_mac_addr; | ||
| 190 | s8 send_grat_arp; | 190 | s8 send_grat_arp; |
| 191 | s8 setup_by_slave; | 191 | s8 setup_by_slave; |
| 192 | struct net_device_stats stats; | 192 | struct net_device_stats stats; |
