From ddbe503203855939946430e39bae58de11b70b69 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 18 Jul 2012 08:11:12 +0000 Subject: ipv6: add ipv6_addr_hash() helper Introduce ipv6_addr_hash() helper doing a XOR on all bits of an IPv6 address, with an optimized x86_64 version. Use it in flow dissector, as suggested by Andrew McGregor, to reduce hash collision probabilities in fq_codel (and other users of flow dissector) Use it in ip6_tunnel.c and use more bit shuffling, as suggested by David Laight, as existing hash was ignoring most of them. Use it in sunrpc and use more bit shuffling, using hash_32(). Use it in net/ipv6/addrconf.c, using hash_32() as well. As a cleanup, use it in net/ipv4/tcp_metrics.c Signed-off-by: Eric Dumazet Reported-by: Andrew McGregor Cc: Dave Taht Cc: Tom Herbert Cc: David Laight Cc: Joe Perches Signed-off-by: David S. Miller --- net/ipv4/tcp_metrics.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'net/ipv4/tcp_metrics.c') diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 5a38a2d5a95b..1a115b665792 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c @@ -211,10 +211,7 @@ static struct tcp_metrics_block *__tcp_get_metrics_req(struct request_sock *req, break; case AF_INET6: *(struct in6_addr *)addr.addr.a6 = inet6_rsk(req)->rmt_addr; - hash = ((__force unsigned int) addr.addr.a6[0] ^ - (__force unsigned int) addr.addr.a6[1] ^ - (__force unsigned int) addr.addr.a6[2] ^ - (__force unsigned int) addr.addr.a6[3]); + hash = ipv6_addr_hash(&inet6_rsk(req)->rmt_addr); break; default: return NULL; @@ -251,10 +248,7 @@ static struct tcp_metrics_block *__tcp_get_metrics_tw(struct inet_timewait_sock case AF_INET6: tw6 = inet6_twsk((struct sock *)tw); *(struct in6_addr *)addr.addr.a6 = tw6->tw_v6_daddr; - hash = ((__force unsigned int) addr.addr.a6[0] ^ - (__force unsigned int) addr.addr.a6[1] ^ - (__force unsigned int) addr.addr.a6[2] ^ - (__force unsigned int) addr.addr.a6[3]); + hash = ipv6_addr_hash(&tw6->tw_v6_daddr); break; default: return NULL; @@ -291,10 +285,7 @@ static struct tcp_metrics_block *tcp_get_metrics(struct sock *sk, break; case AF_INET6: *(struct in6_addr *)addr.addr.a6 = inet6_sk(sk)->daddr; - hash = ((__force unsigned int) addr.addr.a6[0] ^ - (__force unsigned int) addr.addr.a6[1] ^ - (__force unsigned int) addr.addr.a6[2] ^ - (__force unsigned int) addr.addr.a6[3]); + hash = ipv6_addr_hash(&inet6_sk(sk)->daddr); break; default: return NULL; -- cgit v1.2.3