1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#ifndef __IP_SET_BITMAPS_H
#define __IP_SET_BITMAPS_H
/* Macros to generate functions */
#ifdef __KERNEL__
#define BITMAP_CREATE(type) \
static int \
type##_create(struct ip_set *set, const void *data, u_int32_t size) \
{ \
int newbytes; \
const struct ip_set_req_##type##_create *req = data; \
struct ip_set_##type *map; \
\
if (req->from > req->to) { \
DP("bad range"); \
return -ENOEXEC; \
} \
\
map = kmalloc(sizeof(struct ip_set_##type), GFP_KERNEL); \
if (!map) { \
DP("out of memory for %zu bytes", \
sizeof(struct ip_set_##type)); \
return -ENOMEM; \
} \
map->first_ip = req->from; \
map->last_ip = req->to; \
\
newbytes = __##type##_create(req, map); \
if (newbytes < 0) { \
kfree(map); \
return newbytes; \
} \
\
map->size = newbytes; \
map->members = ip_set_malloc(newbytes); \
if (!map->members) { \
DP("out of memory for %i bytes", newbytes); \
kfree(map); \
return -ENOMEM; \
} \
memset(map->members, 0, newbytes); \
\
set->data = map; \
return 0; \
}
#define BITMAP_DESTROY(type) \
static void \
type##_destroy(struct ip_set *set) \
{ \
struct ip_set_##type *map = set->data; \
\
ip_set_free(map->members, map->size); \
kfree(map); \
\
set->data = NULL; \
}
#define BITMAP_FLUSH(type) \
static void \
type##_flush(struct ip_set *set) \
{ \
struct ip_set_##type *map = set->data; \
memset(map->members, 0, map->size); \
}
#define BITMAP_LIST_HEADER(type) \
static void \
type##_list_header(const struct ip_set *set, void *data) \
{ \
const struct ip_set_##type *map = set->data; \
struct ip_set_req_##type##_create *header = data; \
\
header->from = map->first_ip; \
header->to = map->last_ip; \
__##type##_list_header(map, header); \
}
#define BITMAP_LIST_MEMBERS_SIZE(type, dtype, sizeid, testfn) \
static int \
type##_list_members_size(const struct ip_set *set, char dont_align) \
{ \
const struct ip_set_##type *map = set->data; \
ip_set_ip_t i, elements = 0; \
\
if (dont_align) \
return map->size; \
\
for (i = 0; i < sizeid; i++) \
if (testfn) \
elements++; \
\
return elements * IPSET_ALIGN(sizeof(dtype)); \
}
#define IP_SET_TYPE(type, __features) \
struct ip_set_type ip_set_##type = { \
.typename = #type, \
.features = __features, \
.protocol_version = IP_SET_PROTOCOL_VERSION, \
.create = &type##_create, \
.destroy = &type##_destroy, \
.flush = &type##_flush, \
.reqsize = sizeof(struct ip_set_req_##type), \
.addip = &type##_uadd, \
.addip_kernel = &type##_kadd, \
.delip = &type##_udel, \
.delip_kernel = &type##_kdel, \
.testip = &type##_utest, \
.testip_kernel = &type##_ktest, \
.header_size = sizeof(struct ip_set_req_##type##_create),\
.list_header = &type##_list_header, \
.list_members_size = &type##_list_members_size, \
.list_members = &type##_list_members, \
.me = THIS_MODULE, \
};
#endif /* __KERNEL */
#endif /* __IP_SET_BITMAPS_H */
|