aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/igmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r--net/ipv4/igmp.c26
1 files changed, 11 insertions, 15 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 2a4bb76f2132..3c53c2d89e3b 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1269,14 +1269,14 @@ void ip_mc_rejoin_group(struct ip_mc_list *im)
1269 if (im->multiaddr == IGMP_ALL_HOSTS) 1269 if (im->multiaddr == IGMP_ALL_HOSTS)
1270 return; 1270 return;
1271 1271
1272 if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) { 1272 /* a failover is happening and switches
1273 igmp_mod_timer(im, IGMP_Initial_Report_Delay); 1273 * must be notified immediately */
1274 return; 1274 if (IGMP_V1_SEEN(in_dev))
1275 } 1275 igmp_send_report(in_dev, im, IGMP_HOST_MEMBERSHIP_REPORT);
1276 /* else, v3 */ 1276 else if (IGMP_V2_SEEN(in_dev))
1277 im->crcount = in_dev->mr_qrv ? in_dev->mr_qrv : 1277 igmp_send_report(in_dev, im, IGMPV2_HOST_MEMBERSHIP_REPORT);
1278 IGMP_Unsolicited_Report_Count; 1278 else
1279 igmp_ifc_event(in_dev); 1279 igmp_send_report(in_dev, im, IGMPV3_HOST_MEMBERSHIP_REPORT);
1280#endif 1280#endif
1281} 1281}
1282EXPORT_SYMBOL(ip_mc_rejoin_group); 1282EXPORT_SYMBOL(ip_mc_rejoin_group);
@@ -1418,6 +1418,7 @@ void ip_mc_destroy_dev(struct in_device *in_dev)
1418 write_unlock_bh(&in_dev->mc_list_lock); 1418 write_unlock_bh(&in_dev->mc_list_lock);
1419} 1419}
1420 1420
1421/* RTNL is locked */
1421static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) 1422static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
1422{ 1423{
1423 struct flowi fl = { .nl_u = { .ip4_u = 1424 struct flowi fl = { .nl_u = { .ip4_u =
@@ -1428,15 +1429,12 @@ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
1428 1429
1429 if (imr->imr_ifindex) { 1430 if (imr->imr_ifindex) {
1430 idev = inetdev_by_index(net, imr->imr_ifindex); 1431 idev = inetdev_by_index(net, imr->imr_ifindex);
1431 if (idev)
1432 __in_dev_put(idev);
1433 return idev; 1432 return idev;
1434 } 1433 }
1435 if (imr->imr_address.s_addr) { 1434 if (imr->imr_address.s_addr) {
1436 dev = ip_dev_find(net, imr->imr_address.s_addr); 1435 dev = __ip_dev_find(net, imr->imr_address.s_addr, false);
1437 if (!dev) 1436 if (!dev)
1438 return NULL; 1437 return NULL;
1439 dev_put(dev);
1440 } 1438 }
1441 1439
1442 if (!dev && !ip_route_output_key(net, &rt, &fl)) { 1440 if (!dev && !ip_route_output_key(net, &rt, &fl)) {
@@ -2308,10 +2306,8 @@ void ip_mc_drop_socket(struct sock *sk)
2308 2306
2309 in_dev = inetdev_by_index(net, iml->multi.imr_ifindex); 2307 in_dev = inetdev_by_index(net, iml->multi.imr_ifindex);
2310 (void) ip_mc_leave_src(sk, iml, in_dev); 2308 (void) ip_mc_leave_src(sk, iml, in_dev);
2311 if (in_dev != NULL) { 2309 if (in_dev != NULL)
2312 ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr); 2310 ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
2313 in_dev_put(in_dev);
2314 }
2315 /* decrease mem now to avoid the memleak warning */ 2311 /* decrease mem now to avoid the memleak warning */
2316 atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); 2312 atomic_sub(sizeof(*iml), &sk->sk_omem_alloc);
2317 call_rcu(&iml->rcu, ip_mc_socklist_reclaim); 2313 call_rcu(&iml->rcu, ip_mc_socklist_reclaim);