|
@@ -2436,17 +2436,17 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
|
|
|
{
|
|
|
int err;
|
|
|
|
|
|
- /* callers have the socket lock and rtnl lock
|
|
|
- * so no other readers or writers of iml or its sflist
|
|
|
- */
|
|
|
+ write_lock_bh(&iml->sflock);
|
|
|
if (!iml->sflist) {
|
|
|
/* any-source empty exclude case */
|
|
|
- return ip6_mc_del_src(idev, &iml->addr, iml->sfmode, 0, NULL, 0);
|
|
|
+ err = ip6_mc_del_src(idev, &iml->addr, iml->sfmode, 0, NULL, 0);
|
|
|
+ } else {
|
|
|
+ err = ip6_mc_del_src(idev, &iml->addr, iml->sfmode,
|
|
|
+ iml->sflist->sl_count, iml->sflist->sl_addr, 0);
|
|
|
+ sock_kfree_s(sk, iml->sflist, IP6_SFLSIZE(iml->sflist->sl_max));
|
|
|
+ iml->sflist = NULL;
|
|
|
}
|
|
|
- err = ip6_mc_del_src(idev, &iml->addr, iml->sfmode,
|
|
|
- iml->sflist->sl_count, iml->sflist->sl_addr, 0);
|
|
|
- sock_kfree_s(sk, iml->sflist, IP6_SFLSIZE(iml->sflist->sl_max));
|
|
|
- iml->sflist = NULL;
|
|
|
+ write_unlock_bh(&iml->sflock);
|
|
|
return err;
|
|
|
}
|
|
|
|