summaryrefslogtreecommitdiff
path: root/net/ipv6/raw.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-01-14 05:35:31 -0800
committerDavid S. Miller <davem@davemloft.net>2008-01-28 15:02:05 -0800
commitbe185884b31093555dc10aa32efe0b73c835312e (patch)
tree245fe745220352a8757eb8cdff20c9ea59b45314 /net/ipv6/raw.c
parent8d96544475b236a0f319e492f4828aa8c0801c7f (diff)
[NETNS][RAW]: Make ipv[46] raw sockets lookup namespaces aware.
This requires just to pass the appropriate struct net pointer into __raw_v[46]_lookup and skip sockets that do not belong to a needed namespace. The proper net is get from skb->dev in all the cases. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r--net/ipv6/raw.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index cb0b110a2ac8..6f20086064b2 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -76,8 +76,9 @@ static void raw_v6_unhash(struct sock *sk)
}
-static struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
- struct in6_addr *loc_addr, struct in6_addr *rmt_addr, int dif)
+static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
+ unsigned short num, struct in6_addr *loc_addr,
+ struct in6_addr *rmt_addr, int dif)
{
struct hlist_node *node;
int is_multicast = ipv6_addr_is_multicast(loc_addr);
@@ -86,6 +87,9 @@ static struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
if (inet_sk(sk)->num == num) {
struct ipv6_pinfo *np = inet6_sk(sk);
+ if (sk->sk_net != net)
+ continue;
+
if (!ipv6_addr_any(&np->daddr) &&
!ipv6_addr_equal(&np->daddr, rmt_addr))
continue;
@@ -165,6 +169,7 @@ static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
struct sock *sk;
int delivered = 0;
__u8 hash;
+ struct net *net;
saddr = &ipv6_hdr(skb)->saddr;
daddr = saddr + 1;
@@ -182,7 +187,8 @@ static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
if (sk == NULL)
goto out;
- sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, IP6CB(skb)->iif);
+ net = skb->dev->nd_net;
+ sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, IP6CB(skb)->iif);
while (sk) {
int filtered;
@@ -225,7 +231,7 @@ static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
rawv6_rcv(sk, clone);
}
}
- sk = __raw_v6_lookup(sk_next(sk), nexthdr, daddr, saddr,
+ sk = __raw_v6_lookup(net, sk_next(sk), nexthdr, daddr, saddr,
IP6CB(skb)->iif);
}
out:
@@ -359,6 +365,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
struct sock *sk;
int hash;
struct in6_addr *saddr, *daddr;
+ struct net *net;
hash = nexthdr & (RAW_HTABLE_SIZE - 1);
@@ -367,8 +374,9 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
if (sk != NULL) {
saddr = &ipv6_hdr(skb)->saddr;
daddr = &ipv6_hdr(skb)->daddr;
+ net = skb->dev->nd_net;
- while ((sk = __raw_v6_lookup(sk, nexthdr, saddr, daddr,
+ while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr,
IP6CB(skb)->iif))) {
rawv6_err(sk, skb, NULL, type, code,
inner_offset, info);