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

Commit 920a4611 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

udp: multicast packets need to check namespace



Current UDP multicast delivery is not namespace aware.

Signed-off-by: default avatarEric Dumazet <dada1@cosmosbay.com>
Acked-by: default avatarPavel Emelyanov <xemul@openvz.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d1a203ea
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -284,7 +284,7 @@ struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
}
EXPORT_SYMBOL_GPL(udp4_lib_lookup);

static inline struct sock *udp_v4_mcast_next(struct sock *sk,
static inline struct sock *udp_v4_mcast_next(struct net *net, struct sock *sk,
					     __be16 loc_port, __be32 loc_addr,
					     __be16 rmt_port, __be32 rmt_addr,
					     int dif)
@@ -296,7 +296,8 @@ static inline struct sock *udp_v4_mcast_next(struct sock *sk,
	sk_for_each_from(s, node) {
		struct inet_sock *inet = inet_sk(s);

		if (s->sk_hash != hnum					||
		if (!net_eq(sock_net(s), net)				||
		    s->sk_hash != hnum					||
		    (inet->daddr && inet->daddr != rmt_addr)		||
		    (inet->dport != rmt_port && inet->dport)		||
		    (inet->rcv_saddr && inet->rcv_saddr != loc_addr)	||
@@ -1079,15 +1080,16 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
	read_lock(&udp_hash_lock);
	sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]);
	dif = skb->dev->ifindex;
	sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
	sk = udp_v4_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif);
	if (sk) {
		struct sock *sknext = NULL;

		do {
			struct sk_buff *skb1 = skb;

			sknext = udp_v4_mcast_next(sk_next(sk), uh->dest, daddr,
						   uh->source, saddr, dif);
			sknext = udp_v4_mcast_next(net, sk_next(sk), uh->dest,
						   daddr, uh->source, saddr,
						   dif);
			if (sknext)
				skb1 = skb_clone(skb, GFP_ATOMIC);

+4 −4
Original line number Diff line number Diff line
@@ -328,7 +328,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
	return -1;
}

static struct sock *udp_v6_mcast_next(struct sock *sk,
static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk,
				      __be16 loc_port, struct in6_addr *loc_addr,
				      __be16 rmt_port, struct in6_addr *rmt_addr,
				      int dif)
@@ -340,7 +340,7 @@ static struct sock *udp_v6_mcast_next(struct sock *sk,
	sk_for_each_from(s, node) {
		struct inet_sock *inet = inet_sk(s);

		if (sock_net(s) != sock_net(sk))
		if (!net_eq(sock_net(s), net))
			continue;

		if (s->sk_hash == num && s->sk_family == PF_INET6) {
@@ -383,14 +383,14 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
	read_lock(&udp_hash_lock);
	sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]);
	dif = inet6_iif(skb);
	sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
	sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif);
	if (!sk) {
		kfree_skb(skb);
		goto out;
	}

	sk2 = sk;
	while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr,
	while ((sk2 = udp_v6_mcast_next(net, sk_next(sk2), uh->dest, daddr,
					uh->source, saddr, dif))) {
		struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
		if (buff) {