blob: fcc4b64ad1906b8f312a58a44fa8d7d2c17a9faa [file] [log] [blame]
Damjan Marion2e5921b2021-11-28 22:57:15 +01001/* SPDX-License-Identifier: Apache-2.0
2 * Copyright(c) 2021 Cisco Systems, Inc.
3 */
4
5#include <vppinfra/clib.h>
6#include <vppinfra/mem.h>
7#include <vppinfra/vector/toeplitz.h>
8
9static u8 default_key[40] = {
10 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 0x41, 0x67,
11 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, 0xd0, 0xca, 0x2b, 0xcb,
12 0xae, 0x7b, 0x30, 0xb4, 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30,
13 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa,
14};
15
16#ifdef __x86_64__
17static_always_inline void
18clib_toeplitz_hash_key_expand_8 (u64x2 kv, u64x8u *m)
19{
20 u64x8 kv4, a, b, shift = { 0, 1, 2, 3, 4, 5, 6, 7 };
21
22 kv4 = (u64x8){ kv[0], kv[1], kv[0], kv[1], kv[0], kv[1], kv[0], kv[1] };
23
24 /* clang-format off */
25 /* create 8 byte-swapped copies of the bytes 0 - 7 */
26 a = (u64x8) u8x64_shuffle (kv4,
27 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
28 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
29 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
30 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
31 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
32 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
33 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
34 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0);
35 /* create 8 byte-swapped copies of the bytes 4 - 11 */
36 b = (u64x8) u8x64_shuffle (kv4,
37 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4,
38 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4,
39 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4,
40 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4,
41 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4,
42 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4,
43 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4,
44 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4);
45 /* clang-format on */
46
47 /* shift each 64-bit element for 0 - 7 bits */
48 a <<= shift;
49 b <<= shift;
50
51 /* clang-format off */
52 /* construct eight 8x8 bit matrix used by gf2p8affine */
53 * m = (u64x8) u8x64_shuffle2 (a, b,
54 0x07, 0x0f, 0x17, 0x1f, 0x27, 0x2f, 0x37, 0x3f,
55 0x06, 0x0e, 0x16, 0x1e, 0x26, 0x2e, 0x36, 0x3e,
56 0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d,
57 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c,
58 0x47, 0x4f, 0x57, 0x5f, 0x67, 0x6f, 0x77, 0x7f,
59 0x46, 0x4e, 0x56, 0x5e, 0x66, 0x6e, 0x76, 0x7e,
60 0x45, 0x4d, 0x55, 0x5d, 0x65, 0x6d, 0x75, 0x7d,
61 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c);
62 /* clang-format on */
63}
64
65void
66clib_toeplitz_hash_key_expand (u64 *matrixes, u8 *key, int size)
67{
68 u64x8u *m = (u64x8u *) matrixes;
Mohsin Kazmi3b7ef512022-01-10 15:32:35 +000069 u64x2 kv = {}, zero = {};
Damjan Marion2e5921b2021-11-28 22:57:15 +010070
71 while (size >= 8)
72 {
73 kv = *(u64x2u *) key;
74 clib_toeplitz_hash_key_expand_8 (kv, m);
75 key += 8;
76 m++;
77 size -= 8;
78 }
79
80 kv = u64x2_shuffle2 (kv, zero, 1, 2);
81 clib_toeplitz_hash_key_expand_8 (kv, m);
82}
83#endif
84
85__clib_export clib_toeplitz_hash_key_t *
86clib_toeplitz_hash_key_init (u8 *key, u32 keylen)
87{
88 clib_toeplitz_hash_key_t *k;
89 u32 size, gfni_size = 0;
90
91 if (key == 0)
92 {
93 key = default_key;
94 keylen = sizeof (default_key);
95 }
96
97 size =
98 round_pow2 (sizeof (clib_toeplitz_hash_key_t) + round_pow2 (keylen, 16),
99 CLIB_CACHE_LINE_BYTES);
100#ifdef __x86_64__
101 gfni_size = round_pow2 ((keylen + 1) * 8, CLIB_CACHE_LINE_BYTES);
102#endif
103
104 k = clib_mem_alloc_aligned (size + gfni_size, CLIB_CACHE_LINE_BYTES);
105 clib_memset_u8 (k, 0, size + gfni_size);
106 k->key_length = keylen;
107 k->gfni_offset = size;
108 clib_memcpy_fast (k->data, key, keylen);
109
110#ifdef __x86_64__
111 clib_toeplitz_hash_key_expand ((u64 *) ((u8 *) k + k->gfni_offset), k->data,
112 k->key_length);
113#endif
114
115 return k;
116}
117
118__clib_export void
119clib_toeplitz_hash_key_free (clib_toeplitz_hash_key_t *k)
120{
121 clib_mem_free (k);
122}