root/net/xfrm/xfrm_hash.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. __xfrm4_addr_hash
  2. __xfrm6_addr_hash
  3. __xfrm4_daddr_saddr_hash
  4. __xfrm6_daddr_saddr_hash
  5. __bits2mask32
  6. __xfrm4_dpref_spref_hash
  7. __xfrm6_pref_hash
  8. __xfrm6_dpref_spref_hash
  9. __xfrm_dst_hash
  10. __xfrm_src_hash
  11. __xfrm_spi_hash
  12. __idx_hash
  13. __sel_hash
  14. __addr_hash

   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 
   9 static inline unsigned int __xfrm4_addr_hash(const xfrm_address_t *addr)
  10 {
  11         return ntohl(addr->a4);
  12 }
  13 
  14 static inline unsigned int __xfrm6_addr_hash(const xfrm_address_t *addr)
  15 {
  16         return jhash2((__force u32 *)addr->a6, 4, 0);
  17 }
  18 
  19 static 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 
  26 static 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 
  32 static 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 
  44 static 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 
  54 static 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 
  75 static 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 
  84 static 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 
 101 static 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 
 118 static 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 
 134 static inline unsigned int __idx_hash(u32 index, unsigned int hmask)
 135 {
 136         return (index ^ (index >> 8)) & hmask;
 137 }
 138 
 139 static inline unsigned int __sel_hash(const struct xfrm_selector *sel,
 140                                       unsigned short family, unsigned int hmask,
 141                                       u8 dbits, u8 sbits)
 142 {
 143         const xfrm_address_t *daddr = &sel->daddr;
 144         const xfrm_address_t *saddr = &sel->saddr;
 145         unsigned int h = 0;
 146 
 147         switch (family) {
 148         case AF_INET:
 149                 if (sel->prefixlen_d < dbits ||
 150                     sel->prefixlen_s < sbits)
 151                         return hmask + 1;
 152 
 153                 h = __xfrm4_dpref_spref_hash(daddr, saddr, dbits, sbits);
 154                 break;
 155 
 156         case AF_INET6:
 157                 if (sel->prefixlen_d < dbits ||
 158                     sel->prefixlen_s < sbits)
 159                         return hmask + 1;
 160 
 161                 h = __xfrm6_dpref_spref_hash(daddr, saddr, dbits, sbits);
 162                 break;
 163         }
 164         h ^= (h >> 16);
 165         return h & hmask;
 166 }
 167 
 168 static inline unsigned int __addr_hash(const xfrm_address_t *daddr,
 169                                        const xfrm_address_t *saddr,
 170                                        unsigned short family,
 171                                        unsigned int hmask,
 172                                        u8 dbits, u8 sbits)
 173 {
 174         unsigned int h = 0;
 175 
 176         switch (family) {
 177         case AF_INET:
 178                 h = __xfrm4_dpref_spref_hash(daddr, saddr, dbits, sbits);
 179                 break;
 180 
 181         case AF_INET6:
 182                 h = __xfrm6_dpref_spref_hash(daddr, saddr, dbits, sbits);
 183                 break;
 184         }
 185         h ^= (h >> 16);
 186         return h & hmask;
 187 }
 188 
 189 struct hlist_head *xfrm_hash_alloc(unsigned int sz);
 190 void xfrm_hash_free(struct hlist_head *n, unsigned int sz);
 191 
 192 #endif /* _XFRM_HASH_H */

/* [<][>][^][v][top][bottom][index][help] */