Skip to content

Commit ca134ce

Browse files
author
Jozsef Kadlecsik
committed
netfilter: ipset: Move extension data to set structure
Default timeout and extension offsets are moved to struct set, because all set types supports all extensions and it makes possible to generalize extension support. Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
1 parent f925f70 commit ca134ce

15 files changed

+266
-289
lines changed

include/linux/netfilter/ipset/ip_set.h

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ struct ip_set_ext {
7272
u32 timeout;
7373
};
7474

75+
struct ip_set_counter {
76+
atomic64_t bytes;
77+
atomic64_t packets;
78+
};
79+
80+
#define ext_timeout(e, s) \
81+
(unsigned long *)(((void *)(e)) + (s)->offset[IPSET_EXT_ID_TIMEOUT])
82+
#define ext_counter(e, s) \
83+
(struct ip_set_counter *)(((void *)(e)) + (s)->offset[IPSET_EXT_ID_COUNTER])
84+
7585
struct ip_set;
7686

7787
typedef int (*ipset_adtfn)(struct ip_set *set, void *value,
@@ -179,15 +189,16 @@ struct ip_set {
179189
u8 revision;
180190
/* Extensions */
181191
u8 extensions;
192+
/* Default timeout value, if enabled */
193+
u32 timeout;
194+
/* Element data size */
195+
size_t dsize;
196+
/* Offsets to extensions in elements */
197+
size_t offset[IPSET_EXT_ID_MAX];
182198
/* The type specific data */
183199
void *data;
184200
};
185201

186-
struct ip_set_counter {
187-
atomic64_t bytes;
188-
atomic64_t packets;
189-
};
190-
191202
static inline void
192203
ip_set_add_bytes(u64 bytes, struct ip_set_counter *counter)
193204
{
@@ -390,13 +401,13 @@ bitmap_bytes(u32 a, u32 b)
390401

391402
#include <linux/netfilter/ipset/ip_set_timeout.h>
392403

393-
#define IP_SET_INIT_KEXT(skb, opt, map) \
404+
#define IP_SET_INIT_KEXT(skb, opt, set) \
394405
{ .bytes = (skb)->len, .packets = 1, \
395-
.timeout = ip_set_adt_opt_timeout(opt, map) }
406+
.timeout = ip_set_adt_opt_timeout(opt, set) }
396407

397-
#define IP_SET_INIT_UEXT(map) \
408+
#define IP_SET_INIT_UEXT(set) \
398409
{ .bytes = ULLONG_MAX, .packets = ULLONG_MAX, \
399-
.timeout = (map)->timeout }
410+
.timeout = (set)->timeout }
400411

401412
#define IP_SET_INIT_CIDR(a, b) ((a) ? (a) : (b))
402413

include/linux/netfilter/ipset/ip_set_timeout.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
/* Set is defined with timeout support: timeout value may be 0 */
2424
#define IPSET_NO_TIMEOUT UINT_MAX
2525

26-
#define ip_set_adt_opt_timeout(opt, map) \
27-
((opt)->ext.timeout != IPSET_NO_TIMEOUT ? (opt)->ext.timeout : (map)->timeout)
26+
#define ip_set_adt_opt_timeout(opt, set) \
27+
((opt)->ext.timeout != IPSET_NO_TIMEOUT ? (opt)->ext.timeout : (set)->timeout)
2828

2929
static inline unsigned int
3030
ip_set_timeout_uget(struct nlattr *tb)

net/netfilter/ipset/ip_set_bitmap_gen.h

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,7 @@
3232
#define mtype_gc IPSET_TOKEN(MTYPE, _gc)
3333
#define mtype MTYPE
3434

35-
#define ext_timeout(e, m) \
36-
(unsigned long *)((e) + (m)->offset[IPSET_EXT_ID_TIMEOUT])
37-
#define ext_counter(e, m) \
38-
(struct ip_set_counter *)((e) + (m)->offset[IPSET_EXT_ID_COUNTER])
39-
#define get_ext(map, id) ((map)->extensions + (map)->dsize * (id))
35+
#define get_ext(set, map, id) ((map)->extensions + (set)->dsize * (id))
4036

4137
static void
4238
mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
@@ -46,7 +42,7 @@ mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
4642
init_timer(&map->gc);
4743
map->gc.data = (unsigned long) set;
4844
map->gc.function = gc;
49-
map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
45+
map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
5046
add_timer(&map->gc);
5147
}
5248

