diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2013-04-08 17:10:22 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-04-29 14:09:00 -0400 |
commit | f48d19db12e1cde296ce7a13c38303618e38e304 (patch) | |
tree | 521b8f49dab3469b938e8694752eaf598019e946 | |
parent | 34d666d489cf70c246ca99b2387741915c34b88c (diff) |
netfilter: ipset: The bitmap types with counter support
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | net/netfilter/ipset/ip_set_bitmap_gen.h | 14 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_bitmap_ip.c | 62 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_bitmap_ipmac.c | 68 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_bitmap_port.c | 57 |
4 files changed, 186 insertions, 15 deletions
diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h index b9931591cbe9..25243379b887 100644 --- a/net/netfilter/ipset/ip_set_bitmap_gen.h +++ b/net/netfilter/ipset/ip_set_bitmap_gen.h | |||
@@ -37,6 +37,8 @@ | |||
37 | 37 | ||
38 | #define ext_timeout(e, m) \ | 38 | #define ext_timeout(e, m) \ |
39 | (unsigned long *)((e) + (m)->offset[IPSET_OFFSET_TIMEOUT]) | 39 | (unsigned long *)((e) + (m)->offset[IPSET_OFFSET_TIMEOUT]) |
40 | #define ext_counter(e, m) \ | ||
41 | (struct ip_set_counter *)((e) + (m)->offset[IPSET_OFFSET_COUNTER]) | ||
40 | #define get_ext(map, id) ((map)->extensions + (map)->dsize * (id)) | 42 | #define get_ext(map, id) ((map)->extensions + (map)->dsize * (id)) |
41 | 43 | ||
42 | static void | 44 | static void |
@@ -91,7 +93,10 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) | |||
91 | map->memsize + | 93 | map->memsize + |
92 | map->dsize * map->elements)) || | 94 | map->dsize * map->elements)) || |
93 | (SET_WITH_TIMEOUT(set) && | 95 | (SET_WITH_TIMEOUT(set) && |
94 | nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout)))) | 96 | nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))) || |
97 | (SET_WITH_COUNTER(set) && | ||
98 | nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, | ||
99 | htonl(IPSET_FLAG_WITH_COUNTERS)))) | ||
95 | goto nla_put_failure; | 100 | goto nla_put_failure; |
96 | ipset_nest_end(skb, nested); | 101 | ipset_nest_end(skb, nested); |
97 | 102 | ||
@@ -114,6 +119,8 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext, | |||
114 | if (SET_WITH_TIMEOUT(set) && | 119 | if (SET_WITH_TIMEOUT(set) && |
115 | ip_set_timeout_expired(ext_timeout(x, map))) | 120 | ip_set_timeout_expired(ext_timeout(x, map))) |
116 | return 0; | 121 | return 0; |
122 | if (SET_WITH_COUNTER(set)) | ||
123 | ip_set_update_counter(ext_counter(x, map), ext, mext, flags); | ||
117 | return 1; | 124 | return 1; |
118 | } | 125 | } |
119 | 126 | ||
@@ -141,6 +148,8 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, | |||
141 | ip_set_timeout_set(ext_timeout(x, map), ext->timeout); | 148 | ip_set_timeout_set(ext_timeout(x, map), ext->timeout); |
142 | #endif | 149 | #endif |
143 | 150 | ||
151 | if (SET_WITH_COUNTER(set)) | ||
152 | ip_set_init_counter(ext_counter(x, map), ext); | ||
144 | return 0; | 153 | return 0; |
145 | } | 154 | } |
146 | 155 | ||
@@ -205,6 +214,9 @@ mtype_list(const struct ip_set *set, | |||
205 | goto nla_put_failure; | 214 | goto nla_put_failure; |
206 | #endif | 215 | #endif |
207 | } | 216 | } |
217 | if (SET_WITH_COUNTER(set) && | ||
218 | ip_set_put_counter(skb, ext_counter(x, map))) | ||
219 | goto nla_put_failure; | ||
208 | ipset_nest_end(skb, nested); | 220 | ipset_nest_end(skb, nested); |
209 | } | 221 | } |
210 | ipset_nest_end(skb, adt); | 222 | ipset_nest_end(skb, adt); |
diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c index f2ab0116d94f..f1a8128bef01 100644 --- a/net/netfilter/ipset/ip_set_bitmap_ip.c +++ b/net/netfilter/ipset/ip_set_bitmap_ip.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/netfilter/ipset/ip_set_bitmap.h> | 26 | #include <linux/netfilter/ipset/ip_set_bitmap.h> |
27 | 27 | ||
28 | #define REVISION_MIN 0 | 28 | #define REVISION_MIN 0 |
29 | #define REVISION_MAX 0 | 29 | #define REVISION_MAX 1 /* Counter support added */ |
30 | 30 | ||
31 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
32 | MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); | 32 | MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); |
@@ -137,7 +137,9 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[], | |||
137 | int ret = 0; | 137 | int ret = 0; |
138 | 138 | ||
139 | if (unlikely(!tb[IPSET_ATTR_IP] || | 139 | if (unlikely(!tb[IPSET_ATTR_IP] || |
140 | !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) | 140 | !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || |
141 | !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) || | ||
142 | !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES))) | ||
141 | return -IPSET_ERR_PROTOCOL; | 143 | return -IPSET_ERR_PROTOCOL; |
142 | 144 | ||
143 | if (tb[IPSET_ATTR_LINENO]) | 145 | if (tb[IPSET_ATTR_LINENO]) |
@@ -213,6 +215,19 @@ struct bitmap_ipt_elem { | |||
213 | unsigned long timeout; | 215 | unsigned long timeout; |
214 | }; | 216 | }; |
215 | 217 | ||
218 | /* Plain variant with counter */ | ||
219 | |||
220 | struct bitmap_ipc_elem { | ||
221 | struct ip_set_counter counter; | ||
222 | }; | ||
223 | |||
224 | /* Timeout variant with counter */ | ||
225 | |||
226 | struct bitmap_ipct_elem { | ||
227 | unsigned long timeout; | ||
228 | struct ip_set_counter counter; | ||
229 | }; | ||
230 | |||
216 | #include "ip_set_bitmap_gen.h" | 231 | #include "ip_set_bitmap_gen.h" |
217 | 232 | ||
218 | /* Create bitmap:ip type of sets */ | 233 | /* Create bitmap:ip type of sets */ |
@@ -249,13 +264,14 @@ static int | |||
249 | bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) | 264 | bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) |
250 | { | 265 | { |
251 | struct bitmap_ip *map; | 266 | struct bitmap_ip *map; |
252 | u32 first_ip, last_ip, hosts; | 267 | u32 first_ip, last_ip, hosts, cadt_flags = 0; |
253 | u64 elements; | 268 | u64 elements; |
254 | u8 netmask = 32; | 269 | u8 netmask = 32; |
255 | int ret; | 270 | int ret; |
256 | 271 | ||
257 | if (unlikely(!tb[IPSET_ATTR_IP] || | 272 | if (unlikely(!tb[IPSET_ATTR_IP] || |
258 | !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) | 273 | !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || |
274 | !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) | ||
259 | return -IPSET_ERR_PROTOCOL; | 275 | return -IPSET_ERR_PROTOCOL; |
260 | 276 | ||
261 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip); | 277 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip); |
@@ -320,7 +336,40 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) | |||
320 | 336 | ||
321 | map->memsize = bitmap_bytes(0, elements - 1); | 337 | map->memsize = bitmap_bytes(0, elements - 1); |
322 | set->variant = &bitmap_ip; | 338 | set->variant = &bitmap_ip; |
323 | if (tb[IPSET_ATTR_TIMEOUT]) { | 339 | if (tb[IPSET_ATTR_CADT_FLAGS]) |
340 | cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); | ||
341 | if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) { | ||
342 | set->extensions |= IPSET_EXT_COUNTER; | ||
343 | if (tb[IPSET_ATTR_TIMEOUT]) { | ||
344 | map->dsize = sizeof(struct bitmap_ipct_elem); | ||
345 | map->offset[IPSET_OFFSET_TIMEOUT] = | ||
346 | offsetof(struct bitmap_ipct_elem, timeout); | ||
347 | map->offset[IPSET_OFFSET_COUNTER] = | ||
348 | offsetof(struct bitmap_ipct_elem, counter); | ||
349 | |||
350 | if (!init_map_ip(set, map, first_ip, last_ip, | ||
351 | elements, hosts, netmask)) { | ||
352 | kfree(map); | ||
353 | return -ENOMEM; | ||
354 | } | ||
355 | |||
356 | map->timeout = ip_set_timeout_uget( | ||
357 | tb[IPSET_ATTR_TIMEOUT]); | ||
358 | set->extensions |= IPSET_EXT_TIMEOUT; | ||
359 | |||
360 | bitmap_ip_gc_init(set, bitmap_ip_gc); | ||
361 | } else { | ||
362 | map->dsize = sizeof(struct bitmap_ipc_elem); | ||
363 | map->offset[IPSET_OFFSET_COUNTER] = | ||
364 | offsetof(struct bitmap_ipc_elem, counter); | ||
365 | |||
366 | if (!init_map_ip(set, map, first_ip, last_ip, | ||
367 | elements, hosts, netmask)) { | ||
368 | kfree(map); | ||
369 | return -ENOMEM; | ||
370 | } | ||
371 | } | ||
372 | } else if (tb[IPSET_ATTR_TIMEOUT]) { | ||
324 | map->dsize = sizeof(struct bitmap_ipt_elem); | 373 | map->dsize = sizeof(struct bitmap_ipt_elem); |
325 | map->offset[IPSET_OFFSET_TIMEOUT] = | 374 | map->offset[IPSET_OFFSET_TIMEOUT] = |
326 | offsetof(struct bitmap_ipt_elem, timeout); | 375 | offsetof(struct bitmap_ipt_elem, timeout); |
@@ -361,6 +410,7 @@ static struct ip_set_type bitmap_ip_type __read_mostly = { | |||
361 | [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, | 410 | [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, |
362 | [IPSET_ATTR_NETMASK] = { .type = NLA_U8 }, | 411 | [IPSET_ATTR_NETMASK] = { .type = NLA_U8 }, |
363 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, | 412 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, |
413 | [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, | ||
364 | }, | 414 | }, |
365 | .adt_policy = { | 415 | .adt_policy = { |
366 | [IPSET_ATTR_IP] = { .type = NLA_NESTED }, | 416 | [IPSET_ATTR_IP] = { .type = NLA_NESTED }, |
@@ -368,6 +418,8 @@ static struct ip_set_type bitmap_ip_type __read_mostly = { | |||
368 | [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, | 418 | [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, |
369 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, | 419 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, |
370 | [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, | 420 | [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, |
421 | [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, | ||
422 | [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, | ||
371 | }, | 423 | }, |
372 | .me = THIS_MODULE, | 424 | .me = THIS_MODULE, |
373 | }; | 425 | }; |
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c index 960810dfcd81..3b30e0bef890 100644 --- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c +++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/netfilter/ipset/ip_set_bitmap.h> | 26 | #include <linux/netfilter/ipset/ip_set_bitmap.h> |
27 | 27 | ||
28 | #define REVISION_MIN 0 | 28 | #define REVISION_MIN 0 |
29 | #define REVISION_MAX 0 | 29 | #define REVISION_MAX 1 /* Counter support added */ |
30 | 30 | ||
31 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
32 | MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); | 32 | MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); |
@@ -250,7 +250,9 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[], | |||
250 | int ret = 0; | 250 | int ret = 0; |
251 | 251 | ||
252 | if (unlikely(!tb[IPSET_ATTR_IP] || | 252 | if (unlikely(!tb[IPSET_ATTR_IP] || |
253 | !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) | 253 | !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || |
254 | !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) || | ||
255 | !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES))) | ||
254 | return -IPSET_ERR_PROTOCOL; | 256 | return -IPSET_ERR_PROTOCOL; |
255 | 257 | ||
256 | if (tb[IPSET_ATTR_LINENO]) | 258 | if (tb[IPSET_ATTR_LINENO]) |
@@ -299,6 +301,27 @@ struct bitmap_ipmact_elem { | |||
299 | unsigned long timeout; | 301 | unsigned long timeout; |
300 | }; | 302 | }; |
301 | 303 | ||
304 | /* Plain variant with counter */ | ||
305 | |||
306 | struct bitmap_ipmacc_elem { | ||
307 | struct { | ||
308 | unsigned char ether[ETH_ALEN]; | ||
309 | unsigned char filled; | ||
310 | } __attribute__ ((aligned)); | ||
311 | struct ip_set_counter counter; | ||
312 | }; | ||
313 | |||
314 | /* Timeout variant with counter */ | ||
315 | |||
316 | struct bitmap_ipmacct_elem { | ||
317 | struct { | ||
318 | unsigned char ether[ETH_ALEN]; | ||
319 | unsigned char filled; | ||
320 | } __attribute__ ((aligned)); | ||
321 | unsigned long timeout; | ||
322 | struct ip_set_counter counter; | ||
323 | }; | ||
324 | |||
302 | #include "ip_set_bitmap_gen.h" | 325 | #include "ip_set_bitmap_gen.h" |
303 | 326 | ||
304 | /* Create bitmap:ip,mac type of sets */ | 327 | /* Create bitmap:ip,mac type of sets */ |
@@ -332,13 +355,14 @@ static int | |||
332 | bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[], | 355 | bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[], |
333 | u32 flags) | 356 | u32 flags) |
334 | { | 357 | { |
335 | u32 first_ip, last_ip; | 358 | u32 first_ip, last_ip, cadt_flags = 0; |
336 | u64 elements; | 359 | u64 elements; |
337 | struct bitmap_ipmac *map; | 360 | struct bitmap_ipmac *map; |
338 | int ret; | 361 | int ret; |
339 | 362 | ||
340 | if (unlikely(!tb[IPSET_ATTR_IP] || | 363 | if (unlikely(!tb[IPSET_ATTR_IP] || |
341 | !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) | 364 | !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || |
365 | !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) | ||
342 | return -IPSET_ERR_PROTOCOL; | 366 | return -IPSET_ERR_PROTOCOL; |
343 | 367 | ||
344 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip); | 368 | ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip); |
@@ -375,7 +399,38 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[], | |||
375 | 399 | ||
376 | map->memsize = bitmap_bytes(0, elements - 1); | 400 | map->memsize = bitmap_bytes(0, elements - 1); |
377 | set->variant = &bitmap_ipmac; | 401 | set->variant = &bitmap_ipmac; |
378 | if (tb[IPSET_ATTR_TIMEOUT]) { | 402 | if (tb[IPSET_ATTR_CADT_FLAGS]) |
403 | cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); | ||
404 | if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) { | ||
405 | set->extensions |= IPSET_EXT_COUNTER; | ||
406 | if (tb[IPSET_ATTR_TIMEOUT]) { | ||
407 | map->dsize = sizeof(struct bitmap_ipmacct_elem); | ||
408 | map->offset[IPSET_OFFSET_TIMEOUT] = | ||
409 | offsetof(struct bitmap_ipmacct_elem, timeout); | ||
410 | map->offset[IPSET_OFFSET_COUNTER] = | ||
411 | offsetof(struct bitmap_ipmacct_elem, counter); | ||
412 | |||
413 | if (!init_map_ipmac(set, map, first_ip, last_ip, | ||
414 | elements)) { | ||
415 | kfree(map); | ||
416 | return -ENOMEM; | ||
417 | } | ||
418 | map->timeout = ip_set_timeout_uget( | ||
419 | tb[IPSET_ATTR_TIMEOUT]); | ||
420 | set->extensions |= IPSET_EXT_TIMEOUT; | ||
421 | bitmap_ipmac_gc_init(set, bitmap_ipmac_gc); | ||
422 | } else { | ||
423 | map->dsize = sizeof(struct bitmap_ipmacc_elem); | ||
424 | map->offset[IPSET_OFFSET_COUNTER] = | ||
425 | offsetof(struct bitmap_ipmacc_elem, counter); | ||
426 | |||
427 | if (!init_map_ipmac(set, map, first_ip, last_ip, | ||
428 | elements)) { | ||
429 | kfree(map); | ||
430 | return -ENOMEM; | ||
431 | } | ||
432 | } | ||
433 | } else if (tb[IPSET_ATTR_TIMEOUT]) { | ||
379 | map->dsize = sizeof(struct bitmap_ipmact_elem); | 434 | map->dsize = sizeof(struct bitmap_ipmact_elem); |
380 | map->offset[IPSET_OFFSET_TIMEOUT] = | 435 | map->offset[IPSET_OFFSET_TIMEOUT] = |
381 | offsetof(struct bitmap_ipmact_elem, timeout); | 436 | offsetof(struct bitmap_ipmact_elem, timeout); |
@@ -413,6 +468,7 @@ static struct ip_set_type bitmap_ipmac_type = { | |||
413 | [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, | 468 | [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, |
414 | [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, | 469 | [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, |
415 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, | 470 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, |
471 | [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, | ||
416 | }, | 472 | }, |
417 | .adt_policy = { | 473 | .adt_policy = { |
418 | [IPSET_ATTR_IP] = { .type = NLA_NESTED }, | 474 | [IPSET_ATTR_IP] = { .type = NLA_NESTED }, |
@@ -420,6 +476,8 @@ static struct ip_set_type bitmap_ipmac_type = { | |||
420 | .len = ETH_ALEN }, | 476 | .len = ETH_ALEN }, |
421 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, | 477 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, |
422 | [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, | 478 | [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, |
479 | [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, | ||
480 | [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, | ||
423 | }, | 481 | }, |
424 | .me = THIS_MODULE, | 482 | .me = THIS_MODULE, |
425 | }; | 483 | }; |
diff --git a/net/netfilter/ipset/ip_set_bitmap_port.c b/net/netfilter/ipset/ip_set_bitmap_port.c index 27e2c573adcd..8207d1fda528 100644 --- a/net/netfilter/ipset/ip_set_bitmap_port.c +++ b/net/netfilter/ipset/ip_set_bitmap_port.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/netfilter/ipset/ip_set_getport.h> | 21 | #include <linux/netfilter/ipset/ip_set_getport.h> |
22 | 22 | ||
23 | #define REVISION_MIN 0 | 23 | #define REVISION_MIN 0 |
24 | #define REVISION_MAX 0 | 24 | #define REVISION_MAX 1 /* Counter support added */ |
25 | 25 | ||
26 | MODULE_LICENSE("GPL"); | 26 | MODULE_LICENSE("GPL"); |
27 | MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); | 27 | MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); |
@@ -138,7 +138,9 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[], | |||
138 | 138 | ||
139 | if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || | 139 | if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || |
140 | !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || | 140 | !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || |
141 | !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) | 141 | !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || |
142 | !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) || | ||
143 | !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES))) | ||
142 | return -IPSET_ERR_PROTOCOL; | 144 | return -IPSET_ERR_PROTOCOL; |
143 | 145 | ||
144 | if (tb[IPSET_ATTR_LINENO]) | 146 | if (tb[IPSET_ATTR_LINENO]) |
@@ -199,10 +201,24 @@ struct bitmap_port_elem { | |||
199 | }; | 201 | }; |
200 | 202 | ||
201 | /* Timeout variant */ | 203 | /* Timeout variant */ |
204 | |||
202 | struct bitmap_portt_elem { | 205 | struct bitmap_portt_elem { |
203 | unsigned long timeout; | 206 | unsigned long timeout; |
204 | }; | 207 | }; |
205 | 208 | ||
209 | /* Plain variant with counter */ | ||
210 | |||
211 | struct bitmap_portc_elem { | ||
212 | struct ip_set_counter counter; | ||
213 | }; | ||
214 | |||
215 | /* Timeout variant with counter */ | ||
216 | |||
217 | struct bitmap_portct_elem { | ||
218 | unsigned long timeout; | ||
219 | struct ip_set_counter counter; | ||
220 | }; | ||
221 | |||
206 | #include "ip_set_bitmap_gen.h" | 222 | #include "ip_set_bitmap_gen.h" |
207 | 223 | ||
208 | /* Create bitmap:ip type of sets */ | 224 | /* Create bitmap:ip type of sets */ |
@@ -236,10 +252,12 @@ bitmap_port_create(struct ip_set *set, struct nlattr *tb[], u32 flags) | |||
236 | { | 252 | { |
237 | struct bitmap_port *map; | 253 | struct bitmap_port *map; |
238 | u16 first_port, last_port; | 254 | u16 first_port, last_port; |
255 | u32 cadt_flags = 0; | ||
239 | 256 | ||
240 | if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || | 257 | if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || |
241 | !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) || | 258 | !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) || |
242 | !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) | 259 | !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || |
260 | !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) | ||
243 | return -IPSET_ERR_PROTOCOL; | 261 | return -IPSET_ERR_PROTOCOL; |
244 | 262 | ||
245 | first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]); | 263 | first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]); |
@@ -258,7 +276,35 @@ bitmap_port_create(struct ip_set *set, struct nlattr *tb[], u32 flags) | |||
258 | map->elements = last_port - first_port + 1; | 276 | map->elements = last_port - first_port + 1; |
259 | map->memsize = map->elements * sizeof(unsigned long); | 277 | map->memsize = map->elements * sizeof(unsigned long); |
260 | set->variant = &bitmap_port; | 278 | set->variant = &bitmap_port; |
261 | if (tb[IPSET_ATTR_TIMEOUT]) { | 279 | if (tb[IPSET_ATTR_CADT_FLAGS]) |
280 | cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); | ||
281 | if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) { | ||
282 | set->extensions |= IPSET_EXT_COUNTER; | ||
283 | if (tb[IPSET_ATTR_TIMEOUT]) { | ||
284 | map->dsize = sizeof(struct bitmap_portct_elem); | ||
285 | map->offset[IPSET_OFFSET_TIMEOUT] = | ||
286 | offsetof(struct bitmap_portct_elem, timeout); | ||
287 | map->offset[IPSET_OFFSET_COUNTER] = | ||
288 | offsetof(struct bitmap_portct_elem, counter); | ||
289 | if (!init_map_port(set, map, first_port, last_port)) { | ||
290 | kfree(map); | ||
291 | return -ENOMEM; | ||
292 | } | ||
293 | |||
294 | map->timeout = | ||
295 | ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); | ||
296 | set->extensions |= IPSET_EXT_TIMEOUT; | ||
297 | bitmap_port_gc_init(set, bitmap_port_gc); | ||
298 | } else { | ||
299 | map->dsize = sizeof(struct bitmap_portc_elem); | ||
300 | map->offset[IPSET_OFFSET_COUNTER] = | ||
301 | offsetof(struct bitmap_portc_elem, counter); | ||
302 | if (!init_map_port(set, map, first_port, last_port)) { | ||
303 | kfree(map); | ||
304 | return -ENOMEM; | ||
305 | } | ||
306 | } | ||
307 | } else if (tb[IPSET_ATTR_TIMEOUT]) { | ||
262 | map->dsize = sizeof(struct bitmap_portt_elem); | 308 | map->dsize = sizeof(struct bitmap_portt_elem); |
263 | map->offset[IPSET_OFFSET_TIMEOUT] = | 309 | map->offset[IPSET_OFFSET_TIMEOUT] = |
264 | offsetof(struct bitmap_portt_elem, timeout); | 310 | offsetof(struct bitmap_portt_elem, timeout); |
@@ -294,12 +340,15 @@ static struct ip_set_type bitmap_port_type = { | |||
294 | [IPSET_ATTR_PORT] = { .type = NLA_U16 }, | 340 | [IPSET_ATTR_PORT] = { .type = NLA_U16 }, |
295 | [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 }, | 341 | [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 }, |
296 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, | 342 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, |
343 | [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, | ||
297 | }, | 344 | }, |
298 | .adt_policy = { | 345 | .adt_policy = { |
299 | [IPSET_ATTR_PORT] = { .type = NLA_U16 }, | 346 | [IPSET_ATTR_PORT] = { .type = NLA_U16 }, |
300 | [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 }, | 347 | [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 }, |
301 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, | 348 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, |
302 | [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, | 349 | [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, |
350 | [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, | ||
351 | [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, | ||
303 | }, | 352 | }, |
304 | .me = THIS_MODULE, | 353 | .me = THIS_MODULE, |
305 | }; | 354 | }; |