diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/inet_hashtables.c | 36 | ||||
-rw-r--r-- | net/ipv6/inet6_hashtables.c | 27 |
2 files changed, 42 insertions, 21 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 | ||
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index 73f1a00a96af..dea17fd28e50 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c | |||
@@ -87,11 +87,13 @@ struct sock *__inet6_lookup_established(struct net *net, | |||
87 | rcu_read_lock(); | 87 | rcu_read_lock(); |
88 | begin: | 88 | begin: |
89 | sk_nulls_for_each_rcu(sk, node, &head->chain) { | 89 | sk_nulls_for_each_rcu(sk, node, &head->chain) { |
90 | /* For IPV6 do the cheaper port and family tests first. */ | 90 | if (sk->sk_hash != hash) |
91 | if (INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { | 91 | continue; |
92 | if (likely(INET6_MATCH(sk, net, saddr, daddr, ports, dif))) { | ||
92 | if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) | 93 | if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) |
93 | goto begintw; | 94 | goto begintw; |
94 | if (!INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { | 95 | if (unlikely(!INET6_MATCH(sk, net, saddr, daddr, |
96 | ports, dif))) { | ||
95 | sock_put(sk); | 97 | sock_put(sk); |
96 | goto begin; | 98 | goto begin; |
97 | } | 99 | } |
@@ -104,12 +106,16 @@ begin: | |||
104 | begintw: | 106 | begintw: |
105 | /* Must check for a TIME_WAIT'er before going to listener hash. */ | 107 | /* Must check for a TIME_WAIT'er before going to listener hash. */ |
106 | sk_nulls_for_each_rcu(sk, node, &head->twchain) { | 108 | sk_nulls_for_each_rcu(sk, node, &head->twchain) { |
107 | if (INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { | 109 | if (sk->sk_hash != hash) |
110 | continue; | ||
111 | if (likely(INET6_TW_MATCH(sk, net, saddr, daddr, | ||
112 | ports, dif))) { | ||
108 | if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) { | 113 | if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) { |
109 | sk = NULL; | 114 | sk = NULL; |
110 | goto out; | 115 | goto out; |
111 | } | 116 | } |
112 | if (!INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { | 117 | if (unlikely(!INET6_TW_MATCH(sk, net, saddr, daddr, |
118 | ports, dif))) { | ||
113 | sock_put(sk); | 119 | sock_put(sk); |
114 | goto begintw; | 120 | goto begintw; |
115 | } | 121 | } |
@@ -236,9 +242,12 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, | |||
236 | 242 | ||
237 | /* Check TIME-WAIT sockets first. */ | 243 | /* Check TIME-WAIT sockets first. */ |
238 | sk_nulls_for_each(sk2, node, &head->twchain) { | 244 | sk_nulls_for_each(sk2, node, &head->twchain) { |
239 | tw = inet_twsk(sk2); | 245 | if (sk2->sk_hash != hash) |
246 | continue; | ||
240 | 247 | ||
241 | if (INET6_TW_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) { | 248 | if (likely(INET6_TW_MATCH(sk2, net, saddr, daddr, |
249 | ports, dif))) { | ||
250 | tw = inet_twsk(sk2); | ||
242 | if (twsk_unique(sk, sk2, twp)) | 251 | if (twsk_unique(sk, sk2, twp)) |
243 | goto unique; | 252 | goto unique; |
244 | else | 253 | else |
@@ -249,7 +258,9 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, | |||
249 | 258 | ||
250 | /* And established part... */ | 259 | /* And established part... */ |
251 | sk_nulls_for_each(sk2, node, &head->chain) { | 260 | sk_nulls_for_each(sk2, node, &head->chain) { |
252 | if (INET6_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) | 261 | if (sk2->sk_hash != hash) |
262 | continue; | ||
263 | if (likely(INET6_MATCH(sk2, net, saddr, daddr, ports, dif))) | ||
253 | goto not_unique; | 264 | goto not_unique; |
254 | } | 265 | } |
255 | 266 | ||