diff options
-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) |