xref: /xnu-12377.41.6/bsd/net/flowhash.c (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
1*bbb1b6f9SApple OSS Distributions /*
2*bbb1b6f9SApple OSS Distributions  * Copyright (c) 2011-2022 Apple Inc. All rights reserved.
3*bbb1b6f9SApple OSS Distributions  *
4*bbb1b6f9SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*bbb1b6f9SApple OSS Distributions  *
6*bbb1b6f9SApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7*bbb1b6f9SApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8*bbb1b6f9SApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9*bbb1b6f9SApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10*bbb1b6f9SApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11*bbb1b6f9SApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12*bbb1b6f9SApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13*bbb1b6f9SApple OSS Distributions  * terms of an Apple operating system software license agreement.
14*bbb1b6f9SApple OSS Distributions  *
15*bbb1b6f9SApple OSS Distributions  * Please obtain a copy of the License at
16*bbb1b6f9SApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*bbb1b6f9SApple OSS Distributions  *
18*bbb1b6f9SApple OSS Distributions  * The Original Code and all software distributed under the License are
19*bbb1b6f9SApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*bbb1b6f9SApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*bbb1b6f9SApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*bbb1b6f9SApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*bbb1b6f9SApple OSS Distributions  * Please see the License for the specific language governing rights and
24*bbb1b6f9SApple OSS Distributions  * limitations under the License.
25*bbb1b6f9SApple OSS Distributions  *
26*bbb1b6f9SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*bbb1b6f9SApple OSS Distributions  */
28*bbb1b6f9SApple OSS Distributions 
29*bbb1b6f9SApple OSS Distributions /*
30*bbb1b6f9SApple OSS Distributions  * http://code.google.com/p/smhasher/
31*bbb1b6f9SApple OSS Distributions  *
32*bbb1b6f9SApple OSS Distributions  * Copyright (c) 2009-2011 Austin Appleby.
33*bbb1b6f9SApple OSS Distributions  *
34*bbb1b6f9SApple OSS Distributions  * MurmurHash3 was written by Austin Appleby, and is placed in the public
35*bbb1b6f9SApple OSS Distributions  * domain. The author hereby disclaims copyright to this source code.
36*bbb1b6f9SApple OSS Distributions  */
37*bbb1b6f9SApple OSS Distributions 
38*bbb1b6f9SApple OSS Distributions /*
39*bbb1b6f9SApple OSS Distributions  * http://burtleburtle.net/bob/hash/
40*bbb1b6f9SApple OSS Distributions  *
41*bbb1b6f9SApple OSS Distributions  * lookup3.c, by Bob Jenkins, May 2006, Public Domain.
42*bbb1b6f9SApple OSS Distributions  *
43*bbb1b6f9SApple OSS Distributions  * You can use this free for any purpose.  It's in the public domain.
44*bbb1b6f9SApple OSS Distributions  * It has no warranty.
45*bbb1b6f9SApple OSS Distributions  */
46*bbb1b6f9SApple OSS Distributions 
47*bbb1b6f9SApple OSS Distributions #include <stdbool.h>
48*bbb1b6f9SApple OSS Distributions #include <sys/types.h>
49*bbb1b6f9SApple OSS Distributions #include <machine/endian.h>
50*bbb1b6f9SApple OSS Distributions #include <machine/trap.h>
51*bbb1b6f9SApple OSS Distributions #include <net/flowhash.h>
52*bbb1b6f9SApple OSS Distributions #include <os/base.h>
53*bbb1b6f9SApple OSS Distributions 
54*bbb1b6f9SApple OSS Distributions static inline u_int32_t getblock32(const u_int32_t *__bidi_indexable, int);
55*bbb1b6f9SApple OSS Distributions static inline u_int64_t getblock64(const u_int64_t *__bidi_indexable, int);
56*bbb1b6f9SApple OSS Distributions static inline u_int32_t mh3_fmix32(u_int32_t);
57*bbb1b6f9SApple OSS Distributions static inline u_int64_t mh3_fmix64(u_int64_t);
58*bbb1b6f9SApple OSS Distributions 
59*bbb1b6f9SApple OSS Distributions #define ALIGNED16(v)    ((((uintptr_t)(v)) & 1) == 0)
60*bbb1b6f9SApple OSS Distributions #define ALIGNED32(v)    ((((uintptr_t)(v)) & 3) == 0)
61*bbb1b6f9SApple OSS Distributions #define ALIGNED64(v)    ((((uintptr_t)(v)) & 7) == 0)
62*bbb1b6f9SApple OSS Distributions 
63*bbb1b6f9SApple OSS Distributions #define ROTL32(x, r)    (((x) << (r)) | ((x) >> (32 - (r))))
64*bbb1b6f9SApple OSS Distributions #define ROTL64(x, r)    (((x) << (r)) | ((x) >> (64 - (r))))
65*bbb1b6f9SApple OSS Distributions 
66*bbb1b6f9SApple OSS Distributions /*
67*bbb1b6f9SApple OSS Distributions  * The following hash algorithms are selected based on performance:
68*bbb1b6f9SApple OSS Distributions  *
69*bbb1b6f9SApple OSS Distributions  * 64-bit:	MurmurHash3_x64_128
70*bbb1b6f9SApple OSS Distributions  * 32-bit:	JHash
71*bbb1b6f9SApple OSS Distributions  */
72*bbb1b6f9SApple OSS Distributions #if   defined(__LP64__)
73*bbb1b6f9SApple OSS Distributions net_flowhash_fn_t *net_flowhash = net_flowhash_mh3_x64_128;
74*bbb1b6f9SApple OSS Distributions #else /* !__LP64__ */
75*bbb1b6f9SApple OSS Distributions net_flowhash_fn_t *net_flowhash = net_flowhash_jhash;
76*bbb1b6f9SApple OSS Distributions #endif /* !__LP64__ */
77*bbb1b6f9SApple OSS Distributions 
78*bbb1b6f9SApple OSS Distributions #if defined(__i386__) || defined(__x86_64__) || defined(__arm64__)
79*bbb1b6f9SApple OSS Distributions static inline u_int32_t
getblock32(const u_int32_t * __bidi_indexable p,int i)80*bbb1b6f9SApple OSS Distributions getblock32(const u_int32_t *__bidi_indexable p, int i)
81*bbb1b6f9SApple OSS Distributions {
82*bbb1b6f9SApple OSS Distributions 	return p[i];
83*bbb1b6f9SApple OSS Distributions }
84*bbb1b6f9SApple OSS Distributions 
85*bbb1b6f9SApple OSS Distributions static inline u_int64_t
getblock64(const u_int64_t * __bidi_indexable p,int i)86*bbb1b6f9SApple OSS Distributions getblock64(const u_int64_t *__bidi_indexable p, int i)
87*bbb1b6f9SApple OSS Distributions {
88*bbb1b6f9SApple OSS Distributions 	return p[i];
89*bbb1b6f9SApple OSS Distributions }
90*bbb1b6f9SApple OSS Distributions #else /* !__i386__ && !__x86_64__ && !__arm64__*/
91*bbb1b6f9SApple OSS Distributions static inline u_int32_t
getblock32(const u_int32_t * __bidi_indexable p,int i)92*bbb1b6f9SApple OSS Distributions getblock32(const u_int32_t *__bidi_indexable p, int i)
93*bbb1b6f9SApple OSS Distributions {
94*bbb1b6f9SApple OSS Distributions 	const u_int8_t *bytes = (u_int8_t *)(void *)(uintptr_t)(p + i);
95*bbb1b6f9SApple OSS Distributions 	u_int32_t value;
96*bbb1b6f9SApple OSS Distributions 
97*bbb1b6f9SApple OSS Distributions 	if (ALIGNED32(p)) {
98*bbb1b6f9SApple OSS Distributions 		value = p[i];
99*bbb1b6f9SApple OSS Distributions 	} else {
100*bbb1b6f9SApple OSS Distributions #if BYTE_ORDER == BIG_ENDIAN
101*bbb1b6f9SApple OSS Distributions 		value =
102*bbb1b6f9SApple OSS Distributions 		    (((u_int32_t)bytes[0]) << 24) |
103*bbb1b6f9SApple OSS Distributions 		    (((u_int32_t)bytes[1]) << 16) |
104*bbb1b6f9SApple OSS Distributions 		    (((u_int32_t)bytes[2]) << 8) |
105*bbb1b6f9SApple OSS Distributions 		    ((u_int32_t)bytes[3]);
106*bbb1b6f9SApple OSS Distributions #else /* LITTLE_ENDIAN */
107*bbb1b6f9SApple OSS Distributions 		value =
108*bbb1b6f9SApple OSS Distributions 		    (((u_int32_t)bytes[3]) << 24) |
109*bbb1b6f9SApple OSS Distributions 		    (((u_int32_t)bytes[2]) << 16) |
110*bbb1b6f9SApple OSS Distributions 		    (((u_int32_t)bytes[1]) << 8) |
111*bbb1b6f9SApple OSS Distributions 		    ((u_int32_t)bytes[0]);
112*bbb1b6f9SApple OSS Distributions #endif /* LITTLE_ENDIAN */
113*bbb1b6f9SApple OSS Distributions 	}
114*bbb1b6f9SApple OSS Distributions 	return value;
115*bbb1b6f9SApple OSS Distributions }
116*bbb1b6f9SApple OSS Distributions 
117*bbb1b6f9SApple OSS Distributions static inline u_int64_t
getblock64(const u_int64_t * __bidi_indexable p,int i)118*bbb1b6f9SApple OSS Distributions getblock64(const u_int64_t *__bidi_indexable p, int i)
119*bbb1b6f9SApple OSS Distributions {
120*bbb1b6f9SApple OSS Distributions 	const u_int8_t *bytes = (const u_int8_t *)(void *)(uintptr_t)(p + i);
121*bbb1b6f9SApple OSS Distributions 	u_int64_t value;
122*bbb1b6f9SApple OSS Distributions 
123*bbb1b6f9SApple OSS Distributions 	if (ALIGNED64(p)) {
124*bbb1b6f9SApple OSS Distributions 		value = p[i];
125*bbb1b6f9SApple OSS Distributions 	} else {
126*bbb1b6f9SApple OSS Distributions #if BYTE_ORDER == BIG_ENDIAN
127*bbb1b6f9SApple OSS Distributions 		value =
128*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[0]) << 56) |
129*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[1]) << 48) |
130*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[2]) << 40) |
131*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[3]) << 32) |
132*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[4]) << 24) |
133*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[5]) << 16) |
134*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[6]) << 8) |
135*bbb1b6f9SApple OSS Distributions 		    ((u_int64_t)bytes[7]);
136*bbb1b6f9SApple OSS Distributions #else /* LITTLE_ENDIAN */
137*bbb1b6f9SApple OSS Distributions 		value =
138*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[7]) << 56) |
139*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[6]) << 48) |
140*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[5]) << 40) |
141*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[4]) << 32) |
142*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[3]) << 24) |
143*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[2]) << 16) |
144*bbb1b6f9SApple OSS Distributions 		    (((u_int64_t)bytes[1]) << 8) |
145*bbb1b6f9SApple OSS Distributions 		    ((u_int64_t)bytes[0]);
146*bbb1b6f9SApple OSS Distributions #endif /* LITTLE_ENDIAN */
147*bbb1b6f9SApple OSS Distributions 	}
148*bbb1b6f9SApple OSS Distributions 	return value;
149*bbb1b6f9SApple OSS Distributions }
150*bbb1b6f9SApple OSS Distributions #endif /* !__i386__ && !__x86_64 && !__arm64__ */
151*bbb1b6f9SApple OSS Distributions 
152*bbb1b6f9SApple OSS Distributions static inline u_int32_t
mh3_fmix32(u_int32_t h)153*bbb1b6f9SApple OSS Distributions mh3_fmix32(u_int32_t h)
154*bbb1b6f9SApple OSS Distributions {
155*bbb1b6f9SApple OSS Distributions 	h ^= h >> 16;
156*bbb1b6f9SApple OSS Distributions 	h *= 0x85ebca6b;
157*bbb1b6f9SApple OSS Distributions 	h ^= h >> 13;
158*bbb1b6f9SApple OSS Distributions 	h *= 0xc2b2ae35;
159*bbb1b6f9SApple OSS Distributions 	h ^= h >> 16;
160*bbb1b6f9SApple OSS Distributions 
161*bbb1b6f9SApple OSS Distributions 	return h;
162*bbb1b6f9SApple OSS Distributions }
163*bbb1b6f9SApple OSS Distributions 
164*bbb1b6f9SApple OSS Distributions static inline u_int64_t
mh3_fmix64(u_int64_t k)165*bbb1b6f9SApple OSS Distributions mh3_fmix64(u_int64_t k)
166*bbb1b6f9SApple OSS Distributions {
167*bbb1b6f9SApple OSS Distributions 	k ^= k >> 33;
168*bbb1b6f9SApple OSS Distributions 	k *= 0xff51afd7ed558ccdLLU;
169*bbb1b6f9SApple OSS Distributions 	k ^= k >> 33;
170*bbb1b6f9SApple OSS Distributions 	k *= 0xc4ceb9fe1a85ec53LLU;
171*bbb1b6f9SApple OSS Distributions 	k ^= k >> 33;
172*bbb1b6f9SApple OSS Distributions 
173*bbb1b6f9SApple OSS Distributions 	return k;
174*bbb1b6f9SApple OSS Distributions }
175*bbb1b6f9SApple OSS Distributions 
176*bbb1b6f9SApple OSS Distributions /*
177*bbb1b6f9SApple OSS Distributions  * MurmurHash3_x86_32
178*bbb1b6f9SApple OSS Distributions  */
179*bbb1b6f9SApple OSS Distributions #define MH3_X86_32_C1   0xcc9e2d51
180*bbb1b6f9SApple OSS Distributions #define MH3_X86_32_C2   0x1b873593
181*bbb1b6f9SApple OSS Distributions 
182*bbb1b6f9SApple OSS Distributions u_int32_t
net_flowhash_mh3_x86_32(const void * __sized_by (len)key,u_int32_t len,const u_int32_t seed)183*bbb1b6f9SApple OSS Distributions net_flowhash_mh3_x86_32(const void *__sized_by(len) key, u_int32_t len, const u_int32_t seed)
184*bbb1b6f9SApple OSS Distributions {
185*bbb1b6f9SApple OSS Distributions 	const u_int8_t *data = (const u_int8_t *)key;
186*bbb1b6f9SApple OSS Distributions 	const u_int32_t nblocks = len / 4;
187*bbb1b6f9SApple OSS Distributions 	const u_int32_t *blocks;
188*bbb1b6f9SApple OSS Distributions 	const u_int8_t *tail;
189*bbb1b6f9SApple OSS Distributions 	u_int32_t h1 = seed, k1;
190*bbb1b6f9SApple OSS Distributions 	int i;
191*bbb1b6f9SApple OSS Distributions 
192*bbb1b6f9SApple OSS Distributions 	/* body */
193*bbb1b6f9SApple OSS Distributions 	blocks = (const u_int32_t *)(const void *)(data + nblocks * 4);
194*bbb1b6f9SApple OSS Distributions 
195*bbb1b6f9SApple OSS Distributions 	for (i = -nblocks; i; i++) {
196*bbb1b6f9SApple OSS Distributions 		k1 = getblock32(blocks, i);
197*bbb1b6f9SApple OSS Distributions 
198*bbb1b6f9SApple OSS Distributions 		k1 *= MH3_X86_32_C1;
199*bbb1b6f9SApple OSS Distributions 		k1 = ROTL32(k1, 15);
200*bbb1b6f9SApple OSS Distributions 		k1 *= MH3_X86_32_C2;
201*bbb1b6f9SApple OSS Distributions 
202*bbb1b6f9SApple OSS Distributions 		h1 ^= k1;
203*bbb1b6f9SApple OSS Distributions 		h1 = ROTL32(h1, 13);
204*bbb1b6f9SApple OSS Distributions 		h1 = h1 * 5 + 0xe6546b64;
205*bbb1b6f9SApple OSS Distributions 	}
206*bbb1b6f9SApple OSS Distributions 
207*bbb1b6f9SApple OSS Distributions 	/* tail */
208*bbb1b6f9SApple OSS Distributions 	tail = (const u_int8_t *)(const void *)(data + nblocks * 4);
209*bbb1b6f9SApple OSS Distributions 	k1 = 0;
210*bbb1b6f9SApple OSS Distributions 
211*bbb1b6f9SApple OSS Distributions 	switch (len & 3) {
212*bbb1b6f9SApple OSS Distributions 	case 3:
213*bbb1b6f9SApple OSS Distributions 		k1 ^= tail[2] << 16;
214*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
215*bbb1b6f9SApple OSS Distributions 	case 2:
216*bbb1b6f9SApple OSS Distributions 		k1 ^= tail[1] << 8;
217*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
218*bbb1b6f9SApple OSS Distributions 	case 1:
219*bbb1b6f9SApple OSS Distributions 		k1 ^= tail[0];
220*bbb1b6f9SApple OSS Distributions 		k1 *= MH3_X86_32_C1;
221*bbb1b6f9SApple OSS Distributions 		k1 = ROTL32(k1, 15);
222*bbb1b6f9SApple OSS Distributions 		k1 *= MH3_X86_32_C2;
223*bbb1b6f9SApple OSS Distributions 		h1 ^= k1;
224*bbb1b6f9SApple OSS Distributions 	}
225*bbb1b6f9SApple OSS Distributions 	;
226*bbb1b6f9SApple OSS Distributions 
227*bbb1b6f9SApple OSS Distributions 	/* finalization */
228*bbb1b6f9SApple OSS Distributions 	h1 ^= len;
229*bbb1b6f9SApple OSS Distributions 
230*bbb1b6f9SApple OSS Distributions 	h1 = mh3_fmix32(h1);
231*bbb1b6f9SApple OSS Distributions 
232*bbb1b6f9SApple OSS Distributions 	return h1;
233*bbb1b6f9SApple OSS Distributions }
234*bbb1b6f9SApple OSS Distributions 
235*bbb1b6f9SApple OSS Distributions /*
236*bbb1b6f9SApple OSS Distributions  * MurmurHash3_x64_128
237*bbb1b6f9SApple OSS Distributions  */
238*bbb1b6f9SApple OSS Distributions #define MH3_X64_128_C1  0x87c37b91114253d5LLU
239*bbb1b6f9SApple OSS Distributions #define MH3_X64_128_C2  0x4cf5ad432745937fLLU
240*bbb1b6f9SApple OSS Distributions 
241*bbb1b6f9SApple OSS Distributions u_int32_t
net_flowhash_mh3_x64_128(const void * __sized_by (len)key,u_int32_t len,const u_int32_t seed)242*bbb1b6f9SApple OSS Distributions net_flowhash_mh3_x64_128(const void *__sized_by(len) key, u_int32_t len, const u_int32_t seed)
243*bbb1b6f9SApple OSS Distributions {
244*bbb1b6f9SApple OSS Distributions 	const u_int8_t *data = (const u_int8_t *)key;
245*bbb1b6f9SApple OSS Distributions 	const u_int32_t nblocks = len / 16;
246*bbb1b6f9SApple OSS Distributions 	const u_int64_t *blocks;
247*bbb1b6f9SApple OSS Distributions 	const u_int8_t *tail;
248*bbb1b6f9SApple OSS Distributions 	u_int64_t h1 = seed, k1;
249*bbb1b6f9SApple OSS Distributions 	u_int64_t h2 = seed, k2;
250*bbb1b6f9SApple OSS Distributions 	u_int32_t i;
251*bbb1b6f9SApple OSS Distributions 
252*bbb1b6f9SApple OSS Distributions 	/* body */
253*bbb1b6f9SApple OSS Distributions 	blocks = (const u_int64_t *)(const void *)data;
254*bbb1b6f9SApple OSS Distributions 
255*bbb1b6f9SApple OSS Distributions 	for (i = 0; i < nblocks; i++) {
256*bbb1b6f9SApple OSS Distributions 		k1 = getblock64(blocks, i * 2 + 0);
257*bbb1b6f9SApple OSS Distributions 		k2 = getblock64(blocks, i * 2 + 1);
258*bbb1b6f9SApple OSS Distributions 
259*bbb1b6f9SApple OSS Distributions 		k1 *= MH3_X64_128_C1;
260*bbb1b6f9SApple OSS Distributions #if defined(__x86_64__)
261*bbb1b6f9SApple OSS Distributions 		__asm__ ( "rol   $31, %[k1]\n\t" :[k1] "+r" (k1) : :);
262*bbb1b6f9SApple OSS Distributions #elif defined(__arm64__)
263*bbb1b6f9SApple OSS Distributions 		__asm__ ( "ror   %[k1], %[k1], #(64-31)\n\t" :[k1] "+r" (k1) : :);
264*bbb1b6f9SApple OSS Distributions #else /* !__x86_64__ && !__arm64__ */
265*bbb1b6f9SApple OSS Distributions 		k1 = ROTL64(k1, 31);
266*bbb1b6f9SApple OSS Distributions #endif /* !__x86_64__ && !__arm64__ */
267*bbb1b6f9SApple OSS Distributions 		k1 *= MH3_X64_128_C2;
268*bbb1b6f9SApple OSS Distributions 		h1 ^= k1;
269*bbb1b6f9SApple OSS Distributions 
270*bbb1b6f9SApple OSS Distributions #if defined(__x86_64__)
271*bbb1b6f9SApple OSS Distributions 		__asm__ ( "rol   $27, %[h1]\n\t" :[h1] "+r" (h1) : :);
272*bbb1b6f9SApple OSS Distributions #elif defined(__arm64__)
273*bbb1b6f9SApple OSS Distributions 		__asm__ ( "ror   %[h1], %[h1], #(64-27)\n\t" :[h1] "+r" (h1) : :);
274*bbb1b6f9SApple OSS Distributions #else /* !__x86_64__ && !__arm64__ */
275*bbb1b6f9SApple OSS Distributions 		h1 = ROTL64(h1, 27);
276*bbb1b6f9SApple OSS Distributions #endif /* !__x86_64__ && !__arm64__ */
277*bbb1b6f9SApple OSS Distributions 		h1 += h2;
278*bbb1b6f9SApple OSS Distributions 		h1 = h1 * 5 + 0x52dce729;
279*bbb1b6f9SApple OSS Distributions 
280*bbb1b6f9SApple OSS Distributions 		k2 *= MH3_X64_128_C2;
281*bbb1b6f9SApple OSS Distributions #if defined(__x86_64__)
282*bbb1b6f9SApple OSS Distributions 		__asm__ ( "rol   $33, %[k2]\n\t" :[k2] "+r" (k2) : :);
283*bbb1b6f9SApple OSS Distributions #elif defined(__arm64__)
284*bbb1b6f9SApple OSS Distributions 		__asm__ ( "ror   %[k2], %[k2], #(64-33)\n\t" :[k2] "+r" (k2) : :);
285*bbb1b6f9SApple OSS Distributions #else /* !__x86_64__ && !__arm64__ */
286*bbb1b6f9SApple OSS Distributions 		k2 = ROTL64(k2, 33);
287*bbb1b6f9SApple OSS Distributions #endif /* !__x86_64__ && !__arm64__ */
288*bbb1b6f9SApple OSS Distributions 		k2 *= MH3_X64_128_C1;
289*bbb1b6f9SApple OSS Distributions 		h2 ^= k2;
290*bbb1b6f9SApple OSS Distributions 
291*bbb1b6f9SApple OSS Distributions #if defined(__x86_64__)
292*bbb1b6f9SApple OSS Distributions 		__asm__ ( "rol   $31, %[h2]\n\t" :[h2] "+r" (h2) : :);
293*bbb1b6f9SApple OSS Distributions #elif defined(__arm64__)
294*bbb1b6f9SApple OSS Distributions 		__asm__ ( "ror   %[h2], %[h2], #(64-31)\n\t" :[h2] "+r" (h2) : :);
295*bbb1b6f9SApple OSS Distributions #else /* !__x86_64__ && !__arm64__ */
296*bbb1b6f9SApple OSS Distributions 		h2 = ROTL64(h2, 31);
297*bbb1b6f9SApple OSS Distributions #endif /* !__x86_64__ && !__arm64__ */
298*bbb1b6f9SApple OSS Distributions 		h2 += h1;
299*bbb1b6f9SApple OSS Distributions 		h2 = h2 * 5 + 0x38495ab5;
300*bbb1b6f9SApple OSS Distributions 	}
301*bbb1b6f9SApple OSS Distributions 
302*bbb1b6f9SApple OSS Distributions 	/* tail */
303*bbb1b6f9SApple OSS Distributions 	tail = (const u_int8_t *)(const void *)(data + nblocks * 16);
304*bbb1b6f9SApple OSS Distributions 	k1 = 0;
305*bbb1b6f9SApple OSS Distributions 	k2 = 0;
306*bbb1b6f9SApple OSS Distributions 
307*bbb1b6f9SApple OSS Distributions 	switch (len & 15) {
308*bbb1b6f9SApple OSS Distributions 	case 15:
309*bbb1b6f9SApple OSS Distributions 		k2 ^= ((u_int64_t)tail[14]) << 48;
310*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
311*bbb1b6f9SApple OSS Distributions 	case 14:
312*bbb1b6f9SApple OSS Distributions 		k2 ^= ((u_int64_t)tail[13]) << 40;
313*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
314*bbb1b6f9SApple OSS Distributions 	case 13:
315*bbb1b6f9SApple OSS Distributions 		k2 ^= ((u_int64_t)tail[12]) << 32;
316*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
317*bbb1b6f9SApple OSS Distributions 	case 12:
318*bbb1b6f9SApple OSS Distributions 		k2 ^= ((u_int64_t)tail[11]) << 24;
319*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
320*bbb1b6f9SApple OSS Distributions 	case 11:
321*bbb1b6f9SApple OSS Distributions 		k2 ^= ((u_int64_t)tail[10]) << 16;
322*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
323*bbb1b6f9SApple OSS Distributions 	case 10:
324*bbb1b6f9SApple OSS Distributions 		k2 ^= ((u_int64_t)tail[9]) << 8;
325*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
326*bbb1b6f9SApple OSS Distributions 	case 9:
327*bbb1b6f9SApple OSS Distributions 		k2 ^= ((u_int64_t)tail[8]) << 0;
328*bbb1b6f9SApple OSS Distributions 		k2 *= MH3_X64_128_C2;
329*bbb1b6f9SApple OSS Distributions #if defined(__x86_64__)
330*bbb1b6f9SApple OSS Distributions 		__asm__ ( "rol   $33, %[k2]\n\t" :[k2] "+r" (k2) : :);
331*bbb1b6f9SApple OSS Distributions #elif defined(__arm64__)
332*bbb1b6f9SApple OSS Distributions 		__asm__ ( "ror   %[k2], %[k2], #(64-33)\n\t" :[k2] "+r" (k2) : :);
333*bbb1b6f9SApple OSS Distributions #else /* !__x86_64__ && !__arm64__ */
334*bbb1b6f9SApple OSS Distributions 		k2 = ROTL64(k2, 33);
335*bbb1b6f9SApple OSS Distributions #endif /* !__x86_64__ && !__arm64__ */
336*bbb1b6f9SApple OSS Distributions 		k2 *= MH3_X64_128_C1;
337*bbb1b6f9SApple OSS Distributions 		h2 ^= k2;
338*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
339*bbb1b6f9SApple OSS Distributions 	case 8:
340*bbb1b6f9SApple OSS Distributions 		k1 ^= ((u_int64_t)tail[7]) << 56;
341*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
342*bbb1b6f9SApple OSS Distributions 	case 7:
343*bbb1b6f9SApple OSS Distributions 		k1 ^= ((u_int64_t)tail[6]) << 48;
344*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
345*bbb1b6f9SApple OSS Distributions 	case 6:
346*bbb1b6f9SApple OSS Distributions 		k1 ^= ((u_int64_t)tail[5]) << 40;
347*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
348*bbb1b6f9SApple OSS Distributions 	case 5:
349*bbb1b6f9SApple OSS Distributions 		k1 ^= ((u_int64_t)tail[4]) << 32;
350*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
351*bbb1b6f9SApple OSS Distributions 	case 4:
352*bbb1b6f9SApple OSS Distributions 		k1 ^= ((u_int64_t)tail[3]) << 24;
353*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
354*bbb1b6f9SApple OSS Distributions 	case 3:
355*bbb1b6f9SApple OSS Distributions 		k1 ^= ((u_int64_t)tail[2]) << 16;
356*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
357*bbb1b6f9SApple OSS Distributions 	case 2:
358*bbb1b6f9SApple OSS Distributions 		k1 ^= ((u_int64_t)tail[1]) << 8;
359*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
360*bbb1b6f9SApple OSS Distributions 	case 1:
361*bbb1b6f9SApple OSS Distributions 		k1 ^= ((u_int64_t)tail[0]) << 0;
362*bbb1b6f9SApple OSS Distributions 		k1 *= MH3_X64_128_C1;
363*bbb1b6f9SApple OSS Distributions #if defined(__x86_64__)
364*bbb1b6f9SApple OSS Distributions 		__asm__ ( "rol   $31, %[k1]\n\t" :[k1] "+r" (k1) : :);
365*bbb1b6f9SApple OSS Distributions #elif defined(__arm64__)
366*bbb1b6f9SApple OSS Distributions 		__asm__ ( "ror   %[k1], %[k1], #(64-31)\n\t" :[k1] "+r" (k1) : :);
367*bbb1b6f9SApple OSS Distributions #else /* !__x86_64__ && !__arm64__ */
368*bbb1b6f9SApple OSS Distributions 		k1 = ROTL64(k1, 31);
369*bbb1b6f9SApple OSS Distributions #endif /* !__x86_64__ && !__arm64__ */
370*bbb1b6f9SApple OSS Distributions 		k1 *= MH3_X64_128_C2;
371*bbb1b6f9SApple OSS Distributions 		h1 ^= k1;
372*bbb1b6f9SApple OSS Distributions 	}
373*bbb1b6f9SApple OSS Distributions 	;
374*bbb1b6f9SApple OSS Distributions 
375*bbb1b6f9SApple OSS Distributions 	/* finalization */
376*bbb1b6f9SApple OSS Distributions 	h1 ^= len;
377*bbb1b6f9SApple OSS Distributions 	h2 ^= len;
378*bbb1b6f9SApple OSS Distributions 
379*bbb1b6f9SApple OSS Distributions 	h1 += h2;
380*bbb1b6f9SApple OSS Distributions 	h2 += h1;
381*bbb1b6f9SApple OSS Distributions 
382*bbb1b6f9SApple OSS Distributions 	h1 = mh3_fmix64(h1);
383*bbb1b6f9SApple OSS Distributions 	h2 = mh3_fmix64(h2);
384*bbb1b6f9SApple OSS Distributions 
385*bbb1b6f9SApple OSS Distributions 	h1 += h2;
386*bbb1b6f9SApple OSS Distributions 	h2 += h1;
387*bbb1b6f9SApple OSS Distributions 
388*bbb1b6f9SApple OSS Distributions 	/* throw all but lowest 32-bit */
389*bbb1b6f9SApple OSS Distributions 	return h1 & 0xffffffff;
390*bbb1b6f9SApple OSS Distributions }
391*bbb1b6f9SApple OSS Distributions 
392*bbb1b6f9SApple OSS Distributions #define JHASH_INIT      0xdeadbeef
393*bbb1b6f9SApple OSS Distributions 
394*bbb1b6f9SApple OSS Distributions #define JHASH_MIX(a, b, c) {                    \
395*bbb1b6f9SApple OSS Distributions 	a -= c;  a ^= ROTL32(c, 4);   c += b;   \
396*bbb1b6f9SApple OSS Distributions 	b -= a;  b ^= ROTL32(a, 6);   a += c;   \
397*bbb1b6f9SApple OSS Distributions 	c -= b;  c ^= ROTL32(b, 8);   b += a;   \
398*bbb1b6f9SApple OSS Distributions 	a -= c;  a ^= ROTL32(c, 16);  c += b;   \
399*bbb1b6f9SApple OSS Distributions 	b -= a;  b ^= ROTL32(a, 19);  a += c;   \
400*bbb1b6f9SApple OSS Distributions 	c -= b;  c ^= ROTL32(b, 4);   b += a;   \
401*bbb1b6f9SApple OSS Distributions }
402*bbb1b6f9SApple OSS Distributions 
403*bbb1b6f9SApple OSS Distributions #define JHASH_FINAL(a, b, c) {                  \
404*bbb1b6f9SApple OSS Distributions 	c ^= b;  c -= ROTL32(b, 14);            \
405*bbb1b6f9SApple OSS Distributions 	a ^= c;  a -= ROTL32(c, 11);            \
406*bbb1b6f9SApple OSS Distributions 	b ^= a;  b -= ROTL32(a, 25);            \
407*bbb1b6f9SApple OSS Distributions 	c ^= b;  c -= ROTL32(b, 16);            \
408*bbb1b6f9SApple OSS Distributions 	a ^= c;  a -= ROTL32(c, 4);             \
409*bbb1b6f9SApple OSS Distributions 	b ^= a;  b -= ROTL32(a, 14);            \
410*bbb1b6f9SApple OSS Distributions 	c ^= b;  c -= ROTL32(b, 24);            \
411*bbb1b6f9SApple OSS Distributions }
412*bbb1b6f9SApple OSS Distributions 
413*bbb1b6f9SApple OSS Distributions #if BYTE_ORDER == BIG_ENDIAN
414*bbb1b6f9SApple OSS Distributions /*
415*bbb1b6f9SApple OSS Distributions  * hashbig()
416*bbb1b6f9SApple OSS Distributions  */
417*bbb1b6f9SApple OSS Distributions u_int32_t
net_flowhash_jhash(const void * __sized_by (len)key,u_int32_t len,const u_int32_t seed)418*bbb1b6f9SApple OSS Distributions net_flowhash_jhash(const void *__sized_by(len) key, u_int32_t len, const u_int32_t seed)
419*bbb1b6f9SApple OSS Distributions {
420*bbb1b6f9SApple OSS Distributions 	u_int32_t a, b, c;
421*bbb1b6f9SApple OSS Distributions 
422*bbb1b6f9SApple OSS Distributions 	/* Set up the internal state */
423*bbb1b6f9SApple OSS Distributions 	a = b = c = JHASH_INIT + len + seed;
424*bbb1b6f9SApple OSS Distributions 
425*bbb1b6f9SApple OSS Distributions 	if (ALIGNED32(key)) {
426*bbb1b6f9SApple OSS Distributions 		/* read 32-bit chunks */
427*bbb1b6f9SApple OSS Distributions 		u_int32_t k_len = len;
428*bbb1b6f9SApple OSS Distributions 		const u_int32_t *__sized_by(k_len) k = (const u_int32_t *)key;
429*bbb1b6f9SApple OSS Distributions 
430*bbb1b6f9SApple OSS Distributions 		/*
431*bbb1b6f9SApple OSS Distributions 		 * all but last block:
432*bbb1b6f9SApple OSS Distributions 		 * aligned reads and affect 32 bits of (a,b,c)
433*bbb1b6f9SApple OSS Distributions 		 */
434*bbb1b6f9SApple OSS Distributions 		while (k_len > 12) {
435*bbb1b6f9SApple OSS Distributions 			a += k[0];
436*bbb1b6f9SApple OSS Distributions 			b += k[1];
437*bbb1b6f9SApple OSS Distributions 			c += k[2];
438*bbb1b6f9SApple OSS Distributions 			JHASH_MIX(a, b, c);
439*bbb1b6f9SApple OSS Distributions 			k_len -= 12;
440*bbb1b6f9SApple OSS Distributions 			k += 3;
441*bbb1b6f9SApple OSS Distributions 		}
442*bbb1b6f9SApple OSS Distributions 
443*bbb1b6f9SApple OSS Distributions 		/*
444*bbb1b6f9SApple OSS Distributions 		 * handle the last (probably partial) block
445*bbb1b6f9SApple OSS Distributions 		 *
446*bbb1b6f9SApple OSS Distributions 		 * "k[2] << 8" actually reads beyond the end of the string,
447*bbb1b6f9SApple OSS Distributions 		 * but then shifts out the part it's not allowed to read.
448*bbb1b6f9SApple OSS Distributions 		 * Because the string is aligned, the illegal read is in
449*bbb1b6f9SApple OSS Distributions 		 * the same word as the rest of the string.  The masking
450*bbb1b6f9SApple OSS Distributions 		 * trick does make the hash noticably faster for short
451*bbb1b6f9SApple OSS Distributions 		 * strings (like English words).
452*bbb1b6f9SApple OSS Distributions 		 */
453*bbb1b6f9SApple OSS Distributions 		switch (k_len) {
454*bbb1b6f9SApple OSS Distributions 		case 12:
455*bbb1b6f9SApple OSS Distributions 			c += k[2];
456*bbb1b6f9SApple OSS Distributions 			b += k[1];
457*bbb1b6f9SApple OSS Distributions 			a += k[0];
458*bbb1b6f9SApple OSS Distributions 			break;
459*bbb1b6f9SApple OSS Distributions 
460*bbb1b6f9SApple OSS Distributions 		case 11:
461*bbb1b6f9SApple OSS Distributions 			c += k[2] & 0xffffff00;
462*bbb1b6f9SApple OSS Distributions 			b += k[1];
463*bbb1b6f9SApple OSS Distributions 			a += k[0];
464*bbb1b6f9SApple OSS Distributions 			break;
465*bbb1b6f9SApple OSS Distributions 
466*bbb1b6f9SApple OSS Distributions 		case 10:
467*bbb1b6f9SApple OSS Distributions 			c += k[2] & 0xffff0000;
468*bbb1b6f9SApple OSS Distributions 			b += k[1];
469*bbb1b6f9SApple OSS Distributions 			a += k[0];
470*bbb1b6f9SApple OSS Distributions 			break;
471*bbb1b6f9SApple OSS Distributions 
472*bbb1b6f9SApple OSS Distributions 		case 9:
473*bbb1b6f9SApple OSS Distributions 			c += k[2] & 0xff000000;
474*bbb1b6f9SApple OSS Distributions 			b += k[1];
475*bbb1b6f9SApple OSS Distributions 			a += k[0];
476*bbb1b6f9SApple OSS Distributions 			break;
477*bbb1b6f9SApple OSS Distributions 
478*bbb1b6f9SApple OSS Distributions 		case 8:
479*bbb1b6f9SApple OSS Distributions 			b += k[1];
480*bbb1b6f9SApple OSS Distributions 			a += k[0];
481*bbb1b6f9SApple OSS Distributions 			break;
482*bbb1b6f9SApple OSS Distributions 
483*bbb1b6f9SApple OSS Distributions 		case 7:
484*bbb1b6f9SApple OSS Distributions 			b += k[1] & 0xffffff00;
485*bbb1b6f9SApple OSS Distributions 			a += k[0];
486*bbb1b6f9SApple OSS Distributions 			break;
487*bbb1b6f9SApple OSS Distributions 
488*bbb1b6f9SApple OSS Distributions 		case 6:
489*bbb1b6f9SApple OSS Distributions 			b += k[1] & 0xffff0000;
490*bbb1b6f9SApple OSS Distributions 			a += k[0];
491*bbb1b6f9SApple OSS Distributions 			break;
492*bbb1b6f9SApple OSS Distributions 
493*bbb1b6f9SApple OSS Distributions 		case 5:
494*bbb1b6f9SApple OSS Distributions 			b += k[1] & 0xff000000;
495*bbb1b6f9SApple OSS Distributions 			a += k[0];
496*bbb1b6f9SApple OSS Distributions 			break;
497*bbb1b6f9SApple OSS Distributions 
498*bbb1b6f9SApple OSS Distributions 		case 4:
499*bbb1b6f9SApple OSS Distributions 			a += k[0];
500*bbb1b6f9SApple OSS Distributions 			break;
501*bbb1b6f9SApple OSS Distributions 
502*bbb1b6f9SApple OSS Distributions 		case 3:
503*bbb1b6f9SApple OSS Distributions 			a += k[0] & 0xffffff00;
504*bbb1b6f9SApple OSS Distributions 			break;
505*bbb1b6f9SApple OSS Distributions 
506*bbb1b6f9SApple OSS Distributions 		case 2:
507*bbb1b6f9SApple OSS Distributions 			a += k[0] & 0xffff0000;
508*bbb1b6f9SApple OSS Distributions 			break;
509*bbb1b6f9SApple OSS Distributions 
510*bbb1b6f9SApple OSS Distributions 		case 1:
511*bbb1b6f9SApple OSS Distributions 			a += k[0] & 0xff000000;
512*bbb1b6f9SApple OSS Distributions 			break;
513*bbb1b6f9SApple OSS Distributions 
514*bbb1b6f9SApple OSS Distributions 		case 0:
515*bbb1b6f9SApple OSS Distributions 			/* zero length requires no mixing */
516*bbb1b6f9SApple OSS Distributions 			return c;
517*bbb1b6f9SApple OSS Distributions 		}
518*bbb1b6f9SApple OSS Distributions 
519*bbb1b6f9SApple OSS Distributions 		JHASH_FINAL(a, b, c);
520*bbb1b6f9SApple OSS Distributions 
521*bbb1b6f9SApple OSS Distributions 		return c;
522*bbb1b6f9SApple OSS Distributions 	}
523*bbb1b6f9SApple OSS Distributions 
524*bbb1b6f9SApple OSS Distributions 	/* need to read the key one byte at a time */
525*bbb1b6f9SApple OSS Distributions 	u_int32_t k_len = len;
526*bbb1b6f9SApple OSS Distributions 	const u_int8_t *__sized_by(k_len) k = (const u_int8_t *)key;
527*bbb1b6f9SApple OSS Distributions 
528*bbb1b6f9SApple OSS Distributions 	/* all but the last block: affect some 32 bits of (a,b,c) */
529*bbb1b6f9SApple OSS Distributions 	while (k_len > 12) {
530*bbb1b6f9SApple OSS Distributions 		a += ((u_int32_t)k[0]) << 24;
531*bbb1b6f9SApple OSS Distributions 		a += ((u_int32_t)k[1]) << 16;
532*bbb1b6f9SApple OSS Distributions 		a += ((u_int32_t)k[2]) << 8;
533*bbb1b6f9SApple OSS Distributions 		a += ((u_int32_t)k[3]);
534*bbb1b6f9SApple OSS Distributions 		b += ((u_int32_t)k[4]) << 24;
535*bbb1b6f9SApple OSS Distributions 		b += ((u_int32_t)k[5]) << 16;
536*bbb1b6f9SApple OSS Distributions 		b += ((u_int32_t)k[6]) << 8;
537*bbb1b6f9SApple OSS Distributions 		b += ((u_int32_t)k[7]);
538*bbb1b6f9SApple OSS Distributions 		c += ((u_int32_t)k[8]) << 24;
539*bbb1b6f9SApple OSS Distributions 		c += ((u_int32_t)k[9]) << 16;
540*bbb1b6f9SApple OSS Distributions 		c += ((u_int32_t)k[10]) << 8;
541*bbb1b6f9SApple OSS Distributions 		c += ((u_int32_t)k[11]);
542*bbb1b6f9SApple OSS Distributions 		JHASH_MIX(a, b, c);
543*bbb1b6f9SApple OSS Distributions 		k_len -= 12;
544*bbb1b6f9SApple OSS Distributions 		k += 12;
545*bbb1b6f9SApple OSS Distributions 	}
546*bbb1b6f9SApple OSS Distributions 
547*bbb1b6f9SApple OSS Distributions 	/* last block: affect all 32 bits of (c) */
548*bbb1b6f9SApple OSS Distributions 	switch (k_len) {
549*bbb1b6f9SApple OSS Distributions 	case 12:
550*bbb1b6f9SApple OSS Distributions 		c += k[11];
551*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
552*bbb1b6f9SApple OSS Distributions 	case 11:
553*bbb1b6f9SApple OSS Distributions 		c += ((u_int32_t)k[10]) << 8;
554*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
555*bbb1b6f9SApple OSS Distributions 	case 10:
556*bbb1b6f9SApple OSS Distributions 		c += ((u_int32_t)k[9]) << 16;
557*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
558*bbb1b6f9SApple OSS Distributions 	case 9:
559*bbb1b6f9SApple OSS Distributions 		c += ((u_int32_t)k[8]) << 24;
560*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
561*bbb1b6f9SApple OSS Distributions 	case 8:
562*bbb1b6f9SApple OSS Distributions 		b += k[7];
563*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
564*bbb1b6f9SApple OSS Distributions 	case 7:
565*bbb1b6f9SApple OSS Distributions 		b += ((u_int32_t)k[6]) << 8;
566*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
567*bbb1b6f9SApple OSS Distributions 	case 6:
568*bbb1b6f9SApple OSS Distributions 		b += ((u_int32_t)k[5]) << 16;
569*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
570*bbb1b6f9SApple OSS Distributions 	case 5:
571*bbb1b6f9SApple OSS Distributions 		b += ((u_int32_t)k[4]) << 24;
572*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
573*bbb1b6f9SApple OSS Distributions 	case 4:
574*bbb1b6f9SApple OSS Distributions 		a += k[3];
575*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
576*bbb1b6f9SApple OSS Distributions 	case 3:
577*bbb1b6f9SApple OSS Distributions 		a += ((u_int32_t)k[2]) << 8;
578*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
579*bbb1b6f9SApple OSS Distributions 	case 2:
580*bbb1b6f9SApple OSS Distributions 		a += ((u_int32_t)k[1]) << 16;
581*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
582*bbb1b6f9SApple OSS Distributions 	case 1:
583*bbb1b6f9SApple OSS Distributions 		a += ((u_int32_t)k[0]) << 24;
584*bbb1b6f9SApple OSS Distributions 		break;
585*bbb1b6f9SApple OSS Distributions 
586*bbb1b6f9SApple OSS Distributions 	case 0:
587*bbb1b6f9SApple OSS Distributions 		/* zero length requires no mixing */
588*bbb1b6f9SApple OSS Distributions 		return c;
589*bbb1b6f9SApple OSS Distributions 	}
590*bbb1b6f9SApple OSS Distributions 
591*bbb1b6f9SApple OSS Distributions 	JHASH_FINAL(a, b, c);
592*bbb1b6f9SApple OSS Distributions 
593*bbb1b6f9SApple OSS Distributions 	return c;
594*bbb1b6f9SApple OSS Distributions }
595*bbb1b6f9SApple OSS Distributions #else /* LITTLE_ENDIAN */
596*bbb1b6f9SApple OSS Distributions /*
597*bbb1b6f9SApple OSS Distributions  * hashlittle()
598*bbb1b6f9SApple OSS Distributions  */
599*bbb1b6f9SApple OSS Distributions u_int32_t
net_flowhash_jhash(const void * __sized_by (len)key,u_int32_t len,const u_int32_t seed)600*bbb1b6f9SApple OSS Distributions net_flowhash_jhash(const void *__sized_by(len) key, u_int32_t len, const u_int32_t seed)
601*bbb1b6f9SApple OSS Distributions {
602*bbb1b6f9SApple OSS Distributions 	u_int32_t a, b, c;
603*bbb1b6f9SApple OSS Distributions 
604*bbb1b6f9SApple OSS Distributions 	/* Set up the internal state */
605*bbb1b6f9SApple OSS Distributions 	a = b = c = JHASH_INIT + len + seed;
606*bbb1b6f9SApple OSS Distributions 
607*bbb1b6f9SApple OSS Distributions #if defined(__i386__) || defined(__x86_64__)
608*bbb1b6f9SApple OSS Distributions 	/*
609*bbb1b6f9SApple OSS Distributions 	 * On i386/x86_64, it is faster to read 32-bit chunks if the key
610*bbb1b6f9SApple OSS Distributions 	 * is aligned 32-bit OR not 16-bit, and perform 16-bit reads if it
611*bbb1b6f9SApple OSS Distributions 	 * is aligned 16-bit.
612*bbb1b6f9SApple OSS Distributions 	 */
613*bbb1b6f9SApple OSS Distributions 	if (ALIGNED32(key) || !ALIGNED16(key)) {
614*bbb1b6f9SApple OSS Distributions #else /* !defined(__i386__) && !defined(__x86_64__) */
615*bbb1b6f9SApple OSS Distributions 	if (ALIGNED32(key)) {
616*bbb1b6f9SApple OSS Distributions #endif /* !defined(__i386__) && !defined(__x86_64__) */
617*bbb1b6f9SApple OSS Distributions 		/* read 32-bit chunks */
618*bbb1b6f9SApple OSS Distributions 		u_int32_t k_len = len;
619*bbb1b6f9SApple OSS Distributions 		const u_int32_t *__sized_by(k_len) k = (const u_int32_t *)key;
620*bbb1b6f9SApple OSS Distributions 		const u_int16_t *k16 = (const u_int16_t *)key;
621*bbb1b6f9SApple OSS Distributions 		const u_int8_t *k8 = (const u_int8_t *)key;
622*bbb1b6f9SApple OSS Distributions 
623*bbb1b6f9SApple OSS Distributions 		/*
624*bbb1b6f9SApple OSS Distributions 		 * all but last block:
625*bbb1b6f9SApple OSS Distributions 		 * aligned reads and affect 32 bits of (a,b,c)
626*bbb1b6f9SApple OSS Distributions 		 */
627*bbb1b6f9SApple OSS Distributions 		while (k_len > 12) {
628*bbb1b6f9SApple OSS Distributions 			a += k[0];
629*bbb1b6f9SApple OSS Distributions 			b += k[1];
630*bbb1b6f9SApple OSS Distributions 			c += k[2];
631*bbb1b6f9SApple OSS Distributions 			JHASH_MIX(a, b, c);
632*bbb1b6f9SApple OSS Distributions 			k_len -= 12;
633*bbb1b6f9SApple OSS Distributions 			k += 3;
634*bbb1b6f9SApple OSS Distributions 		}
635*bbb1b6f9SApple OSS Distributions 
636*bbb1b6f9SApple OSS Distributions 		/* handle the last (probably partial) block */
637*bbb1b6f9SApple OSS Distributions 		switch (k_len) {
638*bbb1b6f9SApple OSS Distributions 		case 12:
639*bbb1b6f9SApple OSS Distributions 			c += k[2];
640*bbb1b6f9SApple OSS Distributions 			b += k[1];
641*bbb1b6f9SApple OSS Distributions 			a += k[0];
642*bbb1b6f9SApple OSS Distributions 			break;
643*bbb1b6f9SApple OSS Distributions 
644*bbb1b6f9SApple OSS Distributions 		case 11:
645*bbb1b6f9SApple OSS Distributions 			c += ((u_int32_t)k8[10]) << 16;
646*bbb1b6f9SApple OSS Distributions 			c += k16[4];
647*bbb1b6f9SApple OSS Distributions 			b += k[1];
648*bbb1b6f9SApple OSS Distributions 			a += k[0];
649*bbb1b6f9SApple OSS Distributions 			break;
650*bbb1b6f9SApple OSS Distributions 
651*bbb1b6f9SApple OSS Distributions 		case 10:
652*bbb1b6f9SApple OSS Distributions 			c += k16[4];
653*bbb1b6f9SApple OSS Distributions 			b += k[1];
654*bbb1b6f9SApple OSS Distributions 			a += k[0];
655*bbb1b6f9SApple OSS Distributions 			break;
656*bbb1b6f9SApple OSS Distributions 
657*bbb1b6f9SApple OSS Distributions 		case 9:
658*bbb1b6f9SApple OSS Distributions 			c += k8[8];
659*bbb1b6f9SApple OSS Distributions 			b += k[1];
660*bbb1b6f9SApple OSS Distributions 			a += k[0];
661*bbb1b6f9SApple OSS Distributions 			break;
662*bbb1b6f9SApple OSS Distributions 
663*bbb1b6f9SApple OSS Distributions 		case 8:
664*bbb1b6f9SApple OSS Distributions 			b += k[1];
665*bbb1b6f9SApple OSS Distributions 			a += k[0];
666*bbb1b6f9SApple OSS Distributions 			break;
667*bbb1b6f9SApple OSS Distributions 
668*bbb1b6f9SApple OSS Distributions 		case 7:
669*bbb1b6f9SApple OSS Distributions 			b += ((u_int32_t)k8[6]) << 16;
670*bbb1b6f9SApple OSS Distributions 			b += k16[2];
671*bbb1b6f9SApple OSS Distributions 			a += k[0];
672*bbb1b6f9SApple OSS Distributions 			break;
673*bbb1b6f9SApple OSS Distributions 
674*bbb1b6f9SApple OSS Distributions 		case 6:
675*bbb1b6f9SApple OSS Distributions 			b += k16[2];
676*bbb1b6f9SApple OSS Distributions 			a += k[0];
677*bbb1b6f9SApple OSS Distributions 			break;
678*bbb1b6f9SApple OSS Distributions 
679*bbb1b6f9SApple OSS Distributions 		case 5:
680*bbb1b6f9SApple OSS Distributions 			b += k8[4];
681*bbb1b6f9SApple OSS Distributions 			a += k[0];
682*bbb1b6f9SApple OSS Distributions 			break;
683*bbb1b6f9SApple OSS Distributions 
684*bbb1b6f9SApple OSS Distributions 		case 4:
685*bbb1b6f9SApple OSS Distributions 			a += k[0];
686*bbb1b6f9SApple OSS Distributions 			break;
687*bbb1b6f9SApple OSS Distributions 
688*bbb1b6f9SApple OSS Distributions 		case 3:
689*bbb1b6f9SApple OSS Distributions 			a += ((u_int32_t)k8[2]) << 16;
690*bbb1b6f9SApple OSS Distributions 			a += k16[0];
691*bbb1b6f9SApple OSS Distributions 			break;
692*bbb1b6f9SApple OSS Distributions 
693*bbb1b6f9SApple OSS Distributions 		case 2:
694*bbb1b6f9SApple OSS Distributions 			a += k16[0];
695*bbb1b6f9SApple OSS Distributions 			break;
696*bbb1b6f9SApple OSS Distributions 
697*bbb1b6f9SApple OSS Distributions 		case 1:
698*bbb1b6f9SApple OSS Distributions 			a += k8[0];
699*bbb1b6f9SApple OSS Distributions 			break;
700*bbb1b6f9SApple OSS Distributions 
701*bbb1b6f9SApple OSS Distributions 		case 0:
702*bbb1b6f9SApple OSS Distributions 			/* zero length requires no mixing */
703*bbb1b6f9SApple OSS Distributions 			return c;
704*bbb1b6f9SApple OSS Distributions 		}
705*bbb1b6f9SApple OSS Distributions 
706*bbb1b6f9SApple OSS Distributions 		JHASH_FINAL(a, b, c);
707*bbb1b6f9SApple OSS Distributions 
708*bbb1b6f9SApple OSS Distributions 		return c;
709*bbb1b6f9SApple OSS Distributions 	}
710*bbb1b6f9SApple OSS Distributions #if !defined(__i386__) && !defined(__x86_64__)
711*bbb1b6f9SApple OSS Distributions 	else if (ALIGNED16(key)) {
712*bbb1b6f9SApple OSS Distributions #endif /* !defined(__i386__) && !defined(__x86_64__) */
713*bbb1b6f9SApple OSS Distributions 	/* read 16-bit chunks */
714*bbb1b6f9SApple OSS Distributions 	u_int32_t k_len = len;
715*bbb1b6f9SApple OSS Distributions 	const u_int16_t *__sized_by(k_len) k = (const u_int16_t *)key;
716*bbb1b6f9SApple OSS Distributions 	const u_int8_t *k8;
717*bbb1b6f9SApple OSS Distributions 
718*bbb1b6f9SApple OSS Distributions 	/* all but last block: aligned reads and different mixing */
719*bbb1b6f9SApple OSS Distributions 	while (k_len > 12) {
720*bbb1b6f9SApple OSS Distributions 		a += k[0] + (((u_int32_t)k[1]) << 16);
721*bbb1b6f9SApple OSS Distributions 		b += k[2] + (((u_int32_t)k[3]) << 16);
722*bbb1b6f9SApple OSS Distributions 		c += k[4] + (((u_int32_t)k[5]) << 16);
723*bbb1b6f9SApple OSS Distributions 		JHASH_MIX(a, b, c);
724*bbb1b6f9SApple OSS Distributions 		k_len -= 12;
725*bbb1b6f9SApple OSS Distributions 		k += 6;
726*bbb1b6f9SApple OSS Distributions 	}
727*bbb1b6f9SApple OSS Distributions 
728*bbb1b6f9SApple OSS Distributions 	/* handle the last (probably partial) block */
729*bbb1b6f9SApple OSS Distributions 	k8 = (const u_int8_t *)k;
730*bbb1b6f9SApple OSS Distributions 	switch (k_len) {
731*bbb1b6f9SApple OSS Distributions 	case 12:
732*bbb1b6f9SApple OSS Distributions 		c += k[4] + (((u_int32_t)k[5]) << 16);
733*bbb1b6f9SApple OSS Distributions 		b += k[2] + (((u_int32_t)k[3]) << 16);
734*bbb1b6f9SApple OSS Distributions 		a += k[0] + (((u_int32_t)k[1]) << 16);
735*bbb1b6f9SApple OSS Distributions 		break;
736*bbb1b6f9SApple OSS Distributions 
737*bbb1b6f9SApple OSS Distributions 	case 11:
738*bbb1b6f9SApple OSS Distributions 		c += ((u_int32_t)k8[10]) << 16;
739*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
740*bbb1b6f9SApple OSS Distributions 	case 10:
741*bbb1b6f9SApple OSS Distributions 		c += k[4];
742*bbb1b6f9SApple OSS Distributions 		b += k[2] + (((u_int32_t)k[3]) << 16);
743*bbb1b6f9SApple OSS Distributions 		a += k[0] + (((u_int32_t)k[1]) << 16);
744*bbb1b6f9SApple OSS Distributions 		break;
745*bbb1b6f9SApple OSS Distributions 
746*bbb1b6f9SApple OSS Distributions 	case 9:
747*bbb1b6f9SApple OSS Distributions 		c += k8[8];
748*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
749*bbb1b6f9SApple OSS Distributions 	case 8:
750*bbb1b6f9SApple OSS Distributions 		b += k[2] + (((u_int32_t)k[3]) << 16);
751*bbb1b6f9SApple OSS Distributions 		a += k[0] + (((u_int32_t)k[1]) << 16);
752*bbb1b6f9SApple OSS Distributions 		break;
753*bbb1b6f9SApple OSS Distributions 
754*bbb1b6f9SApple OSS Distributions 	case 7:
755*bbb1b6f9SApple OSS Distributions 		b += ((u_int32_t)k8[6]) << 16;
756*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
757*bbb1b6f9SApple OSS Distributions 	case 6:
758*bbb1b6f9SApple OSS Distributions 		b += k[2];
759*bbb1b6f9SApple OSS Distributions 		a += k[0] + (((u_int32_t)k[1]) << 16);
760*bbb1b6f9SApple OSS Distributions 		break;
761*bbb1b6f9SApple OSS Distributions 
762*bbb1b6f9SApple OSS Distributions 	case 5:
763*bbb1b6f9SApple OSS Distributions 		b += k8[4];
764*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
765*bbb1b6f9SApple OSS Distributions 	case 4:
766*bbb1b6f9SApple OSS Distributions 		a += k[0] + (((u_int32_t)k[1]) << 16);
767*bbb1b6f9SApple OSS Distributions 		break;
768*bbb1b6f9SApple OSS Distributions 
769*bbb1b6f9SApple OSS Distributions 	case 3:
770*bbb1b6f9SApple OSS Distributions 		a += ((u_int32_t)k8[2]) << 16;
771*bbb1b6f9SApple OSS Distributions 		OS_FALLTHROUGH;
772*bbb1b6f9SApple OSS Distributions 	case 2:
773*bbb1b6f9SApple OSS Distributions 		a += k[0];
774*bbb1b6f9SApple OSS Distributions 		break;
775*bbb1b6f9SApple OSS Distributions 
776*bbb1b6f9SApple OSS Distributions 	case 1:
777*bbb1b6f9SApple OSS Distributions 		a += k8[0];
778*bbb1b6f9SApple OSS Distributions 		break;
779*bbb1b6f9SApple OSS Distributions 
780*bbb1b6f9SApple OSS Distributions 	case 0:
781*bbb1b6f9SApple OSS Distributions 		/* zero length requires no mixing */
782*bbb1b6f9SApple OSS Distributions 		return c;
783*bbb1b6f9SApple OSS Distributions 	}
784*bbb1b6f9SApple OSS Distributions 
785*bbb1b6f9SApple OSS Distributions 	JHASH_FINAL(a, b, c);
786*bbb1b6f9SApple OSS Distributions 
787*bbb1b6f9SApple OSS Distributions 	return c;
788*bbb1b6f9SApple OSS Distributions #if !defined(__i386__) && !defined(__x86_64__)
789*bbb1b6f9SApple OSS Distributions }
790*bbb1b6f9SApple OSS Distributions 
791*bbb1b6f9SApple OSS Distributions /* need to read the key one byte at a time */
792*bbb1b6f9SApple OSS Distributions u_int32_t k_len = len;
793*bbb1b6f9SApple OSS Distributions const u_int8_t *__sized_by(k_len) k = (const u_int8_t *)key;
794*bbb1b6f9SApple OSS Distributions 
795*bbb1b6f9SApple OSS Distributions /* all but the last block: affect some 32 bits of (a,b,c) */
796*bbb1b6f9SApple OSS Distributions while (k_len > 12) {
797*bbb1b6f9SApple OSS Distributions 	a += k[0];
798*bbb1b6f9SApple OSS Distributions 	a += ((u_int32_t)k[1]) << 8;
799*bbb1b6f9SApple OSS Distributions 	a += ((u_int32_t)k[2]) << 16;
800*bbb1b6f9SApple OSS Distributions 	a += ((u_int32_t)k[3]) << 24;
801*bbb1b6f9SApple OSS Distributions 	b += k[4];
802*bbb1b6f9SApple OSS Distributions 	b += ((u_int32_t)k[5]) << 8;
803*bbb1b6f9SApple OSS Distributions 	b += ((u_int32_t)k[6]) << 16;
804*bbb1b6f9SApple OSS Distributions 	b += ((u_int32_t)k[7]) << 24;
805*bbb1b6f9SApple OSS Distributions 	c += k[8];
806*bbb1b6f9SApple OSS Distributions 	c += ((u_int32_t)k[9]) << 8;
807*bbb1b6f9SApple OSS Distributions 	c += ((u_int32_t)k[10]) << 16;
808*bbb1b6f9SApple OSS Distributions 	c += ((u_int32_t)k[11]) << 24;
809*bbb1b6f9SApple OSS Distributions 	JHASH_MIX(a, b, c);
810*bbb1b6f9SApple OSS Distributions 	k_len -= 12;
811*bbb1b6f9SApple OSS Distributions 	k += 12;
812*bbb1b6f9SApple OSS Distributions }
813*bbb1b6f9SApple OSS Distributions 
814*bbb1b6f9SApple OSS Distributions /* last block: affect all 32 bits of (c) */
815*bbb1b6f9SApple OSS Distributions switch (k_len) {
816*bbb1b6f9SApple OSS Distributions case 12:
817*bbb1b6f9SApple OSS Distributions 	c += ((u_int32_t)k[11]) << 24;
818*bbb1b6f9SApple OSS Distributions 	OS_FALLTHROUGH;
819*bbb1b6f9SApple OSS Distributions case 11:
820*bbb1b6f9SApple OSS Distributions 	c += ((u_int32_t)k[10]) << 16;
821*bbb1b6f9SApple OSS Distributions 	OS_FALLTHROUGH;
822*bbb1b6f9SApple OSS Distributions case 10:
823*bbb1b6f9SApple OSS Distributions 	c += ((u_int32_t)k[9]) << 8;
824*bbb1b6f9SApple OSS Distributions 	OS_FALLTHROUGH;
825*bbb1b6f9SApple OSS Distributions case 9:
826*bbb1b6f9SApple OSS Distributions 	c += k[8];
827*bbb1b6f9SApple OSS Distributions 	OS_FALLTHROUGH;
828*bbb1b6f9SApple OSS Distributions case 8:
829*bbb1b6f9SApple OSS Distributions 	b += ((u_int32_t)k[7]) << 24;
830*bbb1b6f9SApple OSS Distributions 	OS_FALLTHROUGH;
831*bbb1b6f9SApple OSS Distributions case 7:
832*bbb1b6f9SApple OSS Distributions 	b += ((u_int32_t)k[6]) << 16;
833*bbb1b6f9SApple OSS Distributions 	OS_FALLTHROUGH;
834*bbb1b6f9SApple OSS Distributions case 6:
835*bbb1b6f9SApple OSS Distributions 	b += ((u_int32_t)k[5]) << 8;
836*bbb1b6f9SApple OSS Distributions 	OS_FALLTHROUGH;
837*bbb1b6f9SApple OSS Distributions case 5:
838*bbb1b6f9SApple OSS Distributions 	b += k[4];
839*bbb1b6f9SApple OSS Distributions 	OS_FALLTHROUGH;
840*bbb1b6f9SApple OSS Distributions case 4:
841*bbb1b6f9SApple OSS Distributions 	a += ((u_int32_t)k[3]) << 24;
842*bbb1b6f9SApple OSS Distributions 	OS_FALLTHROUGH;
843*bbb1b6f9SApple OSS Distributions case 3:
844*bbb1b6f9SApple OSS Distributions 	a += ((u_int32_t)k[2]) << 16;
845*bbb1b6f9SApple OSS Distributions 	OS_FALLTHROUGH;
846*bbb1b6f9SApple OSS Distributions case 2:
847*bbb1b6f9SApple OSS Distributions 	a += ((u_int32_t)k[1]) << 8;
848*bbb1b6f9SApple OSS Distributions 	OS_FALLTHROUGH;
849*bbb1b6f9SApple OSS Distributions case 1:
850*bbb1b6f9SApple OSS Distributions 	a += k[0];
851*bbb1b6f9SApple OSS Distributions 	break;
852*bbb1b6f9SApple OSS Distributions 
853*bbb1b6f9SApple OSS Distributions case 0:
854*bbb1b6f9SApple OSS Distributions 	/* zero length requires no mixing */
855*bbb1b6f9SApple OSS Distributions 	return c;
856*bbb1b6f9SApple OSS Distributions }
857*bbb1b6f9SApple OSS Distributions 
858*bbb1b6f9SApple OSS Distributions JHASH_FINAL(a, b, c);
859*bbb1b6f9SApple OSS Distributions 
860*bbb1b6f9SApple OSS Distributions return c;
861*bbb1b6f9SApple OSS Distributions #endif /* !defined(__i386__) && !defined(__x86_64__) */
862*bbb1b6f9SApple OSS Distributions }
863*bbb1b6f9SApple OSS Distributions #endif /* LITTLE_ENDIAN */
864