~ubuntu-branches/ubuntu/trusty/xtables-addons/trusty

« back to all changes in this revision

Viewing changes to extensions/ipset-4/ip_set_hashes.h

  • Committer: Package Import Robot
  • Author(s): Pierre Chifflier, Pierre Chifflier, Dmitry Smirnov
  • Date: 2011-12-05 22:10:25 UTC
  • mfrom: (1.3.6)
  • Revision ID: package-import@ubuntu.com-20111205221025-ogq3g7zsm912lmsh
Tags: 1.40-1
[ Pierre Chifflier ]
* Add patch to avoid calling depmod during build
* Add VCS links
* Change license for packaging files to GPL-2+ (with agreement of all
  authors).
* Add Dmitry Smirnov as co-maintainer
  - Merge all changes
* Imported Upstream version 1.40 (2011-11-30)
  Fixes:
  - build: the code actually requires at least iptables 1.4.5
    (would yield a compile error otherwise), make sure configure
    checks for it; update INSTALL
  - xt_ECHO: fix kernel warning about RTAX_HOPLIMIT being used
  - xt_ipv4options: fix an infinite loop
  Changes:
  - xt_ECHO: now calculates UDP checksum
  - Linux kernel versions below 2.6.32 are no longer officially
    supported, and will not be part of compilation testing.
  - update to ipset 6.10
  Enhancements:
  - xt_ECHO: IPv6 support

