cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xfrm_hash.h (4694B)


      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 */