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/inet_hashtables.c | |
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/inet_hashtables.c')
-rw-r--r-- | net/ipv4/inet_hashtables.c | 29 |
1 files changed, 19 insertions, 10 deletions
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 | ||