@@ -59,7 +55,7 @@ mtype_destroy(struct ip_set *set)
5955
del_timer_sync(&map->gc);
6056

6157
ip_set_free(map->members);
62-
if (map->dsize)
58+
if (set->dsize)
6359
ip_set_free(map->extensions);
6460
kfree(map);
6561

@@ -88,9 +84,9 @@ mtype_head(struct ip_set *set, struct sk_buff *skb)
8884
nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
8985
htonl(sizeof(*map) +
9086
map->memsize +
91-
map->dsize * map->elements)) ||
87+
set->dsize * map->elements)) ||
9288
(SET_WITH_TIMEOUT(set) &&
93-
nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))) ||
89+
nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(set->timeout))) ||
9490
(SET_WITH_COUNTER(set) &&
9591
nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS,
9692
htonl(IPSET_FLAG_WITH_COUNTERS))))
@@ -108,16 +104,16 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext,
108104
{
109105
struct mtype *map = set->data;
110106
const struct mtype_adt_elem *e = value;
111-
void *x = get_ext(map, e->id);
112-
int ret = mtype_do_test(e, map);
107+
void *x = get_ext(set, map, e->id);
108+
int ret = mtype_do_test(e, map, set->dsize);
113109

114110
if (ret <= 0)
115111
return ret;
116112
if (SET_WITH_TIMEOUT(set) &&
117-
ip_set_timeout_expired(ext_timeout(x, map)))
113+
ip_set_timeout_expired(ext_timeout(x, set)))
118114
return 0;
119115
if (SET_WITH_COUNTER(set))
120-
ip_set_update_counter(ext_counter(x, map), ext, mext, flags);
116+
ip_set_update_counter(ext_counter(x, set), ext, mext, flags);
121117
return 1;
122118
}
123119

@@ -127,26 +123,26 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
127123
{
128124
struct mtype *map = set->data;
129125
const struct mtype_adt_elem *e = value;
130-
void *x = get_ext(map, e->id);
131-
int ret = mtype_do_add(e, map, flags);
126+
void *x = get_ext(set, map, e->id);
127+
int ret = mtype_do_add(e, map, flags, set->dsize);
132128

133129
if (ret == IPSET_ADD_FAILED) {
134130
if (SET_WITH_TIMEOUT(set) &&
135-
ip_set_timeout_expired(ext_timeout(x, map)))
131+
ip_set_timeout_expired(ext_timeout(x, set)))
136132
ret = 0;
137133
else if (!(flags & IPSET_FLAG_EXIST))
138134
return -IPSET_ERR_EXIST;
139135
}
140136

141137
if (SET_WITH_TIMEOUT(set))
142138
#ifdef IP_SET_BITMAP_STORED_TIMEOUT
143-
mtype_add_timeout(ext_timeout(x, map), e, ext, map, ret);
139+
mtype_add_timeout(ext_timeout(x, set), e, ext, set, map, ret);
144140
#else
145-
ip_set_timeout_set(ext_timeout(x, map), ext->timeout);
141+
ip_set_timeout_set(ext_timeout(x, set), ext->timeout);
146142
#endif
147143

148144
if (SET_WITH_COUNTER(set))
149-
ip_set_init_counter(ext_counter(x, map), ext);
145+
ip_set_init_counter(ext_counter(x, set), ext);
150146
return 0;
151147
}
152148

@@ -156,11 +152,11 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
156152
{
157153
struct mtype *map = set->data;
158154
const struct mtype_adt_elem *e = value;
159-
const void *x = get_ext(map, e->id);
155+
const void *x = get_ext(set, map, e->id);
160156

161157
if (mtype_do_del(e, map) ||
162158
(SET_WITH_TIMEOUT(set) &&
163-
ip_set_timeout_expired(ext_timeout(x, map))))
159+
ip_set_timeout_expired(ext_timeout(x, set))))
164160
return -IPSET_ERR_EXIST;
165161

