ipv6: use a stronger hash for tcp
It looks like its possible to open thousands of TCP IPv6 sessions on a server, all landing in a single slot of TCP hash table. Incoming packets have to lookup sockets in a very long list. We should hash all bits from foreign IPv6 addresses, using a salt and hash mix, not a simple XOR. inet6_ehashfn() can also separately use the ports, instead of xoring them. Reported-by: Neal Cardwell <ncardwell@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Yuchung Cheng <ycheng@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
0ab8a9f5fa
commit
08dcdbf6a7
@@ -248,8 +248,12 @@ EXPORT_SYMBOL(inet_listen);
|
||||
u32 inet_ehash_secret __read_mostly;
|
||||
EXPORT_SYMBOL(inet_ehash_secret);
|
||||
|
||||
u32 ipv6_hash_secret __read_mostly;
|
||||
EXPORT_SYMBOL(ipv6_hash_secret);
|
||||
|
||||
/*
|
||||
* inet_ehash_secret must be set exactly once
|
||||
* inet_ehash_secret must be set exactly once, and to a non nul value
|
||||
* ipv6_hash_secret must be set exactly once.
|
||||
*/
|
||||
void build_ehash_secret(void)
|
||||
{
|
||||
@@ -259,7 +263,8 @@ void build_ehash_secret(void)
|
||||
get_random_bytes(&rnd, sizeof(rnd));
|
||||
} while (rnd == 0);
|
||||
|
||||
cmpxchg(&inet_ehash_secret, 0, rnd);
|
||||
if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0)
|
||||
get_random_bytes(&ipv6_hash_secret, sizeof(ipv6_hash_secret));
|
||||
}
|
||||
EXPORT_SYMBOL(build_ehash_secret);
|
||||
|
||||
|
Reference in New Issue
Block a user