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