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

Commit 54ff9ef3 authored by Marcelo Ricardo Leitner's avatar Marcelo Ricardo Leitner Committed by David S. Miller
Browse files

ipv4, ipv6: kill ip_mc_{join, leave}_group and ipv6_sock_mc_{join, drop}



in favor of their inner __ ones, which doesn't grab rtnl.

As these functions need to operate on a locked socket, we can't be
grabbing rtnl by then. It's too late and doing so causes reversed
locking.

So this patch:
- move rtnl handling to callers instead while already fixing some
  reversed locking situations, like on vxlan and ipvs code.
- renames __ ones to not have the __ mark:
  __ip_mc_{join,leave}_group -> ip_mc_{join,leave}_group
  __ipv6_sock_mc_{join,drop} -> ipv6_sock_mc_{join,drop}

Signed-off-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Acked-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent baf606d9
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1097,7 +1097,6 @@ EXPORT_SYMBOL_GPL(vxlan_sock_release);

/* Callback to update multicast group membership when first VNI on
 * multicast asddress is brought up
 * Done as workqueue because ip_mc_join_group acquires RTNL.
 */
static void vxlan_igmp_join(struct work_struct *work)
{
@@ -1107,6 +1106,7 @@ static void vxlan_igmp_join(struct work_struct *work)
	union vxlan_addr *ip = &vxlan->default_dst.remote_ip;
	int ifindex = vxlan->default_dst.remote_ifindex;

	rtnl_lock();
	lock_sock(sk);
	if (ip->sa.sa_family == AF_INET) {
		struct ip_mreqn mreq = {
@@ -1122,6 +1122,7 @@ static void vxlan_igmp_join(struct work_struct *work)
#endif
	}
	release_sock(sk);
	rtnl_unlock();

	vxlan_sock_release(vs);
	dev_put(vxlan->dev);
@@ -1136,6 +1137,7 @@ static void vxlan_igmp_leave(struct work_struct *work)
	union vxlan_addr *ip = &vxlan->default_dst.remote_ip;
	int ifindex = vxlan->default_dst.remote_ifindex;

	rtnl_lock();
	lock_sock(sk);
	if (ip->sa.sa_family == AF_INET) {
		struct ip_mreqn mreq = {
@@ -1152,6 +1154,7 @@ static void vxlan_igmp_leave(struct work_struct *work)
	}

	release_sock(sk);
	rtnl_unlock();

	vxlan_sock_release(vs);
	dev_put(vxlan->dev);
+0 −2
Original line number Diff line number Diff line
@@ -111,9 +111,7 @@ struct ip_mc_list {

extern int ip_check_mc_rcu(struct in_device *dev, __be32 mc_addr, __be32 src_addr, u16 proto);
extern int igmp_rcv(struct sk_buff *);
extern int __ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr);
extern int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr);
extern int __ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr);
extern int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr);
extern void ip_mc_drop_socket(struct sock *sk);
extern int ip_mc_source(int add, int omode, struct sock *sk,
+0 −4
Original line number Diff line number Diff line
@@ -942,10 +942,6 @@ void ipv6_sysctl_unregister(void);

int ipv6_sock_mc_join(struct sock *sk, int ifindex,
		      const struct in6_addr *addr);
int __ipv6_sock_mc_join(struct sock *sk, int ifindex,
			const struct in6_addr *addr);
int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
		      const struct in6_addr *addr);
int __ipv6_sock_mc_drop(struct sock *sk, int ifindex,
			const struct in6_addr *addr);
#endif /* _NET_IPV6_H */
+2 −2
Original line number Diff line number Diff line
@@ -560,9 +560,9 @@ static int ip_mc_config(struct sock *sk, bool join, const struct in_ifaddr *ifa)

	lock_sock(sk);
	if (join)
		ret = __ip_mc_join_group(sk, &mreq);
		ret = ip_mc_join_group(sk, &mreq);
	else
		ret = __ip_mc_leave_group(sk, &mreq);
		ret = ip_mc_leave_group(sk, &mreq);
	release_sock(sk);

	return ret;
+8 −33
Original line number Diff line number Diff line
@@ -1850,7 +1850,10 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc)
	pmc->sfcount[MCAST_EXCLUDE] = 1;
}

int __ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr)
/* Join a multicast group
 */

int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr)
{
	__be32 addr = imr->imr_multiaddr.s_addr;
	struct ip_mc_socklist *iml, *i;
@@ -1898,20 +1901,6 @@ int __ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr)
done:
	return err;
}
EXPORT_SYMBOL(__ip_mc_join_group);

/* Join a multicast group
 */
int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr)
{
	int ret;

	rtnl_lock();
	ret = __ip_mc_join_group(sk, imr);
	rtnl_unlock();

	return ret;
}
EXPORT_SYMBOL(ip_mc_join_group);

static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
@@ -1934,7 +1923,7 @@ static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
	return err;
}

int __ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
{
	struct inet_sock *inet = inet_sk(sk);
	struct ip_mc_socklist *iml;
@@ -1979,18 +1968,6 @@ int __ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
out:
	return ret;
}
EXPORT_SYMBOL(__ip_mc_leave_group);

int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
{
	int ret;

	rtnl_lock();
	ret = __ip_mc_leave_group(sk, imr);
	rtnl_unlock();

	return ret;
}
EXPORT_SYMBOL(ip_mc_leave_group);

int ip_mc_source(int add, int omode, struct sock *sk, struct
@@ -2010,7 +1987,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
	if (!ipv4_is_multicast(addr))
		return -EINVAL;

	rtnl_lock();
	ASSERT_RTNL();

	imr.imr_multiaddr.s_addr = mreqs->imr_multiaddr;
	imr.imr_address.s_addr = mreqs->imr_interface;
@@ -2124,9 +2101,8 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
	ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 1,
		&mreqs->imr_sourceaddr, 1);
done:
	rtnl_unlock();
	if (leavegroup)
		return ip_mc_leave_group(sk, &imr);
		err = ip_mc_leave_group(sk, &imr);
	return err;
}

@@ -2148,7 +2124,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
	    msf->imsf_fmode != MCAST_EXCLUDE)
		return -EINVAL;

	rtnl_lock();
	ASSERT_RTNL();

	imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
	imr.imr_address.s_addr = msf->imsf_interface;
@@ -2210,7 +2186,6 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
	pmc->sfmode = msf->imsf_fmode;
	err = 0;
done:
	rtnl_unlock();
	if (leavegroup)
		err = ip_mc_leave_group(sk, &imr);
	return err;
Loading