diff options
-rw-r--r-- | include/linux/ipv6.h | 32 | ||||
-rw-r--r-- | include/net/inet_hashtables.h | 48 | ||||
-rw-r--r-- | include/net/inet_sock.h | 8 | ||||
-rw-r--r-- | include/net/inet_timewait_sock.h | 7 | ||||
-rw-r--r-- | include/net/sock.h | 25 | ||||
-rw-r--r-- | net/ipv4/inet_hashtables.c | 36 | ||||
-rw-r--r-- | net/ipv6/inet6_hashtables.c | 27 |
7 files changed, 115 insertions, 68 deletions
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 5e11905a4f01..12729e966dc9 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -364,20 +364,22 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk) | |||
364 | #define inet_v6_ipv6only(__sk) 0 | 364 | #define inet_v6_ipv6only(__sk) 0 |
365 | #endif /* IS_ENABLED(CONFIG_IPV6) */ | 365 | #endif /* IS_ENABLED(CONFIG_IPV6) */ |
366 | 366 | ||
367 | #define INET6_MATCH(__sk, __net, __hash, __saddr, __daddr, __ports, __dif)\ | 367 | #define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif) \ |
368 | (((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net) && \ | 368 | ((inet_sk(__sk)->inet_portpair == (__ports)) && \ |
369 | ((*((__portpair *)&(inet_sk(__sk)->inet_dport))) == (__ports)) && \ | 369 | ((__sk)->sk_family == AF_INET6) && \ |
370 | ((__sk)->sk_family == AF_INET6) && \ | 370 | ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr)) && \ |
371 | ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr)) && \ | 371 | ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \ |
372 | ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \ | 372 | (!(__sk)->sk_bound_dev_if || \ |
373 | (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) | 373 | ((__sk)->sk_bound_dev_if == (__dif))) && \ |
374 | 374 | net_eq(sock_net(__sk), (__net))) | |
375 | #define INET6_TW_MATCH(__sk, __net, __hash, __saddr, __daddr, __ports, __dif) \ | 375 | |
376 | (((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net) && \ | 376 | #define INET6_TW_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif) \ |
377 | (*((__portpair *)&(inet_twsk(__sk)->tw_dport)) == (__ports)) && \ | 377 | ((inet_twsk(__sk)->tw_portpair == (__ports)) && \ |
378 | ((__sk)->sk_family == PF_INET6) && \ | 378 | ((__sk)->sk_family == AF_INET6) && \ |
379 | (ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_daddr, (__saddr))) && \ | 379 | ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_daddr, (__saddr)) && \ |
380 | (ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_rcv_saddr, (__daddr))) && \ | 380 | ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_rcv_saddr, (__daddr)) && \ |
381 | (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) | 381 | (!(__sk)->sk_bound_dev_if || \ |
382 | ((__sk)->sk_bound_dev_if == (__dif))) && \ | ||
383 | net_eq(sock_net(__sk), (__net))) | ||
382 | 384 | ||
383 | #endif /* _IPV6_H */ | 385 | #endif /* _IPV6_H */ |
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 54be0287eb98..d1de4fbd45c2 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h | |||
@@ -299,30 +299,34 @@ typedef __u64 __bitwise __addrpair; | |||
299 | (((__force __u64)(__be32)(__daddr)) << 32) | \ | 299 | (((__force __u64)(__be32)(__daddr)) << 32) | \ |
300 | ((__force __u64)(__be32)(__saddr))); | 300 | ((__force __u64)(__be32)(__saddr))); |
301 | #endif /* __BIG_ENDIAN */ | 301 | #endif /* __BIG_ENDIAN */ |
302 | #define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ | 302 | #define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \ |
303 | (((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) && \ | 303 | ((inet_sk(__sk)->inet_portpair == (__ports)) && \ |
304 | ((*((__addrpair *)&(inet_sk(__sk)->inet_daddr))) == (__cookie)) && \ | 304 | (inet_sk(__sk)->inet_addrpair == (__cookie)) && \ |
305 | ((*((__portpair *)&(inet_sk(__sk)->inet_dport))) == (__ports)) && \ | 305 | (!(__sk)->sk_bound_dev_if || \ |
306 | (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) | 306 | ((__sk)->sk_bound_dev_if == (__dif))) && \ |
307 | #define INET_TW_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ | 307 | net_eq(sock_net(__sk), (__net))) |
308 | (((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) && \ | 308 | #define INET_TW_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif)\ |
309 | ((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \ | 309 | ((inet_twsk(__sk)->tw_portpair == (__ports)) && \ |
310 | ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \ | 310 | (inet_twsk(__sk)->tw_addrpair == (__cookie)) && \ |
311 | (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) | 311 | (!(__sk)->sk_bound_dev_if || \ |
312 | ((__sk)->sk_bound_dev_if == (__dif))) && \ | ||
313 | net_eq(sock_net(__sk), (__net))) | ||
312 | #else /* 32-bit arch */ | 314 | #else /* 32-bit arch */ |
313 | #define INET_ADDR_COOKIE(__name, __saddr, __daddr) | 315 | #define INET_ADDR_COOKIE(__name, __saddr, __daddr) |
314 | #define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif) \ | 316 | #define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \ |
315 | (((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) && \ | 317 | ((inet_sk(__sk)->inet_portpair == (__ports)) && \ |
316 | (inet_sk(__sk)->inet_daddr == (__saddr)) && \ | 318 | (inet_sk(__sk)->inet_daddr == (__saddr)) && \ |
317 | (inet_sk(__sk)->inet_rcv_saddr == (__daddr)) && \ | 319 | (inet_sk(__sk)->inet_rcv_saddr == (__daddr)) && \ |
318 | ((*((__portpair *)&(inet_sk(__sk)->inet_dport))) == (__ports)) && \ | 320 | (!(__sk)->sk_bound_dev_if || \ |
319 | (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) | 321 | ((__sk)->sk_bound_dev_if == (__dif))) && \ |
320 | #define INET_TW_MATCH(__sk, __net, __hash,__cookie, __saddr, __daddr, __ports, __dif) \ | 322 | net_eq(sock_net(__sk), (__net))) |
321 | (((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) && \ | 323 | #define INET_TW_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \ |
322 | (inet_twsk(__sk)->tw_daddr == (__saddr)) && \ | 324 | ((inet_twsk(__sk)->tw_portpair == (__ports)) && \ |
323 | (inet_twsk(__sk)->tw_rcv_saddr == (__daddr)) && \ | 325 | (inet_twsk(__sk)->tw_daddr == (__saddr)) && \ |
324 | ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \ | 326 | (inet_twsk(__sk)->tw_rcv_saddr == (__daddr)) && \ |
325 | (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) | 327 | (!(__sk)->sk_bound_dev_if || \ |
328 | ((__sk)->sk_bound_dev_if == (__dif))) && \ | ||
329 | net_eq(sock_net(__sk), (__net))) | ||
326 | #endif /* 64-bit arch */ | 330 | #endif /* 64-bit arch */ |
327 | 331 | ||
328 | /* | 332 | /* |
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 256c1ed2d69a..a4196cbc84ec 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h | |||
@@ -144,9 +144,11 @@ struct inet_sock { | |||
144 | /* Socket demultiplex comparisons on incoming packets. */ | 144 | /* Socket demultiplex comparisons on incoming packets. */ |
145 | #define inet_daddr sk.__sk_common.skc_daddr | 145 | #define inet_daddr sk.__sk_common.skc_daddr |
146 | #define inet_rcv_saddr sk.__sk_common.skc_rcv_saddr | 146 | #define inet_rcv_saddr sk.__sk_common.skc_rcv_saddr |
147 | #define inet_addrpair sk.__sk_common.skc_addrpair | ||
148 | #define inet_dport sk.__sk_common.skc_dport | ||
149 | #define inet_num sk.__sk_common.skc_num | ||
150 | #define inet_portpair sk.__sk_common.skc_portpair | ||
147 | 151 | ||
148 | __be16 inet_dport; | ||
149 | __u16 inet_num; | ||
150 | __be32 inet_saddr; | 152 | __be32 inet_saddr; |
151 | __s16 uc_ttl; | 153 | __s16 uc_ttl; |
152 | __u16 cmsg_flags; | 154 | __u16 cmsg_flags; |
@@ -154,6 +156,7 @@ struct inet_sock { | |||
154 | __u16 inet_id; | 156 | __u16 inet_id; |
155 | 157 | ||
156 | struct ip_options_rcu __rcu *inet_opt; | 158 | struct ip_options_rcu __rcu *inet_opt; |
159 | int rx_dst_ifindex; | ||
157 | __u8 tos; | 160 | __u8 tos; |
158 | __u8 min_ttl; | 161 | __u8 min_ttl; |
159 | __u8 mc_ttl; | 162 | __u8 mc_ttl; |
@@ -170,7 +173,6 @@ struct inet_sock { | |||
170 | int uc_index; | 173 | int uc_index; |
171 | int mc_index; | 174 | int mc_index; |
172 | __be32 mc_addr; | 175 | __be32 mc_addr; |
173 | int rx_dst_ifindex; | ||
174 | struct ip_mc_socklist __rcu *mc_list; | 176 | struct ip_mc_socklist __rcu *mc_list; |
175 | struct inet_cork_full cork; | 177 | struct inet_cork_full cork; |
176 | }; | 178 | }; |
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index ba52c830a7a5..7d658d577368 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h | |||
@@ -112,6 +112,11 @@ struct inet_timewait_sock { | |||
112 | #define tw_net __tw_common.skc_net | 112 | #define tw_net __tw_common.skc_net |
113 | #define tw_daddr __tw_common.skc_daddr | 113 | #define tw_daddr __tw_common.skc_daddr |
114 | #define tw_rcv_saddr __tw_common.skc_rcv_saddr | 114 | #define tw_rcv_saddr __tw_common.skc_rcv_saddr |
115 | #define tw_addrpair __tw_common.skc_addrpair | ||
116 | #define tw_dport __tw_common.skc_dport | ||
117 | #define tw_num __tw_common.skc_num | ||
118 | #define tw_portpair __tw_common.skc_portpair | ||
119 | |||
115 | int tw_timeout; | 120 | int tw_timeout; |
116 | volatile unsigned char tw_substate; | 121 | volatile unsigned char tw_substate; |
117 | unsigned char tw_rcv_wscale; | 122 | unsigned char tw_rcv_wscale; |
@@ -119,8 +124,6 @@ struct inet_timewait_sock { | |||
119 | /* Socket demultiplex comparisons on incoming packets. */ | 124 | /* Socket demultiplex comparisons on incoming packets. */ |
120 | /* these three are in inet_sock */ | 125 | /* these three are in inet_sock */ |
121 | __be16 tw_sport; | 126 | __be16 tw_sport; |
122 | __be16 tw_dport; | ||
123 | __u16 tw_num; | ||
124 | kmemcheck_bitfield_begin(flags); | 127 | kmemcheck_bitfield_begin(flags); |
125 | /* And these are ours. */ | 128 | /* And these are ours. */ |
126 | unsigned int tw_ipv6only : 1, | 129 | unsigned int tw_ipv6only : 1, |
diff --git a/include/net/sock.h b/include/net/sock.h index c945fba4f543..c4132c1b63a8 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -132,6 +132,8 @@ struct net; | |||
132 | * @skc_rcv_saddr: Bound local IPv4 addr | 132 | * @skc_rcv_saddr: Bound local IPv4 addr |
133 | * @skc_hash: hash value used with various protocol lookup tables | 133 | * @skc_hash: hash value used with various protocol lookup tables |
134 | * @skc_u16hashes: two u16 hash values used by UDP lookup tables | 134 | * @skc_u16hashes: two u16 hash values used by UDP lookup tables |
135 | * @skc_dport: placeholder for inet_dport/tw_dport | ||
136 | * @skc_num: placeholder for inet_num/tw_num | ||
135 | * @skc_family: network address family | 137 | * @skc_family: network address family |
136 | * @skc_state: Connection state | 138 | * @skc_state: Connection state |
137 | * @skc_reuse: %SO_REUSEADDR setting | 139 | * @skc_reuse: %SO_REUSEADDR setting |
@@ -149,16 +151,29 @@ struct net; | |||
149 | * for struct sock and struct inet_timewait_sock. | 151 | * for struct sock and struct inet_timewait_sock. |
150 | */ | 152 | */ |
151 | struct sock_common { | 153 | struct sock_common { |
152 | /* skc_daddr and skc_rcv_saddr must be grouped : | 154 | /* skc_daddr and skc_rcv_saddr must be grouped on a 8 bytes aligned |
153 | * cf INET_MATCH() and INET_TW_MATCH() | 155 | * address on 64bit arches : cf INET_MATCH() and INET_TW_MATCH() |
154 | */ | 156 | */ |
155 | __be32 skc_daddr; | 157 | union { |
156 | __be32 skc_rcv_saddr; | 158 | unsigned long skc_addrpair; |
157 | 159 | struct { | |
160 | __be32 skc_daddr; | ||
161 | __be32 skc_rcv_saddr; | ||
162 | }; | ||
163 | }; | ||
158 | union { | 164 | union { |
159 | unsigned int skc_hash; | 165 | unsigned int skc_hash; |
160 | __u16 skc_u16hashes[2]; | 166 | __u16 skc_u16hashes[2]; |
161 | }; | 167 | }; |
168 | /* skc_dport && skc_num must be grouped as well */ | ||
169 | union { | ||
170 | u32 skc_portpair; | ||
171 | struct { | ||
172 | __be16 skc_dport; | ||
173 | __u16 skc_num; | ||
174 | }; | ||
175 | }; | ||
176 | |||
162 | unsigned short skc_family; | 177 | unsigned short skc_family; |
163 | volatile unsigned char skc_state; | 178 | volatile unsigned char skc_state; |
164 | unsigned char skc_reuse; | 179 | unsigned char skc_reuse; |
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 | ||