diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-01-14 16:35:31 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-29 02:02:05 +0300 |
commit | be185884b31093555dc10aa32efe0b73c835312e (patch) | |
tree | 245fe745220352a8757eb8cdff20c9ea59b45314 /net/ipv4/raw.c | |
parent | 8d96544475b236a0f319e492f4828aa8c0801c7f (diff) | |
download | linux-be185884b31093555dc10aa32efe0b73c835312e.tar.xz |
[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/ipv4/raw.c')
-rw-r--r-- | net/ipv4/raw.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 747911a8241c..a490a9d54712 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -116,16 +116,15 @@ static void raw_v4_unhash(struct sock *sk) raw_unhash_sk(sk, &raw_v4_hashinfo); } -static struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, - __be32 raddr, __be32 laddr, - int dif) +static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, + unsigned short num, __be32 raddr, __be32 laddr, int dif) { struct hlist_node *node; sk_for_each_from(sk, node) { struct inet_sock *inet = inet_sk(sk); - if (inet->num == num && + if (sk->sk_net == net && inet->num == num && !(inet->daddr && inet->daddr != raddr) && !(inet->rcv_saddr && inet->rcv_saddr != laddr) && !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) @@ -169,12 +168,15 @@ static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash) struct sock *sk; struct hlist_head *head; int delivered = 0; + struct net *net; read_lock(&raw_v4_hashinfo.lock); head = &raw_v4_hashinfo.ht[hash]; if (hlist_empty(head)) goto out; - sk = __raw_v4_lookup(__sk_head(head), iph->protocol, + + net = skb->dev->nd_net; + sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol, iph->saddr, iph->daddr, skb->dev->ifindex); @@ -187,7 +189,7 @@ static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash) if (clone) raw_rcv(sk, clone); } - sk = __raw_v4_lookup(sk_next(sk), iph->protocol, + sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol, iph->saddr, iph->daddr, skb->dev->ifindex); } @@ -273,6 +275,7 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info) int hash; struct sock *raw_sk; struct iphdr *iph; + struct net *net; hash = protocol & (RAW_HTABLE_SIZE - 1); @@ -280,8 +283,10 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info) raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]); if (raw_sk != NULL) { iph = (struct iphdr *)skb->data; - while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr, - iph->saddr, + net = skb->dev->nd_net; + + while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol, + iph->daddr, iph->saddr, skb->dev->ifindex)) != NULL) { raw_err(raw_sk, skb, info); raw_sk = sk_next(raw_sk); |