From f6656b4df6b869d237449fa8f28410e92fc80e83 Mon Sep 17 00:00:00 2001 From: David L Stevens Date: Fri, 8 Jul 2005 17:39:23 -0700 Subject: [PATCH] --- yaml --- r: 4404 b: refs/heads/master c: 8cdaaa15da58806ac3c75d96c40aef9e31445a25 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/net/ipv4/igmp.c | 9 +++++++++ trunk/net/ipv4/ip_sockglue.c | 6 +++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index aaa922bb8b69..b03102d94495 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ca9b907d140a5f249250d19f956129dbbbf84f73 +refs/heads/master: 8cdaaa15da58806ac3c75d96c40aef9e31445a25 diff --git a/trunk/net/ipv4/igmp.c b/trunk/net/ipv4/igmp.c index 111eb678cbac..e21ebe759907 100644 --- a/trunk/net/ipv4/igmp.c +++ b/trunk/net/ipv4/igmp.c @@ -1724,6 +1724,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct struct in_device *in_dev = NULL; struct inet_sock *inet = inet_sk(sk); struct ip_sf_socklist *psl; + int leavegroup = 0; int i, j, rv; if (!MULTICAST(addr)) @@ -1775,6 +1776,12 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct if (rv) /* source not found */ goto done; + /* special case - (INCLUDE, empty) == LEAVE_GROUP */ + if (psl->sl_count == 1 && omode == MCAST_INCLUDE) { + leavegroup = 1; + goto done; + } + /* update the interface filter */ ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, omode, 1, &mreqs->imr_sourceaddr, 1); @@ -1831,6 +1838,8 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct &mreqs->imr_sourceaddr, 1); done: rtnl_shunlock(); + if (leavegroup) + return ip_mc_leave_group(sk, &imr); return err; } diff --git a/trunk/net/ipv4/ip_sockglue.c b/trunk/net/ipv4/ip_sockglue.c index f8b172f89811..fc7c481d0d79 100644 --- a/trunk/net/ipv4/ip_sockglue.c +++ b/trunk/net/ipv4/ip_sockglue.c @@ -677,11 +677,11 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, mreq.imr_address.s_addr = mreqs.imr_interface; mreq.imr_ifindex = 0; err = ip_mc_join_group(sk, &mreq); - if (err) + if (err && err != -EADDRINUSE) break; omode = MCAST_INCLUDE; add = 1; - } else /*IP_DROP_SOURCE_MEMBERSHIP */ { + } else /* IP_DROP_SOURCE_MEMBERSHIP */ { omode = MCAST_INCLUDE; add = 0; } @@ -754,7 +754,7 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, mreq.imr_address.s_addr = 0; mreq.imr_ifindex = greqs.gsr_interface; err = ip_mc_join_group(sk, &mreq); - if (err) + if (err && err != -EADDRINUSE) break; greqs.gsr_interface = mreq.imr_ifindex; omode = MCAST_INCLUDE;