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 | |
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>
-rw-r--r-- | Documentation/networking/bonding.txt | 96 | ||||
-rw-r--r-- | drivers/net/bonding/bond_main.c | 185 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 36 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 4 |
4 files changed, 232 insertions, 89 deletions
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index a0cda062bc33..8e6b8d3c7410 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt | |||
@@ -289,35 +289,73 @@ downdelay | |||
289 | fail_over_mac | 289 | fail_over_mac |
290 | 290 | ||
291 | Specifies whether active-backup mode should set all slaves to | 291 | Specifies whether active-backup mode should set all slaves to |
292 | the same MAC address (the traditional behavior), or, when | 292 | the same MAC address at enslavement (the traditional |
293 | enabled, change the bond's MAC address when changing the | 293 | behavior), or, when enabled, perform special handling of the |
294 | active interface (i.e., fail over the MAC address itself). | 294 | bond's MAC address in accordance with the selected policy. |
295 | 295 | ||
296 | Fail over MAC is useful for devices that cannot ever alter | 296 | Possible values are: |
297 | their MAC address, or for devices that refuse incoming | 297 | |
298 | broadcasts with their own source MAC (which interferes with | 298 | none or 0 |
299 | the ARP monitor). | 299 | |
300 | 300 | This setting disables fail_over_mac, and causes | |
301 | The down side of fail over MAC is that every device on the | 301 | bonding to set all slaves of an active-backup bond to |
302 | network must be updated via gratuitous ARP, vs. just updating | 302 | the same MAC address at enslavement time. This is the |
303 | a switch or set of switches (which often takes place for any | 303 | default. |
304 | traffic, not just ARP traffic, if the switch snoops incoming | 304 | |
305 | traffic to update its tables) for the traditional method. If | 305 | active or 1 |
306 | the gratuitous ARP is lost, communication may be disrupted. | 306 | |
307 | 307 | The "active" fail_over_mac policy indicates that the | |
308 | When fail over MAC is used in conjuction with the mii monitor, | 308 | MAC address of the bond should always be the MAC |
309 | devices which assert link up prior to being able to actually | 309 | address of the currently active slave. The MAC |
310 | transmit and receive are particularly susecptible to loss of | 310 | address of the slaves is not changed; instead, the MAC |
311 | the gratuitous ARP, and an appropriate updelay setting may be | 311 | address of the bond changes during a failover. |
312 | required. | 312 | |
313 | 313 | This policy is useful for devices that cannot ever | |
314 | A value of 0 disables fail over MAC, and is the default. A | 314 | alter their MAC address, or for devices that refuse |
315 | value of 1 enables fail over MAC. This option is enabled | 315 | incoming broadcasts with their own source MAC (which |
316 | automatically if the first slave added cannot change its MAC | 316 | interferes with the ARP monitor). |
317 | address. This option may be modified via sysfs only when no | 317 | |
318 | slaves are present in the bond. | 318 | The down side of this policy is that every device on |
319 | 319 | the network must be updated via gratuitous ARP, | |
320 | This option was added in bonding version 3.2.0. | 320 | vs. just updating a switch or set of switches (which |
321 | often takes place for any traffic, not just ARP | ||
322 | traffic, if the switch snoops incoming traffic to | ||
323 | update its tables) for the traditional method. If the | ||
324 | gratuitous ARP is lost, communication may be | ||
325 | disrupted. | ||
326 | |||
327 | When this policy is used in conjuction with the mii | ||
328 | monitor, devices which assert link up prior to being | ||
329 | able to actually transmit and receive are particularly | ||
330 | susecptible to loss of the gratuitous ARP, and an | ||
331 | appropriate updelay setting may be required. | ||
332 | |||
333 | follow or 2 | ||
334 | |||
335 | The "follow" fail_over_mac policy causes the MAC | ||
336 | address of the bond to be selected normally (normally | ||
337 | the MAC address of the first slave added to the bond). | ||
338 | However, the second and subsequent slaves are not set | ||
339 | to this MAC address while they are in a backup role; a | ||
340 | slave is programmed with the bond's MAC address at | ||
341 | failover time (and the formerly active slave receives | ||
342 | the newly active slave's MAC address). | ||
343 | |||
344 | This policy is useful for multiport devices that | ||
345 | either become confused or incur a performance penalty | ||
346 | when multiple ports are programmed with the same MAC | ||
347 | address. | ||
348 | |||
349 | |||
350 | The default policy is none, unless the first slave cannot | ||
351 | change its MAC address, in which case the active policy is | ||
352 | selected by default. | ||
353 | |||
354 | This option may be modified via sysfs only when no slaves are | ||
355 | present in the bond. | ||
356 | |||
357 | This option was added in bonding version 3.2.0. The "follow" | ||
358 | policy was added in bonding version 3.3.0. | ||
321 | 359 | ||
322 | lacp_rate | 360 | lacp_rate |
323 | 361 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 51e0f2de42c6..5b4af3cc2a44 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -100,7 +100,7 @@ static char *xmit_hash_policy = NULL; | |||
100 | static int arp_interval = BOND_LINK_ARP_INTERV; | 100 | static int arp_interval = BOND_LINK_ARP_INTERV; |
101 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; | 101 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; |
102 | static char *arp_validate = NULL; | 102 | static char *arp_validate = NULL; |
103 | static int fail_over_mac = 0; | 103 | static char *fail_over_mac = NULL; |
104 | struct bond_params bonding_defaults; | 104 | struct bond_params bonding_defaults; |
105 | 105 | ||
106 | module_param(max_bonds, int, 0); | 106 | module_param(max_bonds, int, 0); |
@@ -136,8 +136,8 @@ module_param_array(arp_ip_target, charp, NULL, 0); | |||
136 | MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); | 136 | MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); |
137 | module_param(arp_validate, charp, 0); | 137 | module_param(arp_validate, charp, 0); |
138 | MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all"); | 138 | MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all"); |
139 | module_param(fail_over_mac, int, 0); | 139 | module_param(fail_over_mac, charp, 0); |
140 | 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."); | 140 | MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. none (default), active or follow"); |
141 | 141 | ||
142 | /*----------------------------- Global variables ----------------------------*/ | 142 | /*----------------------------- Global variables ----------------------------*/ |
143 | 143 | ||
@@ -190,6 +190,13 @@ struct bond_parm_tbl arp_validate_tbl[] = { | |||
190 | { NULL, -1}, | 190 | { NULL, -1}, |
191 | }; | 191 | }; |
192 | 192 | ||
193 | struct bond_parm_tbl fail_over_mac_tbl[] = { | ||
194 | { "none", BOND_FOM_NONE}, | ||
195 | { "active", BOND_FOM_ACTIVE}, | ||
196 | { "follow", BOND_FOM_FOLLOW}, | ||
197 | { NULL, -1}, | ||
198 | }; | ||
199 | |||
193 | /*-------------------------- Forward declarations ---------------------------*/ | 200 | /*-------------------------- Forward declarations ---------------------------*/ |
194 | 201 | ||
195 | static void bond_send_gratuitous_arp(struct bonding *bond); | 202 | static void bond_send_gratuitous_arp(struct bonding *bond); |
@@ -973,6 +980,82 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct | |||
973 | } | 980 | } |
974 | } | 981 | } |
975 | 982 | ||
983 | /* | ||
984 | * bond_do_fail_over_mac | ||
985 | * | ||
986 | * Perform special MAC address swapping for fail_over_mac settings | ||
987 | * | ||
988 | * Called with RTNL, bond->lock for read, curr_slave_lock for write_bh. | ||
989 | */ | ||
990 | static void bond_do_fail_over_mac(struct bonding *bond, | ||
991 | struct slave *new_active, | ||
992 | struct slave *old_active) | ||
993 | { | ||
994 | u8 tmp_mac[ETH_ALEN]; | ||
995 | struct sockaddr saddr; | ||
996 | int rv; | ||
997 | |||
998 | switch (bond->params.fail_over_mac) { | ||
999 | case BOND_FOM_ACTIVE: | ||
1000 | if (new_active) | ||
1001 | memcpy(bond->dev->dev_addr, new_active->dev->dev_addr, | ||
1002 | new_active->dev->addr_len); | ||
1003 | break; | ||
1004 | case BOND_FOM_FOLLOW: | ||
1005 | /* | ||
1006 | * if new_active && old_active, swap them | ||
1007 | * if just old_active, do nothing (going to no active slave) | ||
1008 | * if just new_active, set new_active to bond's MAC | ||
1009 | */ | ||
1010 | if (!new_active) | ||
1011 | return; | ||
1012 | |||
1013 | write_unlock_bh(&bond->curr_slave_lock); | ||
1014 | read_unlock(&bond->lock); | ||
1015 | |||
1016 | if (old_active) { | ||
1017 | memcpy(tmp_mac, new_active->dev->dev_addr, ETH_ALEN); | ||
1018 | memcpy(saddr.sa_data, old_active->dev->dev_addr, | ||
1019 | ETH_ALEN); | ||
1020 | saddr.sa_family = new_active->dev->type; | ||
1021 | } else { | ||
1022 | memcpy(saddr.sa_data, bond->dev->dev_addr, ETH_ALEN); | ||
1023 | saddr.sa_family = bond->dev->type; | ||
1024 | } | ||
1025 | |||
1026 | rv = dev_set_mac_address(new_active->dev, &saddr); | ||
1027 | if (rv) { | ||
1028 | printk(KERN_ERR DRV_NAME | ||
1029 | ": %s: Error %d setting MAC of slave %s\n", | ||
1030 | bond->dev->name, -rv, new_active->dev->name); | ||
1031 | goto out; | ||
1032 | } | ||
1033 | |||
1034 | if (!old_active) | ||
1035 | goto out; | ||
1036 | |||
1037 | memcpy(saddr.sa_data, tmp_mac, ETH_ALEN); | ||
1038 | saddr.sa_family = old_active->dev->type; | ||
1039 | |||
1040 | rv = dev_set_mac_address(old_active->dev, &saddr); | ||
1041 | if (rv) | ||
1042 | printk(KERN_ERR DRV_NAME | ||
1043 | ": %s: Error %d setting MAC of slave %s\n", | ||
1044 | bond->dev->name, -rv, new_active->dev->name); | ||
1045 | out: | ||
1046 | read_lock(&bond->lock); | ||
1047 | write_lock_bh(&bond->curr_slave_lock); | ||
1048 | break; | ||
1049 | default: | ||
1050 | printk(KERN_ERR DRV_NAME | ||
1051 | ": %s: bond_do_fail_over_mac impossible: bad policy %d\n", | ||
1052 | bond->dev->name, bond->params.fail_over_mac); | ||
1053 | break; | ||
1054 | } | ||
1055 | |||
1056 | } | ||
1057 | |||
1058 | |||
976 | /** | 1059 | /** |
977 | * find_best_interface - select the best available slave to be the active one | 1060 | * find_best_interface - select the best available slave to be the active one |
978 | * @bond: our bonding struct | 1061 | * @bond: our bonding struct |
@@ -1040,7 +1123,8 @@ static struct slave *bond_find_best_slave(struct bonding *bond) | |||
1040 | * because it is apparently the best available slave we have, even though its | 1123 | * because it is apparently the best available slave we have, even though its |
1041 | * updelay hasn't timed out yet. | 1124 | * updelay hasn't timed out yet. |
1042 | * | 1125 | * |
1043 | * Warning: Caller must hold curr_slave_lock for writing. | 1126 | * If new_active is not NULL, caller must hold bond->lock for read and |
1127 | * curr_slave_lock for write_bh. | ||
1044 | */ | 1128 | */ |
1045 | void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | 1129 | void bond_change_active_slave(struct bonding *bond, struct slave *new_active) |
1046 | { | 1130 | { |
@@ -1107,12 +1191,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
1107 | bond_set_slave_active_flags(new_active); | 1191 | bond_set_slave_active_flags(new_active); |
1108 | } | 1192 | } |
1109 | 1193 | ||
1110 | /* when bonding does not set the slave MAC address, the bond MAC | ||
1111 | * address is the one of the active slave. | ||
1112 | */ | ||
1113 | if (new_active && bond->params.fail_over_mac) | 1194 | if (new_active && bond->params.fail_over_mac) |
1114 | memcpy(bond->dev->dev_addr, new_active->dev->dev_addr, | 1195 | bond_do_fail_over_mac(bond, new_active, old_active); |
1115 | new_active->dev->addr_len); | 1196 | |
1116 | bond->send_grat_arp = bond->params.num_grat_arp; | 1197 | bond->send_grat_arp = bond->params.num_grat_arp; |
1117 | if (bond->curr_active_slave && | 1198 | if (bond->curr_active_slave && |
1118 | test_bit(__LINK_STATE_LINKWATCH_PENDING, | 1199 | test_bit(__LINK_STATE_LINKWATCH_PENDING, |
@@ -1137,7 +1218,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
1137 | * - The primary_slave has got its link back. | 1218 | * - The primary_slave has got its link back. |
1138 | * - A slave has got its link back and there's no old curr_active_slave. | 1219 | * - A slave has got its link back and there's no old curr_active_slave. |
1139 | * | 1220 | * |
1140 | * Warning: Caller must hold curr_slave_lock for writing. | 1221 | * Caller must hold bond->lock for read and curr_slave_lock for write_bh. |
1141 | */ | 1222 | */ |
1142 | void bond_select_active_slave(struct bonding *bond) | 1223 | void bond_select_active_slave(struct bonding *bond) |
1143 | { | 1224 | { |
@@ -1384,14 +1465,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1384 | printk(KERN_WARNING DRV_NAME | 1465 | printk(KERN_WARNING DRV_NAME |
1385 | ": %s: Warning: The first slave device " | 1466 | ": %s: Warning: The first slave device " |
1386 | "specified does not support setting the MAC " | 1467 | "specified does not support setting the MAC " |
1387 | "address. Enabling the fail_over_mac option.", | 1468 | "address. Setting fail_over_mac to active.", |
1388 | bond_dev->name); | 1469 | bond_dev->name); |
1389 | bond->params.fail_over_mac = 1; | 1470 | bond->params.fail_over_mac = BOND_FOM_ACTIVE; |
1390 | } else if (!bond->params.fail_over_mac) { | 1471 | } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { |
1391 | printk(KERN_ERR DRV_NAME | 1472 | printk(KERN_ERR DRV_NAME |
1392 | ": %s: Error: The slave device specified " | 1473 | ": %s: Error: The slave device specified " |
1393 | "does not support setting the MAC address, " | 1474 | "does not support setting the MAC address, " |
1394 | "but fail_over_mac is not enabled.\n" | 1475 | "but fail_over_mac is not set to active.\n" |
1395 | , bond_dev->name); | 1476 | , bond_dev->name); |
1396 | res = -EOPNOTSUPP; | 1477 | res = -EOPNOTSUPP; |
1397 | goto err_undo_flags; | 1478 | goto err_undo_flags; |
@@ -1498,6 +1579,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1498 | 1579 | ||
1499 | bond_compute_features(bond); | 1580 | bond_compute_features(bond); |
1500 | 1581 | ||
1582 | write_unlock_bh(&bond->lock); | ||
1583 | |||
1584 | read_lock(&bond->lock); | ||
1585 | |||
1501 | new_slave->last_arp_rx = jiffies; | 1586 | new_slave->last_arp_rx = jiffies; |
1502 | 1587 | ||
1503 | if (bond->params.miimon && !bond->params.use_carrier) { | 1588 | if (bond->params.miimon && !bond->params.use_carrier) { |
@@ -1574,6 +1659,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1574 | } | 1659 | } |
1575 | } | 1660 | } |
1576 | 1661 | ||
1662 | write_lock_bh(&bond->curr_slave_lock); | ||
1663 | |||
1577 | switch (bond->params.mode) { | 1664 | switch (bond->params.mode) { |
1578 | case BOND_MODE_ACTIVEBACKUP: | 1665 | case BOND_MODE_ACTIVEBACKUP: |
1579 | bond_set_slave_inactive_flags(new_slave); | 1666 | bond_set_slave_inactive_flags(new_slave); |
@@ -1621,9 +1708,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1621 | break; | 1708 | break; |
1622 | } /* switch(bond_mode) */ | 1709 | } /* switch(bond_mode) */ |
1623 | 1710 | ||
1711 | write_unlock_bh(&bond->curr_slave_lock); | ||
1712 | |||
1624 | bond_set_carrier(bond); | 1713 | bond_set_carrier(bond); |
1625 | 1714 | ||
1626 | write_unlock_bh(&bond->lock); | 1715 | read_unlock(&bond->lock); |
1627 | 1716 | ||
1628 | res = bond_create_slave_symlinks(bond_dev, slave_dev); | 1717 | res = bond_create_slave_symlinks(bond_dev, slave_dev); |
1629 | if (res) | 1718 | if (res) |
@@ -1647,6 +1736,10 @@ err_unset_master: | |||
1647 | 1736 | ||
1648 | err_restore_mac: | 1737 | err_restore_mac: |
1649 | if (!bond->params.fail_over_mac) { | 1738 | if (!bond->params.fail_over_mac) { |
1739 | /* XXX TODO - fom follow mode needs to change master's | ||
1740 | * MAC if this slave's MAC is in use by the bond, or at | ||
1741 | * least print a warning. | ||
1742 | */ | ||
1650 | memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); | 1743 | memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); |
1651 | addr.sa_family = slave_dev->type; | 1744 | addr.sa_family = slave_dev->type; |
1652 | dev_set_mac_address(slave_dev, &addr); | 1745 | dev_set_mac_address(slave_dev, &addr); |
@@ -1701,20 +1794,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1701 | return -EINVAL; | 1794 | return -EINVAL; |
1702 | } | 1795 | } |
1703 | 1796 | ||
1704 | mac_addr_differ = memcmp(bond_dev->dev_addr, | 1797 | if (!bond->params.fail_over_mac) { |
1705 | slave->perm_hwaddr, | 1798 | mac_addr_differ = memcmp(bond_dev->dev_addr, slave->perm_hwaddr, |
1706 | ETH_ALEN); | 1799 | ETH_ALEN); |
1707 | if (!mac_addr_differ && (bond->slave_cnt > 1)) { | 1800 | if (!mac_addr_differ && (bond->slave_cnt > 1)) |
1708 | printk(KERN_WARNING DRV_NAME | 1801 | printk(KERN_WARNING DRV_NAME |
1709 | ": %s: Warning: the permanent HWaddr of %s - " | 1802 | ": %s: Warning: the permanent HWaddr of %s - " |
1710 | "%s - is still in use by %s. " | 1803 | "%s - is still in use by %s. " |
1711 | "Set the HWaddr of %s to a different address " | 1804 | "Set the HWaddr of %s to a different address " |
1712 | "to avoid conflicts.\n", | 1805 | "to avoid conflicts.\n", |
1713 | bond_dev->name, | 1806 | bond_dev->name, slave_dev->name, |
1714 | slave_dev->name, | 1807 | print_mac(mac, slave->perm_hwaddr), |
1715 | print_mac(mac, slave->perm_hwaddr), | 1808 | bond_dev->name, slave_dev->name); |
1716 | bond_dev->name, | ||
1717 | slave_dev->name); | ||
1718 | } | 1809 | } |
1719 | 1810 | ||
1720 | /* Inform AD package of unbinding of slave. */ | 1811 | /* Inform AD package of unbinding of slave. */ |
@@ -1841,7 +1932,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1841 | /* close slave before restoring its mac address */ | 1932 | /* close slave before restoring its mac address */ |
1842 | dev_close(slave_dev); | 1933 | dev_close(slave_dev); |
1843 | 1934 | ||
1844 | if (!bond->params.fail_over_mac) { | 1935 | if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { |
1845 | /* restore original ("permanent") mac address */ | 1936 | /* restore original ("permanent") mac address */ |
1846 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 1937 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
1847 | addr.sa_family = slave_dev->type; | 1938 | addr.sa_family = slave_dev->type; |
@@ -3164,7 +3255,8 @@ static void bond_info_show_master(struct seq_file *seq) | |||
3164 | 3255 | ||
3165 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP && | 3256 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP && |
3166 | bond->params.fail_over_mac) | 3257 | bond->params.fail_over_mac) |
3167 | seq_printf(seq, " (fail_over_mac)"); | 3258 | seq_printf(seq, " (fail_over_mac %s)", |
3259 | fail_over_mac_tbl[bond->params.fail_over_mac].modename); | ||
3168 | 3260 | ||
3169 | seq_printf(seq, "\n"); | 3261 | seq_printf(seq, "\n"); |
3170 | 3262 | ||
@@ -4092,10 +4184,10 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr) | |||
4092 | dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None")); | 4184 | dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None")); |
4093 | 4185 | ||
4094 | /* | 4186 | /* |
4095 | * If fail_over_mac is enabled, do nothing and return success. | 4187 | * If fail_over_mac is set to active, do nothing and return |
4096 | * Returning an error causes ifenslave to fail. | 4188 | * success. Returning an error causes ifenslave to fail. |
4097 | */ | 4189 | */ |
4098 | if (bond->params.fail_over_mac) | 4190 | if (bond->params.fail_over_mac == BOND_FOM_ACTIVE) |
4099 | return 0; | 4191 | return 0; |
4100 | 4192 | ||
4101 | if (!is_valid_ether_addr(sa->sa_data)) { | 4193 | if (!is_valid_ether_addr(sa->sa_data)) { |
@@ -4600,7 +4692,7 @@ int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl) | |||
4600 | 4692 | ||
4601 | static int bond_check_params(struct bond_params *params) | 4693 | static int bond_check_params(struct bond_params *params) |
4602 | { | 4694 | { |
4603 | int arp_validate_value; | 4695 | int arp_validate_value, fail_over_mac_value; |
4604 | 4696 | ||
4605 | /* | 4697 | /* |
4606 | * Convert string parameters. | 4698 | * Convert string parameters. |
@@ -4875,10 +4967,23 @@ static int bond_check_params(struct bond_params *params) | |||
4875 | primary = NULL; | 4967 | primary = NULL; |
4876 | } | 4968 | } |
4877 | 4969 | ||
4878 | if (fail_over_mac && (bond_mode != BOND_MODE_ACTIVEBACKUP)) | 4970 | if (fail_over_mac) { |
4879 | printk(KERN_WARNING DRV_NAME | 4971 | fail_over_mac_value = bond_parse_parm(fail_over_mac, |
4880 | ": Warning: fail_over_mac only affects " | 4972 | fail_over_mac_tbl); |
4881 | "active-backup mode.\n"); | 4973 | if (fail_over_mac_value == -1) { |
4974 | printk(KERN_ERR DRV_NAME | ||
4975 | ": Error: invalid fail_over_mac \"%s\"\n", | ||
4976 | arp_validate == NULL ? "NULL" : arp_validate); | ||
4977 | return -EINVAL; | ||
4978 | } | ||
4979 | |||
4980 | if (bond_mode != BOND_MODE_ACTIVEBACKUP) | ||
4981 | printk(KERN_WARNING DRV_NAME | ||
4982 | ": Warning: fail_over_mac only affects " | ||
4983 | "active-backup mode.\n"); | ||
4984 | } else { | ||
4985 | fail_over_mac_value = BOND_FOM_NONE; | ||
4986 | } | ||
4882 | 4987 | ||
4883 | /* fill params struct with the proper values */ | 4988 | /* fill params struct with the proper values */ |
4884 | params->mode = bond_mode; | 4989 | params->mode = bond_mode; |
@@ -4892,7 +4997,7 @@ static int bond_check_params(struct bond_params *params) | |||
4892 | params->use_carrier = use_carrier; | 4997 | params->use_carrier = use_carrier; |
4893 | params->lacp_fast = lacp_fast; | 4998 | params->lacp_fast = lacp_fast; |
4894 | params->primary[0] = 0; | 4999 | params->primary[0] = 0; |
4895 | params->fail_over_mac = fail_over_mac; | 5000 | params->fail_over_mac = fail_over_mac_value; |
4896 | 5001 | ||
4897 | if (primary) { | 5002 | if (primary) { |
4898 | strncpy(params->primary, primary, IFNAMSIZ); | 5003 | strncpy(params->primary, primary, IFNAMSIZ); |
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); |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 8766b1213690..89fd9963db7a 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -248,6 +248,10 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) | |||
248 | return (struct bonding *)slave->dev->master->priv; | 248 | return (struct bonding *)slave->dev->master->priv; |
249 | } | 249 | } |
250 | 250 | ||
251 | #define BOND_FOM_NONE 0 | ||
252 | #define BOND_FOM_ACTIVE 1 | ||
253 | #define BOND_FOM_FOLLOW 2 | ||
254 | |||
251 | #define BOND_ARP_VALIDATE_NONE 0 | 255 | #define BOND_ARP_VALIDATE_NONE 0 |
252 | #define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE) | 256 | #define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE) |
253 | #define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP) | 257 | #define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP) |