[Dmitry Smirnov] <onlyjob@member.fsf.org>
* Major repackaging (Closes: #638061)
  * Obsolete ipset_v4 replaced with new ipset_v6 (Closes: #648083)
  * debian/copyright updated for DEP5 compatibility
  * debian/control updated
    - Standards version update
    - Depends update
    - Build-depends tightening
  * debian/watch fixed
  * debian/rules rewrite
    - get-orig-source target added
    - build-time cleanup (make clean) is fixed
    - second build do not fail
    - offload most tasks to debhelper (with minimum overrides)
    - standalone debian/rules for xtables-addons-source
    - using CFLAGS/Hardening if provided by DPKG
    - dynamically prepare DKMS config during build
    - configure for Kbuild only if headers available
  * lintianization
    - override for package-name-doesnt-match-sonames
  * DKMS package cleanup
    - broken post-init script removed
    - only clean source is packaged
    - improved configuration
  * source package cleanup
    - module-assistant rules use debhelper more
    - using CFLAGS if provided by DPKG
  * lintian override
  * DKMS config sanitation (all argument in double quotes)
  * patch to avoid build-time depmod invocation
* Imported Upstream version 1.39 (2011-09-21)
  - libxt_ACCOUNT: fix compilation after missing libxtables_CFLAGS
  - build: fix compilation after missing libxtables_CFLAGS in submodules
  - build: add missing linux/version.h includes where needed
  - Remove unsupported ipset 4.x from the Xtables-addons distribution
  - ipset: move ipset_errcode from src to library to avoid undefined reference
  - update to ipset 6.9.1
  - xt_CHECKSUM: abort build when the feature is already provided by mainline
  - xt_SYSRQ: fix UDPLITE header lookup in IPv6
  - xt_TARPIT: fix kernel warning about RTAX_HOPLIMIT being used
  - xt_TEE: abort build when the feature is already provided by mainline
  - xt_ipp2p: support UDPLITE
  - xt_pknock: support UDPLITE
  - xt_psd: restore functionality with UDP
  - xt_psd: support UDPLITE
  - support for Linux 3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#ifndef __IP_SET_HASHES_H
2
 
#define __IP_SET_HASHES_H
3
 
 
4
 
#define initval_t uint32_t
5
 
 
6
 
/* Macros to generate functions */
7
 
 
8
 
#ifdef __KERNEL__
9
 
#define HASH_RETRY0(type, dtype, cond)                                  \
10
 
static int                                                              \
11
 
type##_retry(struct ip_set *set)                                        \
12
 
{                                                                       \
13
 
        struct ip_set_##type *map = set->data, *tmp;                    \
14
 
        dtype *elem;                                                    \
15
 
        void *members;                                                  \
16
 
        u_int32_t i, hashsize = map->hashsize;                          \
17
 
        int res;                                                        \
18
 
                                                                        \
19
 
        if (map->resize == 0)                                           \
20
 
                return -ERANGE;                                         \
21
 
                                                                        \
22
 
    again:                                                              \
23
 
        res = 0;                                                        \
24
 
                                                                        \
25
 
        /* Calculate new hash size */                                   \
26
 
        hashsize += (hashsize * map->resize)/100;                       \
27
 
        if (hashsize == map->hashsize)                                  \
28
 
                hashsize++;                                             \
29
 
                                                                        \
30
 
        ip_set_printk("rehashing of set %s triggered: "                 \
31
 
                      "hashsize grows from %lu to %lu",                 \
32
 
                      set->name,                                        \
33
 
                      (long unsigned)map->hashsize,                     \
34
 
                      (long unsigned)hashsize);                         \
35
 
                                                                        \
36
 
        tmp = kmalloc(sizeof(struct ip_set_##type)                      \
37
 
                      + map->probes * sizeof(initval_t), GFP_ATOMIC);   \
38
 
        if (!tmp) {                                                     \
39
 
                DP("out of memory for %zu bytes",                       \
40
 
                   sizeof(struct ip_set_##type)                         \
41
 
                   + map->probes * sizeof(initval_t));                  \
42
 
                return -ENOMEM;                                         \
43
 
        }                                                               \
44
 
        tmp->members = harray_malloc(hashsize, sizeof(dtype), GFP_ATOMIC);\
45
 
        if (!tmp->members) {                                            \
46
 
                DP("out of memory for %zu bytes", hashsize * sizeof(dtype));\
47
 
                kfree(tmp);                                             \
48
 
                return -ENOMEM;                                         \
49
 
        }                                                               \
50
 
        tmp->hashsize = hashsize;                                       \
51
 
        tmp->elements = 0;                                              \
52
 
        tmp->probes = map->probes;                                      \
53
 
        tmp->resize = map->resize;                                      \
54
 
        memcpy(tmp->initval, map->initval, map->probes * sizeof(initval_t));\
55
 
        __##type##_retry(tmp, map);                                     \
56
 
                                                                        \
57
 
        write_lock_bh(&set->lock);                                      \
58
 
        map = set->data; /* Play safe */                                \
59
 
        for (i = 0; i < map->hashsize && res == 0; i++) {               \
60
 
                elem = HARRAY_ELEM(map->members, dtype *, i);           \
61
 
                if (cond)                                               \
62
 
                        res = __##type##_add(tmp, elem);                \
63
 
        }                                                               \
64
 
        if (res) {                                                      \
65
 
                /* Failure, try again */                                \
66
 
                write_unlock_bh(&set->lock);                            \
67
 
                harray_free(tmp->members);                              \
68
 
                kfree(tmp);                                             \
69
 
                goto again;                                             \
70
 
        }                                                               \
71
 
                                                                        \
72
 
        /* Success at resizing! */                                      \
73
 
        members = map->members;                                         \
74
 
                                                                        \
75
 
        map->hashsize = tmp->hashsize;                                  \
76
 
        map->members = tmp->members;                                    \
77
 
        write_unlock_bh(&set->lock);                                    \
78
 
                                                                        \
79
 
        harray_free(members);                                           \
80
 
        kfree(tmp);                                                     \
81
 
                                                                        \
82
 
        return 0;                                                       \
83
 
}
84
 
 
85
 
#define HASH_RETRY(type, dtype)                                         \
86
 
        HASH_RETRY0(type, dtype, *elem)
87
 
 
88
 
#define HASH_RETRY2(type, dtype)                                                \
89
 
        HASH_RETRY0(type, dtype, elem->ip || elem->ip1)
90
 
 
91
 
#define HASH_CREATE(type, dtype)                                        \
92
 
static int                                                              \
93
 
type##_create(struct ip_set *set, const void *data, u_int32_t size)     \
94
 
{                                                                       \
95
 
        const struct ip_set_req_##type##_create *req = data;            \
96
 
        struct ip_set_##type *map;                                      \
97
 
        uint16_t i;                                                     \
98
 
                                                                        \
99
 
        if (req->hashsize < 1) {                                        \
100
 
                ip_set_printk("hashsize too small");                    \
101
 
                return -ENOEXEC;                                        \
102
 
        }                                                               \
103
 
                                                                        \
104
 
        if (req->probes < 1) {                                          \
105
 
                ip_set_printk("probes too small");                      \
106
 
                return -ENOEXEC;                                        \
107
 
        }                                                               \
108
 
                                                                        \
109
 
        map = kmalloc(sizeof(struct ip_set_##type)                      \
110
 
                      + req->probes * sizeof(initval_t), GFP_KERNEL);   \
111
 
        if (!map) {                                                     \
112
 
                DP("out of memory for %zu bytes",                       \
113
 
                   sizeof(struct ip_set_##type)                         \
114
 
                   + req->probes * sizeof(initval_t));                  \
115
 
                return -ENOMEM;                                         \
116
 
        }                                                               \
117
 
        for (i = 0; i < req->probes; i++)                               \
118
 
                get_random_bytes(((initval_t *) map->initval)+i, 4);    \
119
 
        map->elements = 0;                                              \
120
 
        map->hashsize = req->hashsize;                                  \
121
 
        map->probes = req->probes;                                      \
122
 
        map->resize = req->resize;                                      \
123
 
        if (__##type##_create(req, map)) {                              \
124
 
                kfree(map);                                             \
125
 
                return -ENOEXEC;                                        \
126
 
        }                                                               \
127
 
        map->members = harray_malloc(map->hashsize, sizeof(dtype), GFP_KERNEL);\
128
 
        if (!map->members) {                                            \
129
 
                DP("out of memory for %zu bytes", map->hashsize * sizeof(dtype));\
130
 
                kfree(map);                                             \
131
 
                return -ENOMEM;                                         \
132
 
        }                                                               \
133
 
                                                                        \
134
 
        set->data = map;                                                \
135
 
        return 0;                                                       \
136
 
}
137
 
 
138
 
#define HASH_DESTROY(type)                                              \
139
 
static void                                                             \
140
 
type##_destroy(struct ip_set *set)                                      \
141
 
{                                                                       \
142
 
        struct ip_set_##type *map = set->data;                          \
143
 
                                                                        \
144
 
        harray_free(map->members);                                      \
145
 
        kfree(map);                                                     \
146
 
                                                                        \
147
 
        set->data = NULL;                                               \
148
 
}
149
 
 
150
 
#define HASH_FLUSH(type, dtype)                                         \
151
 
static void                                                             \
152
 
type##_flush(struct ip_set *set)                                        \
153
 
{                                                                       \
154
 
        struct ip_set_##type *map = set->data;                          \
155
 
        harray_flush(map->members, map->hashsize, sizeof(dtype));       \
156
 
        map->elements = 0;                                              \
157
 
}
158
 
 
159
 
#define HASH_FLUSH_CIDR(type, dtype)                                    \
160
 
static void                                                             \
161
 
type##_flush(struct ip_set *set)                                        \
162
 
{                                                                       \
163
 
        struct ip_set_##type *map = set->data;                          \
164
 
        harray_flush(map->members, map->hashsize, sizeof(dtype));       \
165
 
        memset(map->cidr, 0, sizeof(map->cidr));                        \
166
 
        memset(map->nets, 0, sizeof(map->nets));                        \
167
 
        map->elements = 0;                                              \
168
 
}
169
 
 
170
 
#define HASH_LIST_HEADER(type)                                          \
171
 
static void                                                             \
172
 
type##_list_header(const struct ip_set *set, void *data)                \
173
 
{                                                                       \
174
 
        const struct ip_set_##type *map = set->data;                    \
175
 
        struct ip_set_req_##type##_create *header = data;               \
176
 
                                                                        \
177
 
        header->hashsize = map->hashsize;                               \
178
 
        header->probes = map->probes;                                   \
179
 
        header->resize = map->resize;                                   \
180
 
        __##type##_list_header(map, header);                            \
181
 
}
182
 
 
183
 
#define HASH_LIST_MEMBERS_SIZE(type, dtype)                             \
184
 
static int                                                              \
185
 
type##_list_members_size(const struct ip_set *set, char dont_align)     \
186
 
{                                                                       \
187
 
        const struct ip_set_##type *map = set->data;                    \
188
 
                                                                        \
189
 
        return (map->elements * IPSET_VALIGN(sizeof(dtype), dont_align));\
190
 
}
191
 
 
192
 
#define HASH_LIST_MEMBERS(type, dtype)                                  \
193
 
static void                                                             \
194
 
type##_list_members(const struct ip_set *set, void *data, char dont_align)\
195
 
{                                                                       \
196
 
        const struct ip_set_##type *map = set->data;                    \
197
 
        dtype *elem, *d;                                                \
198
 
        uint32_t i, n = 0;                                              \
199
 
                                                                        \
200
 
        for (i = 0; i < map->hashsize; i++) {                           \
201
 
                elem = HARRAY_ELEM(map->members, dtype *, i);           \
202
 
                if (*elem) {                                            \
203
 
                        d = data + n * IPSET_VALIGN(sizeof(dtype), dont_align);\
204
 
                        *d = *elem;                                     \
205
 
                        n++;                                            \
206
 
                }                                                       \
207
 
        }                                                               \
208
 
}
209
 
 
210
 
#define HASH_LIST_MEMBERS_MEMCPY(type, dtype, nonzero)                  \
211
 
static void                                                             \
212
 
type##_list_members(const struct ip_set *set, void *data, char dont_align)\
213
 
{                                                                       \
214
 
        const struct ip_set_##type *map = set->data;                    \
215
 
        dtype *elem;                                                    \
216
 
        uint32_t i, n = 0;                                              \
217
 
                                                                        \
218
 
        for (i = 0; i < map->hashsize; i++) {                           \
219
 
                elem = HARRAY_ELEM(map->members, dtype *, i);           \
220
 
                if (nonzero) {                                          \
221
 
                        memcpy(data + n * IPSET_VALIGN(sizeof(dtype), dont_align),\
222
 
                               elem, sizeof(dtype));                    \
223
 
                        n++;                                            \
224
 
                }                                                       \
225
 
        }                                                               \
226
 
}
227
 
 
228
 
#define IP_SET_RTYPE(type, __features)                                  \
229
 
struct ip_set_type ip_set_##type = {                                    \
230
 
        .typename               = #type,                                \
231
 
        .features               = __features,                           \
232
 
        .protocol_version       = IP_SET_PROTOCOL_VERSION,              \
233
 
        .create                 = &type##_create,                       \
234
 
        .retry                  = &type##_retry,                        \
235
 
        .destroy                = &type##_destroy,                      \
236
 
        .flush                  = &type##_flush,                        \
237
 
        .reqsize                = sizeof(struct ip_set_req_##type),     \
238
 
        .addip                  = &type##_uadd,                         \
239
 
        .addip_kernel           = &type##_kadd,                         \
240
 
        .delip                  = &type##_udel,                         \
241
 
        .delip_kernel           = &type##_kdel,                         \
242
 
        .testip                 = &type##_utest,                        \
243
 
        .testip_kernel          = &type##_ktest,                        \
244
 
        .header_size            = sizeof(struct ip_set_req_##type##_create),\
245
 
        .list_header            = &type##_list_header,                  \
246
 
        .list_members_size      = &type##_list_members_size,            \
247
 
        .list_members           = &type##_list_members,                 \
248
 
        .me                     = THIS_MODULE,                          \
249
 
};
250
 
 
251
 
/* Helper functions */
252
 
static inline void
253
 
add_cidr_size(uint8_t *cidr, uint8_t size)
254
 
{
255
 
        uint8_t next;
256
 
        int i;
257
 
        
258
 
        for (i = 0; i < 30 && cidr[i]; i++) {
259
 
                if (cidr[i] < size) {
260
 
                        next = cidr[i];
261
 
                        cidr[i] = size;
262
 
                        size = next;
263
 
                }
264
 
        }
265
 
        if (i < 30)
266
 
                cidr[i] = size;
267
 
}
268
 
 
269
 
static inline void
270
 
del_cidr_size(uint8_t *cidr, uint8_t size)
271
 
{
272
 
        int i;
273
 
        
274
 
        for (i = 0; i < 29 && cidr[i]; i++) {
275
 
                if (cidr[i] == size)
276
 
                        cidr[i] = size = cidr[i+1];
277
 
        }
278
 
        cidr[29] = 0;
279
 
}
280
 
#else
281
 
#include <arpa/inet.h>
282
 
#endif /* __KERNEL */
283
 
 
284
 
#ifndef UINT16_MAX
285
 
#define UINT16_MAX 65535
286
 
#endif
287
 
 
288
 
static unsigned char shifts[] = {255, 253, 249, 241, 225, 193, 129, 1};
289
 
 
290
 
static inline ip_set_ip_t 
291
 
pack_ip_cidr(ip_set_ip_t ip, unsigned char cidr)
292
 
{
293
 
        ip_set_ip_t addr, *paddr = &addr;
294
 
        unsigned char n, t, *a;
295
 
 
296
 
        addr = htonl(ip & (0xFFFFFFFF << (32 - (cidr))));
297
 
#ifdef __KERNEL__
298
 
        DP("ip:%u.%u.%u.%u/%u", NIPQUAD(addr), cidr);
299
 
#endif
300
 
        n = cidr / 8;
301
 
        t = cidr % 8;   
302
 
        a = &((unsigned char *)paddr)[n];
303
 
        *a = *a /(1 << (8 - t)) + shifts[t];
304
 
#ifdef __KERNEL__
305
 
        DP("n: %u, t: %u, a: %u", n, t, *a);
306
 
        DP("ip:%u.%u.%u.%u/%u, %u.%u.%u.%u",
307
 
           HIPQUAD(ip), cidr, NIPQUAD(addr));
308
 
#endif
309
 
 
310
 
        return ntohl(addr);
311
 
}
312
 
 
313
 
 
314
 
#endif /* __IP_SET_HASHES_H */