diff options
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r-- | net/ipv4/igmp.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 6748d420f714..db710b059bab 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -1944,6 +1944,10 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | |||
1944 | 1944 | ||
1945 | rtnl_lock(); | 1945 | rtnl_lock(); |
1946 | in_dev = ip_mc_find_dev(net, imr); | 1946 | in_dev = ip_mc_find_dev(net, imr); |
1947 | if (!in_dev) { | ||
1948 | ret = -ENODEV; | ||
1949 | goto out; | ||
1950 | } | ||
1947 | ifindex = imr->imr_ifindex; | 1951 | ifindex = imr->imr_ifindex; |
1948 | for (imlp = &inet->mc_list; | 1952 | for (imlp = &inet->mc_list; |
1949 | (iml = rtnl_dereference(*imlp)) != NULL; | 1953 | (iml = rtnl_dereference(*imlp)) != NULL; |
@@ -1961,16 +1965,14 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | |||
1961 | 1965 | ||
1962 | *imlp = iml->next_rcu; | 1966 | *imlp = iml->next_rcu; |
1963 | 1967 | ||
1964 | if (in_dev) | 1968 | ip_mc_dec_group(in_dev, group); |
1965 | ip_mc_dec_group(in_dev, group); | ||
1966 | rtnl_unlock(); | 1969 | rtnl_unlock(); |
1967 | /* decrease mem now to avoid the memleak warning */ | 1970 | /* decrease mem now to avoid the memleak warning */ |
1968 | atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); | 1971 | atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); |
1969 | kfree_rcu(iml, rcu); | 1972 | kfree_rcu(iml, rcu); |
1970 | return 0; | 1973 | return 0; |
1971 | } | 1974 | } |
1972 | if (!in_dev) | 1975 | out: |
1973 | ret = -ENODEV; | ||
1974 | rtnl_unlock(); | 1976 | rtnl_unlock(); |
1975 | return ret; | 1977 | return ret; |
1976 | } | 1978 | } |