mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-22 06:32:08 +00:00
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 <edumazet@google.com> Reported-by: Andrew McGregor <andrewmcgr@gmail.com> Cc: Dave Taht <dave.taht@gmail.com> Cc: Tom Herbert <therbert@google.com> Cc: David Laight <David.Laight@ACULAB.COM> Cc: Joe Perches <joe@perches.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
dc9059512c
commit
ddbe503203
7 changed files with 45 additions and 54 deletions
|
@ -104,23 +104,9 @@ static void ip_map_put(struct kref *kref)
|
|||
kfree(im);
|
||||
}
|
||||
|
||||
#if IP_HASHBITS == 8
|
||||
/* hash_long on a 64 bit machine is currently REALLY BAD for
|
||||
* IP addresses in reverse-endian (i.e. on a little-endian machine).
|
||||
* So use a trivial but reliable hash instead
|
||||
*/
|
||||
static inline int hash_ip(__be32 ip)
|
||||
static inline int hash_ip6(const struct in6_addr *ip)
|
||||
{
|
||||
int hash = (__force u32)ip ^ ((__force u32)ip>>16);
|
||||
return (hash ^ (hash>>8)) & 0xff;
|
||||
}
|
||||
#endif
|
||||
static inline int hash_ip6(struct in6_addr ip)
|
||||
{
|
||||
return (hash_ip(ip.s6_addr32[0]) ^
|
||||
hash_ip(ip.s6_addr32[1]) ^
|
||||
hash_ip(ip.s6_addr32[2]) ^
|
||||
hash_ip(ip.s6_addr32[3]));
|
||||
return hash_32(ipv6_addr_hash(ip), IP_HASHBITS);
|
||||
}
|
||||
static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
|
||||
{
|
||||
|
@ -301,7 +287,7 @@ static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class,
|
|||
ip.m_addr = *addr;
|
||||
ch = sunrpc_cache_lookup(cd, &ip.h,
|
||||
hash_str(class, IP_HASHBITS) ^
|
||||
hash_ip6(*addr));
|
||||
hash_ip6(addr));
|
||||
|
||||
if (ch)
|
||||
return container_of(ch, struct ip_map, h);
|
||||
|
@ -331,7 +317,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
|
|||
ip.h.expiry_time = expiry;
|
||||
ch = sunrpc_cache_update(cd, &ip.h, &ipm->h,
|
||||
hash_str(ipm->m_class, IP_HASHBITS) ^
|
||||
hash_ip6(ipm->m_addr));
|
||||
hash_ip6(&ipm->m_addr));
|
||||
if (!ch)
|
||||
return -ENOMEM;
|
||||
cache_put(ch, cd);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue