diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 87 |
1 files changed, 59 insertions, 28 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6ae45931d1b2..6508e0b2ea72 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1096,6 +1096,14 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
1096 | if (new_active) { | 1096 | if (new_active) { |
1097 | bond_set_slave_active_flags(new_active); | 1097 | bond_set_slave_active_flags(new_active); |
1098 | } | 1098 | } |
1099 | |||
1100 | /* when bonding does not set the slave MAC address, the bond MAC | ||
1101 | * address is the one of the active slave. | ||
1102 | */ | ||
1103 | if (new_active && !bond->do_set_mac_addr) | ||
1104 | memcpy(bond->dev->dev_addr, new_active->dev->dev_addr, | ||
1105 | new_active->dev->addr_len); | ||
1106 | |||
1099 | bond_send_gratuitous_arp(bond); | 1107 | bond_send_gratuitous_arp(bond); |
1100 | } | 1108 | } |
1101 | } | 1109 | } |
@@ -1346,13 +1354,22 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1346 | } | 1354 | } |
1347 | 1355 | ||
1348 | if (slave_dev->set_mac_address == NULL) { | 1356 | if (slave_dev->set_mac_address == NULL) { |
1349 | printk(KERN_ERR DRV_NAME | 1357 | if (bond->slave_cnt == 0) { |
1350 | ": %s: Error: The slave device you specified does " | 1358 | printk(KERN_WARNING DRV_NAME |
1351 | "not support setting the MAC address. " | 1359 | ": %s: Warning: The first slave device you " |
1352 | "Your kernel likely does not support slave " | 1360 | "specified does not support setting the MAC " |
1353 | "devices.\n", bond_dev->name); | 1361 | "address. This bond MAC address would be that " |
1354 | res = -EOPNOTSUPP; | 1362 | "of the active slave.\n", bond_dev->name); |
1355 | goto err_undo_flags; | 1363 | bond->do_set_mac_addr = 0; |
1364 | } else if (bond->do_set_mac_addr) { | ||
1365 | printk(KERN_ERR DRV_NAME | ||
1366 | ": %s: Error: The slave device you specified " | ||
1367 | "does not support setting the MAC addres,." | ||
1368 | "but this bond uses this practice. \n" | ||
1369 | , bond_dev->name); | ||
1370 | res = -EOPNOTSUPP; | ||
1371 | goto err_undo_flags; | ||
1372 | } | ||
1356 | } | 1373 | } |
1357 | 1374 | ||
1358 | new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); | 1375 | new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); |
@@ -1373,16 +1390,18 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1373 | */ | 1390 | */ |
1374 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); | 1391 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); |
1375 | 1392 | ||
1376 | /* | 1393 | if (bond->do_set_mac_addr) { |
1377 | * Set slave to master's mac address. The application already | 1394 | /* |
1378 | * set the master's mac address to that of the first slave | 1395 | * Set slave to master's mac address. The application already |
1379 | */ | 1396 | * set the master's mac address to that of the first slave |
1380 | memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len); | 1397 | */ |
1381 | addr.sa_family = slave_dev->type; | 1398 | memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len); |
1382 | res = dev_set_mac_address(slave_dev, &addr); | 1399 | addr.sa_family = slave_dev->type; |
1383 | if (res) { | 1400 | res = dev_set_mac_address(slave_dev, &addr); |
1384 | dprintk("Error %d calling set_mac_address\n", res); | 1401 | if (res) { |
1385 | goto err_free; | 1402 | dprintk("Error %d calling set_mac_address\n", res); |
1403 | goto err_free; | ||
1404 | } | ||
1386 | } | 1405 | } |
1387 | 1406 | ||
1388 | res = netdev_set_master(slave_dev, bond_dev); | 1407 | res = netdev_set_master(slave_dev, bond_dev); |
@@ -1607,9 +1626,11 @@ err_close: | |||
1607 | dev_close(slave_dev); | 1626 | dev_close(slave_dev); |
1608 | 1627 | ||
1609 | err_restore_mac: | 1628 | err_restore_mac: |
1610 | memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); | 1629 | if (bond->do_set_mac_addr) { |
1611 | addr.sa_family = slave_dev->type; | 1630 | memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); |
1612 | dev_set_mac_address(slave_dev, &addr); | 1631 | addr.sa_family = slave_dev->type; |
1632 | dev_set_mac_address(slave_dev, &addr); | ||
1633 | } | ||
1613 | 1634 | ||
1614 | err_free: | 1635 | err_free: |
1615 | kfree(new_slave); | 1636 | kfree(new_slave); |
@@ -1782,10 +1803,12 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1782 | /* close slave before restoring its mac address */ | 1803 | /* close slave before restoring its mac address */ |
1783 | dev_close(slave_dev); | 1804 | dev_close(slave_dev); |
1784 | 1805 | ||
1785 | /* restore original ("permanent") mac address */ | 1806 | if (bond->do_set_mac_addr) { |
1786 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 1807 | /* restore original ("permanent") mac address */ |
1787 | addr.sa_family = slave_dev->type; | 1808 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
1788 | dev_set_mac_address(slave_dev, &addr); | 1809 | addr.sa_family = slave_dev->type; |
1810 | dev_set_mac_address(slave_dev, &addr); | ||
1811 | } | ||
1789 | 1812 | ||
1790 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | | 1813 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | |
1791 | IFF_SLAVE_INACTIVE | IFF_BONDING | | 1814 | IFF_SLAVE_INACTIVE | IFF_BONDING | |
@@ -1872,10 +1895,12 @@ static int bond_release_all(struct net_device *bond_dev) | |||
1872 | /* close slave before restoring its mac address */ | 1895 | /* close slave before restoring its mac address */ |
1873 | dev_close(slave_dev); | 1896 | dev_close(slave_dev); |
1874 | 1897 | ||
1875 | /* restore original ("permanent") mac address*/ | 1898 | if (bond->do_set_mac_addr) { |
1876 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 1899 | /* restore original ("permanent") mac address*/ |
1877 | addr.sa_family = slave_dev->type; | 1900 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
1878 | dev_set_mac_address(slave_dev, &addr); | 1901 | addr.sa_family = slave_dev->type; |
1902 | dev_set_mac_address(slave_dev, &addr); | ||
1903 | } | ||
1879 | 1904 | ||
1880 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | | 1905 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | |
1881 | IFF_SLAVE_INACTIVE); | 1906 | IFF_SLAVE_INACTIVE); |
@@ -3913,6 +3938,9 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr) | |||
3913 | 3938 | ||
3914 | dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None")); | 3939 | dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None")); |
3915 | 3940 | ||
3941 | if (!bond->do_set_mac_addr) | ||
3942 | return -EOPNOTSUPP; | ||
3943 | |||
3916 | if (!is_valid_ether_addr(sa->sa_data)) { | 3944 | if (!is_valid_ether_addr(sa->sa_data)) { |
3917 | return -EADDRNOTAVAIL; | 3945 | return -EADDRNOTAVAIL; |
3918 | } | 3946 | } |
@@ -4299,6 +4327,9 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) | |||
4299 | bond_create_proc_entry(bond); | 4327 | bond_create_proc_entry(bond); |
4300 | #endif | 4328 | #endif |
4301 | 4329 | ||
4330 | /* set do_set_mac_addr to true on startup */ | ||
4331 | bond->do_set_mac_addr = 1; | ||
4332 | |||
4302 | list_add_tail(&bond->bond_list, &bond_dev_list); | 4333 | list_add_tail(&bond->bond_list, &bond_dev_list); |
4303 | 4334 | ||
4304 | return 0; | 4335 | return 0; |