From a558d13e2f527f4f5acddc94c19cda9c31568bb3 Mon Sep 17 00:00:00 2001 From: tedu Date: Thu, 18 Dec 2014 19:02:56 +0000 Subject: [PATCH] use siphash for pf_lb. for ipv6, we stretch it out a bit, but good enough. ok reyk --- sys/net/pf_lb.c | 58 +++++++++++++++++-------------------------------- 1 file changed, 20 insertions(+), 38 deletions(-) diff --git a/sys/net/pf_lb.c b/sys/net/pf_lb.c index 392fa85c843..bbaa2984b8d 100644 --- a/sys/net/pf_lb.c +++ b/sys/net/pf_lb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_lb.c,v 1.36 2014/11/18 02:37:31 tedu Exp $ */ +/* $OpenBSD: pf_lb.c,v 1.37 2014/12/18 19:02:56 tedu Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -53,6 +53,7 @@ #include #include +#include #include #include @@ -103,19 +104,6 @@ int pf_map_addr_sticky(sa_family_t, struct pf_rule *, struct pf_src_node **, struct pf_pool *, enum pf_sn_types); -#define mix(a,b,c) \ - do { \ - a -= b; a -= c; a ^= (c >> 13); \ - b -= c; b -= a; b ^= (a << 8); \ - c -= a; c -= b; c ^= (b >> 13); \ - a -= b; a -= c; a ^= (c >> 12); \ - b -= c; b -= a; b ^= (a << 16); \ - c -= a; c -= b; c ^= (b >> 5); \ - a -= b; a -= c; a ^= (c >> 3); \ - b -= c; b -= a; b ^= (a << 10); \ - c -= a; c -= b; c ^= (b >> 15); \ - } while (0) - /* * hash function based on bridge_hash in if_bridge.c */ @@ -123,38 +111,32 @@ void pf_hash(struct pf_addr *inaddr, struct pf_addr *hash, struct pf_poolhashkey *key, sa_family_t af) { - u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0]; +#ifdef INET6 + union { + uint64_t hash64; + uint32_t hash32[2]; + } h; +#endif switch (af) { #ifdef INET case AF_INET: - a += inaddr->addr32[0]; - b += key->key32[1]; - mix(a, b, c); - hash->addr32[0] = c + key->key32[2]; + hash->addr32[0] = SipHash24((SIPHASH_KEY *)key, + &inaddr->addr32[0], sizeof(inaddr->addr32[0])); break; #endif /* INET */ #ifdef INET6 case AF_INET6: - a += inaddr->addr32[0]; - b += inaddr->addr32[2]; - mix(a, b, c); - hash->addr32[0] = c; - a += inaddr->addr32[1]; - b += inaddr->addr32[3]; - c += key->key32[1]; - mix(a, b, c); - hash->addr32[1] = c; - a += inaddr->addr32[2]; - b += inaddr->addr32[1]; - c += key->key32[2]; - mix(a, b, c); - hash->addr32[2] = c; - a += inaddr->addr32[3]; - b += inaddr->addr32[0]; - c += key->key32[3]; - mix(a, b, c); - hash->addr32[3] = c; + h.hash64 = SipHash24((SIPHASH_KEY *)key, &inaddr->addr32[0], + 4 * sizeof(inaddr->addr32[0])); + hash->addr32[0] = h.hash32[0]; + hash->addr32[1] = h.hash32[1]; + /* + * siphash isn't big enough, but flipping it around is + * good enough here. + */ + hash->addr32[2] = ~h.hash32[1]; + hash->addr32[3] = ~h.hash32[0]; break; #endif /* INET6 */ } -- 2.20.1