netfilter: ipset: bitmap:ip set type support
[linux-2.6.git] / net / netfilter / ipset / ip_set_bitmap_ip.c
1 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2  *                         Patrick Schaaf <bof@bof.de>
3  * Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  */
9
10 /* Kernel module implementing an IP set type: the bitmap:ip type */
11
12 #include <linux/module.h>
13 #include <linux/ip.h>
14 #include <linux/skbuff.h>
15 #include <linux/errno.h>
16 #include <linux/uaccess.h>
17 #include <linux/bitops.h>
18 #include <linux/spinlock.h>
19 #include <linux/netlink.h>
20 #include <linux/jiffies.h>
21 #include <linux/timer.h>
22 #include <net/netlink.h>
23 #include <net/tcp.h>
24
25 #include <linux/netfilter/ipset/pfxlen.h>
26 #include <linux/netfilter/ipset/ip_set.h>
27 #include <linux/netfilter/ipset/ip_set_bitmap.h>
28 #define IP_SET_BITMAP_TIMEOUT
29 #include <linux/netfilter/ipset/ip_set_timeout.h>
30
31 MODULE_LICENSE("GPL");
32 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
33 MODULE_DESCRIPTION("bitmap:ip type of IP sets");
34 MODULE_ALIAS("ip_set_bitmap:ip");
35
36 /* Type structure */
37 struct bitmap_ip {
38         void *members;          /* the set members */
39         u32 first_ip;           /* host byte order, included in range */
40         u32 last_ip;            /* host byte order, included in range */
41         u32 elements;           /* number of max elements in the set */
42         u32 hosts;              /* number of hosts in a subnet */
43         size_t memsize;         /* members size */
44         u8 netmask;             /* subnet netmask */
45         u32 timeout;            /* timeout parameter */
46         struct timer_list gc;   /* garbage collection */
47 };
48
49 /* Base variant */
50
51 static inline u32
52 ip_to_id(const struct bitmap_ip *m, u32 ip)
53 {
54         return ((ip & ip_set_hostmask(m->netmask)) - m->first_ip)/m->hosts;
55 }
56
57 static int
58 bitmap_ip_test(struct ip_set *set, void *value, u32 timeout)
59 {
60         const struct bitmap_ip *map = set->data;
61         u16 id = *(u16 *)value;
62
63         return !!test_bit(id, map->members);
64 }
65
66 static int
67 bitmap_ip_add(struct ip_set *set, void *value, u32 timeout)
68 {
69         struct bitmap_ip *map = set->data;
70         u16 id = *(u16 *)value;
71
72         if (test_and_set_bit(id, map->members))
73                 return -IPSET_ERR_EXIST;
74
75         return 0;
76 }
77
78 static int
79 bitmap_ip_del(struct ip_set *set, void *value, u32 timeout)
80 {
81         struct bitmap_ip *map = set->data;
82         u16 id = *(u16 *)value;
83
84         if (!test_and_clear_bit(id, map->members))
85                 return -IPSET_ERR_EXIST;
86
87         return 0;
88 }
89
90 static int
91 bitmap_ip_list(const struct ip_set *set,
92                struct sk_buff *skb, struct netlink_callback *cb)
93 {
94         const struct bitmap_ip *map = set->data;
95         struct nlattr *atd, *nested;
96         u32 id, first = cb->args[2];
97
98         atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
99         if (!atd)
100                 return -EMSGSIZE;
101         for (; cb->args[2] < map->elements; cb->args[2]++) {
102                 id = cb->args[2];
103                 if (!test_bit(id, map->members))
104                         continue;
105                 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
106                 if (!nested) {
107                         if (id == first) {
108                                 nla_nest_cancel(skb, atd);
109                                 return -EMSGSIZE;
110                         } else
111                                 goto nla_put_failure;
112                 }
113                 NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP,
114                                 htonl(map->first_ip + id * map->hosts));
115                 ipset_nest_end(skb, nested);
116         }
117         ipset_nest_end(skb, atd);
118         /* Set listing finished */
119         cb->args[2] = 0;
120         return 0;
121
122 nla_put_failure:
123         nla_nest_cancel(skb, nested);
124         ipset_nest_end(skb, atd);
125         if (unlikely(id == first)) {
126                 cb->args[2] = 0;
127                 return -EMSGSIZE;
128         }
129         return 0;
130 }
131
132 /* Timeout variant */
133
134 static int
135 bitmap_ip_ttest(struct ip_set *set, void *value, u32 timeout)
136 {
137         const struct bitmap_ip *map = set->data;
138         const unsigned long *members = map->members;
139         u16 id = *(u16 *)value;
140
141         return ip_set_timeout_test(members[id]);
142 }
143
144 static int
145 bitmap_ip_tadd(struct ip_set *set, void *value, u32 timeout)
146 {
147         struct bitmap_ip *map = set->data;
148         unsigned long *members = map->members;
149         u16 id = *(u16 *)value;
150
151         if (ip_set_timeout_test(members[id]))
152                 return -IPSET_ERR_EXIST;
153
154         members[id] = ip_set_timeout_set(timeout);
155
156         return 0;
157 }
158
159 static int
160 bitmap_ip_tdel(struct ip_set *set, void *value, u32 timeout)
161 {
162         struct bitmap_ip *map = set->data;
163         unsigned long *members = map->members;
164         u16 id = *(u16 *)value;
165         int ret = -IPSET_ERR_EXIST;
166
167         if (ip_set_timeout_test(members[id]))
168                 ret = 0;
169
170         members[id] = IPSET_ELEM_UNSET;
171         return ret;
172 }
173
174 static int
175 bitmap_ip_tlist(const struct ip_set *set,
176                 struct sk_buff *skb, struct netlink_callback *cb)
177 {
178         const struct bitmap_ip *map = set->data;
179         struct nlattr *adt, *nested;
180         u32 id, first = cb->args[2];
181         const unsigned long *members = map->members;
182
183         adt = ipset_nest_start(skb, IPSET_ATTR_ADT);
184         if (!adt)
185                 return -EMSGSIZE;
186         for (; cb->args[2] < map->elements; cb->args[2]++) {
187                 id = cb->args[2];
188                 if (!ip_set_timeout_test(members[id]))
189                         continue;
190                 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
191                 if (!nested) {
192                         if (id == first) {
193                                 nla_nest_cancel(skb, adt);
194                                 return -EMSGSIZE;
195                         } else
196                                 goto nla_put_failure;
197                 }
198                 NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP,
199                                 htonl(map->first_ip + id * map->hosts));
200                 NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
201                               htonl(ip_set_timeout_get(members[id])));
202                 ipset_nest_end(skb, nested);
203         }
204         ipset_nest_end(skb, adt);
205
206         /* Set listing finished */
207         cb->args[2] = 0;
208
209         return 0;
210
211 nla_put_failure:
212         nla_nest_cancel(skb, nested);
213         ipset_nest_end(skb, adt);
214         if (unlikely(id == first)) {
215                 cb->args[2] = 0;
216                 return -EMSGSIZE;
217         }
218         return 0;
219 }
220
221 static int
222 bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
223                enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
224 {
225         struct bitmap_ip *map = set->data;
226         ipset_adtfn adtfn = set->variant->adt[adt];
227         u32 ip;
228
229         ip = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC));
230         if (ip < map->first_ip || ip > map->last_ip)
231                 return -IPSET_ERR_BITMAP_RANGE;
232
233         ip = ip_to_id(map, ip);
234
235         return adtfn(set, &ip, map->timeout);
236 }
237
238 static int
239 bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
240                enum ipset_adt adt, u32 *lineno, u32 flags)
241 {
242         struct bitmap_ip *map = set->data;
243         ipset_adtfn adtfn = set->variant->adt[adt];
244         u32 timeout = map->timeout;
245         u32 ip, ip_to, id;
246         int ret = 0;
247
248         if (unlikely(!tb[IPSET_ATTR_IP] ||
249                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
250                 return -IPSET_ERR_PROTOCOL;
251
252         if (tb[IPSET_ATTR_LINENO])
253                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
254
255         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
256         if (ret)
257                 return ret;
258
259         if (ip < map->first_ip || ip > map->last_ip)
260                 return -IPSET_ERR_BITMAP_RANGE;
261
262         if (tb[IPSET_ATTR_TIMEOUT]) {
263                 if (!with_timeout(map->timeout))
264                         return -IPSET_ERR_TIMEOUT;
265                 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
266         }
267
268         if (adt == IPSET_TEST) {
269                 id = ip_to_id(map, ip);
270                 return adtfn(set, &id, timeout);
271         }
272
273         if (tb[IPSET_ATTR_IP_TO]) {
274                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
275                 if (ret)
276                         return ret;
277                 if (ip > ip_to) {
278                         swap(ip, ip_to);
279                         if (ip < map->first_ip)
280                                 return -IPSET_ERR_BITMAP_RANGE;
281                 }
282         } else if (tb[IPSET_ATTR_CIDR]) {
283                 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
284
285                 if (cidr > 32)
286                         return -IPSET_ERR_INVALID_CIDR;
287                 ip &= ip_set_hostmask(cidr);
288                 ip_to = ip | ~ip_set_hostmask(cidr);
289         } else
290                 ip_to = ip;
291
292         if (ip_to > map->last_ip)
293                 return -IPSET_ERR_BITMAP_RANGE;
294
295         for (; !before(ip_to, ip); ip += map->hosts) {
296                 id = ip_to_id(map, ip);
297                 ret = adtfn(set, &id, timeout);;
298
299                 if (ret && !ip_set_eexist(ret, flags))
300                         return ret;
301                 else
302                         ret = 0;
303         }
304         return ret;
305 }
306
307 static void
308 bitmap_ip_destroy(struct ip_set *set)
309 {
310         struct bitmap_ip *map = set->data;
311
312         if (with_timeout(map->timeout))
313                 del_timer_sync(&map->gc);
314
315         ip_set_free(map->members);
316         kfree(map);
317
318         set->data = NULL;
319 }
320
321 static void
322 bitmap_ip_flush(struct ip_set *set)
323 {
324         struct bitmap_ip *map = set->data;
325
326         memset(map->members, 0, map->memsize);
327 }
328
329 static int
330 bitmap_ip_head(struct ip_set *set, struct sk_buff *skb)
331 {
332         const struct bitmap_ip *map = set->data;
333         struct nlattr *nested;
334
335         nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
336         if (!nested)
337                 goto nla_put_failure;
338         NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, htonl(map->first_ip));
339         NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip));
340         if (map->netmask != 32)
341                 NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, map->netmask);
342         NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES,
343                       htonl(atomic_read(&set->ref) - 1));
344         NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
345                       htonl(sizeof(*map) + map->memsize));
346         if (with_timeout(map->timeout))
347                 NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout));
348         ipset_nest_end(skb, nested);
349
350         return 0;
351 nla_put_failure:
352         return -EMSGSIZE;
353 }
354
355 static bool
356 bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
357 {
358         const struct bitmap_ip *x = a->data;
359         const struct bitmap_ip *y = b->data;
360
361         return x->first_ip == y->first_ip &&
362                x->last_ip == y->last_ip &&
363                x->netmask == y->netmask &&
364                x->timeout == y->timeout;
365 }
366
367 static const struct ip_set_type_variant bitmap_ip = {
368         .kadt   = bitmap_ip_kadt,
369         .uadt   = bitmap_ip_uadt,
370         .adt    = {
371                 [IPSET_ADD] = bitmap_ip_add,
372                 [IPSET_DEL] = bitmap_ip_del,
373                 [IPSET_TEST] = bitmap_ip_test,
374         },
375         .destroy = bitmap_ip_destroy,
376         .flush  = bitmap_ip_flush,
377         .head   = bitmap_ip_head,
378         .list   = bitmap_ip_list,
379         .same_set = bitmap_ip_same_set,
380 };
381
382 static const struct ip_set_type_variant bitmap_tip = {
383         .kadt   = bitmap_ip_kadt,
384         .uadt   = bitmap_ip_uadt,
385         .adt    = {
386                 [IPSET_ADD] = bitmap_ip_tadd,
387                 [IPSET_DEL] = bitmap_ip_tdel,
388                 [IPSET_TEST] = bitmap_ip_ttest,
389         },
390         .destroy = bitmap_ip_destroy,
391         .flush  = bitmap_ip_flush,
392         .head   = bitmap_ip_head,
393         .list   = bitmap_ip_tlist,
394         .same_set = bitmap_ip_same_set,
395 };
396
397 static void
398 bitmap_ip_gc(unsigned long ul_set)
399 {
400         struct ip_set *set = (struct ip_set *) ul_set;
401         struct bitmap_ip *map = set->data;
402         unsigned long *table = map->members;
403         u32 id;
404
405         /* We run parallel with other readers (test element)
406          * but adding/deleting new entries is locked out */
407         read_lock_bh(&set->lock);
408         for (id = 0; id < map->elements; id++)
409                 if (ip_set_timeout_expired(table[id]))
410                         table[id] = IPSET_ELEM_UNSET;
411         read_unlock_bh(&set->lock);
412
413         map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
414         add_timer(&map->gc);
415 }
416
417 static void
418 bitmap_ip_gc_init(struct ip_set *set)
419 {
420         struct bitmap_ip *map = set->data;
421
422         init_timer(&map->gc);
423         map->gc.data = (unsigned long) set;
424         map->gc.function = bitmap_ip_gc;
425         map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
426         add_timer(&map->gc);
427 }
428
429 /* Create bitmap:ip type of sets */
430
431 static bool
432 init_map_ip(struct ip_set *set, struct bitmap_ip *map,
433             u32 first_ip, u32 last_ip,
434             u32 elements, u32 hosts, u8 netmask)
435 {
436         map->members = ip_set_alloc(map->memsize);
437         if (!map->members)
438                 return false;
439         map->first_ip = first_ip;
440         map->last_ip = last_ip;
441         map->elements = elements;
442         map->hosts = hosts;
443         map->netmask = netmask;
444         map->timeout = IPSET_NO_TIMEOUT;
445
446         set->data = map;
447         set->family = AF_INET;
448
449         return true;
450 }
451
452 static int
453 bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
454 {
455         struct bitmap_ip *map;
456         u32 first_ip, last_ip, hosts, elements;
457         u8 netmask = 32;
458         int ret;
459
460         if (unlikely(!tb[IPSET_ATTR_IP] ||
461                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
462                 return -IPSET_ERR_PROTOCOL;
463
464         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
465         if (ret)
466                 return ret;
467
468         if (tb[IPSET_ATTR_IP_TO]) {
469                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip);
470                 if (ret)
471                         return ret;
472                 if (first_ip > last_ip) {
473                         u32 tmp = first_ip;
474
475                         first_ip = last_ip;
476                         last_ip = tmp;
477                 }
478         } else if (tb[IPSET_ATTR_CIDR]) {
479                 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
480
481                 if (cidr >= 32)
482                         return -IPSET_ERR_INVALID_CIDR;
483                 last_ip = first_ip | ~ip_set_hostmask(cidr);
484         } else
485                 return -IPSET_ERR_PROTOCOL;
486
487         if (tb[IPSET_ATTR_NETMASK]) {
488                 netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]);
489
490                 if (netmask > 32)
491                         return -IPSET_ERR_INVALID_NETMASK;
492
493                 first_ip &= ip_set_hostmask(netmask);
494                 last_ip |= ~ip_set_hostmask(netmask);
495         }
496
497         if (netmask == 32) {
498                 hosts = 1;
499                 elements = last_ip - first_ip + 1;
500         } else {
501                 u8 mask_bits;
502                 u32 mask;
503
504                 mask = range_to_mask(first_ip, last_ip, &mask_bits);
505
506                 if ((!mask && (first_ip || last_ip != 0xFFFFFFFF)) ||
507                     netmask <= mask_bits)
508                         return -IPSET_ERR_BITMAP_RANGE;
509
510                 pr_debug("mask_bits %u, netmask %u\n", mask_bits, netmask);
511                 hosts = 2 << (32 - netmask - 1);
512                 elements = 2 << (netmask - mask_bits - 1);
513         }
514         if (elements > IPSET_BITMAP_MAX_RANGE + 1)
515                 return -IPSET_ERR_BITMAP_RANGE_SIZE;
516
517         pr_debug("hosts %u, elements %u\n", hosts, elements);
518
519         map = kzalloc(sizeof(*map), GFP_KERNEL);
520         if (!map)
521                 return -ENOMEM;
522
523         if (tb[IPSET_ATTR_TIMEOUT]) {
524                 map->memsize = elements * sizeof(unsigned long);
525
526                 if (!init_map_ip(set, map, first_ip, last_ip,
527                                  elements, hosts, netmask)) {
528                         kfree(map);
529                         return -ENOMEM;
530                 }
531
532                 map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
533                 set->variant = &bitmap_tip;
534
535                 bitmap_ip_gc_init(set);
536         } else {
537                 map->memsize = bitmap_bytes(0, elements - 1);
538
539                 if (!init_map_ip(set, map, first_ip, last_ip,
540                                  elements, hosts, netmask)) {
541                         kfree(map);
542                         return -ENOMEM;
543                 }
544
545                 set->variant = &bitmap_ip;
546         }
547         return 0;
548 }
549
550 static struct ip_set_type bitmap_ip_type __read_mostly = {
551         .name           = "bitmap:ip",
552         .protocol       = IPSET_PROTOCOL,
553         .features       = IPSET_TYPE_IP,
554         .dimension      = IPSET_DIM_ONE,
555         .family         = AF_INET,
556         .revision       = 0,
557         .create         = bitmap_ip_create,
558         .create_policy  = {
559                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
560                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
561                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
562                 [IPSET_ATTR_NETMASK]    = { .type = NLA_U8  },
563                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
564         },
565         .adt_policy     = {
566                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
567                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
568                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
569                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
570                 [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
571         },
572         .me             = THIS_MODULE,
573 };
574
575 static int __init
576 bitmap_ip_init(void)
577 {
578         return ip_set_type_register(&bitmap_ip_type);
579 }
580
581 static void __exit
582 bitmap_ip_fini(void)
583 {
584         ip_set_type_unregister(&bitmap_ip_type);
585 }
586
587 module_init(bitmap_ip_init);
588 module_exit(bitmap_ip_fini);