166162
return 0;
@@ -180,13 +176,13 @@ mtype_list(const struct ip_set *set,
180176
return -EMSGSIZE;
181177
for (; cb->args[2] < map->elements; cb->args[2]++) {
182178
id = cb->args[2];
183-
x = get_ext(map, id);
179+
x = get_ext(set, map, id);
184180
if (!test_bit(id, map->members) ||
185181
(SET_WITH_TIMEOUT(set) &&
186182
#ifdef IP_SET_BITMAP_STORED_TIMEOUT
187183
mtype_is_filled((const struct mtype_elem *) x) &&
188184
#endif
189-
ip_set_timeout_expired(ext_timeout(x, map))))
185+
ip_set_timeout_expired(ext_timeout(x, set))))
190186
continue;
191187
nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
192188
if (!nested) {
@@ -196,23 +192,24 @@ mtype_list(const struct ip_set *set,
196192
} else
197193
goto nla_put_failure;
198194
}
199-
if (mtype_do_list(skb, map, id))
195+
if (mtype_do_list(skb, map, id, set->dsize))
200196
goto nla_put_failure;
201197
if (SET_WITH_TIMEOUT(set)) {
202198
#ifdef IP_SET_BITMAP_STORED_TIMEOUT
203199
if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
204200
htonl(ip_set_timeout_stored(map, id,
205-
ext_timeout(x, map)))))
201+
ext_timeout(x, set),
202+
set->dsize))))
206203
goto nla_put_failure;
207204
#else
208205
if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
209206
htonl(ip_set_timeout_get(
210-
ext_timeout(x, map)))))
207+
ext_timeout(x, set)))))
211208
goto nla_put_failure;
212209
#endif
213210
}
214211
if (SET_WITH_COUNTER(set) &&
215-
ip_set_put_counter(skb, ext_counter(x, map)))
212+
ip_set_put_counter(skb, ext_counter(x, set)))
216213
goto nla_put_failure;
217214
ipset_nest_end(skb, nested);
218215
}
@@ -245,14 +242,14 @@ mtype_gc(unsigned long ul_set)
245242
* but adding/deleting new entries is locked out */
246243
read_lock_bh(&set->lock);
247244
for (id = 0; id < map->elements; id++)
248-
if (mtype_gc_test(id, map)) {
249-
x = get_ext(map, id);
250-
if (ip_set_timeout_expired(ext_timeout(x, map)))
245+
if (mtype_gc_test(id, map, set->dsize)) {
246+
x = get_ext(set, map, id);
247+
if (ip_set_timeout_expired(ext_timeout(x, set)))
251248
clear_bit(id, map->members);
252249
}
253250
read_unlock_bh(&set->lock);
254251

255-
map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
252+
map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
256253
add_timer(&map->gc);
257254
}
258255

net/netfilter/ipset/ip_set_bitmap_ip.c

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,7 @@ struct bitmap_ip {
4444
u32 elements; /* number of max elements in the set */
4545
u32 hosts; /* number of hosts in a subnet */
4646
size_t memsize; /* members size */
47-
size_t dsize; /* extensions struct size */
48-
size_t offset[IPSET_EXT_ID_MAX]; /* Offsets to extensions */
4947
u8 netmask; /* subnet netmask */
50-
u32 timeout; /* timeout parameter */
5148
struct timer_list gc; /* garbage collection */
5249
};
5350

@@ -65,20 +62,21 @@ ip_to_id(const struct bitmap_ip *m, u32 ip)
6562
/* Common functions */
6663

6764
static inline int
68-
bitmap_ip_do_test(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map)
65+
bitmap_ip_do_test(const struct bitmap_ip_adt_elem *e,
66+
struct bitmap_ip *map, size_t dsize)
6967
{
7068
return !!test_bit(e->id, map->members);
7169
}
7270

7371
static inline int
74-
bitmap_ip_gc_test(u16 id, const struct bitmap_ip *map)
72+
bitmap_ip_gc_test(u16 id, const struct bitmap_ip *map, size_t dsize)
7573
{
7674
return !!test_bit(id, map->members);
7775
}
7876

7977
static inline int
8078
bitmap_ip_do_add(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map,
81-
u32 flags)
79+
u32 flags, size_t dsize)
8280
{
8381
return !!test_and_set_bit(e->id, map->members);
8482
}
@@ -90,7 +88,8 @@ bitmap_ip_do_del(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map)
9088
}
9189

9290
static inline int
93-
bitmap_ip_do_list(struct sk_buff *skb, const struct bitmap_ip *map, u32 id)
91+
bitmap_ip_do_list(struct sk_buff *skb, const struct bitmap_ip *map, u32 id,
92+
size_t dsize)
9493
{
9594
return nla_put_ipaddr4(skb, IPSET_ATTR_IP,
9695
htonl(map->first_ip + id * map->hosts));
@@ -113,7 +112,7 @@ bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
113112
struct bitmap_ip *map = set->data;
114113
ipset_adtfn adtfn = set->variant->adt[adt];
115114
struct bitmap_ip_adt_elem e = { };
116-
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map);
115+
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
117116
u32 ip;
118117

