aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/igmp.c
diff options
context:
space:
mode:
authorDavid L Stevens <dlstevens@us.ibm.com>2005-07-08 20:39:23 -0400
committerDavid S. Miller <davem@davemloft.net>2005-07-08 20:39:23 -0400
commit8cdaaa15da58806ac3c75d96c40aef9e31445a25 (patch)
treebdeee63b026525963143d3ffe07d93110c25297c /net/ipv4/igmp.c
parentca9b907d140a5f249250d19f956129dbbbf84f73 (diff)
[IPV4]: multicast API "join" issues
1) Changes IP_ADD_SOURCE_MEMBERSHIP and MCAST_JOIN_SOURCE_GROUP to ignore EADDRINUSE errors on a "courtesy join" -- prior membership or not is ok for these. 2) Adds "leave group" equivalence of (INCLUDE, empty) filters in the delta-based API. Without this, mixing delta-based API calls that end in an (INCLUDE, empty) filter would not allow a subsequent regular IP_ADD_MEMBERSHIP. It also frees socket buffer memory that isn't needed for both the multicast group record and source filter. Signed-off-by: David L Stevens <dlstevens@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
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