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