diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-01-31 08:06:40 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-31 22:28:19 -0500 |
commit | c67499c0e772064b37ad75eb69b28fc218752636 (patch) | |
tree | 7d2873308f16080c0c3801d6024881360dd8e196 /net/ipv4 | |
parent | 941b1d22cc035ad58b3d9b44a1c74efac2d7e499 (diff) |
[NETNS]: Tcp-v4 sockets per-net lookup.
Add a net argument to inet_lookup and propagate it further
into lookup calls. Plus tune the __inet_check_established.
The dccp and inet_diag, which use that lookup functions
pass the init_net into them.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/inet_diag.c | 2 | ||||
-rw-r--r-- | net/ipv4/inet_hashtables.c | 29 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 15 |
3 files changed, 28 insertions, 18 deletions
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 4cfb15c461f1..95c9f1429228 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -268,7 +268,7 @@ static int inet_diag_get_exact(struct sk_buff *in_skb, | |||
268 | err = -EINVAL; | 268 | err = -EINVAL; |
269 | 269 | ||
270 | if (req->idiag_family == AF_INET) { | 270 | if (req->idiag_family == AF_INET) { |
271 | sk = inet_lookup(hashinfo, req->id.idiag_dst[0], | 271 | sk = inet_lookup(&init_net, hashinfo, req->id.idiag_dst[0], |
272 | req->id.idiag_dport, req->id.idiag_src[0], | 272 | req->id.idiag_dport, req->id.idiag_src[0], |
273 | req->id.idiag_sport, req->id.idiag_if); | 273 | req->id.idiag_sport, req->id.idiag_if); |
274 | } | 274 | } |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index db1e53a865c2..48d45008f749 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -127,7 +127,8 @@ EXPORT_SYMBOL(inet_listen_wlock); | |||
127 | * remote address for the connection. So always assume those are both | 127 | * remote address for the connection. So always assume those are both |
128 | * wildcarded during the search since they can never be otherwise. | 128 | * wildcarded during the search since they can never be otherwise. |
129 | */ | 129 | */ |
130 | static struct sock *inet_lookup_listener_slow(const struct hlist_head *head, | 130 | static struct sock *inet_lookup_listener_slow(struct net *net, |
131 | const struct hlist_head *head, | ||
131 | const __be32 daddr, | 132 | const __be32 daddr, |
132 | const unsigned short hnum, | 133 | const unsigned short hnum, |
133 | const int dif) | 134 | const int dif) |
@@ -139,7 +140,8 @@ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head, | |||
139 | sk_for_each(sk, node, head) { | 140 | sk_for_each(sk, node, head) { |
140 | const struct inet_sock *inet = inet_sk(sk); | 141 | const struct inet_sock *inet = inet_sk(sk); |
141 | 142 | ||
142 | if (inet->num == hnum && !ipv6_only_sock(sk)) { | 143 | if (sk->sk_net == net && inet->num == hnum && |
144 | !ipv6_only_sock(sk)) { | ||
143 | const __be32 rcv_saddr = inet->rcv_saddr; | 145 | const __be32 rcv_saddr = inet->rcv_saddr; |
144 | int score = sk->sk_family == PF_INET ? 1 : 0; | 146 | int score = sk->sk_family == PF_INET ? 1 : 0; |
145 | 147 | ||
@@ -165,7 +167,8 @@ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head, | |||
165 | } | 167 | } |
166 | 168 | ||
167 | /* Optimize the common listener case. */ | 169 | /* Optimize the common listener case. */ |
168 | struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo, | 170 | struct sock *__inet_lookup_listener(struct net *net, |
171 | struct inet_hashinfo *hashinfo, | ||
169 | const __be32 daddr, const unsigned short hnum, | 172 | const __be32 daddr, const unsigned short hnum, |
170 | const int dif) | 173 | const int dif) |
171 | { | 174 | { |
@@ -180,9 +183,9 @@ struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo, | |||
180 | if (inet->num == hnum && !sk->sk_node.next && | 183 | if (inet->num == hnum && !sk->sk_node.next && |
181 | (!inet->rcv_saddr || inet->rcv_saddr == daddr) && | 184 | (!inet->rcv_saddr || inet->rcv_saddr == daddr) && |
182 | (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) && | 185 | (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) && |
183 | !sk->sk_bound_dev_if) | 186 | !sk->sk_bound_dev_if && sk->sk_net == net) |
184 | goto sherry_cache; | 187 | goto sherry_cache; |
185 | sk = inet_lookup_listener_slow(head, daddr, hnum, dif); | 188 | sk = inet_lookup_listener_slow(net, head, daddr, hnum, dif); |
186 | } | 189 | } |
187 | if (sk) { | 190 | if (sk) { |
188 | sherry_cache: | 191 | sherry_cache: |
@@ -193,7 +196,8 @@ sherry_cache: | |||
193 | } | 196 | } |
194 | EXPORT_SYMBOL_GPL(__inet_lookup_listener); | 197 | EXPORT_SYMBOL_GPL(__inet_lookup_listener); |
195 | 198 | ||
196 | struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo, | 199 | struct sock * __inet_lookup_established(struct net *net, |
200 | struct inet_hashinfo *hashinfo, | ||
197 | const __be32 saddr, const __be16 sport, | 201 | const __be32 saddr, const __be16 sport, |
198 | const __be32 daddr, const u16 hnum, | 202 | const __be32 daddr, const u16 hnum, |
199 | const int dif) | 203 | const int dif) |
@@ -212,13 +216,15 @@ struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo, | |||
212 | prefetch(head->chain.first); | 216 | prefetch(head->chain.first); |
213 | read_lock(lock); | 217 | read_lock(lock); |
214 | sk_for_each(sk, node, &head->chain) { | 218 | sk_for_each(sk, node, &head->chain) { |
215 | if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) | 219 | if (INET_MATCH(sk, net, hash, acookie, |
220 | saddr, daddr, ports, dif)) | ||
216 | goto hit; /* You sunk my battleship! */ | 221 | goto hit; /* You sunk my battleship! */ |
217 | } | 222 | } |
218 | 223 | ||
219 | /* Must check for a TIME_WAIT'er before going to listener hash. */ | 224 | /* Must check for a TIME_WAIT'er before going to listener hash. */ |
220 | sk_for_each(sk, node, &head->twchain) { | 225 | sk_for_each(sk, node, &head->twchain) { |
221 | if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) | 226 | if (INET_TW_MATCH(sk, net, hash, acookie, |
227 | saddr, daddr, ports, dif)) | ||
222 | goto hit; | 228 | goto hit; |
223 | } | 229 | } |
224 | sk = NULL; | 230 | sk = NULL; |
@@ -249,6 +255,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, | |||
249 | struct sock *sk2; | 255 | struct sock *sk2; |
250 | const struct hlist_node *node; | 256 | const struct hlist_node *node; |
251 | struct inet_timewait_sock *tw; | 257 | struct inet_timewait_sock *tw; |
258 | struct net *net = sk->sk_net; | ||
252 | 259 | ||
253 | prefetch(head->chain.first); | 260 | prefetch(head->chain.first); |
254 | write_lock(lock); | 261 | write_lock(lock); |
@@ -257,7 +264,8 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, | |||
257 | sk_for_each(sk2, node, &head->twchain) { | 264 | sk_for_each(sk2, node, &head->twchain) { |
258 | tw = inet_twsk(sk2); | 265 | tw = inet_twsk(sk2); |
259 | 266 | ||
260 | if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) { | 267 | if (INET_TW_MATCH(sk2, net, hash, acookie, |
268 | saddr, daddr, ports, dif)) { | ||
261 | if (twsk_unique(sk, sk2, twp)) | 269 | if (twsk_unique(sk, sk2, twp)) |
262 | goto unique; | 270 | goto unique; |
263 | else | 271 | else |
@@ -268,7 +276,8 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, | |||
268 | 276 | ||
269 | /* And established part... */ | 277 | /* And established part... */ |
270 | sk_for_each(sk2, node, &head->chain) { | 278 | sk_for_each(sk2, node, &head->chain) { |
271 | if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) | 279 | if (INET_MATCH(sk2, net, hash, acookie, |
280 | saddr, daddr, ports, dif)) | ||
272 | goto not_unique; | 281 | goto not_unique; |
273 | } | 282 | } |
274 | 283 | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 9aea88b8d4fc..77c1939a2b0d 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -369,8 +369,8 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) | |||
369 | return; | 369 | return; |
370 | } | 370 | } |
371 | 371 | ||
372 | sk = inet_lookup(&tcp_hashinfo, iph->daddr, th->dest, iph->saddr, | 372 | sk = inet_lookup(skb->dev->nd_net, &tcp_hashinfo, iph->daddr, th->dest, |
373 | th->source, inet_iif(skb)); | 373 | iph->saddr, th->source, inet_iif(skb)); |
374 | if (!sk) { | 374 | if (!sk) { |
375 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 375 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); |
376 | return; | 376 | return; |
@@ -1503,8 +1503,8 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) | |||
1503 | if (req) | 1503 | if (req) |
1504 | return tcp_check_req(sk, skb, req, prev); | 1504 | return tcp_check_req(sk, skb, req, prev); |
1505 | 1505 | ||
1506 | nsk = inet_lookup_established(&tcp_hashinfo, iph->saddr, th->source, | 1506 | nsk = inet_lookup_established(sk->sk_net, &tcp_hashinfo, iph->saddr, |
1507 | iph->daddr, th->dest, inet_iif(skb)); | 1507 | th->source, iph->daddr, th->dest, inet_iif(skb)); |
1508 | 1508 | ||
1509 | if (nsk) { | 1509 | if (nsk) { |
1510 | if (nsk->sk_state != TCP_TIME_WAIT) { | 1510 | if (nsk->sk_state != TCP_TIME_WAIT) { |
@@ -1661,8 +1661,8 @@ int tcp_v4_rcv(struct sk_buff *skb) | |||
1661 | TCP_SKB_CB(skb)->flags = iph->tos; | 1661 | TCP_SKB_CB(skb)->flags = iph->tos; |
1662 | TCP_SKB_CB(skb)->sacked = 0; | 1662 | TCP_SKB_CB(skb)->sacked = 0; |
1663 | 1663 | ||
1664 | sk = __inet_lookup(&tcp_hashinfo, iph->saddr, th->source, | 1664 | sk = __inet_lookup(skb->dev->nd_net, &tcp_hashinfo, iph->saddr, |
1665 | iph->daddr, th->dest, inet_iif(skb)); | 1665 | th->source, iph->daddr, th->dest, inet_iif(skb)); |
1666 | if (!sk) | 1666 | if (!sk) |
1667 | goto no_tcp_socket; | 1667 | goto no_tcp_socket; |
1668 | 1668 | ||
@@ -1735,7 +1735,8 @@ do_time_wait: | |||
1735 | } | 1735 | } |
1736 | switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { | 1736 | switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { |
1737 | case TCP_TW_SYN: { | 1737 | case TCP_TW_SYN: { |
1738 | struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo, | 1738 | struct sock *sk2 = inet_lookup_listener(skb->dev->nd_net, |
1739 | &tcp_hashinfo, | ||
1739 | iph->daddr, th->dest, | 1740 | iph->daddr, th->dest, |
1740 | inet_iif(skb)); | 1741 | inet_iif(skb)); |
1741 | if (sk2) { | 1742 | if (sk2) { |