~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to net/xfrm/xfrm_hash.h

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
        return ntohl(addr->a4);
 
10
}
 
11
 
 
12
static inline unsigned int __xfrm6_addr_hash(const xfrm_address_t *addr)
 
13
{
 
14
        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
        u32 sum = (__force u32)daddr->a4 + (__force u32)saddr->a4;
 
21
        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
        return ntohl(daddr->a6[2] ^ daddr->a6[3] ^
 
28
                     saddr->a6[2] ^ saddr->a6[3]);
 
29
}
 
30
 
 
31
static 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
 
 
48
static inline unsigned __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
 
 
65
static 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
 
 
81
static inline unsigned int __idx_hash(u32 index, unsigned int hmask)
 
82
{
 
83
        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
        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
 
 
114
static 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
 
 
133
extern struct hlist_head *xfrm_hash_alloc(unsigned int sz);
 
134
extern void xfrm_hash_free(struct hlist_head *n, unsigned int sz);
 
135
 
 
136
#endif /* _XFRM_HASH_H */