xref: /openbsd/sys/net/toeplitz.h (revision d415bd75)
1 /*	$OpenBSD: toeplitz.h,v 1.11 2023/05/17 10:22:17 dlg Exp $ */
2 
3 /*
4  * Copyright (c) 2019 David Gwynne <dlg@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef _SYS_NET_TOEPLITZ_H_
20 #define _SYS_NET_TOEPLITZ_H_
21 
22 #include <sys/endian.h>
23 
24 /*
25  * symmetric toeplitz
26  */
27 
28 typedef uint16_t stoeplitz_key;
29 
30 struct stoeplitz_cache {
31 	uint16_t	bytes[256];
32 };
33 
34 static __unused inline uint16_t
35 stoeplitz_cache_entry(const struct stoeplitz_cache *scache, uint8_t byte)
36 {
37 	return (scache->bytes[byte]);
38 }
39 
40 void		stoeplitz_cache_init(struct stoeplitz_cache *, stoeplitz_key);
41 
42 uint16_t	stoeplitz_hash_ip4(const struct stoeplitz_cache *,
43 		    uint32_t, uint32_t);
44 uint16_t	stoeplitz_hash_ip4port(const struct stoeplitz_cache *,
45 		    uint32_t, uint32_t, uint16_t, uint16_t);
46 
47 #ifdef INET6
48 struct in6_addr;
49 uint16_t	stoeplitz_hash_ip6(const struct stoeplitz_cache *,
50 		    const struct in6_addr *, const struct in6_addr *);
51 uint16_t	stoeplitz_hash_ip6port(const struct stoeplitz_cache *,
52 		    const struct in6_addr *, const struct in6_addr *,
53 		    uint16_t, uint16_t);
54 #endif
55 
56 uint16_t	stoeplitz_hash_eaddr(const struct stoeplitz_cache *,
57 		    const uint8_t *);
58 
59 /* hash a uint16_t in network byte order */
60 static __unused inline uint16_t
61 stoeplitz_hash_n16(const struct stoeplitz_cache *scache, uint16_t n16)
62 {
63 	uint16_t hi, lo;
64 
65 	hi = stoeplitz_cache_entry(scache, n16 >> 8);
66 	lo = stoeplitz_cache_entry(scache, n16);
67 
68 	return (hi ^ swap16(lo));
69 }
70 
71 /* hash a uint32_t in network byte order */
72 static __unused inline uint16_t
73 stoeplitz_hash_n32(const struct stoeplitz_cache *scache, uint32_t n32)
74 {
75 	return (stoeplitz_hash_n16(scache, n32 ^ (n32 >> 16)));
76 }
77 
78 /* hash a uint16_t in host byte order */
79 static __unused inline uint16_t
80 stoeplitz_hash_h16(const struct stoeplitz_cache *scache, uint16_t h16)
81 {
82 	uint16_t lo, hi;
83 
84 	lo = stoeplitz_cache_entry(scache, h16);
85 	hi = stoeplitz_cache_entry(scache, h16 >> 8);
86 
87 #if _BYTE_ORDER == _BIG_ENDIAN
88 	return (hi ^ swap16(lo));
89 #else
90 	return (swap16(hi) ^ lo);
91 #endif
92 }
93 
94 static __unused inline uint16_t
95 stoeplitz_hash_h32(const struct stoeplitz_cache *scache, uint32_t h32)
96 {
97 	return (stoeplitz_hash_h16(scache, h32 ^ (h32 >> 16)));
98 }
99 
100 static __unused inline uint16_t
101 stoeplitz_hash_h64(const struct stoeplitz_cache *scache, uint64_t h64)
102 {
103 	return (stoeplitz_hash_h32(scache, h64 ^ (h64 >> 32)));
104 }
105 
106 /*
107  * system provided symmetric toeplitz
108  */
109 
110 #define STOEPLITZ_KEYSEED	0x6d5a
111 
112 void		stoeplitz_init(void);
113 
114 void		stoeplitz_to_key(void *, size_t)
115 		    __bounded((__buffer__, 1, 2));
116 
117 extern const struct stoeplitz_cache *const stoeplitz_cache;
118 
119 #define stoeplitz_n16(_n16) \
120 	stoeplitz_hash_n16(stoeplitz_cache, (_n16))
121 #define stoeplitz_n32(_n32) \
122 	stoeplitz_hash_n32(stoeplitz_cache, (_n32))
123 #define stoeplitz_h16(_h16) \
124 	stoeplitz_hash_h16(stoeplitz_cache, (_h16))
125 #define stoeplitz_h32(_h32) \
126 	stoeplitz_hash_h32(stoeplitz_cache, (_h32))
127 #define stoeplitz_h64(_h64) \
128 	stoeplitz_hash_h64(stoeplitz_cache, (_h64))
129 #define stoeplitz_port(_p)	stoeplitz_n16((_p))
130 #define stoeplitz_ip4(_sa4, _da4) \
131 	stoeplitz_hash_ip4(stoeplitz_cache, (_sa4), (_da4))
132 #define stoeplitz_ip4port(_sa4, _da4, _sp, _dp) \
133 	stoeplitz_hash_ip4port(stoeplitz_cache, (_sa4), (_da4), (_sp), (_dp))
134 #ifdef INET6
135 #define stoeplitz_ip6(_sa6, _da6) \
136 	stoeplitz_hash_ip6(stoeplitz_cache, (_sa6), (_da6))
137 #define stoeplitz_ip6port(_sa6, _da6, _sp, _dp) \
138 	stoeplitz_hash_ip6port(stoeplitz_cache, (_sa6), (_da6), (_sp), (_dp))
139 #endif
140 #define stoeplitz_eaddr(_ea) \
141 	stoeplitz_hash_eaddr(stoeplitz_cache, (_ea))
142 
143 #endif /* _SYS_NET_TOEPLITZ_H_ */
144