aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMoni Shoua <monis@voltaire.com>2007-10-09 22:43:39 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-15 14:20:46 -0400
commit2ab82852a2706b47c257ac87675ab8b06bc214dd (patch)
treefa8174d8179d3b43f98aff04855f1bc241ba13e2 /drivers/net
parent872254dd6b1f80cb95ee9e2e22980888533fc293 (diff)
net/bonding: Enable bonding to enslave netdevices not supporting set_mac_address()
This patch allows for enslaving netdevices which do not support the set_mac_address() function. In that case the bond mac address is the one of the active slave, where remote peers are notified on the mac address (neighbour) change by Gratuitous ARP sent by bonding when fail-over occurs (this is already done by the bonding code). Signed-off-by: Moni Shoua <monis at voltaire.com> Signed-off-by: Or Gerlitz <ogerlitz at voltaire.com> Acked-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bonding/bond_main.c87
-rw-r--r--drivers/net/bonding/bonding.h1
2 files changed, 60 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
1609err_restore_mac: 1628err_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
1614err_free: 1635err_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;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 2a6af7d23728..5011ba9e4661 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -185,6 +185,7 @@ struct bonding {
185 struct timer_list mii_timer; 185 struct timer_list mii_timer;
186 struct timer_list arp_timer; 186 struct timer_list arp_timer;
187 s8 kill_timers; 187 s8 kill_timers;
188 s8 do_set_mac_addr;
188 struct net_device_stats stats; 189 struct net_device_stats stats;
189#ifdef CONFIG_PROC_FS 190#ifdef CONFIG_PROC_FS
190 struct proc_dir_entry *proc_entry; 191 struct proc_dir_entry *proc_entry;