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.c50
1 files changed, 24 insertions, 26 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index d41e5de79a82..76c08402c933 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1899,8 +1899,9 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1899 err = -EADDRNOTAVAIL; 1899 err = -EADDRNOTAVAIL;
1900 1900
1901 for (pmc=inet->mc_list; pmc; pmc=pmc->next) { 1901 for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
1902 if (pmc->multi.imr_multiaddr.s_addr == imr.imr_multiaddr.s_addr 1902 if ((pmc->multi.imr_multiaddr.s_addr ==
1903 && pmc->multi.imr_ifindex == imr.imr_ifindex) 1903 imr.imr_multiaddr.s_addr) &&
1904 (pmc->multi.imr_ifindex == imr.imr_ifindex))
1904 break; 1905 break;
1905 } 1906 }
1906 if (!pmc) { /* must have a prior join */ 1907 if (!pmc) { /* must have a prior join */
@@ -2311,9 +2312,10 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
2311 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); 2312 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
2312 2313
2313 state->in_dev = NULL; 2314 state->in_dev = NULL;
2314 for_each_netdev(net, state->dev) { 2315 for_each_netdev_rcu(net, state->dev) {
2315 struct in_device *in_dev; 2316 struct in_device *in_dev;
2316 in_dev = in_dev_get(state->dev); 2317
2318 in_dev = __in_dev_get_rcu(state->dev);
2317 if (!in_dev) 2319 if (!in_dev)
2318 continue; 2320 continue;
2319 read_lock(&in_dev->mc_list_lock); 2321 read_lock(&in_dev->mc_list_lock);
@@ -2323,7 +2325,6 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
2323 break; 2325 break;
2324 } 2326 }
2325 read_unlock(&in_dev->mc_list_lock); 2327 read_unlock(&in_dev->mc_list_lock);
2326 in_dev_put(in_dev);
2327 } 2328 }
2328 return im; 2329 return im;
2329} 2330}
@@ -2333,16 +2334,15 @@ static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_li
2333 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); 2334 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
2334 im = im->next; 2335 im = im->next;
2335 while (!im) { 2336 while (!im) {
2336 if (likely(state->in_dev != NULL)) { 2337 if (likely(state->in_dev != NULL))
2337 read_unlock(&state->in_dev->mc_list_lock); 2338 read_unlock(&state->in_dev->mc_list_lock);
2338 in_dev_put(state->in_dev); 2339
2339 } 2340 state->dev = next_net_device_rcu(state->dev);
2340 state->dev = next_net_device(state->dev);
2341 if (!state->dev) { 2341 if (!state->dev) {
2342 state->in_dev = NULL; 2342 state->in_dev = NULL;
2343 break; 2343 break;
2344 } 2344 }
2345 state->in_dev = in_dev_get(state->dev); 2345 state->in_dev = __in_dev_get_rcu(state->dev);
2346 if (!state->in_dev) 2346 if (!state->in_dev)
2347 continue; 2347 continue;
2348 read_lock(&state->in_dev->mc_list_lock); 2348 read_lock(&state->in_dev->mc_list_lock);
@@ -2361,9 +2361,9 @@ static struct ip_mc_list *igmp_mc_get_idx(struct seq_file *seq, loff_t pos)
2361} 2361}
2362 2362
2363static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos) 2363static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos)
2364 __acquires(dev_base_lock) 2364 __acquires(rcu)
2365{ 2365{
2366 read_lock(&dev_base_lock); 2366 rcu_read_lock();
2367 return *pos ? igmp_mc_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; 2367 return *pos ? igmp_mc_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
2368} 2368}
2369 2369
@@ -2379,16 +2379,15 @@ static void *igmp_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2379} 2379}
2380 2380
2381static void igmp_mc_seq_stop(struct seq_file *seq, void *v) 2381static void igmp_mc_seq_stop(struct seq_file *seq, void *v)
2382 __releases(dev_base_lock) 2382 __releases(rcu)
2383{ 2383{
2384 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); 2384 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
2385 if (likely(state->in_dev != NULL)) { 2385 if (likely(state->in_dev != NULL)) {
2386 read_unlock(&state->in_dev->mc_list_lock); 2386 read_unlock(&state->in_dev->mc_list_lock);
2387 in_dev_put(state->in_dev);
2388 state->in_dev = NULL; 2387 state->in_dev = NULL;
2389 } 2388 }
2390 state->dev = NULL; 2389 state->dev = NULL;
2391 read_unlock(&dev_base_lock); 2390 rcu_read_unlock();
2392} 2391}
2393 2392
2394static int igmp_mc_seq_show(struct seq_file *seq, void *v) 2393static int igmp_mc_seq_show(struct seq_file *seq, void *v)
@@ -2462,9 +2461,9 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
2462 2461
2463 state->idev = NULL; 2462 state->idev = NULL;
2464 state->im = NULL; 2463 state->im = NULL;
2465 for_each_netdev(net, state->dev) { 2464 for_each_netdev_rcu(net, state->dev) {
2466 struct in_device *idev; 2465 struct in_device *idev;
2467 idev = in_dev_get(state->dev); 2466 idev = __in_dev_get_rcu(state->dev);
2468 if (unlikely(idev == NULL)) 2467 if (unlikely(idev == NULL))
2469 continue; 2468 continue;
2470 read_lock(&idev->mc_list_lock); 2469 read_lock(&idev->mc_list_lock);
@@ -2480,7 +2479,6 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
2480 spin_unlock_bh(&im->lock); 2479 spin_unlock_bh(&im->lock);
2481 } 2480 }
2482 read_unlock(&idev->mc_list_lock); 2481 read_unlock(&idev->mc_list_lock);
2483 in_dev_put(idev);
2484 } 2482 }
2485 return psf; 2483 return psf;
2486} 2484}
@@ -2494,16 +2492,15 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l
2494 spin_unlock_bh(&state->im->lock); 2492 spin_unlock_bh(&state->im->lock);
2495 state->im = state->im->next; 2493 state->im = state->im->next;
2496 while (!state->im) { 2494 while (!state->im) {
2497 if (likely(state->idev != NULL)) { 2495 if (likely(state->idev != NULL))
2498 read_unlock(&state->idev->mc_list_lock); 2496 read_unlock(&state->idev->mc_list_lock);
2499 in_dev_put(state->idev); 2497
2500 } 2498 state->dev = next_net_device_rcu(state->dev);
2501 state->dev = next_net_device(state->dev);
2502 if (!state->dev) { 2499 if (!state->dev) {
2503 state->idev = NULL; 2500 state->idev = NULL;
2504 goto out; 2501 goto out;
2505 } 2502 }
2506 state->idev = in_dev_get(state->dev); 2503 state->idev = __in_dev_get_rcu(state->dev);
2507 if (!state->idev) 2504 if (!state->idev)
2508 continue; 2505 continue;
2509 read_lock(&state->idev->mc_list_lock); 2506 read_lock(&state->idev->mc_list_lock);
@@ -2528,8 +2525,9 @@ static struct ip_sf_list *igmp_mcf_get_idx(struct seq_file *seq, loff_t pos)
2528} 2525}
2529 2526
2530static void *igmp_mcf_seq_start(struct seq_file *seq, loff_t *pos) 2527static void *igmp_mcf_seq_start(struct seq_file *seq, loff_t *pos)
2528 __acquires(rcu)
2531{ 2529{
2532 read_lock(&dev_base_lock); 2530 rcu_read_lock();
2533 return *pos ? igmp_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; 2531 return *pos ? igmp_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
2534} 2532}
2535 2533
@@ -2545,6 +2543,7 @@ static void *igmp_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2545} 2543}
2546 2544
2547static void igmp_mcf_seq_stop(struct seq_file *seq, void *v) 2545static void igmp_mcf_seq_stop(struct seq_file *seq, void *v)
2546 __releases(rcu)
2548{ 2547{
2549 struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq); 2548 struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq);
2550 if (likely(state->im != NULL)) { 2549 if (likely(state->im != NULL)) {
@@ -2553,11 +2552,10 @@ static void igmp_mcf_seq_stop(struct seq_file *seq, void *v)
2553 } 2552 }
2554 if (likely(state->idev != NULL)) { 2553 if (likely(state->idev != NULL)) {
2555 read_unlock(&state->idev->mc_list_lock); 2554 read_unlock(&state->idev->mc_list_lock);
2556 in_dev_put(state->idev);
2557 state->idev = NULL; 2555 state->idev = NULL;
2558 } 2556 }
2559 state->dev = NULL; 2557 state->dev = NULL;
2560 read_unlock(&dev_base_lock); 2558 rcu_read_unlock();
2561} 2559}
2562 2560
2563static int igmp_mcf_seq_show(struct seq_file *seq, void *v) 2561static int igmp_mcf_seq_show(struct seq_file *seq, void *v)