119118
ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
@@ -133,7 +132,7 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
133132
ipset_adtfn adtfn = set->variant->adt[adt];
134133
u32 ip = 0, ip_to = 0;
135134
struct bitmap_ip_adt_elem e = { };
136-
struct ip_set_ext ext = IP_SET_INIT_UEXT(map);
135+
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
137136
int ret = 0;
138137

139138
if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -200,7 +199,7 @@ bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
200199
return x->first_ip == y->first_ip &&
201200
x->last_ip == y->last_ip &&
202201
x->netmask == y->netmask &&
203-
x->timeout == y->timeout &&
202+
a->timeout == b->timeout &&
204203
a->extensions == b->extensions;
205204
}
206205

@@ -240,8 +239,8 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
240239
map->members = ip_set_alloc(map->memsize);
241240
if (!map->members)
242241
return false;
243-
if (map->dsize) {
244-
map->extensions = ip_set_alloc(map->dsize * elements);
242+
if (set->dsize) {
243+
map->extensions = ip_set_alloc(set->dsize * elements);
245244
if (!map->extensions) {
246245
kfree(map->members);
247246
return false;
@@ -252,7 +251,7 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
252251
map->elements = elements;
253252
map->hosts = hosts;
254253
map->netmask = netmask;
255-
map->timeout = IPSET_NO_TIMEOUT;
254+
set->timeout = IPSET_NO_TIMEOUT;
256255

257256
set->data = map;
258257
set->family = NFPROTO_IPV4;
@@ -341,10 +340,10 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
341340
if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) {
342341
set->extensions |= IPSET_EXT_COUNTER;
343342
if (tb[IPSET_ATTR_TIMEOUT]) {
344-
map->dsize = sizeof(struct bitmap_ipct_elem);
345-
map->offset[IPSET_EXT_ID_TIMEOUT] =
343+
set->dsize = sizeof(struct bitmap_ipct_elem);
344+
set->offset[IPSET_EXT_ID_TIMEOUT] =
346345
offsetof(struct bitmap_ipct_elem, timeout);
347-
map->offset[IPSET_EXT_ID_COUNTER] =
346+
set->offset[IPSET_EXT_ID_COUNTER] =
348347
offsetof(struct bitmap_ipct_elem, counter);
349348

350349
if (!init_map_ip(set, map, first_ip, last_ip,
@@ -353,14 +352,14 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
353352
return -ENOMEM;
354353
}
355354

356-
map->timeout = ip_set_timeout_uget(
355+
set->timeout = ip_set_timeout_uget(
357356
tb[IPSET_ATTR_TIMEOUT]);
358357
set->extensions |= IPSET_EXT_TIMEOUT;
359358

360359
bitmap_ip_gc_init(set, bitmap_ip_gc);
361360
} else {
362-
map->dsize = sizeof(struct bitmap_ipc_elem);
363-
map->offset[IPSET_EXT_ID_COUNTER] =
361+
set->dsize = sizeof(struct bitmap_ipc_elem);
362+
set->offset[IPSET_EXT_ID_COUNTER] =
364363
offsetof(struct bitmap_ipc_elem, counter);
365364

366365
if (!init_map_ip(set, map, first_ip, last_ip,
@@ -370,8 +369,8 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
370369
}
371370
}
372371
} else if (tb[IPSET_ATTR_TIMEOUT]) {
373-
map->dsize = sizeof(struct bitmap_ipt_elem);
374-
map->offset[IPSET_EXT_ID_TIMEOUT] =
372+
set->dsize = sizeof(struct bitmap_ipt_elem);
373+
set->offset[IPSET_EXT_ID_TIMEOUT] =
375374
offsetof(struct bitmap_ipt_elem, timeout);
376375

377376
if (!init_map_ip(set, map, first_ip, last_ip,
@@ -380,12 +379,12 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
380379
return -ENOMEM;
381380
}
382381

383-
map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
382+
set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
384383
set->extensions |= IPSET_EXT_TIMEOUT;
385384

386385
bitmap_ip_gc_init(set, bitmap_ip_gc);
387386
} else {
388-
map->dsize = 0;
387+
set->dsize = 0;
389388
if (!init_map_ip(set, map, first_ip, last_ip,
390389
elements, hosts, netmask)) {
391390
kfree(map);

0 commit comments

Comments
 (0)