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