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; |