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.3 knakahar /* 124 1.3 knakahar * system also provided asymmetric toeplitz 125 1.3 knakahar */ 126 1.3 knakahar 127 1.3 knakahar uint32_t toeplitz_vhash(const uint8_t *, size_t, ...); 128 1.3 knakahar 129 1.1 jmcneill #endif /* _SYS_NET_TOEPLITZ_H_ */ 130