diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/inet_hashtables.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 7880af970208..fa3ae8148710 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -237,12 +237,14 @@ struct sock *__inet_lookup_established(struct net *net, | |||
237 | rcu_read_lock(); | 237 | rcu_read_lock(); |
238 | begin: | 238 | begin: |
239 | sk_nulls_for_each_rcu(sk, node, &head->chain) { | 239 | sk_nulls_for_each_rcu(sk, node, &head->chain) { |
240 | if (INET_MATCH(sk, net, hash, acookie, | 240 | if (sk->sk_hash != hash) |
241 | saddr, daddr, ports, dif)) { | 241 | continue; |
242 | if (likely(INET_MATCH(sk, net, acookie, | ||
243 | saddr, daddr, ports, dif))) { | ||
242 | if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) | 244 | if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) |
243 | goto begintw; | 245 | goto begintw; |
244 | if (unlikely(!INET_MATCH(sk, net, hash, acookie, | 246 | if (unlikely(!INET_MATCH(sk, net, acookie, |
245 | saddr, daddr, ports, dif))) { | 247 | saddr, daddr, ports, dif))) { |
246 | sock_put(sk); | 248 | sock_put(sk); |
247 | goto begin; | 249 | goto begin; |
248 | } | 250 | } |
@@ -260,14 +262,18 @@ begin: | |||
260 | begintw: | 262 | begintw: |
261 | /* Must check for a TIME_WAIT'er before going to listener hash. */ | 263 | /* Must check for a TIME_WAIT'er before going to listener hash. */ |
262 | sk_nulls_for_each_rcu(sk, node, &head->twchain) { | 264 | sk_nulls_for_each_rcu(sk, node, &head->twchain) { |
263 | if (INET_TW_MATCH(sk, net, hash, acookie, | 265 | if (sk->sk_hash != hash) |
264 | saddr, daddr, ports, dif)) { | 266 | continue; |
267 | if (likely(INET_TW_MATCH(sk, net, acookie, | ||
268 | saddr, daddr, ports, | ||
269 | dif))) { | ||
265 | if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) { | 270 | if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) { |
266 | sk = NULL; | 271 | sk = NULL; |
267 | goto out; | 272 | goto out; |
268 | } | 273 | } |
269 | if (unlikely(!INET_TW_MATCH(sk, net, hash, acookie, | 274 | if (unlikely(!INET_TW_MATCH(sk, net, acookie, |
270 | saddr, daddr, ports, dif))) { | 275 | saddr, daddr, ports, |
276 | dif))) { | ||
271 | sock_put(sk); | 277 | sock_put(sk); |
272 | goto begintw; | 278 | goto begintw; |
273 | } | 279 | } |
@@ -314,10 +320,12 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, | |||
314 | 320 | ||
315 | /* Check TIME-WAIT sockets first. */ | 321 | /* Check TIME-WAIT sockets first. */ |
316 | sk_nulls_for_each(sk2, node, &head->twchain) { | 322 | sk_nulls_for_each(sk2, node, &head->twchain) { |
317 | tw = inet_twsk(sk2); | 323 | if (sk2->sk_hash != hash) |
324 | continue; | ||
318 | 325 | ||
319 | if (INET_TW_MATCH(sk2, net, hash, acookie, | 326 | if (likely(INET_TW_MATCH(sk2, net, acookie, |
320 | saddr, daddr, ports, dif)) { | 327 | saddr, daddr, ports, dif))) { |
328 | tw = inet_twsk(sk2); | ||
321 | if (twsk_unique(sk, sk2, twp)) | 329 | if (twsk_unique(sk, sk2, twp)) |
322 | goto unique; | 330 | goto unique; |
323 | else | 331 | else |
@@ -328,8 +336,10 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, | |||
328 | 336 | ||
329 | /* And established part... */ | 337 | /* And established part... */ |
330 | sk_nulls_for_each(sk2, node, &head->chain) { | 338 | sk_nulls_for_each(sk2, node, &head->chain) { |
331 | if (INET_MATCH(sk2, net, hash, acookie, | 339 | if (sk2->sk_hash != hash) |
332 | saddr, daddr, ports, dif)) | 340 | continue; |
341 | if (likely(INET_MATCH(sk2, net, acookie, | ||
342 | saddr, daddr, ports, dif))) | ||
333 | goto not_unique; | 343 | goto not_unique; |
334 | } | 344 | } |
335 | 345 | ||