aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/igmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r--net/ipv4/igmp.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 111eb678cbac..e21ebe759907 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1724,6 +1724,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1724 struct in_device *in_dev = NULL; 1724 struct in_device *in_dev = NULL;
1725 struct inet_sock *inet = inet_sk(sk); 1725 struct inet_sock *inet = inet_sk(sk);
1726 struct ip_sf_socklist *psl; 1726 struct ip_sf_socklist *psl;
1727 int leavegroup = 0;
1727 int i, j, rv; 1728 int i, j, rv;
1728 1729
1729 if (!MULTICAST(addr)) 1730 if (!MULTICAST(addr))
@@ -1775,6 +1776,12 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1775 if (rv) /* source not found */ 1776 if (rv) /* source not found */
1776 goto done; 1777 goto done;
1777 1778
1779 /* special case - (INCLUDE, empty) == LEAVE_GROUP */
1780 if (psl->sl_count == 1 && omode == MCAST_INCLUDE) {
1781 leavegroup = 1;
1782 goto done;
1783 }
1784
1778 /* update the interface filter */ 1785 /* update the interface filter */
1779 ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, omode, 1, 1786 ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, omode, 1,
1780 &mreqs->imr_sourceaddr, 1); 1787 &mreqs->imr_sourceaddr, 1);
@@ -1831,6 +1838,8 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1831 &mreqs->imr_sourceaddr, 1); 1838 &mreqs->imr_sourceaddr, 1);
1832done: 1839done:
1833 rtnl_shunlock(); 1840 rtnl_shunlock();
1841 if (leavegroup)
1842 return ip_mc_leave_group(sk, &imr);
1834 return err; 1843 return err;
1835} 1844}
1836 1845