diff options
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r-- | net/ipv4/igmp.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index dbbfa09de4e8..7af3146939dc 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -1849,13 +1849,14 @@ done: | |||
1849 | 1849 | ||
1850 | int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex) | 1850 | int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex) |
1851 | { | 1851 | { |
1852 | int err; | 1852 | int err = 0; |
1853 | struct ip_mreqn imr; | 1853 | struct ip_mreqn imr; |
1854 | u32 addr = msf->imsf_multiaddr; | 1854 | u32 addr = msf->imsf_multiaddr; |
1855 | struct ip_mc_socklist *pmc; | 1855 | struct ip_mc_socklist *pmc; |
1856 | struct in_device *in_dev; | 1856 | struct in_device *in_dev; |
1857 | struct inet_sock *inet = inet_sk(sk); | 1857 | struct inet_sock *inet = inet_sk(sk); |
1858 | struct ip_sf_socklist *newpsl, *psl; | 1858 | struct ip_sf_socklist *newpsl, *psl; |
1859 | int leavegroup = 0; | ||
1859 | 1860 | ||
1860 | if (!MULTICAST(addr)) | 1861 | if (!MULTICAST(addr)) |
1861 | return -EINVAL; | 1862 | return -EINVAL; |
@@ -1875,6 +1876,12 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex) | |||
1875 | goto done; | 1876 | goto done; |
1876 | } | 1877 | } |
1877 | 1878 | ||
1879 | /* special case - (INCLUDE, empty) == LEAVE_GROUP */ | ||
1880 | if (msf->imsf_fmode == MCAST_INCLUDE && msf->imsf_numsrc == 0) { | ||
1881 | leavegroup = 1; | ||
1882 | goto done; | ||
1883 | } | ||
1884 | |||
1878 | for (pmc=inet->mc_list; pmc; pmc=pmc->next) { | 1885 | for (pmc=inet->mc_list; pmc; pmc=pmc->next) { |
1879 | if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && | 1886 | if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && |
1880 | pmc->multi.imr_ifindex == imr.imr_ifindex) | 1887 | pmc->multi.imr_ifindex == imr.imr_ifindex) |
@@ -1915,6 +1922,8 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex) | |||
1915 | err = 0; | 1922 | err = 0; |
1916 | done: | 1923 | done: |
1917 | rtnl_shunlock(); | 1924 | rtnl_shunlock(); |
1925 | if (leavegroup) | ||
1926 | err = ip_mc_leave_group(sk, &imr); | ||
1918 | return err; | 1927 | return err; |
1919 | } | 1928 | } |
1920 | 1929 | ||