Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8cdaaa15 authored by David L Stevens's avatar David L Stevens Committed by David S. Miller
Browse files

[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: default avatarDavid L Stevens <dlstevens@us.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ca9b907d
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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;
}

+3 −3
Original line number Diff line number Diff line
@@ -677,7 +677,7 @@ 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;
@@ -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;