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