aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bonding/bond_main.c8
-rw-r--r--include/linux/igmp.h2
-rw-r--r--net/ipv4/igmp.c32
3 files changed, 22 insertions, 20 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 518844852f06..e588b2e1c3b3 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -873,15 +873,11 @@ static void bond_mc_del(struct bonding *bond, void *addr)
873static void __bond_resend_igmp_join_requests(struct net_device *dev) 873static void __bond_resend_igmp_join_requests(struct net_device *dev)
874{ 874{
875 struct in_device *in_dev; 875 struct in_device *in_dev;
876 struct ip_mc_list *im;
877 876
878 rcu_read_lock(); 877 rcu_read_lock();
879 in_dev = __in_dev_get_rcu(dev); 878 in_dev = __in_dev_get_rcu(dev);
880 if (in_dev) { 879 if (in_dev)
881 for (im = in_dev->mc_list; im; im = im->next) 880 ip_mc_rejoin_groups(in_dev);
882 ip_mc_rejoin_group(im);
883 }
884
885 rcu_read_unlock(); 881 rcu_read_unlock();
886} 882}
887 883
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index 7d164670f264..c4987f265109 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -238,7 +238,7 @@ extern void ip_mc_unmap(struct in_device *);
238extern void ip_mc_remap(struct in_device *); 238extern void ip_mc_remap(struct in_device *);
239extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr); 239extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr);
240extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr); 240extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr);
241extern void ip_mc_rejoin_group(struct ip_mc_list *im); 241extern void ip_mc_rejoin_groups(struct in_device *in_dev);
242 242
243#endif 243#endif
244#endif 244#endif
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index afb1e82a59f9..50f6bc1a002a 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1267,26 +1267,32 @@ EXPORT_SYMBOL(ip_mc_inc_group);
1267 1267
1268/* 1268/*
1269 * Resend IGMP JOIN report; used for bonding. 1269 * Resend IGMP JOIN report; used for bonding.
1270 * Called with rcu_read_lock()
1270 */ 1271 */
1271void ip_mc_rejoin_group(struct ip_mc_list *im) 1272void ip_mc_rejoin_groups(struct in_device *in_dev)
1272{ 1273{
1273#ifdef CONFIG_IP_MULTICAST 1274#ifdef CONFIG_IP_MULTICAST
1274 struct in_device *in_dev = im->interface; 1275 struct ip_mc_list *im;
1276 int type;
1275 1277
1276 if (im->multiaddr == IGMP_ALL_HOSTS) 1278 for_each_pmc_rcu(in_dev, im) {
1277 return; 1279 if (im->multiaddr == IGMP_ALL_HOSTS)
1280 continue;
1278 1281
1279 /* a failover is happening and switches 1282 /* a failover is happening and switches
1280 * must be notified immediately */ 1283 * must be notified immediately
1281 if (IGMP_V1_SEEN(in_dev)) 1284 */
1282 igmp_send_report(in_dev, im, IGMP_HOST_MEMBERSHIP_REPORT); 1285 if (IGMP_V1_SEEN(in_dev))
1283 else if (IGMP_V2_SEEN(in_dev)) 1286 type = IGMP_HOST_MEMBERSHIP_REPORT;
1284 igmp_send_report(in_dev, im, IGMPV2_HOST_MEMBERSHIP_REPORT); 1287 else if (IGMP_V2_SEEN(in_dev))
1285 else 1288 type = IGMPV2_HOST_MEMBERSHIP_REPORT;
1286 igmp_send_report(in_dev, im, IGMPV3_HOST_MEMBERSHIP_REPORT); 1289 else
1290 type = IGMPV3_HOST_MEMBERSHIP_REPORT;
1291 igmp_send_report(in_dev, im, type);
1292 }
1287#endif 1293#endif
1288} 1294}
1289EXPORT_SYMBOL(ip_mc_rejoin_group); 1295EXPORT_SYMBOL(ip_mc_rejoin_groups);
1290 1296
1291/* 1297/*
1292 * A socket has left a multicast group on device dev 1298 * A socket has left a multicast group on device dev