summaryrefslogtreecommitdiffstats
path: root/kernel/include/linux/netfilter/ip_set_jhash.h
blob: d5e0d6d039c57f57693b43c2965ab4e78f229ef4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#ifndef _LINUX_JHASH_H
#define _LINUX_JHASH_H
/* jhash.c: Jenkins hash support.
 *
 * Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net)
 *
 * http://burtleburtle.net/bob/hash/
 *
 * These are the credits from Bob's sources:
 *
 * lookup3.c, by Bob Jenkins, May 2006, Public Domain.
 *
 * These are functions for producing 32-bit hashes for hash table lookup.
 * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() 
 * are externally useful functions.  Routines to test the hash are included 
 * if SELF_TEST is defined.  You can use this free for any purpose.  It's in
 * the public domain.  It has no warranty.
 *
 * Copyright (C) 2009-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
 *
 * I've modified Bob's hash to be useful in the Linux kernel, and
 * any bugs present are my fault. The generic jhash is left out intentionally.
 * Jozsef
 */
#ifdef __KERNEL__
#include <asm/byteorder.h>

/* Best hash sizes are of power of two */
#define jhash_size(n)   ((u32)1<<(n))
/* Mask the hash value, i.e (value & jhash_mask(n)) instead of (value % n) */
#define jhash_mask(n)   (jhash_size(n)-1)

/* __jhash_rot - rotate 32 bit */
#define __jhash_rot(x,k)	(((x)<<(k)) | ((x)>>(32-(k))))

/* __jhash_mix -- mix 3 32-bit values reversibly. */
#define __jhash_mix(a,b,c)			\
{						\
  a -= c;  a ^= __jhash_rot(c, 4);  c += b;	\
  b -= a;  b ^= __jhash_rot(a, 6);  a += c;	\
  c -= b;  c ^= __jhash_rot(b, 8);  b += a;	\
  a -= c;  a ^= __jhash_rot(c,16);  c += b;	\
  b -= a;  b ^= __jhash_rot(a,19);  a += c;	\
  c -= b;  c ^= __jhash_rot(b, 4);  b += a;	\
}

/* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */
#define __jhash_final(a,b,c)			\
{						\
  c ^= b; c -= __jhash_rot(b,14);		\
  a ^= c; a -= __jhash_rot(c,11);		\
  b ^= a; b -= __jhash_rot(a,25);		\
  c ^= b; c -= __jhash_rot(b,16);		\
  a ^= c; a -= __jhash_rot(c,4);		\
  b ^= a; b -= __jhash_rot(a,14);		\
  c ^= b; c -= __jhash_rot(b,24);		\
}

#define JHASH_INITVAL		0xdeadbeef

/* jhash2 - hash an array of u32's
 * @k: the key which must be an array of u32's
 * @length: the number of u32's in the key
 * @initval: the previous hash, or an arbitray value
 *
 * Returns the hash value of the key.
 */
static inline u32 jhash2(const u32 *k, u32 length, u32 initval)
{
	u32 a, b, c;

	/* Set up the internal state */
	a = b = c = JHASH_INITVAL + (length<<2) + initval;

	/* Handle most of the key */
	while (length > 3) {
		a += k[0];
		b += k[1];
		c += k[2];
		__jhash_mix(a,b,c);
		length -= 3;
		k += 3;
	}
	
	/* Handle the last 3 u32's: all the case statements fall through */
	switch(length) {
	case 3: c += k[2];
	case 2: b += k[1];
	case 1: a += k[0];
	__jhash_final(a,b,c);
	case 0:	/* Nothing left to add */
		break;
	}

	return c;
}

/* jhash_3words - hash exactly 3, 2 or 1 word(s) */
static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
{
	a += JHASH_INITVAL;
	b += JHASH_INITVAL;
	c += initval;

	__jhash_final(a,b,c);
	
	return c;
}
static inline u32 jhash_2words(u32 a, u32 b, u32 initval)
{
	return jhash_3words(a, b, 0, initval);
}

static inline u32 jhash_1word(u32 a, u32 initval)
{
	 return jhash_3words(a, 0, 0, initval);
}

#endif /* __KERNEL__ */

#endif /* _LINUX_JHASH_H */