[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>
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 747911a..a490a9d 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -116,16 +116,15 @@
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 @@
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 @@
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 @@
int hash;
struct sock *raw_sk;
struct iphdr *iph;
+ struct net *net;
hash = protocol & (RAW_HTABLE_SIZE - 1);
@@ -280,8 +283,10 @@
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);