summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-07-23 16:53:03 -0700
committerDavid S. Miller <davem@davemloft.net>2013-07-23 16:53:03 -0700
commit45c9149024dd082f1ac51fe46b0622f7c923f77f (patch)
tree71a8b0b141e7a44afcf18304911d036d5be77c6e /net/ipv4
parentab2cfbb2bddb7c7bc4394e52e91044d5ff645cb4 (diff)
parent492b200efdd20b8fcfdac873f3cd8d4902386581 (diff)
downloadlinux-45c9149024dd082f1ac51fe46b0622f7c923f77f.tar.gz
linux-45c9149024dd082f1ac51fe46b0622f7c923f77f.tar.bz2
linux-45c9149024dd082f1ac51fe46b0622f7c923f77f.zip
Merge branch 'team' ("add support for peer notifications and igmp rejoins for team")
Jiri Pirko says: ==================== The middle patch adjusts core infrastructure so the bonding code can be generalized and reused by team. v1->v2: using msecs_to_jiffies() as suggested by Eric Jiri Pirko (3): team: add peer notification net: convert resend IGMP to notifier event team: add support for sending multicast rejoins ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/igmp.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index cd71190d2962..375aca372250 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1323,16 +1323,17 @@ out:
EXPORT_SYMBOL(ip_mc_inc_group);
/*
- * Resend IGMP JOIN report; used for bonding.
- * Called with rcu_read_lock()
+ * Resend IGMP JOIN report; used by netdev notifier.
*/
-void ip_mc_rejoin_groups(struct in_device *in_dev)
+static void ip_mc_rejoin_groups(struct in_device *in_dev)
{
#ifdef CONFIG_IP_MULTICAST
struct ip_mc_list *im;
int type;
- for_each_pmc_rcu(in_dev, im) {
+ ASSERT_RTNL();
+
+ for_each_pmc_rtnl(in_dev, im) {
if (im->multiaddr == IGMP_ALL_HOSTS)
continue;
@@ -1349,7 +1350,6 @@ void ip_mc_rejoin_groups(struct in_device *in_dev)
}
#endif
}
-EXPORT_SYMBOL(ip_mc_rejoin_groups);
/*
* A socket has left a multicast group on device dev
@@ -2735,8 +2735,42 @@ static struct pernet_operations igmp_net_ops = {
.exit = igmp_net_exit,
};
+static int igmp_netdev_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+ struct in_device *in_dev;
+
+ switch (event) {
+ case NETDEV_RESEND_IGMP:
+ in_dev = __in_dev_get_rtnl(dev);
+ if (in_dev)
+ ip_mc_rejoin_groups(in_dev);
+ break;
+ default:
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block igmp_notifier = {
+ .notifier_call = igmp_netdev_event,
+};
+
int __init igmp_mc_proc_init(void)
{
- return register_pernet_subsys(&igmp_net_ops);
+ int err;
+
+ err = register_pernet_subsys(&igmp_net_ops);
+ if (err)
+ return err;
+ err = register_netdevice_notifier(&igmp_notifier);
+ if (err)
+ goto reg_notif_fail;
+ return 0;
+
+reg_notif_fail:
+ unregister_pernet_subsys(&igmp_net_ops);
+ return err;
}
#endif