^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef _XFRM_HASH_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define _XFRM_HASH_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/xfrm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/jhash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) static inline unsigned int __xfrm4_addr_hash(const xfrm_address_t *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) return ntohl(addr->a4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) static inline unsigned int __xfrm6_addr_hash(const xfrm_address_t *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) return jhash2((__force u32 *)addr->a6, 4, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static inline unsigned int __xfrm4_daddr_saddr_hash(const xfrm_address_t *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) const xfrm_address_t *saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) u32 sum = (__force u32)daddr->a4 + (__force u32)saddr->a4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) return ntohl((__force __be32)sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static inline unsigned int __xfrm6_daddr_saddr_hash(const xfrm_address_t *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) const xfrm_address_t *saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return __xfrm6_addr_hash(daddr) ^ __xfrm6_addr_hash(saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static inline u32 __bits2mask32(__u8 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u32 mask32 = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (bits == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) mask32 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) else if (bits < 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) mask32 <<= (32 - bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return mask32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static inline unsigned int __xfrm4_dpref_spref_hash(const xfrm_address_t *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) const xfrm_address_t *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) __u8 dbits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) __u8 sbits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return jhash_2words(ntohl(daddr->a4) & __bits2mask32(dbits),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) ntohl(saddr->a4) & __bits2mask32(sbits),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static inline unsigned int __xfrm6_pref_hash(const xfrm_address_t *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __u8 prefixlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned int pdw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned int pbi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u32 initval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) pdw = prefixlen >> 5; /* num of whole u32 in prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (pbi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) __be32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) mask = htonl((0xffffffff) << (32 - pbi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) initval = (__force u32)(addr->a6[pdw] & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return jhash2((__force u32 *)addr->a6, pdw, initval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static inline unsigned int __xfrm6_dpref_spref_hash(const xfrm_address_t *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) const xfrm_address_t *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) __u8 dbits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) __u8 sbits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return __xfrm6_pref_hash(daddr, dbits) ^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) __xfrm6_pref_hash(saddr, sbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static inline unsigned int __xfrm_dst_hash(const xfrm_address_t *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) const xfrm_address_t *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u32 reqid, unsigned short family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned int hmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned int h = family ^ reqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) h ^= __xfrm4_daddr_saddr_hash(daddr, saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) h ^= __xfrm6_daddr_saddr_hash(daddr, saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return (h ^ (h >> 16)) & hmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static inline unsigned int __xfrm_src_hash(const xfrm_address_t *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) const xfrm_address_t *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned short family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) unsigned int hmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned int h = family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) h ^= __xfrm4_daddr_saddr_hash(daddr, saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) h ^= __xfrm6_daddr_saddr_hash(daddr, saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return (h ^ (h >> 16)) & hmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static inline unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) __xfrm_spi_hash(const xfrm_address_t *daddr, __be32 spi, u8 proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) unsigned short family, unsigned int hmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned int h = (__force u32)spi ^ proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) h ^= __xfrm4_addr_hash(daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) h ^= __xfrm6_addr_hash(daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return (h ^ (h >> 10) ^ (h >> 20)) & hmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static inline unsigned int __idx_hash(u32 index, unsigned int hmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return (index ^ (index >> 8)) & hmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static inline unsigned int __sel_hash(const struct xfrm_selector *sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) unsigned short family, unsigned int hmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u8 dbits, u8 sbits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) const xfrm_address_t *daddr = &sel->daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) const xfrm_address_t *saddr = &sel->saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) unsigned int h = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (sel->prefixlen_d < dbits ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) sel->prefixlen_s < sbits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return hmask + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) h = __xfrm4_dpref_spref_hash(daddr, saddr, dbits, sbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (sel->prefixlen_d < dbits ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) sel->prefixlen_s < sbits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return hmask + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) h = __xfrm6_dpref_spref_hash(daddr, saddr, dbits, sbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) h ^= (h >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return h & hmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static inline unsigned int __addr_hash(const xfrm_address_t *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) const xfrm_address_t *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) unsigned short family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) unsigned int hmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u8 dbits, u8 sbits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsigned int h = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) h = __xfrm4_dpref_spref_hash(daddr, saddr, dbits, sbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) h = __xfrm6_dpref_spref_hash(daddr, saddr, dbits, sbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) h ^= (h >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return h & hmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct hlist_head *xfrm_hash_alloc(unsigned int sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) void xfrm_hash_free(struct hlist_head *n, unsigned int sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #endif /* _XFRM_HASH_H */