netfilter: ipset: references are protected by rwlock instead of mutex
[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/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, htonl(set->ref - 1));
342         NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
343                       htonl(sizeof(*map) + map->memsize));
344         if (with_timeout(map->timeout))
345                 NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout));
346         ipset_nest_end(skb, nested);
347
348         return 0;
349 nla_put_failure:
350         return -EMSGSIZE;
351 }
352
353 static bool
354 bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
355 {
356         const struct bitmap_ip *x = a->data;
357         const struct bitmap_ip *y = b->data;
358
359         return x->first_ip == y->first_ip &&
360                x->last_ip == y->last_ip &&
361                x->netmask == y->netmask &&
362                x->timeout == y->timeout;
363 }
364
365 static const struct ip_set_type_variant bitmap_ip = {
366         .kadt   = bitmap_ip_kadt,
367         .uadt   = bitmap_ip_uadt,
368         .adt    = {
369                 [IPSET_ADD] = bitmap_ip_add,
370                 [IPSET_DEL] = bitmap_ip_del,
371                 [IPSET_TEST] = bitmap_ip_test,
372         },
373         .destroy = bitmap_ip_destroy,
374         .flush  = bitmap_ip_flush,
375         .head   = bitmap_ip_head,
376         .list   = bitmap_ip_list,
377         .same_set = bitmap_ip_same_set,
378 };
379
380 static const struct ip_set_type_variant bitmap_tip = {
381         .kadt   = bitmap_ip_kadt,
382         .uadt   = bitmap_ip_uadt,
383         .adt    = {
384                 [IPSET_ADD] = bitmap_ip_tadd,
385                 [IPSET_DEL] = bitmap_ip_tdel,
386                 [IPSET_TEST] = bitmap_ip_ttest,
387         },
388         .destroy = bitmap_ip_destroy,
389         .flush  = bitmap_ip_flush,
390         .head   = bitmap_ip_head,
391         .list   = bitmap_ip_tlist,
392         .same_set = bitmap_ip_same_set,
393 };
394
395 static void
396 bitmap_ip_gc(unsigned long ul_set)
397 {
398         struct ip_set *set = (struct ip_set *) ul_set;
399         struct bitmap_ip *map = set->data;
400         unsigned long *table = map->members;
401         u32 id;
402
403         /* We run parallel with other readers (test element)
404          * but adding/deleting new entries is locked out */
405         read_lock_bh(&set->lock);
406         for (id = 0; id < map->elements; id++)
407                 if (ip_set_timeout_expired(table[id]))
408                         table[id] = IPSET_ELEM_UNSET;
409         read_unlock_bh(&set->lock);
410
411         map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
412         add_timer(&map->gc);
413 }
414
415 static void
416 bitmap_ip_gc_init(struct ip_set *set)
417 {
418         struct bitmap_ip *map = set->data;
419
420         init_timer(&map->gc);
421         map->gc.data = (unsigned long) set;
422         map->gc.function = bitmap_ip_gc;
423         map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
424         add_timer(&map->gc);
425 }
426
427 /* Create bitmap:ip type of sets */
428
429 static bool
430 init_map_ip(struct ip_set *set, struct bitmap_ip *map,
431             u32 first_ip, u32 last_ip,
432             u32 elements, u32 hosts, u8 netmask)
433 {
434         map->members = ip_set_alloc(map->memsize);
435         if (!map->members)
436                 return false;
437         map->first_ip = first_ip;
438         map->last_ip = last_ip;
439         map->elements = elements;
440         map->hosts = hosts;
441         map->netmask = netmask;
442         map->timeout = IPSET_NO_TIMEOUT;
443
444         set->data = map;
445         set->family = AF_INET;
446
447         return true;
448 }
449
450 static int
451 bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
452 {
453         struct bitmap_ip *map;
454         u32 first_ip, last_ip, hosts, elements;
455         u8 netmask = 32;
456         int ret;
457
458         if (unlikely(!tb[IPSET_ATTR_IP] ||
459                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
460                 return -IPSET_ERR_PROTOCOL;
461
462         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
463         if (ret)
464                 return ret;
465
466         if (tb[IPSET_ATTR_IP_TO]) {
467                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip);
468                 if (ret)
469                         return ret;
470                 if (first_ip > last_ip) {
471                         u32 tmp = first_ip;
472
473                         first_ip = last_ip;
474                         last_ip = tmp;
475                 }
476         } else if (tb[IPSET_ATTR_CIDR]) {
477                 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
478
479                 if (cidr >= 32)
480                         return -IPSET_ERR_INVALID_CIDR;
481                 last_ip = first_ip | ~ip_set_hostmask(cidr);
482         } else
483                 return -IPSET_ERR_PROTOCOL;
484
485         if (tb[IPSET_ATTR_NETMASK]) {
486                 netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]);
487
488                 if (netmask > 32)
489                         return -IPSET_ERR_INVALID_NETMASK;
490
491                 first_ip &= ip_set_hostmask(netmask);
492                 last_ip |= ~ip_set_hostmask(netmask);
493         }
494
495         if (netmask == 32) {
496                 hosts = 1;
497                 elements = last_ip - first_ip + 1;
498         } else {
499                 u8 mask_bits;
500                 u32 mask;
501
502                 mask = range_to_mask(first_ip, last_ip, &mask_bits);
503
504                 if ((!mask && (first_ip || last_ip != 0xFFFFFFFF)) ||
505                     netmask <= mask_bits)
506                         return -IPSET_ERR_BITMAP_RANGE;
507
508                 pr_debug("mask_bits %u, netmask %u\n", mask_bits, netmask);
509                 hosts = 2 << (32 - netmask - 1);
510                 elements = 2 << (netmask - mask_bits - 1);
511         }
512         if (elements > IPSET_BITMAP_MAX_RANGE + 1)
513                 return -IPSET_ERR_BITMAP_RANGE_SIZE;
514
515         pr_debug("hosts %u, elements %u\n", hosts, elements);
516
517         map = kzalloc(sizeof(*map), GFP_KERNEL);
518         if (!map)
519                 return -ENOMEM;
520
521         if (tb[IPSET_ATTR_TIMEOUT]) {
522                 map->memsize = elements * sizeof(unsigned long);
523
524                 if (!init_map_ip(set, map, first_ip, last_ip,
525                                  elements, hosts, netmask)) {
526                         kfree(map);
527                         return -ENOMEM;
528                 }
529
530                 map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
531                 set->variant = &bitmap_tip;
532
533                 bitmap_ip_gc_init(set);
534         } else {
535                 map->memsize = bitmap_bytes(0, elements - 1);
536
537                 if (!init_map_ip(set, map, first_ip, last_ip,
538                                  elements, hosts, netmask)) {
539                         kfree(map);
540                         return -ENOMEM;
541                 }
542
543                 set->variant = &bitmap_ip;
544         }
545         return 0;
546 }
547
548 static struct ip_set_type bitmap_ip_type __read_mostly = {
549         .name           = "bitmap:ip",
550         .protocol       = IPSET_PROTOCOL,
551         .features       = IPSET_TYPE_IP,
552         .dimension      = IPSET_DIM_ONE,
553         .family         = AF_INET,
554         .revision       = 0,
555         .create         = bitmap_ip_create,
556         .create_policy  = {
557                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
558                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
559                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
560                 [IPSET_ATTR_NETMASK]    = { .type = NLA_U8  },
561                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
562         },
563         .adt_policy     = {
564                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
565                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
566                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
567                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
568                 [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
569         },
570         .me             = THIS_MODULE,
571 };
572
573 static int __init
574 bitmap_ip_init(void)
575 {
576         return ip_set_type_register(&bitmap_ip_type);
577 }
578
579 static void __exit
580 bitmap_ip_fini(void)
581 {
582         ip_set_type_unregister(&bitmap_ip_type);
583 }
584
585 module_init(bitmap_ip_init);
586 module_exit(bitmap_ip_fini);