aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2007-07-09 13:42:47 -0400
committerJeff Garzik <jeff@garzik.org>2007-07-10 12:41:19 -0400
commitc2edacf80e155ef54ae4774379d461b60896bc2e (patch)
tree0ec119a16bc4af036968cf22cde402c381efca25
parent89c0d26be7037cd5bbce3bbf12580ba70ed8f382 (diff)
bonding / ipv6: no addrconf for slaves separately from master
At present, when a device is enslaved to bonding, if ipv6 is active then addrconf will be initated on the slave (because it is closed then opened during the enslavement processing). This causes DAD and RS packets to be sent from the slave. These packets in turn can confuse switches that perform ipv6 snooping, causing them to incorrectly update their forwarding tables (if, e.g., the slave being added is an inactve backup that won't be used right away) and direct traffic away from the active slave to a backup slave (where the incoming packets will be dropped). This patch alters the behavior so that addrconf will only run on the master device itself. I believe this is logically correct, as it prevents slaves from having an IPv6 identity independent from the master. This is consistent with the IPv4 behavior for bonding. This is accomplished by (a) having bonding set IFF_SLAVE sooner in the enslavement processing than currently occurs (before open, not after), and (b) having ipv6 addrconf ignore UP and CHANGE events on slave devices. The eql driver also uses the IFF_SLAVE flag. I inspected eql, and I believe this change is reasonable for its usage of IFF_SLAVE, but I did not test it. Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/bonding/bond_main.c11
-rw-r--r--net/ipv6/addrconf.c3
2 files changed, 8 insertions, 6 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6287ffbda7f7..2bb70e052090 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1390,6 +1390,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1390 goto err_free; 1390 goto err_free;
1391 } 1391 }
1392 1392
1393 res = netdev_set_master(slave_dev, bond_dev);
1394 if (res) {
1395 dprintk("Error %d calling netdev_set_master\n", res);
1396 goto err_close;
1397 }
1393 /* open the slave since the application closed it */ 1398 /* open the slave since the application closed it */
1394 res = dev_open(slave_dev); 1399 res = dev_open(slave_dev);
1395 if (res) { 1400 if (res) {
@@ -1397,12 +1402,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1397 goto err_restore_mac; 1402 goto err_restore_mac;
1398 } 1403 }
1399 1404
1400 res = netdev_set_master(slave_dev, bond_dev);
1401 if (res) {
1402 dprintk("Error %d calling netdev_set_master\n", res);
1403 goto err_close;
1404 }
1405
1406 new_slave->dev = slave_dev; 1405 new_slave->dev = slave_dev;
1407 slave_dev->priv_flags |= IFF_BONDING; 1406 slave_dev->priv_flags |= IFF_BONDING;
1408 1407
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f96ed76d8fa4..79b79f3de24c 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2268,6 +2268,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
2268 break; 2268 break;
2269 case NETDEV_UP: 2269 case NETDEV_UP:
2270 case NETDEV_CHANGE: 2270 case NETDEV_CHANGE:
2271 if (dev->flags & IFF_SLAVE)
2272 break;
2273
2271 if (event == NETDEV_UP) { 2274 if (event == NETDEV_UP) {
2272 if (!netif_carrier_ok(dev)) { 2275 if (!netif_carrier_ok(dev)) {
2273 /* device is not ready yet. */ 2276 /* device is not ready yet. */