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