diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-01-14 08:35:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:02:05 -0500 |
commit | be185884b31093555dc10aa32efe0b73c835312e (patch) | |
tree | 245fe745220352a8757eb8cdff20c9ea59b45314 /net/ipv4/raw.c | |
parent | 8d96544475b236a0f319e492f4828aa8c0801c7f (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/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) | |||
116 | raw_unhash_sk(sk, &raw_v4_hashinfo); | 116 | raw_unhash_sk(sk, &raw_v4_hashinfo); |
117 | } | 117 | } |
118 | 118 | ||
119 | static struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, | 119 | static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, |
120 | __be32 raddr, __be32 laddr, | 120 | unsigned short num, __be32 raddr, __be32 laddr, int dif) |
121 | int dif) | ||
122 | { | 121 | { |
123 | struct hlist_node *node; | 122 | struct hlist_node *node; |
124 | 123 | ||
125 | sk_for_each_from(sk, node) { | 124 | sk_for_each_from(sk, node) { |
126 | struct inet_sock *inet = inet_sk(sk); | 125 | struct inet_sock *inet = inet_sk(sk); |
127 | 126 | ||
128 | if (inet->num == num && | 127 | if (sk->sk_net == net && inet->num == num && |
129 | !(inet->daddr && inet->daddr != raddr) && | 128 | !(inet->daddr && inet->daddr != raddr) && |
130 | !(inet->rcv_saddr && inet->rcv_saddr != laddr) && | 129 | !(inet->rcv_saddr && inet->rcv_saddr != laddr) && |
131 | !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) | 130 | !(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) | |||
169 | struct sock *sk; | 168 | struct sock *sk; |
170 | struct hlist_head *head; | 169 | struct hlist_head *head; |
171 | int delivered = 0; | 170 | int delivered = 0; |
171 | struct net *net; | ||
172 | 172 | ||
173 | read_lock(&raw_v4_hashinfo.lock); | 173 | read_lock(&raw_v4_hashinfo.lock); |
174 | head = &raw_v4_hashinfo.ht[hash]; | 174 | head = &raw_v4_hashinfo.ht[hash]; |
175 | if (hlist_empty(head)) | 175 | if (hlist_empty(head)) |
176 | goto out; | 176 | goto out; |
177 | sk = __raw_v4_lookup(__sk_head(head), iph->protocol, | 177 | |
178 | net = skb->dev->nd_net; | ||
179 | sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol, | ||
178 | iph->saddr, iph->daddr, | 180 | iph->saddr, iph->daddr, |
179 | skb->dev->ifindex); | 181 | skb->dev->ifindex); |
180 | 182 | ||
@@ -187,7 +189,7 @@ static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash) | |||
187 | if (clone) | 189 | if (clone) |
188 | raw_rcv(sk, clone); | 190 | raw_rcv(sk, clone); |
189 | } | 191 | } |
190 | sk = __raw_v4_lookup(sk_next(sk), iph->protocol, | 192 | sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol, |
191 | iph->saddr, iph->daddr, | 193 | iph->saddr, iph->daddr, |
192 | skb->dev->ifindex); | 194 | skb->dev->ifindex); |
193 | } | 195 | } |
@@ -273,6 +275,7 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info) | |||
273 | int hash; | 275 | int hash; |
274 | struct sock *raw_sk; | 276 | struct sock *raw_sk; |
275 | struct iphdr *iph; | 277 | struct iphdr *iph; |
278 | struct net *net; | ||
276 | 279 | ||
277 | hash = protocol & (RAW_HTABLE_SIZE - 1); | 280 | hash = protocol & (RAW_HTABLE_SIZE - 1); |
278 | 281 | ||
@@ -280,8 +283,10 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info) | |||
280 | raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]); | 283 | raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]); |
281 | if (raw_sk != NULL) { | 284 | if (raw_sk != NULL) { |
282 | iph = (struct iphdr *)skb->data; | 285 | iph = (struct iphdr *)skb->data; |
283 | while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr, | 286 | net = skb->dev->nd_net; |
284 | iph->saddr, | 287 | |
288 | while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol, | ||
289 | iph->daddr, iph->saddr, | ||
285 | skb->dev->ifindex)) != NULL) { | 290 | skb->dev->ifindex)) != NULL) { |
286 | raw_err(raw_sk, skb, info); | 291 | raw_err(raw_sk, skb, info); |
287 | raw_sk = sk_next(raw_sk); | 292 | raw_sk = sk_next(raw_sk); |