Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4aa5dee4 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller
Browse files

net: convert resend IGMP to notifier event



Until now, bond_resend_igmp_join_requests() looks for vlans attached to
bonding device, bridge where bonding act as port manually. It does not
care of other scenarios, like stacked bonds or team device above. Make
this more generic and use netdev notifier to propagate the event to
upper devices and to actually call ip_mc_rejoin_groups().

Signed-off-by: default avatarJiri Pirko <jiri@resnulli.us>
Acked-by: default avatarVeaceslav Falico <vfalico@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fc423ff0
Loading
Loading
Loading
Loading
+9 −35
Original line number Diff line number Diff line
@@ -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;
	}
+4 −0
Original line number Diff line number Diff line
@@ -2785,6 +2785,10 @@ static int team_device_event(struct notifier_block *unused,
	case NETDEV_PRE_TYPE_CHANGE:
		/* Forbid to change type of underlaying device */
		return NOTIFY_BAD;
	case NETDEV_RESEND_IGMP:
		/* Propagate to master device */
		call_netdevice_notifiers(event, port->team->dev);
		break;
	}
	return NOTIFY_DONE;
}
+0 −1
Original line number Diff line number Diff line
@@ -129,6 +129,5 @@ extern void ip_mc_unmap(struct in_device *);
extern void ip_mc_remap(struct in_device *);
extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr);
extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr);
extern void ip_mc_rejoin_groups(struct in_device *in_dev);

#endif
+1 −0
Original line number Diff line number Diff line
@@ -1633,6 +1633,7 @@ struct packet_offload {
#define NETDEV_NOTIFY_PEERS	0x0013
#define NETDEV_JOIN		0x0014
#define NETDEV_CHANGEUPPER	0x0015
#define NETDEV_RESEND_IGMP	0x0016

extern int register_netdevice_notifier(struct notifier_block *nb);
extern int unregister_netdevice_notifier(struct notifier_block *nb);
+1 −0
Original line number Diff line number Diff line
@@ -459,6 +459,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,

	case NETDEV_NOTIFY_PEERS:
	case NETDEV_BONDING_FAILOVER:
	case NETDEV_RESEND_IGMP:
		/* Propagate to vlan devices */
		vlan_group_for_each_dev(grp, i, vlandev)
			call_netdevice_notifiers(event, vlandev);
Loading