user per registers vs. ptrace single stepping
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / net / netfilter / ipset / ip_set_bitmap_port.c
blob29ba93bb94be14268877354e69c7fe46d57cf7eb
1 /* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation.
6 */
8 /* Kernel module implementing an IP set type: the bitmap:port type */
10 #include <linux/module.h>
11 #include <linux/ip.h>
12 #include <linux/skbuff.h>
13 #include <linux/errno.h>
14 #include <linux/netlink.h>
15 #include <linux/jiffies.h>
16 #include <linux/timer.h>
17 #include <net/netlink.h>
19 #include <linux/netfilter/ipset/ip_set.h>
20 #include <linux/netfilter/ipset/ip_set_bitmap.h>
21 #include <linux/netfilter/ipset/ip_set_getport.h>
22 #define IP_SET_BITMAP_TIMEOUT
23 #include <linux/netfilter/ipset/ip_set_timeout.h>
25 MODULE_LICENSE("GPL");
26 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
27 MODULE_DESCRIPTION("bitmap:port type of IP sets");
28 MODULE_ALIAS("ip_set_bitmap:port");
30 /* Type structure */
31 struct bitmap_port {
32 void *members; /* the set members */
33 u16 first_port; /* host byte order, included in range */
34 u16 last_port; /* host byte order, included in range */
35 size_t memsize; /* members size */
36 u32 timeout; /* timeout parameter */
37 struct timer_list gc; /* garbage collection */
40 /* Base variant */
42 static int
43 bitmap_port_test(struct ip_set *set, void *value, u32 timeout, u32 flags)
45 const struct bitmap_port *map = set->data;
46 u16 id = *(u16 *)value;
48 return !!test_bit(id, map->members);
51 static int
52 bitmap_port_add(struct ip_set *set, void *value, u32 timeout, u32 flags)
54 struct bitmap_port *map = set->data;
55 u16 id = *(u16 *)value;
57 if (test_and_set_bit(id, map->members))
58 return -IPSET_ERR_EXIST;
60 return 0;
63 static int
64 bitmap_port_del(struct ip_set *set, void *value, u32 timeout, u32 flags)
66 struct bitmap_port *map = set->data;
67 u16 id = *(u16 *)value;
69 if (!test_and_clear_bit(id, map->members))
70 return -IPSET_ERR_EXIST;
72 return 0;
75 static int
76 bitmap_port_list(const struct ip_set *set,
77 struct sk_buff *skb, struct netlink_callback *cb)
79 const struct bitmap_port *map = set->data;
80 struct nlattr *atd, *nested;
81 u16 id, first = cb->args[2];
82 u16 last = map->last_port - map->first_port;
84 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
85 if (!atd)
86 return -EMSGSIZE;
87 for (; cb->args[2] <= last; cb->args[2]++) {
88 id = cb->args[2];
89 if (!test_bit(id, map->members))
90 continue;
91 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
92 if (!nested) {
93 if (id == first) {
94 nla_nest_cancel(skb, atd);
95 return -EMSGSIZE;
96 } else
97 goto nla_put_failure;
99 NLA_PUT_NET16(skb, IPSET_ATTR_PORT,
100 htons(map->first_port + id));
101 ipset_nest_end(skb, nested);
103 ipset_nest_end(skb, atd);
104 /* Set listing finished */
105 cb->args[2] = 0;
107 return 0;
109 nla_put_failure:
110 nla_nest_cancel(skb, nested);
111 ipset_nest_end(skb, atd);
112 if (unlikely(id == first)) {
113 cb->args[2] = 0;
114 return -EMSGSIZE;
116 return 0;
119 /* Timeout variant */
121 static int
122 bitmap_port_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags)
124 const struct bitmap_port *map = set->data;
125 const unsigned long *members = map->members;
126 u16 id = *(u16 *)value;
128 return ip_set_timeout_test(members[id]);
131 static int
132 bitmap_port_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags)
134 struct bitmap_port *map = set->data;
135 unsigned long *members = map->members;
136 u16 id = *(u16 *)value;
138 if (ip_set_timeout_test(members[id]) && !(flags & IPSET_FLAG_EXIST))
139 return -IPSET_ERR_EXIST;
141 members[id] = ip_set_timeout_set(timeout);
143 return 0;
146 static int
147 bitmap_port_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags)
149 struct bitmap_port *map = set->data;
150 unsigned long *members = map->members;
151 u16 id = *(u16 *)value;
152 int ret = -IPSET_ERR_EXIST;
154 if (ip_set_timeout_test(members[id]))
155 ret = 0;
157 members[id] = IPSET_ELEM_UNSET;
158 return ret;
161 static int
162 bitmap_port_tlist(const struct ip_set *set,
163 struct sk_buff *skb, struct netlink_callback *cb)
165 const struct bitmap_port *map = set->data;
166 struct nlattr *adt, *nested;
167 u16 id, first = cb->args[2];
168 u16 last = map->last_port - map->first_port;
169 const unsigned long *members = map->members;
171 adt = ipset_nest_start(skb, IPSET_ATTR_ADT);
172 if (!adt)
173 return -EMSGSIZE;
174 for (; cb->args[2] <= last; cb->args[2]++) {
175 id = cb->args[2];
176 if (!ip_set_timeout_test(members[id]))
177 continue;
178 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
179 if (!nested) {
180 if (id == first) {
181 nla_nest_cancel(skb, adt);
182 return -EMSGSIZE;
183 } else
184 goto nla_put_failure;
186 NLA_PUT_NET16(skb, IPSET_ATTR_PORT,
187 htons(map->first_port + id));
188 NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
189 htonl(ip_set_timeout_get(members[id])));
190 ipset_nest_end(skb, nested);
192 ipset_nest_end(skb, adt);
194 /* Set listing finished */
195 cb->args[2] = 0;
197 return 0;
199 nla_put_failure:
200 nla_nest_cancel(skb, nested);
201 ipset_nest_end(skb, adt);
202 if (unlikely(id == first)) {
203 cb->args[2] = 0;
204 return -EMSGSIZE;
206 return 0;
209 static int
210 bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb,
211 const struct xt_action_param *par,
212 enum ipset_adt adt, const struct ip_set_adt_opt *opt)
214 struct bitmap_port *map = set->data;
215 ipset_adtfn adtfn = set->variant->adt[adt];
216 __be16 __port;
217 u16 port = 0;
219 if (!ip_set_get_ip_port(skb, opt->family,
220 opt->flags & IPSET_DIM_ONE_SRC, &__port))
221 return -EINVAL;
223 port = ntohs(__port);
225 if (port < map->first_port || port > map->last_port)
226 return -IPSET_ERR_BITMAP_RANGE;
228 port -= map->first_port;
230 return adtfn(set, &port, opt_timeout(opt, map), opt->cmdflags);
233 static int
234 bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[],
235 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
237 struct bitmap_port *map = set->data;
238 ipset_adtfn adtfn = set->variant->adt[adt];
239 u32 timeout = map->timeout;
240 u32 port; /* wraparound */
241 u16 id, port_to;
242 int ret = 0;
244 if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
245 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
246 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
247 return -IPSET_ERR_PROTOCOL;
249 if (tb[IPSET_ATTR_LINENO])
250 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
252 port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
253 if (port < map->first_port || port > map->last_port)
254 return -IPSET_ERR_BITMAP_RANGE;
256 if (tb[IPSET_ATTR_TIMEOUT]) {
257 if (!with_timeout(map->timeout))
258 return -IPSET_ERR_TIMEOUT;
259 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
262 if (adt == IPSET_TEST) {
263 id = port - map->first_port;
264 return adtfn(set, &id, timeout, flags);
267 if (tb[IPSET_ATTR_PORT_TO]) {
268 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
269 if (port > port_to) {
270 swap(port, port_to);
271 if (port < map->first_port)
272 return -IPSET_ERR_BITMAP_RANGE;
274 } else
275 port_to = port;
277 if (port_to > map->last_port)
278 return -IPSET_ERR_BITMAP_RANGE;
280 for (; port <= port_to; port++) {
281 id = port - map->first_port;
282 ret = adtfn(set, &id, timeout, flags);
284 if (ret && !ip_set_eexist(ret, flags))
285 return ret;
286 else
287 ret = 0;
289 return ret;
292 static void
293 bitmap_port_destroy(struct ip_set *set)
295 struct bitmap_port *map = set->data;
297 if (with_timeout(map->timeout))
298 del_timer_sync(&map->gc);
300 ip_set_free(map->members);
301 kfree(map);
303 set->data = NULL;
306 static void
307 bitmap_port_flush(struct ip_set *set)
309 struct bitmap_port *map = set->data;
311 memset(map->members, 0, map->memsize);
314 static int
315 bitmap_port_head(struct ip_set *set, struct sk_buff *skb)
317 const struct bitmap_port *map = set->data;
318 struct nlattr *nested;
320 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
321 if (!nested)
322 goto nla_put_failure;
323 NLA_PUT_NET16(skb, IPSET_ATTR_PORT, htons(map->first_port));
324 NLA_PUT_NET16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port));
325 NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
326 NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
327 htonl(sizeof(*map) + map->memsize));
328 if (with_timeout(map->timeout))
329 NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout));
330 ipset_nest_end(skb, nested);
332 return 0;
333 nla_put_failure:
334 return -EMSGSIZE;
337 static bool
338 bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b)
340 const struct bitmap_port *x = a->data;
341 const struct bitmap_port *y = b->data;
343 return x->first_port == y->first_port &&
344 x->last_port == y->last_port &&
345 x->timeout == y->timeout;
348 static const struct ip_set_type_variant bitmap_port = {
349 .kadt = bitmap_port_kadt,
350 .uadt = bitmap_port_uadt,
351 .adt = {
352 [IPSET_ADD] = bitmap_port_add,
353 [IPSET_DEL] = bitmap_port_del,
354 [IPSET_TEST] = bitmap_port_test,
356 .destroy = bitmap_port_destroy,
357 .flush = bitmap_port_flush,
358 .head = bitmap_port_head,
359 .list = bitmap_port_list,
360 .same_set = bitmap_port_same_set,
363 static const struct ip_set_type_variant bitmap_tport = {
364 .kadt = bitmap_port_kadt,
365 .uadt = bitmap_port_uadt,
366 .adt = {
367 [IPSET_ADD] = bitmap_port_tadd,
368 [IPSET_DEL] = bitmap_port_tdel,
369 [IPSET_TEST] = bitmap_port_ttest,
371 .destroy = bitmap_port_destroy,
372 .flush = bitmap_port_flush,
373 .head = bitmap_port_head,
374 .list = bitmap_port_tlist,
375 .same_set = bitmap_port_same_set,
378 static void
379 bitmap_port_gc(unsigned long ul_set)
381 struct ip_set *set = (struct ip_set *) ul_set;
382 struct bitmap_port *map = set->data;
383 unsigned long *table = map->members;
384 u32 id; /* wraparound */
385 u16 last = map->last_port - map->first_port;
387 /* We run parallel with other readers (test element)
388 * but adding/deleting new entries is locked out */
389 read_lock_bh(&set->lock);
390 for (id = 0; id <= last; id++)
391 if (ip_set_timeout_expired(table[id]))
392 table[id] = IPSET_ELEM_UNSET;
393 read_unlock_bh(&set->lock);
395 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
396 add_timer(&map->gc);
399 static void
400 bitmap_port_gc_init(struct ip_set *set)
402 struct bitmap_port *map = set->data;
404 init_timer(&map->gc);
405 map->gc.data = (unsigned long) set;
406 map->gc.function = bitmap_port_gc;
407 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
408 add_timer(&map->gc);
411 /* Create bitmap:ip type of sets */
413 static bool
414 init_map_port(struct ip_set *set, struct bitmap_port *map,
415 u16 first_port, u16 last_port)
417 map->members = ip_set_alloc(map->memsize);
418 if (!map->members)
419 return false;
420 map->first_port = first_port;
421 map->last_port = last_port;
422 map->timeout = IPSET_NO_TIMEOUT;
424 set->data = map;
425 set->family = AF_UNSPEC;
427 return true;
430 static int
431 bitmap_port_create(struct ip_set *set, struct nlattr *tb[],
432 u32 flags)
434 struct bitmap_port *map;
435 u16 first_port, last_port;
437 if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
438 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) ||
439 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
440 return -IPSET_ERR_PROTOCOL;
442 first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
443 last_port = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
444 if (first_port > last_port) {
445 u16 tmp = first_port;
447 first_port = last_port;
448 last_port = tmp;
451 map = kzalloc(sizeof(*map), GFP_KERNEL);
452 if (!map)
453 return -ENOMEM;
455 if (tb[IPSET_ATTR_TIMEOUT]) {
456 map->memsize = (last_port - first_port + 1)
457 * sizeof(unsigned long);
459 if (!init_map_port(set, map, first_port, last_port)) {
460 kfree(map);
461 return -ENOMEM;
464 map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
465 set->variant = &bitmap_tport;
467 bitmap_port_gc_init(set);
468 } else {
469 map->memsize = bitmap_bytes(0, last_port - first_port);
470 pr_debug("memsize: %zu\n", map->memsize);
471 if (!init_map_port(set, map, first_port, last_port)) {
472 kfree(map);
473 return -ENOMEM;
476 set->variant = &bitmap_port;
478 return 0;
481 static struct ip_set_type bitmap_port_type = {
482 .name = "bitmap:port",
483 .protocol = IPSET_PROTOCOL,
484 .features = IPSET_TYPE_PORT,
485 .dimension = IPSET_DIM_ONE,
486 .family = AF_UNSPEC,
487 .revision_min = 0,
488 .revision_max = 0,
489 .create = bitmap_port_create,
490 .create_policy = {
491 [IPSET_ATTR_PORT] = { .type = NLA_U16 },
492 [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 },
493 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
495 .adt_policy = {
496 [IPSET_ATTR_PORT] = { .type = NLA_U16 },
497 [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 },
498 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
499 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
501 .me = THIS_MODULE,
504 static int __init
505 bitmap_port_init(void)
507 return ip_set_type_register(&bitmap_port_type);
510 static void __exit
511 bitmap_port_fini(void)
513 ip_set_type_unregister(&bitmap_port_type);
516 module_init(bitmap_port_init);
517 module_exit(bitmap_port_fini);