linux/net/xfrm/xfrm_hash.h
<<
>>
Prefs
   1#ifndef _XFRM_HASH_H
   2#define _XFRM_HASH_H
   3
   4#include <linux/xfrm.h>
   5#include <linux/socket.h>
   6
   7static inline unsigned int __xfrm4_addr_hash(const xfrm_address_t *addr)
   8{
   9        return ntohl(addr->a4);
  10}
  11
  12static inline unsigned int __xfrm6_addr_hash(const xfrm_address_t *addr)
  13{
  14        return ntohl(addr->a6[2] ^ addr->a6[3]);
  15}
  16
  17static inline unsigned int __xfrm4_daddr_saddr_hash(const xfrm_address_t *daddr,
  18                                                    const xfrm_address_t *saddr)
  19{
  20        u32 sum = (__force u32)daddr->a4 + (__force u32)saddr->a4;
  21        return ntohl((__force __be32)sum);
  22}
  23
  24static inline unsigned int __xfrm6_daddr_saddr_hash(const xfrm_address_t *daddr,
  25                                                    const xfrm_address_t *saddr)
  26{
  27        return ntohl(daddr->a6[2] ^ daddr->a6[3] ^
  28                     saddr->a6[2] ^ saddr->a6[3]);
  29}
  30
  31static inline unsigned int __xfrm_dst_hash(const xfrm_address_t *daddr,
  32                                           const xfrm_address_t *saddr,
  33                                           u32 reqid, unsigned short family,
  34                                           unsigned int hmask)
  35{
  36        unsigned int h = family ^ reqid;
  37        switch (family) {
  38        case AF_INET:
  39                h ^= __xfrm4_daddr_saddr_hash(daddr, saddr);
  40                break;
  41        case AF_INET6:
  42                h ^= __xfrm6_daddr_saddr_hash(daddr, saddr);
  43                break;
  44        }
  45        return (h ^ (h >> 16)) & hmask;
  46}
  47
  48static inline unsigned int __xfrm_src_hash(const xfrm_address_t *daddr,
  49                                           const xfrm_address_t *saddr,
  50                                           unsigned short family,
  51                                           unsigned int hmask)
  52{
  53        unsigned int h = family;
  54        switch (family) {
  55        case AF_INET:
  56                h ^= __xfrm4_daddr_saddr_hash(daddr, saddr);
  57                break;
  58        case AF_INET6:
  59                h ^= __xfrm6_daddr_saddr_hash(daddr, saddr);
  60                break;
  61        }
  62        return (h ^ (h >> 16)) & hmask;
  63}
  64
  65static inline unsigned int
  66__xfrm_spi_hash(const xfrm_address_t *daddr, __be32 spi, u8 proto,
  67                unsigned short family, unsigned int hmask)
  68{
  69        unsigned int h = (__force u32)spi ^ proto;
  70        switch (family) {
  71        case AF_INET:
  72                h ^= __xfrm4_addr_hash(daddr);
  73                break;
  74        case AF_INET6:
  75                h ^= __xfrm6_addr_hash(daddr);
  76                break;
  77        }
  78        return (h ^ (h >> 10) ^ (h >> 20)) & hmask;
  79}
  80
  81static inline unsigned int __idx_hash(u32 index, unsigned int hmask)
  82{
  83        return (index ^ (index >> 8)) & hmask;
  84}
  85
  86static inline unsigned int __sel_hash(const struct xfrm_selector *sel,
  87                                      unsigned short family, unsigned int hmask)
  88{
  89        const xfrm_address_t *daddr = &sel->daddr;
  90        const xfrm_address_t *saddr = &sel->saddr;
  91        unsigned int h = 0;
  92
  93        switch (family) {
  94        case AF_INET:
  95                if (sel->prefixlen_d != 32 ||
  96                    sel->prefixlen_s != 32)
  97                        return hmask + 1;
  98
  99                h = __xfrm4_daddr_saddr_hash(daddr, saddr);
 100                break;
 101
 102        case AF_INET6:
 103                if (sel->prefixlen_d != 128 ||
 104                    sel->prefixlen_s != 128)
 105                        return hmask + 1;
 106
 107                h = __xfrm6_daddr_saddr_hash(daddr, saddr);
 108                break;
 109        }
 110        h ^= (h >> 16);
 111        return h & hmask;
 112}
 113
 114static inline unsigned int __addr_hash(const xfrm_address_t *daddr,
 115                                       const xfrm_address_t *saddr,
 116                                       unsigned short family, unsigned int hmask)
 117{
 118        unsigned int h = 0;
 119
 120        switch (family) {
 121        case AF_INET:
 122                h = __xfrm4_daddr_saddr_hash(daddr, saddr);
 123                break;
 124
 125        case AF_INET6:
 126                h = __xfrm6_daddr_saddr_hash(daddr, saddr);
 127                break;
 128        }
 129        h ^= (h >> 16);
 130        return h & hmask;
 131}
 132
 133struct hlist_head *xfrm_hash_alloc(unsigned int sz);
 134void xfrm_hash_free(struct hlist_head *n, unsigned int sz);
 135
 136#endif /* _XFRM_HASH_H */
 137