diff options
Diffstat (limited to 'net/ipv6/mcast.c')
-rw-r--r-- | net/ipv6/mcast.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 75c1fc54f188..14a3903f1c82 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -276,16 +276,14 @@ static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net, | |||
276 | return idev; | 276 | return idev; |
277 | } | 277 | } |
278 | 278 | ||
279 | void ipv6_sock_mc_close(struct sock *sk) | 279 | void __ipv6_sock_mc_close(struct sock *sk) |
280 | { | 280 | { |
281 | struct ipv6_pinfo *np = inet6_sk(sk); | 281 | struct ipv6_pinfo *np = inet6_sk(sk); |
282 | struct ipv6_mc_socklist *mc_lst; | 282 | struct ipv6_mc_socklist *mc_lst; |
283 | struct net *net = sock_net(sk); | 283 | struct net *net = sock_net(sk); |
284 | 284 | ||
285 | if (!rcu_access_pointer(np->ipv6_mc_list)) | 285 | ASSERT_RTNL(); |
286 | return; | ||
287 | 286 | ||
288 | rtnl_lock(); | ||
289 | while ((mc_lst = rtnl_dereference(np->ipv6_mc_list)) != NULL) { | 287 | while ((mc_lst = rtnl_dereference(np->ipv6_mc_list)) != NULL) { |
290 | struct net_device *dev; | 288 | struct net_device *dev; |
291 | 289 | ||
@@ -303,8 +301,17 @@ void ipv6_sock_mc_close(struct sock *sk) | |||
303 | 301 | ||
304 | atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); | 302 | atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); |
305 | kfree_rcu(mc_lst, rcu); | 303 | kfree_rcu(mc_lst, rcu); |
306 | |||
307 | } | 304 | } |
305 | } | ||
306 | |||
307 | void ipv6_sock_mc_close(struct sock *sk) | ||
308 | { | ||
309 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
310 | |||
311 | if (!rcu_access_pointer(np->ipv6_mc_list)) | ||
312 | return; | ||
313 | rtnl_lock(); | ||
314 | __ipv6_sock_mc_close(sk); | ||
308 | rtnl_unlock(); | 315 | rtnl_unlock(); |
309 | } | 316 | } |
310 | 317 | ||