diff options
author | Jesper Dangaard Brouer <brouer@redhat.com> | 2018-08-10 14:02:57 +0200 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2018-08-10 16:07:49 +0200 |
commit | 11395686586bc9ca867b3f27501fd6c48244187a (patch) | |
tree | 4f53275a6ac49883aae2eb93e96425c6c8bd4f8b /samples | |
parent | eb91e4d4db06adef06e7f50c02813c13c6ca5a5b (diff) | |
download | linux-11395686586bc9ca867b3f27501fd6c48244187a.tar.gz linux-11395686586bc9ca867b3f27501fd6c48244187a.tar.bz2 linux-11395686586bc9ca867b3f27501fd6c48244187a.zip |
samples/bpf: add Paul Hsieh's (LGPL 2.1) hash function SuperFastHash
Adjusted function call API to take an initval. This allow the API
user to set the initial value, as a seed. This could also be used for
inputting the previous hash.
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'samples')
-rw-r--r-- | samples/bpf/hash_func01.h | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/samples/bpf/hash_func01.h b/samples/bpf/hash_func01.h new file mode 100644 index 000000000000..38255812e376 --- /dev/null +++ b/samples/bpf/hash_func01.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1 + * + * Based on Paul Hsieh's (LGPG 2.1) hash function + * From: http://www.azillionmonkeys.com/qed/hash.html + */ + +#define get16bits(d) (*((const __u16 *) (d))) + +static __always_inline +__u32 SuperFastHash (const char *data, int len, __u32 initval) { + __u32 hash = initval; + __u32 tmp; + int rem; + + if (len <= 0 || data == NULL) return 0; + + rem = len & 3; + len >>= 2; + + /* Main loop */ +#pragma clang loop unroll(full) + for (;len > 0; len--) { + hash += get16bits (data); + tmp = (get16bits (data+2) << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2*sizeof (__u16); + hash += hash >> 11; + } + + /* Handle end cases */ + switch (rem) { + case 3: hash += get16bits (data); + hash ^= hash << 16; + hash ^= ((signed char)data[sizeof (__u16)]) << 18; + hash += hash >> 11; + break; + case 2: hash += get16bits (data); + hash ^= hash << 11; + hash += hash >> 17; + break; + case 1: hash += (signed char)*data; + hash ^= hash << 10; + hash += hash >> 1; + } + + /* Force "avalanching" of final 127 bits */ + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash; +} |