diff options
-rw-r--r-- | drivers/net/bonding/bond_main.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index dea8ce20fea4..dbbea0eec134 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -846,8 +846,10 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, | |||
846 | if (bond->dev->flags & IFF_ALLMULTI) | 846 | if (bond->dev->flags & IFF_ALLMULTI) |
847 | dev_set_allmulti(old_active->dev, -1); | 847 | dev_set_allmulti(old_active->dev, -1); |
848 | 848 | ||
849 | netif_addr_lock_bh(bond->dev); | ||
849 | netdev_for_each_mc_addr(ha, bond->dev) | 850 | netdev_for_each_mc_addr(ha, bond->dev) |
850 | dev_mc_del(old_active->dev, ha->addr); | 851 | dev_mc_del(old_active->dev, ha->addr); |
852 | netif_addr_unlock_bh(bond->dev); | ||
851 | } | 853 | } |
852 | 854 | ||
853 | if (new_active) { | 855 | if (new_active) { |
@@ -858,8 +860,10 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, | |||
858 | if (bond->dev->flags & IFF_ALLMULTI) | 860 | if (bond->dev->flags & IFF_ALLMULTI) |
859 | dev_set_allmulti(new_active->dev, 1); | 861 | dev_set_allmulti(new_active->dev, 1); |
860 | 862 | ||
863 | netif_addr_lock_bh(bond->dev); | ||
861 | netdev_for_each_mc_addr(ha, bond->dev) | 864 | netdev_for_each_mc_addr(ha, bond->dev) |
862 | dev_mc_add(new_active->dev, ha->addr); | 865 | dev_mc_add(new_active->dev, ha->addr); |
866 | netif_addr_unlock_bh(bond->dev); | ||
863 | } | 867 | } |
864 | } | 868 | } |
865 | 869 | ||
@@ -1901,9 +1905,26 @@ err_dest_symlinks: | |||
1901 | bond_destroy_slave_symlinks(bond_dev, slave_dev); | 1905 | bond_destroy_slave_symlinks(bond_dev, slave_dev); |
1902 | 1906 | ||
1903 | err_detach: | 1907 | err_detach: |
1908 | if (!USES_PRIMARY(bond->params.mode)) { | ||
1909 | netif_addr_lock_bh(bond_dev); | ||
1910 | bond_mc_list_flush(bond_dev, slave_dev); | ||
1911 | netif_addr_unlock_bh(bond_dev); | ||
1912 | } | ||
1913 | bond_del_vlans_from_slave(bond, slave_dev); | ||
1904 | write_lock_bh(&bond->lock); | 1914 | write_lock_bh(&bond->lock); |
1905 | bond_detach_slave(bond, new_slave); | 1915 | bond_detach_slave(bond, new_slave); |
1916 | if (bond->primary_slave == new_slave) | ||
1917 | bond->primary_slave = NULL; | ||
1906 | write_unlock_bh(&bond->lock); | 1918 | write_unlock_bh(&bond->lock); |
1919 | if (bond->curr_active_slave == new_slave) { | ||
1920 | read_lock(&bond->lock); | ||
1921 | write_lock_bh(&bond->curr_slave_lock); | ||
1922 | bond_change_active_slave(bond, NULL); | ||
1923 | bond_select_active_slave(bond); | ||
1924 | write_unlock_bh(&bond->curr_slave_lock); | ||
1925 | read_unlock(&bond->lock); | ||
1926 | } | ||
1927 | slave_disable_netpoll(new_slave); | ||
1907 | 1928 | ||
1908 | err_close: | 1929 | err_close: |
1909 | slave_dev->priv_flags &= ~IFF_BONDING; | 1930 | slave_dev->priv_flags &= ~IFF_BONDING; |