|
@@ -715,15 +715,6 @@ static int bond_set_allmulti(struct bonding *bond, int inc)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-static void __bond_resend_igmp_join_requests(struct net_device *dev)
|
|
|
-{
|
|
|
- struct in_device *in_dev;
|
|
|
-
|
|
|
- in_dev = __in_dev_get_rcu(dev);
|
|
|
- if (in_dev)
|
|
|
- ip_mc_rejoin_groups(in_dev);
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* Retrieve the list of registered multicast addresses for the bonding
|
|
|
* device and retransmit an IGMP JOIN request to the current active
|
|
@@ -731,33 +722,12 @@ static void __bond_resend_igmp_join_requests(struct net_device *dev)
|
|
|
*/
|
|
|
static void bond_resend_igmp_join_requests(struct bonding *bond)
|
|
|
{
|
|
|
- struct net_device *bond_dev, *vlan_dev, *upper_dev;
|
|
|
- struct vlan_entry *vlan;
|
|
|
-
|
|
|
- read_lock(&bond->lock);
|
|
|
- rcu_read_lock();
|
|
|
-
|
|
|
- bond_dev = bond->dev;
|
|
|
-
|
|
|
- /* rejoin all groups on bond device */
|
|
|
- __bond_resend_igmp_join_requests(bond_dev);
|
|
|
-
|
|
|
- /*
|
|
|
- * if bond is enslaved to a bridge,
|
|
|
- * then rejoin all groups on its master
|
|
|
- */
|
|
|
- upper_dev = netdev_master_upper_dev_get_rcu(bond_dev);
|
|
|
- if (upper_dev && upper_dev->priv_flags & IFF_EBRIDGE)
|
|
|
- __bond_resend_igmp_join_requests(upper_dev);
|
|
|
-
|
|
|
- /* rejoin all groups on vlan devices */
|
|
|
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
|
|
|
- vlan_dev = __vlan_find_dev_deep(bond_dev, htons(ETH_P_8021Q),
|
|
|
- vlan->vlan_id);
|
|
|
- if (vlan_dev)
|
|
|
- __bond_resend_igmp_join_requests(vlan_dev);
|
|
|
+ if (!rtnl_trylock()) {
|
|
|
+ queue_delayed_work(bond->wq, &bond->mcast_work, 0);
|
|
|
+ return;
|
|
|
}
|
|
|
- rcu_read_unlock();
|
|
|
+ call_netdevice_notifiers(NETDEV_RESEND_IGMP, bond->dev);
|
|
|
+ rtnl_unlock();
|
|
|
|
|
|
/* We use curr_slave_lock to protect against concurrent access to
|
|
|
* igmp_retrans from multiple running instances of this function and
|
|
@@ -3234,6 +3204,10 @@ static int bond_slave_netdev_event(unsigned long event,
|
|
|
case NETDEV_FEAT_CHANGE:
|
|
|
bond_compute_features(bond);
|
|
|
break;
|
|
|
+ case NETDEV_RESEND_IGMP:
|
|
|
+ /* Propagate to master device */
|
|
|
+ call_netdevice_notifiers(event, slave->bond->dev);
|
|
|
+ break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|