Skip to content

Commit

Permalink
Merge branch 'bonding'
Browse files Browse the repository at this point in the history
Nikolay Aleksandrov says:

====================
This patch-set fixes mainly bugs on enslave failure and one occasion
of a needed locking. The patches are:

	1. On enslave failure mc addresses are not flushed from the slave
	2. On enslave failure vlans are not cleaned up from the slave
	3. On enslave failure the bond's primary and curr_active_slave
	   are not cleaned up (which might result in use of freed memory)
	4. On enslave failure netpoll is not disabled which might result in
	   a memory leak
	5. In bond_mc_swap() the bond's mc addr list is walked without
	   netif_addr_lock, since it can be called without rtnl, add it

v2: patch 01 - fix log message and remove unnecessary code move
====================

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 19, 2013
2 parents cb95ec6 + d632ce9 commit 0cb670e
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -846,8 +846,10 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
if (bond->dev->flags & IFF_ALLMULTI)
dev_set_allmulti(old_active->dev, -1);

netif_addr_lock_bh(bond->dev);
netdev_for_each_mc_addr(ha, bond->dev)
dev_mc_del(old_active->dev, ha->addr);
netif_addr_unlock_bh(bond->dev);
}

if (new_active) {
Expand All @@ -858,8 +860,10 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
if (bond->dev->flags & IFF_ALLMULTI)
dev_set_allmulti(new_active->dev, 1);

netif_addr_lock_bh(bond->dev);
netdev_for_each_mc_addr(ha, bond->dev)
dev_mc_add(new_active->dev, ha->addr);
netif_addr_unlock_bh(bond->dev);
}
}

Expand Down Expand Up @@ -1901,9 +1905,26 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
bond_destroy_slave_symlinks(bond_dev, slave_dev);

err_detach:
if (!USES_PRIMARY(bond->params.mode)) {
netif_addr_lock_bh(bond_dev);
bond_mc_list_flush(bond_dev, slave_dev);
netif_addr_unlock_bh(bond_dev);
}
bond_del_vlans_from_slave(bond, slave_dev);
write_lock_bh(&bond->lock);
bond_detach_slave(bond, new_slave);
if (bond->primary_slave == new_slave)
bond->primary_slave = NULL;
write_unlock_bh(&bond->lock);
if (bond->curr_active_slave == new_slave) {
read_lock(&bond->lock);
write_lock_bh(&bond->curr_slave_lock);
bond_change_active_slave(bond, NULL);
bond_select_active_slave(bond);
write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock);
}
slave_disable_netpoll(new_slave);

err_close:
slave_dev->priv_flags &= ~IFF_BONDING;
Expand Down

0 comments on commit 0cb670e

Please sign in to comment.