aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/mcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/mcast.c')
-rw-r--r--net/ipv6/mcast.c17
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
279void ipv6_sock_mc_close(struct sock *sk) 279void __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
307void 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