Root/net/xfrm/xfrm_hash.h

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
133extern struct hlist_head *xfrm_hash_alloc(unsigned int sz);
134extern void xfrm_hash_free(struct hlist_head *n, unsigned int sz);
135
136#endif /* _XFRM_HASH_H */
137

Archive Download this file



interactive