diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-15 16:30:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-15 16:30:35 -0400 |
commit | 43d39ae0cf8f891c35e8316948229c7cbffa3994 (patch) | |
tree | c8af6999a9327c8b9bbc7384efe8f52f851ff3d8 /drivers/net/bonding | |
parent | 63bd8c48e04bbbc9cee3d752857914609d8d406f (diff) | |
parent | 84284d3c1d6372bc9ab496607661d230d9c45de4 (diff) |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (35 commits)
xen-netfront: rearrange netfront structure to separate tx and rx
netdev: convert non-obvious instances to use ARRAY_SIZE()
ucc_geth: Fix build break introduced by commit 09f75cd7bf13720738e6a196cc0107ce9a5bd5a0
gianfar: Fix regression caused by new napi interface
gianfar: Cleanup compile warning caused by 0795af57
gianfar: Fix compile regression caused by bea3348e
add new prom.h for AU1x00
update AU1000 get_ethernet_addr()
MIPSsim: General cleanup
Jazzsonic: Fix warning about unused variable.
Remove msic_dcr_read() in axon_msi.c
Use dcr_host_t.base in dcr_unmap()
Add dcr_host_t.base in dcr_read()/dcr_write()
Use dcr_host_t.base in ibm_emac_mal
Update ibm_newemac to use dcr_host_t.base
tehuti: possible leak in bdx_probe
TC35815: Fix build
SAA9730: Fix build
AR7 ethernet
myri10ge: update driver version to 1.3.2-1.287
...
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 207 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 74 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 10 |
3 files changed, 244 insertions, 47 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 64bfec32e2a6..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 | ||
@@ -1096,7 +1099,21 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
1096 | if (new_active) { | 1099 | if (new_active) { |
1097 | bond_set_slave_active_flags(new_active); | 1100 | bond_set_slave_active_flags(new_active); |
1098 | } | 1101 | } |
1099 | bond_send_gratuitous_arp(bond); | 1102 | |
1103 | /* when bonding does not set the slave MAC address, the bond MAC | ||
1104 | * address is the one of the active slave. | ||
1105 | */ | ||
1106 | if (new_active && bond->params.fail_over_mac) | ||
1107 | memcpy(bond->dev->dev_addr, new_active->dev->dev_addr, | ||
1108 | new_active->dev->addr_len); | ||
1109 | if (bond->curr_active_slave && | ||
1110 | test_bit(__LINK_STATE_LINKWATCH_PENDING, | ||
1111 | &bond->curr_active_slave->dev->state)) { | ||
1112 | dprintk("delaying gratuitous arp on %s\n", | ||
1113 | bond->curr_active_slave->dev->name); | ||
1114 | bond->send_grat_arp = 1; | ||
1115 | } else | ||
1116 | bond_send_gratuitous_arp(bond); | ||
1100 | } | 1117 | } |
1101 | } | 1118 | } |
1102 | 1119 | ||
@@ -1217,7 +1234,8 @@ static int bond_compute_features(struct bonding *bond) | |||
1217 | struct slave *slave; | 1234 | struct slave *slave; |
1218 | struct net_device *bond_dev = bond->dev; | 1235 | struct net_device *bond_dev = bond->dev; |
1219 | unsigned long features = bond_dev->features; | 1236 | unsigned long features = bond_dev->features; |
1220 | unsigned short max_hard_header_len = ETH_HLEN; | 1237 | unsigned short max_hard_header_len = max((u16)ETH_HLEN, |
1238 | bond_dev->hard_header_len); | ||
1221 | int i; | 1239 | int i; |
1222 | 1240 | ||
1223 | features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES); | 1241 | features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES); |
@@ -1238,6 +1256,23 @@ static int bond_compute_features(struct bonding *bond) | |||
1238 | return 0; | 1256 | return 0; |
1239 | } | 1257 | } |
1240 | 1258 | ||
1259 | |||
1260 | static void bond_setup_by_slave(struct net_device *bond_dev, | ||
1261 | struct net_device *slave_dev) | ||
1262 | { | ||
1263 | struct bonding *bond = bond_dev->priv; | ||
1264 | |||
1265 | bond_dev->neigh_setup = slave_dev->neigh_setup; | ||
1266 | |||
1267 | bond_dev->type = slave_dev->type; | ||
1268 | bond_dev->hard_header_len = slave_dev->hard_header_len; | ||
1269 | bond_dev->addr_len = slave_dev->addr_len; | ||
1270 | |||
1271 | memcpy(bond_dev->broadcast, slave_dev->broadcast, | ||
1272 | slave_dev->addr_len); | ||
1273 | bond->setup_by_slave = 1; | ||
1274 | } | ||
1275 | |||
1241 | /* enslave device <slave> to bond device <master> */ | 1276 | /* enslave device <slave> to bond device <master> */ |
1242 | int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | 1277 | int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) |
1243 | { | 1278 | { |
@@ -1258,8 +1293,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1258 | 1293 | ||
1259 | /* bond must be initialized by bond_open() before enslaving */ | 1294 | /* bond must be initialized by bond_open() before enslaving */ |
1260 | if (!(bond_dev->flags & IFF_UP)) { | 1295 | if (!(bond_dev->flags & IFF_UP)) { |
1261 | dprintk("Error, master_dev is not up\n"); | 1296 | printk(KERN_WARNING DRV_NAME |
1262 | return -EPERM; | 1297 | " %s: master_dev is not up in bond_enslave\n", |
1298 | bond_dev->name); | ||
1263 | } | 1299 | } |
1264 | 1300 | ||
1265 | /* already enslaved */ | 1301 | /* already enslaved */ |
@@ -1312,14 +1348,42 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1312 | goto err_undo_flags; | 1348 | goto err_undo_flags; |
1313 | } | 1349 | } |
1314 | 1350 | ||
1351 | /* set bonding device ether type by slave - bonding netdevices are | ||
1352 | * created with ether_setup, so when the slave type is not ARPHRD_ETHER | ||
1353 | * there is a need to override some of the type dependent attribs/funcs. | ||
1354 | * | ||
1355 | * bond ether type mutual exclusion - don't allow slaves of dissimilar | ||
1356 | * ether type (eg ARPHRD_ETHER and ARPHRD_INFINIBAND) share the same bond | ||
1357 | */ | ||
1358 | if (bond->slave_cnt == 0) { | ||
1359 | if (slave_dev->type != ARPHRD_ETHER) | ||
1360 | bond_setup_by_slave(bond_dev, slave_dev); | ||
1361 | } else if (bond_dev->type != slave_dev->type) { | ||
1362 | printk(KERN_ERR DRV_NAME ": %s ether type (%d) is different " | ||
1363 | "from other slaves (%d), can not enslave it.\n", | ||
1364 | slave_dev->name, | ||
1365 | slave_dev->type, bond_dev->type); | ||
1366 | res = -EINVAL; | ||
1367 | goto err_undo_flags; | ||
1368 | } | ||
1369 | |||
1315 | if (slave_dev->set_mac_address == NULL) { | 1370 | if (slave_dev->set_mac_address == NULL) { |
1316 | printk(KERN_ERR DRV_NAME | 1371 | if (bond->slave_cnt == 0) { |
1317 | ": %s: Error: The slave device you specified does " | 1372 | printk(KERN_WARNING DRV_NAME |
1318 | "not support setting the MAC address. " | 1373 | ": %s: Warning: The first slave device " |
1319 | "Your kernel likely does not support slave " | 1374 | "specified does not support setting the MAC " |
1320 | "devices.\n", bond_dev->name); | 1375 | "address. Enabling the fail_over_mac option.", |
1321 | res = -EOPNOTSUPP; | 1376 | bond_dev->name); |
1322 | goto err_undo_flags; | 1377 | bond->params.fail_over_mac = 1; |
1378 | } else if (!bond->params.fail_over_mac) { | ||
1379 | printk(KERN_ERR DRV_NAME | ||
1380 | ": %s: Error: The slave device specified " | ||
1381 | "does not support setting the MAC address, " | ||
1382 | "but fail_over_mac is not enabled.\n" | ||
1383 | , bond_dev->name); | ||
1384 | res = -EOPNOTSUPP; | ||
1385 | goto err_undo_flags; | ||
1386 | } | ||
1323 | } | 1387 | } |
1324 | 1388 | ||
1325 | new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); | 1389 | new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); |
@@ -1340,16 +1404,18 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1340 | */ | 1404 | */ |
1341 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); | 1405 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); |
1342 | 1406 | ||
1343 | /* | 1407 | if (!bond->params.fail_over_mac) { |
1344 | * Set slave to master's mac address. The application already | 1408 | /* |
1345 | * set the master's mac address to that of the first slave | 1409 | * Set slave to master's mac address. The application already |
1346 | */ | 1410 | * set the master's mac address to that of the first slave |
1347 | memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len); | 1411 | */ |
1348 | addr.sa_family = slave_dev->type; | 1412 | memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len); |
1349 | res = dev_set_mac_address(slave_dev, &addr); | 1413 | addr.sa_family = slave_dev->type; |
1350 | if (res) { | 1414 | res = dev_set_mac_address(slave_dev, &addr); |
1351 | dprintk("Error %d calling set_mac_address\n", res); | 1415 | if (res) { |
1352 | goto err_free; | 1416 | dprintk("Error %d calling set_mac_address\n", res); |
1417 | goto err_free; | ||
1418 | } | ||
1353 | } | 1419 | } |
1354 | 1420 | ||
1355 | res = netdev_set_master(slave_dev, bond_dev); | 1421 | res = netdev_set_master(slave_dev, bond_dev); |
@@ -1574,9 +1640,11 @@ err_close: | |||
1574 | dev_close(slave_dev); | 1640 | dev_close(slave_dev); |
1575 | 1641 | ||
1576 | err_restore_mac: | 1642 | err_restore_mac: |
1577 | memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); | 1643 | if (!bond->params.fail_over_mac) { |
1578 | addr.sa_family = slave_dev->type; | 1644 | memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); |
1579 | dev_set_mac_address(slave_dev, &addr); | 1645 | addr.sa_family = slave_dev->type; |
1646 | dev_set_mac_address(slave_dev, &addr); | ||
1647 | } | ||
1580 | 1648 | ||
1581 | err_free: | 1649 | err_free: |
1582 | kfree(new_slave); | 1650 | kfree(new_slave); |
@@ -1749,10 +1817,12 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1749 | /* close slave before restoring its mac address */ | 1817 | /* close slave before restoring its mac address */ |
1750 | dev_close(slave_dev); | 1818 | dev_close(slave_dev); |
1751 | 1819 | ||
1752 | /* restore original ("permanent") mac address */ | 1820 | if (!bond->params.fail_over_mac) { |
1753 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 1821 | /* restore original ("permanent") mac address */ |
1754 | addr.sa_family = slave_dev->type; | 1822 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
1755 | dev_set_mac_address(slave_dev, &addr); | 1823 | addr.sa_family = slave_dev->type; |
1824 | dev_set_mac_address(slave_dev, &addr); | ||
1825 | } | ||
1756 | 1826 | ||
1757 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | | 1827 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | |
1758 | IFF_SLAVE_INACTIVE | IFF_BONDING | | 1828 | IFF_SLAVE_INACTIVE | IFF_BONDING | |
@@ -1764,6 +1834,35 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1764 | } | 1834 | } |
1765 | 1835 | ||
1766 | /* | 1836 | /* |
1837 | * Destroy a bonding device. | ||
1838 | * Must be under rtnl_lock when this function is called. | ||
1839 | */ | ||
1840 | void bond_destroy(struct bonding *bond) | ||
1841 | { | ||
1842 | bond_deinit(bond->dev); | ||
1843 | bond_destroy_sysfs_entry(bond); | ||
1844 | unregister_netdevice(bond->dev); | ||
1845 | } | ||
1846 | |||
1847 | /* | ||
1848 | * First release a slave and than destroy the bond if no more slaves iare left. | ||
1849 | * Must be under rtnl_lock when this function is called. | ||
1850 | */ | ||
1851 | int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev) | ||
1852 | { | ||
1853 | struct bonding *bond = bond_dev->priv; | ||
1854 | int ret; | ||
1855 | |||
1856 | ret = bond_release(bond_dev, slave_dev); | ||
1857 | if ((ret == 0) && (bond->slave_cnt == 0)) { | ||
1858 | printk(KERN_INFO DRV_NAME ": %s: destroying bond %s.\n", | ||
1859 | bond_dev->name, bond_dev->name); | ||
1860 | bond_destroy(bond); | ||
1861 | } | ||
1862 | return ret; | ||
1863 | } | ||
1864 | |||
1865 | /* | ||
1767 | * This function releases all slaves. | 1866 | * This function releases all slaves. |
1768 | */ | 1867 | */ |
1769 | static int bond_release_all(struct net_device *bond_dev) | 1868 | static int bond_release_all(struct net_device *bond_dev) |
@@ -1839,10 +1938,12 @@ static int bond_release_all(struct net_device *bond_dev) | |||
1839 | /* close slave before restoring its mac address */ | 1938 | /* close slave before restoring its mac address */ |
1840 | dev_close(slave_dev); | 1939 | dev_close(slave_dev); |
1841 | 1940 | ||
1842 | /* restore original ("permanent") mac address*/ | 1941 | if (!bond->params.fail_over_mac) { |
1843 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 1942 | /* restore original ("permanent") mac address*/ |
1844 | addr.sa_family = slave_dev->type; | 1943 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
1845 | dev_set_mac_address(slave_dev, &addr); | 1944 | addr.sa_family = slave_dev->type; |
1945 | dev_set_mac_address(slave_dev, &addr); | ||
1946 | } | ||
1846 | 1947 | ||
1847 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | | 1948 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | |
1848 | IFF_SLAVE_INACTIVE); | 1949 | IFF_SLAVE_INACTIVE); |
@@ -2013,6 +2114,17 @@ void bond_mii_monitor(struct net_device *bond_dev) | |||
2013 | * program could monitor the link itself if needed. | 2114 | * program could monitor the link itself if needed. |
2014 | */ | 2115 | */ |
2015 | 2116 | ||
2117 | if (bond->send_grat_arp) { | ||
2118 | if (bond->curr_active_slave && test_bit(__LINK_STATE_LINKWATCH_PENDING, | ||
2119 | &bond->curr_active_slave->dev->state)) | ||
2120 | dprintk("Needs to send gratuitous arp but not yet\n"); | ||
2121 | else { | ||
2122 | dprintk("sending delayed gratuitous arp on on %s\n", | ||
2123 | bond->curr_active_slave->dev->name); | ||
2124 | bond_send_gratuitous_arp(bond); | ||
2125 | bond->send_grat_arp = 0; | ||
2126 | } | ||
2127 | } | ||
2016 | read_lock(&bond->curr_slave_lock); | 2128 | read_lock(&bond->curr_slave_lock); |
2017 | oldcurrent = bond->curr_active_slave; | 2129 | oldcurrent = bond->curr_active_slave; |
2018 | read_unlock(&bond->curr_slave_lock); | 2130 | read_unlock(&bond->curr_slave_lock); |
@@ -2414,7 +2526,7 @@ static void bond_send_gratuitous_arp(struct bonding *bond) | |||
2414 | 2526 | ||
2415 | if (bond->master_ip) { | 2527 | if (bond->master_ip) { |
2416 | bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip, | 2528 | bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip, |
2417 | bond->master_ip, 0); | 2529 | bond->master_ip, 0); |
2418 | } | 2530 | } |
2419 | 2531 | ||
2420 | list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { | 2532 | list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { |
@@ -2951,9 +3063,15 @@ static void bond_info_show_master(struct seq_file *seq) | |||
2951 | curr = bond->curr_active_slave; | 3063 | curr = bond->curr_active_slave; |
2952 | read_unlock(&bond->curr_slave_lock); | 3064 | read_unlock(&bond->curr_slave_lock); |
2953 | 3065 | ||
2954 | seq_printf(seq, "Bonding Mode: %s\n", | 3066 | seq_printf(seq, "Bonding Mode: %s", |
2955 | bond_mode_name(bond->params.mode)); | 3067 | bond_mode_name(bond->params.mode)); |
2956 | 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 | |||
2957 | if (bond->params.mode == BOND_MODE_XOR || | 3075 | if (bond->params.mode == BOND_MODE_XOR || |
2958 | bond->params.mode == BOND_MODE_8023AD) { | 3076 | bond->params.mode == BOND_MODE_8023AD) { |
2959 | seq_printf(seq, "Transmit Hash Policy: %s (%d)\n", | 3077 | seq_printf(seq, "Transmit Hash Policy: %s (%d)\n", |
@@ -3248,6 +3366,11 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave | |||
3248 | * ... Or is it this? | 3366 | * ... Or is it this? |
3249 | */ | 3367 | */ |
3250 | break; | 3368 | break; |
3369 | case NETDEV_GOING_DOWN: | ||
3370 | dprintk("slave %s is going down\n", slave_dev->name); | ||
3371 | if (bond->setup_by_slave) | ||
3372 | bond_release_and_destroy(bond_dev, slave_dev); | ||
3373 | break; | ||
3251 | case NETDEV_CHANGEMTU: | 3374 | case NETDEV_CHANGEMTU: |
3252 | /* | 3375 | /* |
3253 | * TODO: Should slaves be allowed to | 3376 | * TODO: Should slaves be allowed to |
@@ -3880,6 +4003,13 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr) | |||
3880 | 4003 | ||
3881 | 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")); |
3882 | 4005 | ||
4006 | /* | ||
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; | ||
4012 | |||
3883 | if (!is_valid_ether_addr(sa->sa_data)) { | 4013 | if (!is_valid_ether_addr(sa->sa_data)) { |
3884 | return -EADDRNOTAVAIL; | 4014 | return -EADDRNOTAVAIL; |
3885 | } | 4015 | } |
@@ -4217,6 +4347,8 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) | |||
4217 | bond->current_arp_slave = NULL; | 4347 | bond->current_arp_slave = NULL; |
4218 | bond->primary_slave = NULL; | 4348 | bond->primary_slave = NULL; |
4219 | bond->dev = bond_dev; | 4349 | bond->dev = bond_dev; |
4350 | bond->send_grat_arp = 0; | ||
4351 | bond->setup_by_slave = 0; | ||
4220 | INIT_LIST_HEAD(&bond->vlan_list); | 4352 | INIT_LIST_HEAD(&bond->vlan_list); |
4221 | 4353 | ||
4222 | /* Initialize the device entry points */ | 4354 | /* Initialize the device entry points */ |
@@ -4265,7 +4397,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) | |||
4265 | #ifdef CONFIG_PROC_FS | 4397 | #ifdef CONFIG_PROC_FS |
4266 | bond_create_proc_entry(bond); | 4398 | bond_create_proc_entry(bond); |
4267 | #endif | 4399 | #endif |
4268 | |||
4269 | list_add_tail(&bond->bond_list, &bond_dev_list); | 4400 | list_add_tail(&bond->bond_list, &bond_dev_list); |
4270 | 4401 | ||
4271 | return 0; | 4402 | return 0; |
@@ -4599,6 +4730,11 @@ static int bond_check_params(struct bond_params *params) | |||
4599 | primary = NULL; | 4730 | primary = NULL; |
4600 | } | 4731 | } |
4601 | 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 | |||
4602 | /* fill params struct with the proper values */ | 4738 | /* fill params struct with the proper values */ |
4603 | params->mode = bond_mode; | 4739 | params->mode = bond_mode; |
4604 | params->xmit_policy = xmit_hashtype; | 4740 | params->xmit_policy = xmit_hashtype; |
@@ -4610,6 +4746,7 @@ static int bond_check_params(struct bond_params *params) | |||
4610 | params->use_carrier = use_carrier; | 4746 | params->use_carrier = use_carrier; |
4611 | params->lacp_fast = lacp_fast; | 4747 | params->lacp_fast = lacp_fast; |
4612 | params->primary[0] = 0; | 4748 | params->primary[0] = 0; |
4749 | params->fail_over_mac = fail_over_mac; | ||
4613 | 4750 | ||
4614 | if (primary) { | 4751 | if (primary) { |
4615 | 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 6f49ca7e9b66..80c0c8c415ed 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -164,9 +164,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t | |||
164 | printk(KERN_INFO DRV_NAME | 164 | printk(KERN_INFO DRV_NAME |
165 | ": %s is being deleted...\n", | 165 | ": %s is being deleted...\n", |
166 | bond->dev->name); | 166 | bond->dev->name); |
167 | bond_deinit(bond->dev); | 167 | bond_destroy(bond); |
168 | bond_destroy_sysfs_entry(bond); | ||
169 | unregister_netdevice(bond->dev); | ||
170 | rtnl_unlock(); | 168 | rtnl_unlock(); |
171 | goto out; | 169 | goto out; |
172 | } | 170 | } |
@@ -260,17 +258,16 @@ static ssize_t bonding_store_slaves(struct device *d, | |||
260 | char command[IFNAMSIZ + 1] = { 0, }; | 258 | char command[IFNAMSIZ + 1] = { 0, }; |
261 | char *ifname; | 259 | char *ifname; |
262 | int i, res, found, ret = count; | 260 | int i, res, found, ret = count; |
261 | u32 original_mtu; | ||
263 | struct slave *slave; | 262 | struct slave *slave; |
264 | struct net_device *dev = NULL; | 263 | struct net_device *dev = NULL; |
265 | struct bonding *bond = to_bond(d); | 264 | struct bonding *bond = to_bond(d); |
266 | 265 | ||
267 | /* Quick sanity check -- is the bond interface up? */ | 266 | /* Quick sanity check -- is the bond interface up? */ |
268 | if (!(bond->dev->flags & IFF_UP)) { | 267 | if (!(bond->dev->flags & IFF_UP)) { |
269 | printk(KERN_ERR DRV_NAME | 268 | printk(KERN_WARNING DRV_NAME |
270 | ": %s: Unable to update slaves because interface is down.\n", | 269 | ": %s: doing slave updates when interface is down.\n", |
271 | bond->dev->name); | 270 | bond->dev->name); |
272 | ret = -EPERM; | ||
273 | goto out; | ||
274 | } | 271 | } |
275 | 272 | ||
276 | /* Note: We can't hold bond->lock here, as bond_create grabs it. */ | 273 | /* Note: We can't hold bond->lock here, as bond_create grabs it. */ |
@@ -327,6 +324,7 @@ static ssize_t bonding_store_slaves(struct device *d, | |||
327 | } | 324 | } |
328 | 325 | ||
329 | /* Set the slave's MTU to match the bond */ | 326 | /* Set the slave's MTU to match the bond */ |
327 | original_mtu = dev->mtu; | ||
330 | if (dev->mtu != bond->dev->mtu) { | 328 | if (dev->mtu != bond->dev->mtu) { |
331 | if (dev->change_mtu) { | 329 | if (dev->change_mtu) { |
332 | res = dev->change_mtu(dev, | 330 | res = dev->change_mtu(dev, |
@@ -341,6 +339,9 @@ static ssize_t bonding_store_slaves(struct device *d, | |||
341 | } | 339 | } |
342 | rtnl_lock(); | 340 | rtnl_lock(); |
343 | res = bond_enslave(bond->dev, dev); | 341 | res = bond_enslave(bond->dev, dev); |
342 | bond_for_each_slave(bond, slave, i) | ||
343 | if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) | ||
344 | slave->original_mtu = original_mtu; | ||
344 | rtnl_unlock(); | 345 | rtnl_unlock(); |
345 | if (res) { | 346 | if (res) { |
346 | ret = res; | 347 | ret = res; |
@@ -353,13 +354,17 @@ static ssize_t bonding_store_slaves(struct device *d, | |||
353 | bond_for_each_slave(bond, slave, i) | 354 | bond_for_each_slave(bond, slave, i) |
354 | if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { | 355 | if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { |
355 | dev = slave->dev; | 356 | dev = slave->dev; |
357 | original_mtu = slave->original_mtu; | ||
356 | break; | 358 | break; |
357 | } | 359 | } |
358 | if (dev) { | 360 | if (dev) { |
359 | printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n", | 361 | printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n", |
360 | bond->dev->name, dev->name); | 362 | bond->dev->name, dev->name); |
361 | rtnl_lock(); | 363 | rtnl_lock(); |
362 | res = bond_release(bond->dev, dev); | 364 | if (bond->setup_by_slave) |
365 | res = bond_release_and_destroy(bond->dev, dev); | ||
366 | else | ||
367 | res = bond_release(bond->dev, dev); | ||
363 | rtnl_unlock(); | 368 | rtnl_unlock(); |
364 | if (res) { | 369 | if (res) { |
365 | ret = res; | 370 | ret = res; |
@@ -367,9 +372,9 @@ static ssize_t bonding_store_slaves(struct device *d, | |||
367 | } | 372 | } |
368 | /* set the slave MTU to the default */ | 373 | /* set the slave MTU to the default */ |
369 | if (dev->change_mtu) { | 374 | if (dev->change_mtu) { |
370 | dev->change_mtu(dev, 1500); | 375 | dev->change_mtu(dev, original_mtu); |
371 | } else { | 376 | } else { |
372 | dev->mtu = 1500; | 377 | dev->mtu = original_mtu; |
373 | } | 378 | } |
374 | } | 379 | } |
375 | else { | 380 | else { |
@@ -563,6 +568,54 @@ static ssize_t bonding_store_arp_validate(struct device *d, | |||
563 | 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); |
564 | 569 | ||
565 | /* | 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 | /* | ||
566 | * 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 |
567 | * here. First, if ARP monitoring is activated, then we must disable | 620 | * here. First, if ARP monitoring is activated, then we must disable |
568 | * 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 |
@@ -1383,6 +1436,7 @@ static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL); | |||
1383 | static struct attribute *per_bond_attrs[] = { | 1436 | static struct attribute *per_bond_attrs[] = { |
1384 | &dev_attr_slaves.attr, | 1437 | &dev_attr_slaves.attr, |
1385 | &dev_attr_mode.attr, | 1438 | &dev_attr_mode.attr, |
1439 | &dev_attr_fail_over_mac.attr, | ||
1386 | &dev_attr_arp_validate.attr, | 1440 | &dev_attr_arp_validate.attr, |
1387 | &dev_attr_arp_interval.attr, | 1441 | &dev_attr_arp_interval.attr, |
1388 | &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 2a6af7d23728..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; |
@@ -156,6 +157,7 @@ struct slave { | |||
156 | s8 link; /* one of BOND_LINK_XXXX */ | 157 | s8 link; /* one of BOND_LINK_XXXX */ |
157 | s8 state; /* one of BOND_STATE_XXXX */ | 158 | s8 state; /* one of BOND_STATE_XXXX */ |
158 | u32 original_flags; | 159 | u32 original_flags; |
160 | u32 original_mtu; | ||
159 | u32 link_failure_count; | 161 | u32 link_failure_count; |
160 | u16 speed; | 162 | u16 speed; |
161 | u8 duplex; | 163 | u8 duplex; |
@@ -185,6 +187,8 @@ struct bonding { | |||
185 | struct timer_list mii_timer; | 187 | struct timer_list mii_timer; |
186 | struct timer_list arp_timer; | 188 | struct timer_list arp_timer; |
187 | s8 kill_timers; | 189 | s8 kill_timers; |
190 | s8 send_grat_arp; | ||
191 | s8 setup_by_slave; | ||
188 | struct net_device_stats stats; | 192 | struct net_device_stats stats; |
189 | #ifdef CONFIG_PROC_FS | 193 | #ifdef CONFIG_PROC_FS |
190 | struct proc_dir_entry *proc_entry; | 194 | struct proc_dir_entry *proc_entry; |
@@ -292,6 +296,8 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond) | |||
292 | struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); | 296 | struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); |
293 | int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); | 297 | int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); |
294 | int bond_create(char *name, struct bond_params *params, struct bonding **newbond); | 298 | int bond_create(char *name, struct bond_params *params, struct bonding **newbond); |
299 | void bond_destroy(struct bonding *bond); | ||
300 | int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev); | ||
295 | void bond_deinit(struct net_device *bond_dev); | 301 | void bond_deinit(struct net_device *bond_dev); |
296 | int bond_create_sysfs(void); | 302 | int bond_create_sysfs(void); |
297 | void bond_destroy_sysfs(void); | 303 | void bond_destroy_sysfs(void); |