forked from Minki/linux
udp: multicast packets need to check namespace
Current UDP multicast delivery is not namespace aware. Signed-off-by: Eric Dumazet <dada1@cosmosbay.com> Acked-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d1a203eac0
commit
920a46115c
@ -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);
|
||||
|
||||
|
@ -328,7 +328,7 @@ drop:
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user