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.c357
1 files changed, 161 insertions, 196 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 2a4bb76f2132..f1d27f6c9351 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -153,17 +153,27 @@ static void ip_ma_put(struct ip_mc_list *im)
153{ 153{
154 if (atomic_dec_and_test(&im->refcnt)) { 154 if (atomic_dec_and_test(&im->refcnt)) {
155 in_dev_put(im->interface); 155 in_dev_put(im->interface);
156 kfree(im); 156 kfree_rcu(im, rcu);
157 } 157 }
158} 158}
159 159
160#define for_each_pmc_rcu(in_dev, pmc) \
161 for (pmc = rcu_dereference(in_dev->mc_list); \
162 pmc != NULL; \
163 pmc = rcu_dereference(pmc->next_rcu))
164
165#define for_each_pmc_rtnl(in_dev, pmc) \
166 for (pmc = rtnl_dereference(in_dev->mc_list); \
167 pmc != NULL; \
168 pmc = rtnl_dereference(pmc->next_rcu))
169
160#ifdef CONFIG_IP_MULTICAST 170#ifdef CONFIG_IP_MULTICAST
161 171
162/* 172/*
163 * Timer management 173 * Timer management
164 */ 174 */
165 175
166static __inline__ void igmp_stop_timer(struct ip_mc_list *im) 176static void igmp_stop_timer(struct ip_mc_list *im)
167{ 177{
168 spin_lock_bh(&im->lock); 178 spin_lock_bh(&im->lock);
169 if (del_timer(&im->timer)) 179 if (del_timer(&im->timer))
@@ -284,6 +294,8 @@ igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted)
284 return scount; 294 return scount;
285} 295}
286 296
297#define igmp_skb_size(skb) (*(unsigned int *)((skb)->cb))
298
287static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) 299static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
288{ 300{
289 struct sk_buff *skb; 301 struct sk_buff *skb;
@@ -291,24 +303,24 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
291 struct iphdr *pip; 303 struct iphdr *pip;
292 struct igmpv3_report *pig; 304 struct igmpv3_report *pig;
293 struct net *net = dev_net(dev); 305 struct net *net = dev_net(dev);
306 struct flowi4 fl4;
294 307
295 skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC); 308 while (1) {
296 if (skb == NULL) 309 skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev),
297 return NULL; 310 GFP_ATOMIC | __GFP_NOWARN);
298 311 if (skb)
299 { 312 break;
300 struct flowi fl = { .oif = dev->ifindex, 313 size >>= 1;
301 .nl_u = { .ip4_u = { 314 if (size < 256)
302 .daddr = IGMPV3_ALL_MCR } },
303 .proto = IPPROTO_IGMP };
304 if (ip_route_output_key(net, &rt, &fl)) {
305 kfree_skb(skb);
306 return NULL; 315 return NULL;
307 }
308 } 316 }
309 if (rt->rt_src == 0) { 317 igmp_skb_size(skb) = size;
318
319 rt = ip_route_output_ports(net, &fl4, NULL, IGMPV3_ALL_MCR, 0,
320 0, 0,
321 IPPROTO_IGMP, 0, dev->ifindex);
322 if (IS_ERR(rt)) {
310 kfree_skb(skb); 323 kfree_skb(skb);
311 ip_rt_put(rt);
312 return NULL; 324 return NULL;
313 } 325 }
314 326
@@ -326,8 +338,8 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
326 pip->tos = 0xc0; 338 pip->tos = 0xc0;
327 pip->frag_off = htons(IP_DF); 339 pip->frag_off = htons(IP_DF);
328 pip->ttl = 1; 340 pip->ttl = 1;
329 pip->daddr = rt->rt_dst; 341 pip->daddr = fl4.daddr;
330 pip->saddr = rt->rt_src; 342 pip->saddr = fl4.saddr;
331 pip->protocol = IPPROTO_IGMP; 343 pip->protocol = IPPROTO_IGMP;
332 pip->tot_len = 0; /* filled in later */ 344 pip->tot_len = 0; /* filled in later */
333 ip_select_ident(pip, &rt->dst, NULL); 345 ip_select_ident(pip, &rt->dst, NULL);
@@ -384,7 +396,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc,
384 return skb; 396 return skb;
385} 397}
386 398
387#define AVAILABLE(skb) ((skb) ? ((skb)->dev ? (skb)->dev->mtu - (skb)->len : \ 399#define AVAILABLE(skb) ((skb) ? ((skb)->dev ? igmp_skb_size(skb) - (skb)->len : \
388 skb_tailroom(skb)) : 0) 400 skb_tailroom(skb)) : 0)
389 401
390static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, 402static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
@@ -502,8 +514,8 @@ static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc)
502 int type; 514 int type;
503 515
504 if (!pmc) { 516 if (!pmc) {
505 read_lock(&in_dev->mc_list_lock); 517 rcu_read_lock();
506 for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { 518 for_each_pmc_rcu(in_dev, pmc) {
507 if (pmc->multiaddr == IGMP_ALL_HOSTS) 519 if (pmc->multiaddr == IGMP_ALL_HOSTS)
508 continue; 520 continue;
509 spin_lock_bh(&pmc->lock); 521 spin_lock_bh(&pmc->lock);
@@ -514,7 +526,7 @@ static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc)
514 skb = add_grec(skb, pmc, type, 0, 0); 526 skb = add_grec(skb, pmc, type, 0, 0);
515 spin_unlock_bh(&pmc->lock); 527 spin_unlock_bh(&pmc->lock);
516 } 528 }
517 read_unlock(&in_dev->mc_list_lock); 529 rcu_read_unlock();
518 } else { 530 } else {
519 spin_lock_bh(&pmc->lock); 531 spin_lock_bh(&pmc->lock);
520 if (pmc->sfcount[MCAST_EXCLUDE]) 532 if (pmc->sfcount[MCAST_EXCLUDE])
@@ -556,7 +568,7 @@ static void igmpv3_send_cr(struct in_device *in_dev)
556 struct sk_buff *skb = NULL; 568 struct sk_buff *skb = NULL;
557 int type, dtype; 569 int type, dtype;
558 570
559 read_lock(&in_dev->mc_list_lock); 571 rcu_read_lock();
560 spin_lock_bh(&in_dev->mc_tomb_lock); 572 spin_lock_bh(&in_dev->mc_tomb_lock);
561 573
562 /* deleted MCA's */ 574 /* deleted MCA's */
@@ -593,7 +605,7 @@ static void igmpv3_send_cr(struct in_device *in_dev)
593 spin_unlock_bh(&in_dev->mc_tomb_lock); 605 spin_unlock_bh(&in_dev->mc_tomb_lock);
594 606
595 /* change recs */ 607 /* change recs */
596 for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { 608 for_each_pmc_rcu(in_dev, pmc) {
597 spin_lock_bh(&pmc->lock); 609 spin_lock_bh(&pmc->lock);
598 if (pmc->sfcount[MCAST_EXCLUDE]) { 610 if (pmc->sfcount[MCAST_EXCLUDE]) {
599 type = IGMPV3_BLOCK_OLD_SOURCES; 611 type = IGMPV3_BLOCK_OLD_SOURCES;
@@ -616,7 +628,7 @@ static void igmpv3_send_cr(struct in_device *in_dev)
616 } 628 }
617 spin_unlock_bh(&pmc->lock); 629 spin_unlock_bh(&pmc->lock);
618 } 630 }
619 read_unlock(&in_dev->mc_list_lock); 631 rcu_read_unlock();
620 632
621 if (!skb) 633 if (!skb)
622 return; 634 return;
@@ -633,6 +645,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
633 struct net_device *dev = in_dev->dev; 645 struct net_device *dev = in_dev->dev;
634 struct net *net = dev_net(dev); 646 struct net *net = dev_net(dev);
635 __be32 group = pmc ? pmc->multiaddr : 0; 647 __be32 group = pmc ? pmc->multiaddr : 0;
648 struct flowi4 fl4;
636 __be32 dst; 649 __be32 dst;
637 650
638 if (type == IGMPV3_HOST_MEMBERSHIP_REPORT) 651 if (type == IGMPV3_HOST_MEMBERSHIP_REPORT)
@@ -642,17 +655,11 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
642 else 655 else
643 dst = group; 656 dst = group;
644 657
645 { 658 rt = ip_route_output_ports(net, &fl4, NULL, dst, 0,
646 struct flowi fl = { .oif = dev->ifindex, 659 0, 0,
647 .nl_u = { .ip4_u = { .daddr = dst } }, 660 IPPROTO_IGMP, 0, dev->ifindex);
648 .proto = IPPROTO_IGMP }; 661 if (IS_ERR(rt))
649 if (ip_route_output_key(net, &rt, &fl))
650 return -1;
651 }
652 if (rt->rt_src == 0) {
653 ip_rt_put(rt);
654 return -1; 662 return -1;
655 }
656 663
657 skb = alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC); 664 skb = alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
658 if (skb == NULL) { 665 if (skb == NULL) {
@@ -674,7 +681,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
674 iph->frag_off = htons(IP_DF); 681 iph->frag_off = htons(IP_DF);
675 iph->ttl = 1; 682 iph->ttl = 1;
676 iph->daddr = dst; 683 iph->daddr = dst;
677 iph->saddr = rt->rt_src; 684 iph->saddr = fl4.saddr;
678 iph->protocol = IPPROTO_IGMP; 685 iph->protocol = IPPROTO_IGMP;
679 ip_select_ident(iph, &rt->dst, NULL); 686 ip_select_ident(iph, &rt->dst, NULL);
680 ((u8*)&iph[1])[0] = IPOPT_RA; 687 ((u8*)&iph[1])[0] = IPOPT_RA;
@@ -813,14 +820,14 @@ static void igmp_heard_report(struct in_device *in_dev, __be32 group)
813 if (group == IGMP_ALL_HOSTS) 820 if (group == IGMP_ALL_HOSTS)
814 return; 821 return;
815 822
816 read_lock(&in_dev->mc_list_lock); 823 rcu_read_lock();
817 for (im=in_dev->mc_list; im!=NULL; im=im->next) { 824 for_each_pmc_rcu(in_dev, im) {
818 if (im->multiaddr == group) { 825 if (im->multiaddr == group) {
819 igmp_stop_timer(im); 826 igmp_stop_timer(im);
820 break; 827 break;
821 } 828 }
822 } 829 }
823 read_unlock(&in_dev->mc_list_lock); 830 rcu_read_unlock();
824} 831}
825 832
826static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, 833static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
@@ -906,8 +913,8 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
906 * - Use the igmp->igmp_code field as the maximum 913 * - Use the igmp->igmp_code field as the maximum
907 * delay possible 914 * delay possible
908 */ 915 */
909 read_lock(&in_dev->mc_list_lock); 916 rcu_read_lock();
910 for (im=in_dev->mc_list; im!=NULL; im=im->next) { 917 for_each_pmc_rcu(in_dev, im) {
911 int changed; 918 int changed;
912 919
913 if (group && group != im->multiaddr) 920 if (group && group != im->multiaddr)
@@ -925,7 +932,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
925 if (changed) 932 if (changed)
926 igmp_mod_timer(im, max_delay); 933 igmp_mod_timer(im, max_delay);
927 } 934 }
928 read_unlock(&in_dev->mc_list_lock); 935 rcu_read_unlock();
929} 936}
930 937
931/* called in rcu_read_lock() section */ 938/* called in rcu_read_lock() section */
@@ -961,7 +968,7 @@ int igmp_rcv(struct sk_buff *skb)
961 case IGMP_HOST_MEMBERSHIP_REPORT: 968 case IGMP_HOST_MEMBERSHIP_REPORT:
962 case IGMPV2_HOST_MEMBERSHIP_REPORT: 969 case IGMPV2_HOST_MEMBERSHIP_REPORT:
963 /* Is it our report looped back? */ 970 /* Is it our report looped back? */
964 if (skb_rtable(skb)->fl.iif == 0) 971 if (rt_is_output_route(skb_rtable(skb)))
965 break; 972 break;
966 /* don't rely on MC router hearing unicast reports */ 973 /* don't rely on MC router hearing unicast reports */
967 if (skb->pkt_type == PACKET_MULTICAST || 974 if (skb->pkt_type == PACKET_MULTICAST ||
@@ -1110,8 +1117,8 @@ static void igmpv3_clear_delrec(struct in_device *in_dev)
1110 kfree(pmc); 1117 kfree(pmc);
1111 } 1118 }
1112 /* clear dead sources, too */ 1119 /* clear dead sources, too */
1113 read_lock(&in_dev->mc_list_lock); 1120 rcu_read_lock();
1114 for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { 1121 for_each_pmc_rcu(in_dev, pmc) {
1115 struct ip_sf_list *psf, *psf_next; 1122 struct ip_sf_list *psf, *psf_next;
1116 1123
1117 spin_lock_bh(&pmc->lock); 1124 spin_lock_bh(&pmc->lock);
@@ -1123,7 +1130,7 @@ static void igmpv3_clear_delrec(struct in_device *in_dev)
1123 kfree(psf); 1130 kfree(psf);
1124 } 1131 }
1125 } 1132 }
1126 read_unlock(&in_dev->mc_list_lock); 1133 rcu_read_unlock();
1127} 1134}
1128#endif 1135#endif
1129 1136
@@ -1148,20 +1155,18 @@ static void igmp_group_dropped(struct ip_mc_list *im)
1148 1155
1149 if (!in_dev->dead) { 1156 if (!in_dev->dead) {
1150 if (IGMP_V1_SEEN(in_dev)) 1157 if (IGMP_V1_SEEN(in_dev))
1151 goto done; 1158 return;
1152 if (IGMP_V2_SEEN(in_dev)) { 1159 if (IGMP_V2_SEEN(in_dev)) {
1153 if (reporter) 1160 if (reporter)
1154 igmp_send_report(in_dev, im, IGMP_HOST_LEAVE_MESSAGE); 1161 igmp_send_report(in_dev, im, IGMP_HOST_LEAVE_MESSAGE);
1155 goto done; 1162 return;
1156 } 1163 }
1157 /* IGMPv3 */ 1164 /* IGMPv3 */
1158 igmpv3_add_delrec(in_dev, im); 1165 igmpv3_add_delrec(in_dev, im);
1159 1166
1160 igmp_ifc_event(in_dev); 1167 igmp_ifc_event(in_dev);
1161 } 1168 }
1162done:
1163#endif 1169#endif
1164 ip_mc_clear_src(im);
1165} 1170}
1166 1171
1167static void igmp_group_added(struct ip_mc_list *im) 1172static void igmp_group_added(struct ip_mc_list *im)
@@ -1209,7 +1214,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
1209 1214
1210 ASSERT_RTNL(); 1215 ASSERT_RTNL();
1211 1216
1212 for (im=in_dev->mc_list; im; im=im->next) { 1217 for_each_pmc_rtnl(in_dev, im) {
1213 if (im->multiaddr == addr) { 1218 if (im->multiaddr == addr) {
1214 im->users++; 1219 im->users++;
1215 ip_mc_add_src(in_dev, &addr, MCAST_EXCLUDE, 0, NULL, 0); 1220 ip_mc_add_src(in_dev, &addr, MCAST_EXCLUDE, 0, NULL, 0);
@@ -1217,7 +1222,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
1217 } 1222 }
1218 } 1223 }
1219 1224
1220 im = kmalloc(sizeof(*im), GFP_KERNEL); 1225 im = kzalloc(sizeof(*im), GFP_KERNEL);
1221 if (!im) 1226 if (!im)
1222 goto out; 1227 goto out;
1223 1228
@@ -1227,26 +1232,18 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
1227 im->multiaddr = addr; 1232 im->multiaddr = addr;
1228 /* initial mode is (EX, empty) */ 1233 /* initial mode is (EX, empty) */
1229 im->sfmode = MCAST_EXCLUDE; 1234 im->sfmode = MCAST_EXCLUDE;
1230 im->sfcount[MCAST_INCLUDE] = 0;
1231 im->sfcount[MCAST_EXCLUDE] = 1; 1235 im->sfcount[MCAST_EXCLUDE] = 1;
1232 im->sources = NULL;
1233 im->tomb = NULL;
1234 im->crcount = 0;
1235 atomic_set(&im->refcnt, 1); 1236 atomic_set(&im->refcnt, 1);
1236 spin_lock_init(&im->lock); 1237 spin_lock_init(&im->lock);
1237#ifdef CONFIG_IP_MULTICAST 1238#ifdef CONFIG_IP_MULTICAST
1238 im->tm_running = 0;
1239 setup_timer(&im->timer, &igmp_timer_expire, (unsigned long)im); 1239 setup_timer(&im->timer, &igmp_timer_expire, (unsigned long)im);
1240 im->unsolicit_count = IGMP_Unsolicited_Report_Count; 1240 im->unsolicit_count = IGMP_Unsolicited_Report_Count;
1241 im->reporter = 0;
1242 im->gsquery = 0;
1243#endif 1241#endif
1244 im->loaded = 0; 1242
1245 write_lock_bh(&in_dev->mc_list_lock); 1243 im->next_rcu = in_dev->mc_list;
1246 im->next = in_dev->mc_list;
1247 in_dev->mc_list = im;
1248 in_dev->mc_count++; 1244 in_dev->mc_count++;
1249 write_unlock_bh(&in_dev->mc_list_lock); 1245 rcu_assign_pointer(in_dev->mc_list, im);
1246
1250#ifdef CONFIG_IP_MULTICAST 1247#ifdef CONFIG_IP_MULTICAST
1251 igmpv3_del_delrec(in_dev, im->multiaddr); 1248 igmpv3_del_delrec(in_dev, im->multiaddr);
1252#endif 1249#endif
@@ -1260,26 +1257,32 @@ EXPORT_SYMBOL(ip_mc_inc_group);
1260 1257
1261/* 1258/*
1262 * Resend IGMP JOIN report; used for bonding. 1259 * Resend IGMP JOIN report; used for bonding.
1260 * Called with rcu_read_lock()
1263 */ 1261 */
1264void ip_mc_rejoin_group(struct ip_mc_list *im) 1262void ip_mc_rejoin_groups(struct in_device *in_dev)
1265{ 1263{
1266#ifdef CONFIG_IP_MULTICAST 1264#ifdef CONFIG_IP_MULTICAST
1267 struct in_device *in_dev = im->interface; 1265 struct ip_mc_list *im;
1266 int type;
1268 1267
1269 if (im->multiaddr == IGMP_ALL_HOSTS) 1268 for_each_pmc_rcu(in_dev, im) {
1270 return; 1269 if (im->multiaddr == IGMP_ALL_HOSTS)
1270 continue;
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 */
1275 if (IGMP_V1_SEEN(in_dev))
1276 type = IGMP_HOST_MEMBERSHIP_REPORT;
1277 else if (IGMP_V2_SEEN(in_dev))
1278 type = IGMPV2_HOST_MEMBERSHIP_REPORT;
1279 else
1280 type = IGMPV3_HOST_MEMBERSHIP_REPORT;
1281 igmp_send_report(in_dev, im, type);
1275 } 1282 }
1276 /* else, v3 */
1277 im->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
1278 IGMP_Unsolicited_Report_Count;
1279 igmp_ifc_event(in_dev);
1280#endif 1283#endif
1281} 1284}
1282EXPORT_SYMBOL(ip_mc_rejoin_group); 1285EXPORT_SYMBOL(ip_mc_rejoin_groups);
1283 1286
1284/* 1287/*
1285 * A socket has left a multicast group on device dev 1288 * A socket has left a multicast group on device dev
@@ -1287,18 +1290,20 @@ EXPORT_SYMBOL(ip_mc_rejoin_group);
1287 1290
1288void ip_mc_dec_group(struct in_device *in_dev, __be32 addr) 1291void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
1289{ 1292{
1290 struct ip_mc_list *i, **ip; 1293 struct ip_mc_list *i;
1294 struct ip_mc_list __rcu **ip;
1291 1295
1292 ASSERT_RTNL(); 1296 ASSERT_RTNL();
1293 1297
1294 for (ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next) { 1298 for (ip = &in_dev->mc_list;
1299 (i = rtnl_dereference(*ip)) != NULL;
1300 ip = &i->next_rcu) {
1295 if (i->multiaddr == addr) { 1301 if (i->multiaddr == addr) {
1296 if (--i->users == 0) { 1302 if (--i->users == 0) {
1297 write_lock_bh(&in_dev->mc_list_lock); 1303 *ip = i->next_rcu;
1298 *ip = i->next;
1299 in_dev->mc_count--; 1304 in_dev->mc_count--;
1300 write_unlock_bh(&in_dev->mc_list_lock);
1301 igmp_group_dropped(i); 1305 igmp_group_dropped(i);
1306 ip_mc_clear_src(i);
1302 1307
1303 if (!in_dev->dead) 1308 if (!in_dev->dead)
1304 ip_rt_multicast_event(in_dev); 1309 ip_rt_multicast_event(in_dev);
@@ -1316,34 +1321,34 @@ EXPORT_SYMBOL(ip_mc_dec_group);
1316 1321
1317void ip_mc_unmap(struct in_device *in_dev) 1322void ip_mc_unmap(struct in_device *in_dev)
1318{ 1323{
1319 struct ip_mc_list *i; 1324 struct ip_mc_list *pmc;
1320 1325
1321 ASSERT_RTNL(); 1326 ASSERT_RTNL();
1322 1327
1323 for (i = in_dev->mc_list; i; i = i->next) 1328 for_each_pmc_rtnl(in_dev, pmc)
1324 igmp_group_dropped(i); 1329 igmp_group_dropped(pmc);
1325} 1330}
1326 1331
1327void ip_mc_remap(struct in_device *in_dev) 1332void ip_mc_remap(struct in_device *in_dev)
1328{ 1333{
1329 struct ip_mc_list *i; 1334 struct ip_mc_list *pmc;
1330 1335
1331 ASSERT_RTNL(); 1336 ASSERT_RTNL();
1332 1337
1333 for (i = in_dev->mc_list; i; i = i->next) 1338 for_each_pmc_rtnl(in_dev, pmc)
1334 igmp_group_added(i); 1339 igmp_group_added(pmc);
1335} 1340}
1336 1341
1337/* Device going down */ 1342/* Device going down */
1338 1343
1339void ip_mc_down(struct in_device *in_dev) 1344void ip_mc_down(struct in_device *in_dev)
1340{ 1345{
1341 struct ip_mc_list *i; 1346 struct ip_mc_list *pmc;
1342 1347
1343 ASSERT_RTNL(); 1348 ASSERT_RTNL();
1344 1349
1345 for (i=in_dev->mc_list; i; i=i->next) 1350 for_each_pmc_rtnl(in_dev, pmc)
1346 igmp_group_dropped(i); 1351 igmp_group_dropped(pmc);
1347 1352
1348#ifdef CONFIG_IP_MULTICAST 1353#ifdef CONFIG_IP_MULTICAST
1349 in_dev->mr_ifc_count = 0; 1354 in_dev->mr_ifc_count = 0;
@@ -1374,7 +1379,6 @@ void ip_mc_init_dev(struct in_device *in_dev)
1374 in_dev->mr_qrv = IGMP_Unsolicited_Report_Count; 1379 in_dev->mr_qrv = IGMP_Unsolicited_Report_Count;
1375#endif 1380#endif
1376 1381
1377 rwlock_init(&in_dev->mc_list_lock);
1378 spin_lock_init(&in_dev->mc_tomb_lock); 1382 spin_lock_init(&in_dev->mc_tomb_lock);
1379} 1383}
1380 1384
@@ -1382,14 +1386,14 @@ void ip_mc_init_dev(struct in_device *in_dev)
1382 1386
1383void ip_mc_up(struct in_device *in_dev) 1387void ip_mc_up(struct in_device *in_dev)
1384{ 1388{
1385 struct ip_mc_list *i; 1389 struct ip_mc_list *pmc;
1386 1390
1387 ASSERT_RTNL(); 1391 ASSERT_RTNL();
1388 1392
1389 ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS); 1393 ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);
1390 1394
1391 for (i=in_dev->mc_list; i; i=i->next) 1395 for_each_pmc_rtnl(in_dev, pmc)
1392 igmp_group_added(i); 1396 igmp_group_added(pmc);
1393} 1397}
1394 1398
1395/* 1399/*
@@ -1405,43 +1409,40 @@ void ip_mc_destroy_dev(struct in_device *in_dev)
1405 /* Deactivate timers */ 1409 /* Deactivate timers */
1406 ip_mc_down(in_dev); 1410 ip_mc_down(in_dev);
1407 1411
1408 write_lock_bh(&in_dev->mc_list_lock); 1412 while ((i = rtnl_dereference(in_dev->mc_list)) != NULL) {
1409 while ((i = in_dev->mc_list) != NULL) { 1413 in_dev->mc_list = i->next_rcu;
1410 in_dev->mc_list = i->next;
1411 in_dev->mc_count--; 1414 in_dev->mc_count--;
1412 write_unlock_bh(&in_dev->mc_list_lock);
1413 igmp_group_dropped(i);
1414 ip_ma_put(i);
1415 1415
1416 write_lock_bh(&in_dev->mc_list_lock); 1416 /* We've dropped the groups in ip_mc_down already */
1417 ip_mc_clear_src(i);
1418 ip_ma_put(i);
1417 } 1419 }
1418 write_unlock_bh(&in_dev->mc_list_lock);
1419} 1420}
1420 1421
1422/* RTNL is locked */
1421static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) 1423static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
1422{ 1424{
1423 struct flowi fl = { .nl_u = { .ip4_u =
1424 { .daddr = imr->imr_multiaddr.s_addr } } };
1425 struct rtable *rt;
1426 struct net_device *dev = NULL; 1425 struct net_device *dev = NULL;
1427 struct in_device *idev = NULL; 1426 struct in_device *idev = NULL;
1428 1427
1429 if (imr->imr_ifindex) { 1428 if (imr->imr_ifindex) {
1430 idev = inetdev_by_index(net, imr->imr_ifindex); 1429 idev = inetdev_by_index(net, imr->imr_ifindex);
1431 if (idev)
1432 __in_dev_put(idev);
1433 return idev; 1430 return idev;
1434 } 1431 }
1435 if (imr->imr_address.s_addr) { 1432 if (imr->imr_address.s_addr) {
1436 dev = ip_dev_find(net, imr->imr_address.s_addr); 1433 dev = __ip_dev_find(net, imr->imr_address.s_addr, false);
1437 if (!dev) 1434 if (!dev)
1438 return NULL; 1435 return NULL;
1439 dev_put(dev);
1440 } 1436 }
1441 1437
1442 if (!dev && !ip_route_output_key(net, &rt, &fl)) { 1438 if (!dev) {
1443 dev = rt->dst.dev; 1439 struct rtable *rt = ip_route_output(net,
1444 ip_rt_put(rt); 1440 imr->imr_multiaddr.s_addr,
1441 0, 0, 0);
1442 if (!IS_ERR(rt)) {
1443 dev = rt->dst.dev;
1444 ip_rt_put(rt);
1445 }
1445 } 1446 }
1446 if (dev) { 1447 if (dev) {
1447 imr->imr_ifindex = dev->ifindex; 1448 imr->imr_ifindex = dev->ifindex;
@@ -1515,18 +1516,18 @@ static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
1515 1516
1516 if (!in_dev) 1517 if (!in_dev)
1517 return -ENODEV; 1518 return -ENODEV;
1518 read_lock(&in_dev->mc_list_lock); 1519 rcu_read_lock();
1519 for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { 1520 for_each_pmc_rcu(in_dev, pmc) {
1520 if (*pmca == pmc->multiaddr) 1521 if (*pmca == pmc->multiaddr)
1521 break; 1522 break;
1522 } 1523 }
1523 if (!pmc) { 1524 if (!pmc) {
1524 /* MCA not found?? bug */ 1525 /* MCA not found?? bug */
1525 read_unlock(&in_dev->mc_list_lock); 1526 rcu_read_unlock();
1526 return -ESRCH; 1527 return -ESRCH;
1527 } 1528 }
1528 spin_lock_bh(&pmc->lock); 1529 spin_lock_bh(&pmc->lock);
1529 read_unlock(&in_dev->mc_list_lock); 1530 rcu_read_unlock();
1530#ifdef CONFIG_IP_MULTICAST 1531#ifdef CONFIG_IP_MULTICAST
1531 sf_markstate(pmc); 1532 sf_markstate(pmc);
1532#endif 1533#endif
@@ -1687,18 +1688,18 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
1687 1688
1688 if (!in_dev) 1689 if (!in_dev)
1689 return -ENODEV; 1690 return -ENODEV;
1690 read_lock(&in_dev->mc_list_lock); 1691 rcu_read_lock();
1691 for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { 1692 for_each_pmc_rcu(in_dev, pmc) {
1692 if (*pmca == pmc->multiaddr) 1693 if (*pmca == pmc->multiaddr)
1693 break; 1694 break;
1694 } 1695 }
1695 if (!pmc) { 1696 if (!pmc) {
1696 /* MCA not found?? bug */ 1697 /* MCA not found?? bug */
1697 read_unlock(&in_dev->mc_list_lock); 1698 rcu_read_unlock();
1698 return -ESRCH; 1699 return -ESRCH;
1699 } 1700 }
1700 spin_lock_bh(&pmc->lock); 1701 spin_lock_bh(&pmc->lock);
1701 read_unlock(&in_dev->mc_list_lock); 1702 rcu_read_unlock();
1702 1703
1703#ifdef CONFIG_IP_MULTICAST 1704#ifdef CONFIG_IP_MULTICAST
1704 sf_markstate(pmc); 1705 sf_markstate(pmc);
@@ -1795,7 +1796,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
1795 1796
1796 err = -EADDRINUSE; 1797 err = -EADDRINUSE;
1797 ifindex = imr->imr_ifindex; 1798 ifindex = imr->imr_ifindex;
1798 for (i = inet->mc_list; i; i = i->next) { 1799 for_each_pmc_rtnl(inet, i) {
1799 if (i->multi.imr_multiaddr.s_addr == addr && 1800 if (i->multi.imr_multiaddr.s_addr == addr &&
1800 i->multi.imr_ifindex == ifindex) 1801 i->multi.imr_ifindex == ifindex)
1801 goto done; 1802 goto done;
@@ -1809,7 +1810,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
1809 goto done; 1810 goto done;
1810 1811
1811 memcpy(&iml->multi, imr, sizeof(*imr)); 1812 memcpy(&iml->multi, imr, sizeof(*imr));
1812 iml->next = inet->mc_list; 1813 iml->next_rcu = inet->mc_list;
1813 iml->sflist = NULL; 1814 iml->sflist = NULL;
1814 iml->sfmode = MCAST_EXCLUDE; 1815 iml->sfmode = MCAST_EXCLUDE;
1815 rcu_assign_pointer(inet->mc_list, iml); 1816 rcu_assign_pointer(inet->mc_list, iml);
@@ -1821,19 +1822,10 @@ done:
1821} 1822}
1822EXPORT_SYMBOL(ip_mc_join_group); 1823EXPORT_SYMBOL(ip_mc_join_group);
1823 1824
1824static void ip_sf_socklist_reclaim(struct rcu_head *rp)
1825{
1826 struct ip_sf_socklist *psf;
1827
1828 psf = container_of(rp, struct ip_sf_socklist, rcu);
1829 /* sk_omem_alloc should have been decreased by the caller*/
1830 kfree(psf);
1831}
1832
1833static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml, 1825static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
1834 struct in_device *in_dev) 1826 struct in_device *in_dev)
1835{ 1827{
1836 struct ip_sf_socklist *psf = iml->sflist; 1828 struct ip_sf_socklist *psf = rtnl_dereference(iml->sflist);
1837 int err; 1829 int err;
1838 1830
1839 if (psf == NULL) { 1831 if (psf == NULL) {
@@ -1846,21 +1838,10 @@ static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
1846 rcu_assign_pointer(iml->sflist, NULL); 1838 rcu_assign_pointer(iml->sflist, NULL);
1847 /* decrease mem now to avoid the memleak warning */ 1839 /* decrease mem now to avoid the memleak warning */
1848 atomic_sub(IP_SFLSIZE(psf->sl_max), &sk->sk_omem_alloc); 1840 atomic_sub(IP_SFLSIZE(psf->sl_max), &sk->sk_omem_alloc);
1849 call_rcu(&psf->rcu, ip_sf_socklist_reclaim); 1841 kfree_rcu(psf, rcu);
1850 return err; 1842 return err;
1851} 1843}
1852 1844
1853
1854static void ip_mc_socklist_reclaim(struct rcu_head *rp)
1855{
1856 struct ip_mc_socklist *iml;
1857
1858 iml = container_of(rp, struct ip_mc_socklist, rcu);
1859 /* sk_omem_alloc should have been decreased by the caller*/
1860 kfree(iml);
1861}
1862
1863
1864/* 1845/*
1865 * Ask a socket to leave a group. 1846 * Ask a socket to leave a group.
1866 */ 1847 */
@@ -1868,7 +1849,8 @@ static void ip_mc_socklist_reclaim(struct rcu_head *rp)
1868int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) 1849int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
1869{ 1850{
1870 struct inet_sock *inet = inet_sk(sk); 1851 struct inet_sock *inet = inet_sk(sk);
1871 struct ip_mc_socklist *iml, **imlp; 1852 struct ip_mc_socklist *iml;
1853 struct ip_mc_socklist __rcu **imlp;
1872 struct in_device *in_dev; 1854 struct in_device *in_dev;
1873 struct net *net = sock_net(sk); 1855 struct net *net = sock_net(sk);
1874 __be32 group = imr->imr_multiaddr.s_addr; 1856 __be32 group = imr->imr_multiaddr.s_addr;
@@ -1878,7 +1860,9 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
1878 rtnl_lock(); 1860 rtnl_lock();
1879 in_dev = ip_mc_find_dev(net, imr); 1861 in_dev = ip_mc_find_dev(net, imr);
1880 ifindex = imr->imr_ifindex; 1862 ifindex = imr->imr_ifindex;
1881 for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp = &iml->next) { 1863 for (imlp = &inet->mc_list;
1864 (iml = rtnl_dereference(*imlp)) != NULL;
1865 imlp = &iml->next_rcu) {
1882 if (iml->multi.imr_multiaddr.s_addr != group) 1866 if (iml->multi.imr_multiaddr.s_addr != group)
1883 continue; 1867 continue;
1884 if (ifindex) { 1868 if (ifindex) {
@@ -1890,14 +1874,14 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
1890 1874
1891 (void) ip_mc_leave_src(sk, iml, in_dev); 1875 (void) ip_mc_leave_src(sk, iml, in_dev);
1892 1876
1893 rcu_assign_pointer(*imlp, iml->next); 1877 *imlp = iml->next_rcu;
1894 1878
1895 if (in_dev) 1879 if (in_dev)
1896 ip_mc_dec_group(in_dev, group); 1880 ip_mc_dec_group(in_dev, group);
1897 rtnl_unlock(); 1881 rtnl_unlock();
1898 /* decrease mem now to avoid the memleak warning */ 1882 /* decrease mem now to avoid the memleak warning */
1899 atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); 1883 atomic_sub(sizeof(*iml), &sk->sk_omem_alloc);
1900 call_rcu(&iml->rcu, ip_mc_socklist_reclaim); 1884 kfree_rcu(iml, rcu);
1901 return 0; 1885 return 0;
1902 } 1886 }
1903 if (!in_dev) 1887 if (!in_dev)
@@ -1936,7 +1920,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1936 } 1920 }
1937 err = -EADDRNOTAVAIL; 1921 err = -EADDRNOTAVAIL;
1938 1922
1939 for (pmc=inet->mc_list; pmc; pmc=pmc->next) { 1923 for_each_pmc_rtnl(inet, pmc) {
1940 if ((pmc->multi.imr_multiaddr.s_addr == 1924 if ((pmc->multi.imr_multiaddr.s_addr ==
1941 imr.imr_multiaddr.s_addr) && 1925 imr.imr_multiaddr.s_addr) &&
1942 (pmc->multi.imr_ifindex == imr.imr_ifindex)) 1926 (pmc->multi.imr_ifindex == imr.imr_ifindex))
@@ -1960,7 +1944,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1960 pmc->sfmode = omode; 1944 pmc->sfmode = omode;
1961 } 1945 }
1962 1946
1963 psl = pmc->sflist; 1947 psl = rtnl_dereference(pmc->sflist);
1964 if (!add) { 1948 if (!add) {
1965 if (!psl) 1949 if (!psl)
1966 goto done; /* err = -EADDRNOTAVAIL */ 1950 goto done; /* err = -EADDRNOTAVAIL */
@@ -2014,7 +1998,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
2014 newpsl->sl_addr[i] = psl->sl_addr[i]; 1998 newpsl->sl_addr[i] = psl->sl_addr[i];
2015 /* decrease mem now to avoid the memleak warning */ 1999 /* decrease mem now to avoid the memleak warning */
2016 atomic_sub(IP_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc); 2000 atomic_sub(IP_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc);
2017 call_rcu(&psl->rcu, ip_sf_socklist_reclaim); 2001 kfree_rcu(psl, rcu);
2018 } 2002 }
2019 rcu_assign_pointer(pmc->sflist, newpsl); 2003 rcu_assign_pointer(pmc->sflist, newpsl);
2020 psl = newpsl; 2004 psl = newpsl;
@@ -2079,7 +2063,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
2079 goto done; 2063 goto done;
2080 } 2064 }
2081 2065
2082 for (pmc=inet->mc_list; pmc; pmc=pmc->next) { 2066 for_each_pmc_rtnl(inet, pmc) {
2083 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && 2067 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr &&
2084 pmc->multi.imr_ifindex == imr.imr_ifindex) 2068 pmc->multi.imr_ifindex == imr.imr_ifindex)
2085 break; 2069 break;
@@ -2109,13 +2093,13 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
2109 (void) ip_mc_add_src(in_dev, &msf->imsf_multiaddr, 2093 (void) ip_mc_add_src(in_dev, &msf->imsf_multiaddr,
2110 msf->imsf_fmode, 0, NULL, 0); 2094 msf->imsf_fmode, 0, NULL, 0);
2111 } 2095 }
2112 psl = pmc->sflist; 2096 psl = rtnl_dereference(pmc->sflist);
2113 if (psl) { 2097 if (psl) {
2114 (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, 2098 (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode,
2115 psl->sl_count, psl->sl_addr, 0); 2099 psl->sl_count, psl->sl_addr, 0);
2116 /* decrease mem now to avoid the memleak warning */ 2100 /* decrease mem now to avoid the memleak warning */
2117 atomic_sub(IP_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc); 2101 atomic_sub(IP_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc);
2118 call_rcu(&psl->rcu, ip_sf_socklist_reclaim); 2102 kfree_rcu(psl, rcu);
2119 } else 2103 } else
2120 (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, 2104 (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode,
2121 0, NULL, 0); 2105 0, NULL, 0);
@@ -2157,7 +2141,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
2157 } 2141 }
2158 err = -EADDRNOTAVAIL; 2142 err = -EADDRNOTAVAIL;
2159 2143
2160 for (pmc=inet->mc_list; pmc; pmc=pmc->next) { 2144 for_each_pmc_rtnl(inet, pmc) {
2161 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && 2145 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr &&
2162 pmc->multi.imr_ifindex == imr.imr_ifindex) 2146 pmc->multi.imr_ifindex == imr.imr_ifindex)
2163 break; 2147 break;
@@ -2165,7 +2149,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
2165 if (!pmc) /* must have a prior join */ 2149 if (!pmc) /* must have a prior join */
2166 goto done; 2150 goto done;
2167 msf->imsf_fmode = pmc->sfmode; 2151 msf->imsf_fmode = pmc->sfmode;
2168 psl = pmc->sflist; 2152 psl = rtnl_dereference(pmc->sflist);
2169 rtnl_unlock(); 2153 rtnl_unlock();
2170 if (!psl) { 2154 if (!psl) {
2171 len = 0; 2155 len = 0;
@@ -2210,7 +2194,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
2210 2194
2211 err = -EADDRNOTAVAIL; 2195 err = -EADDRNOTAVAIL;
2212 2196
2213 for (pmc=inet->mc_list; pmc; pmc=pmc->next) { 2197 for_each_pmc_rtnl(inet, pmc) {
2214 if (pmc->multi.imr_multiaddr.s_addr == addr && 2198 if (pmc->multi.imr_multiaddr.s_addr == addr &&
2215 pmc->multi.imr_ifindex == gsf->gf_interface) 2199 pmc->multi.imr_ifindex == gsf->gf_interface)
2216 break; 2200 break;
@@ -2218,7 +2202,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
2218 if (!pmc) /* must have a prior join */ 2202 if (!pmc) /* must have a prior join */
2219 goto done; 2203 goto done;
2220 gsf->gf_fmode = pmc->sfmode; 2204 gsf->gf_fmode = pmc->sfmode;
2221 psl = pmc->sflist; 2205 psl = rtnl_dereference(pmc->sflist);
2222 rtnl_unlock(); 2206 rtnl_unlock();
2223 count = psl ? psl->sl_count : 0; 2207 count = psl ? psl->sl_count : 0;
2224 copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc; 2208 copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc;
@@ -2259,7 +2243,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
2259 goto out; 2243 goto out;
2260 2244
2261 rcu_read_lock(); 2245 rcu_read_lock();
2262 for (pmc=rcu_dereference(inet->mc_list); pmc; pmc=rcu_dereference(pmc->next)) { 2246 for_each_pmc_rcu(inet, pmc) {
2263 if (pmc->multi.imr_multiaddr.s_addr == loc_addr && 2247 if (pmc->multi.imr_multiaddr.s_addr == loc_addr &&
2264 pmc->multi.imr_ifindex == dif) 2248 pmc->multi.imr_ifindex == dif)
2265 break; 2249 break;
@@ -2267,7 +2251,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
2267 ret = inet->mc_all; 2251 ret = inet->mc_all;
2268 if (!pmc) 2252 if (!pmc)
2269 goto unlock; 2253 goto unlock;
2270 psl = pmc->sflist; 2254 psl = rcu_dereference(pmc->sflist);
2271 ret = (pmc->sfmode == MCAST_EXCLUDE); 2255 ret = (pmc->sfmode == MCAST_EXCLUDE);
2272 if (!psl) 2256 if (!psl)
2273 goto unlock; 2257 goto unlock;
@@ -2302,31 +2286,29 @@ void ip_mc_drop_socket(struct sock *sk)
2302 return; 2286 return;
2303 2287
2304 rtnl_lock(); 2288 rtnl_lock();
2305 while ((iml = inet->mc_list) != NULL) { 2289 while ((iml = rtnl_dereference(inet->mc_list)) != NULL) {
2306 struct in_device *in_dev; 2290 struct in_device *in_dev;
2307 rcu_assign_pointer(inet->mc_list, iml->next);
2308 2291
2292 inet->mc_list = iml->next_rcu;
2309 in_dev = inetdev_by_index(net, iml->multi.imr_ifindex); 2293 in_dev = inetdev_by_index(net, iml->multi.imr_ifindex);
2310 (void) ip_mc_leave_src(sk, iml, in_dev); 2294 (void) ip_mc_leave_src(sk, iml, in_dev);
2311 if (in_dev != NULL) { 2295 if (in_dev != NULL)
2312 ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr); 2296 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 */ 2297 /* decrease mem now to avoid the memleak warning */
2316 atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); 2298 atomic_sub(sizeof(*iml), &sk->sk_omem_alloc);
2317 call_rcu(&iml->rcu, ip_mc_socklist_reclaim); 2299 kfree_rcu(iml, rcu);
2318 } 2300 }
2319 rtnl_unlock(); 2301 rtnl_unlock();
2320} 2302}
2321 2303
2322int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 proto) 2304/* called with rcu_read_lock() */
2305int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 proto)
2323{ 2306{
2324 struct ip_mc_list *im; 2307 struct ip_mc_list *im;
2325 struct ip_sf_list *psf; 2308 struct ip_sf_list *psf;
2326 int rv = 0; 2309 int rv = 0;
2327 2310
2328 read_lock(&in_dev->mc_list_lock); 2311 for_each_pmc_rcu(in_dev, im) {
2329 for (im=in_dev->mc_list; im; im=im->next) {
2330 if (im->multiaddr == mc_addr) 2312 if (im->multiaddr == mc_addr)
2331 break; 2313 break;
2332 } 2314 }
@@ -2347,7 +2329,6 @@ int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 p
2347 } else 2329 } else
2348 rv = 1; /* unspecified source; tentatively allow */ 2330 rv = 1; /* unspecified source; tentatively allow */
2349 } 2331 }
2350 read_unlock(&in_dev->mc_list_lock);
2351 return rv; 2332 return rv;
2352} 2333}
2353 2334
@@ -2373,13 +2354,11 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
2373 in_dev = __in_dev_get_rcu(state->dev); 2354 in_dev = __in_dev_get_rcu(state->dev);
2374 if (!in_dev) 2355 if (!in_dev)
2375 continue; 2356 continue;
2376 read_lock(&in_dev->mc_list_lock); 2357 im = rcu_dereference(in_dev->mc_list);
2377 im = in_dev->mc_list;
2378 if (im) { 2358 if (im) {
2379 state->in_dev = in_dev; 2359 state->in_dev = in_dev;
2380 break; 2360 break;
2381 } 2361 }
2382 read_unlock(&in_dev->mc_list_lock);
2383 } 2362 }
2384 return im; 2363 return im;
2385} 2364}
@@ -2387,11 +2366,9 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
2387static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_list *im) 2366static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_list *im)
2388{ 2367{
2389 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); 2368 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
2390 im = im->next;
2391 while (!im) {
2392 if (likely(state->in_dev != NULL))
2393 read_unlock(&state->in_dev->mc_list_lock);
2394 2369
2370 im = rcu_dereference(im->next_rcu);
2371 while (!im) {
2395 state->dev = next_net_device_rcu(state->dev); 2372 state->dev = next_net_device_rcu(state->dev);
2396 if (!state->dev) { 2373 if (!state->dev) {
2397 state->in_dev = NULL; 2374 state->in_dev = NULL;
@@ -2400,8 +2377,7 @@ static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_li
2400 state->in_dev = __in_dev_get_rcu(state->dev); 2377 state->in_dev = __in_dev_get_rcu(state->dev);
2401 if (!state->in_dev) 2378 if (!state->in_dev)
2402 continue; 2379 continue;
2403 read_lock(&state->in_dev->mc_list_lock); 2380 im = rcu_dereference(state->in_dev->mc_list);
2404 im = state->in_dev->mc_list;
2405 } 2381 }
2406 return im; 2382 return im;
2407} 2383}
@@ -2437,10 +2413,8 @@ static void igmp_mc_seq_stop(struct seq_file *seq, void *v)
2437 __releases(rcu) 2413 __releases(rcu)
2438{ 2414{
2439 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); 2415 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
2440 if (likely(state->in_dev != NULL)) { 2416
2441 read_unlock(&state->in_dev->mc_list_lock); 2417 state->in_dev = NULL;
2442 state->in_dev = NULL;
2443 }
2444 state->dev = NULL; 2418 state->dev = NULL;
2445 rcu_read_unlock(); 2419 rcu_read_unlock();
2446} 2420}
@@ -2462,7 +2436,7 @@ static int igmp_mc_seq_show(struct seq_file *seq, void *v)
2462 querier = "NONE"; 2436 querier = "NONE";
2463#endif 2437#endif
2464 2438
2465 if (state->in_dev->mc_list == im) { 2439 if (rcu_dereference(state->in_dev->mc_list) == im) {
2466 seq_printf(seq, "%d\t%-10s: %5d %7s\n", 2440 seq_printf(seq, "%d\t%-10s: %5d %7s\n",
2467 state->dev->ifindex, state->dev->name, state->in_dev->mc_count, querier); 2441 state->dev->ifindex, state->dev->name, state->in_dev->mc_count, querier);
2468 } 2442 }
@@ -2521,8 +2495,7 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
2521 idev = __in_dev_get_rcu(state->dev); 2495 idev = __in_dev_get_rcu(state->dev);
2522 if (unlikely(idev == NULL)) 2496 if (unlikely(idev == NULL))
2523 continue; 2497 continue;
2524 read_lock(&idev->mc_list_lock); 2498 im = rcu_dereference(idev->mc_list);
2525 im = idev->mc_list;
2526 if (likely(im != NULL)) { 2499 if (likely(im != NULL)) {
2527 spin_lock_bh(&im->lock); 2500 spin_lock_bh(&im->lock);
2528 psf = im->sources; 2501 psf = im->sources;
@@ -2533,7 +2506,6 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
2533 } 2506 }
2534 spin_unlock_bh(&im->lock); 2507 spin_unlock_bh(&im->lock);
2535 } 2508 }
2536 read_unlock(&idev->mc_list_lock);
2537 } 2509 }
2538 return psf; 2510 return psf;
2539} 2511}
@@ -2547,9 +2519,6 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l
2547 spin_unlock_bh(&state->im->lock); 2519 spin_unlock_bh(&state->im->lock);
2548 state->im = state->im->next; 2520 state->im = state->im->next;
2549 while (!state->im) { 2521 while (!state->im) {
2550 if (likely(state->idev != NULL))
2551 read_unlock(&state->idev->mc_list_lock);
2552
2553 state->dev = next_net_device_rcu(state->dev); 2522 state->dev = next_net_device_rcu(state->dev);
2554 if (!state->dev) { 2523 if (!state->dev) {
2555 state->idev = NULL; 2524 state->idev = NULL;
@@ -2558,8 +2527,7 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l
2558 state->idev = __in_dev_get_rcu(state->dev); 2527 state->idev = __in_dev_get_rcu(state->dev);
2559 if (!state->idev) 2528 if (!state->idev)
2560 continue; 2529 continue;
2561 read_lock(&state->idev->mc_list_lock); 2530 state->im = rcu_dereference(state->idev->mc_list);
2562 state->im = state->idev->mc_list;
2563 } 2531 }
2564 if (!state->im) 2532 if (!state->im)
2565 break; 2533 break;
@@ -2605,10 +2573,7 @@ static void igmp_mcf_seq_stop(struct seq_file *seq, void *v)
2605 spin_unlock_bh(&state->im->lock); 2573 spin_unlock_bh(&state->im->lock);
2606 state->im = NULL; 2574 state->im = NULL;
2607 } 2575 }
2608 if (likely(state->idev != NULL)) { 2576 state->idev = NULL;
2609 read_unlock(&state->idev->mc_list_lock);
2610 state->idev = NULL;
2611 }
2612 state->dev = NULL; 2577 state->dev = NULL;
2613 rcu_read_unlock(); 2578 rcu_read_unlock();
2614} 2579}