Linux Audio

Check our new training course

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