ip_set_bitmap_port.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
  2. *
  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. */
  7. /* Kernel module implementing an IP set type: the bitmap:port type */
  8. #include <linux/module.h>
  9. #include <linux/ip.h>
  10. #include <linux/skbuff.h>
  11. #include <linux/errno.h>
  12. #include <linux/netlink.h>
  13. #include <linux/jiffies.h>
  14. #include <linux/timer.h>
  15. #include <net/netlink.h>
  16. #include <linux/netfilter/ipset/ip_set.h>
  17. #include <linux/netfilter/ipset/ip_set_bitmap.h>
  18. #include <linux/netfilter/ipset/ip_set_getport.h>
  19. #define IPSET_TYPE_REV_MIN 0
  20. /* 1 Counter support added */
  21. /* 2 Comment support added */
  22. #define IPSET_TYPE_REV_MAX 3 /* skbinfo support added */
  23. MODULE_LICENSE("GPL");
  24. MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
  25. IP_SET_MODULE_DESC("bitmap:port", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
  26. MODULE_ALIAS("ip_set_bitmap:port");
  27. #define MTYPE bitmap_port
  28. /* Type structure */
  29. struct bitmap_port {
  30. void *members; /* the set members */
  31. u16 first_port; /* host byte order, included in range */
  32. u16 last_port; /* host byte order, included in range */
  33. u32 elements; /* number of max elements in the set */
  34. size_t memsize; /* members size */
  35. struct timer_list gc; /* garbage collection */
  36. unsigned char extensions[0] /* data extensions */
  37. __aligned(__alignof__(u64));
  38. };
  39. /* ADT structure for generic function args */
  40. struct bitmap_port_adt_elem {
  41. u16 id;
  42. };
  43. static inline u16
  44. port_to_id(const struct bitmap_port *m, u16 port)
  45. {
  46. return port - m->first_port;
  47. }
  48. /* Common functions */
  49. static inline int
  50. bitmap_port_do_test(const struct bitmap_port_adt_elem *e,
  51. const struct bitmap_port *map, size_t dsize)
  52. {
  53. return !!test_bit(e->id, map->members);
  54. }
  55. static inline int
  56. bitmap_port_gc_test(u16 id, const struct bitmap_port *map, size_t dsize)
  57. {
  58. return !!test_bit(id, map->members);
  59. }
  60. static inline int
  61. bitmap_port_do_add(const struct bitmap_port_adt_elem *e,
  62. struct bitmap_port *map, u32 flags, size_t dsize)
  63. {
  64. return !!test_bit(e->id, map->members);
  65. }
  66. static inline int
  67. bitmap_port_do_del(const struct bitmap_port_adt_elem *e,
  68. struct bitmap_port *map)
  69. {
  70. return !test_and_clear_bit(e->id, map->members);
  71. }
  72. static inline int
  73. bitmap_port_do_list(struct sk_buff *skb, const struct bitmap_port *map, u32 id,
  74. size_t dsize)
  75. {
  76. return nla_put_net16(skb, IPSET_ATTR_PORT,
  77. htons(map->first_port + id));
  78. }
  79. static inline int
  80. bitmap_port_do_head(struct sk_buff *skb, const struct bitmap_port *map)
  81. {
  82. return nla_put_net16(skb, IPSET_ATTR_PORT, htons(map->first_port)) ||
  83. nla_put_net16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port));
  84. }
  85. static int
  86. bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb,
  87. const struct xt_action_param *par,
  88. enum ipset_adt adt, struct ip_set_adt_opt *opt)
  89. {
  90. struct bitmap_port *map = set->data;
  91. ipset_adtfn adtfn = set->variant->adt[adt];
  92. struct bitmap_port_adt_elem e = { .id = 0 };
  93. struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
  94. __be16 __port;
  95. u16 port = 0;
  96. if (!ip_set_get_ip_port(skb, opt->family,
  97. opt->flags & IPSET_DIM_ONE_SRC, &__port))
  98. return -EINVAL;
  99. port = ntohs(__port);
  100. if (port < map->first_port || port > map->last_port)
  101. return -IPSET_ERR_BITMAP_RANGE;
  102. e.id = port_to_id(map, port);
  103. return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
  104. }
  105. static int
  106. bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[],
  107. enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
  108. {
  109. struct bitmap_port *map = set->data;
  110. ipset_adtfn adtfn = set->variant->adt[adt];
  111. struct bitmap_port_adt_elem e = { .id = 0 };
  112. struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
  113. u32 port; /* wraparound */
  114. u16 port_to;
  115. int ret = 0;
  116. if (tb[IPSET_ATTR_LINENO])
  117. *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
  118. if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
  119. !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO)))
  120. return -IPSET_ERR_PROTOCOL;
  121. port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
  122. if (port < map->first_port || port > map->last_port)
  123. return -IPSET_ERR_BITMAP_RANGE;
  124. ret = ip_set_get_extensions(set, tb, &ext);
  125. if (ret)
  126. return ret;
  127. if (adt == IPSET_TEST) {
  128. e.id = port_to_id(map, port);
  129. return adtfn(set, &e, &ext, &ext, flags);
  130. }
  131. if (tb[IPSET_ATTR_PORT_TO]) {
  132. port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
  133. if (port > port_to) {
  134. swap(port, port_to);
  135. if (port < map->first_port)
  136. return -IPSET_ERR_BITMAP_RANGE;
  137. }
  138. } else {
  139. port_to = port;
  140. }
  141. if (port_to > map->last_port)
  142. return -IPSET_ERR_BITMAP_RANGE;
  143. for (; port <= port_to; port++) {
  144. e.id = port_to_id(map, port);
  145. ret = adtfn(set, &e, &ext, &ext, flags);
  146. if (ret && !ip_set_eexist(ret, flags))
  147. return ret;
  148. ret = 0;
  149. }
  150. return ret;
  151. }
  152. static bool
  153. bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b)
  154. {
  155. const struct bitmap_port *x = a->data;
  156. const struct bitmap_port *y = b->data;
  157. return x->first_port == y->first_port &&
  158. x->last_port == y->last_port &&
  159. a->timeout == b->timeout &&
  160. a->extensions == b->extensions;
  161. }
  162. /* Plain variant */
  163. struct bitmap_port_elem {
  164. };
  165. #include "ip_set_bitmap_gen.h"
  166. /* Create bitmap:ip type of sets */
  167. static bool
  168. init_map_port(struct ip_set *set, struct bitmap_port *map,
  169. u16 first_port, u16 last_port)
  170. {
  171. map->members = ip_set_alloc(map->memsize);
  172. if (!map->members)
  173. return false;
  174. map->first_port = first_port;
  175. map->last_port = last_port;
  176. set->timeout = IPSET_NO_TIMEOUT;
  177. set->data = map;
  178. set->family = NFPROTO_UNSPEC;
  179. return true;
  180. }
  181. static int
  182. bitmap_port_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
  183. u32 flags)
  184. {
  185. struct bitmap_port *map;
  186. u16 first_port, last_port;
  187. u32 elements;
  188. if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
  189. !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) ||
  190. !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
  191. !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
  192. return -IPSET_ERR_PROTOCOL;
  193. first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
  194. last_port = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
  195. if (first_port > last_port) {
  196. u16 tmp = first_port;
  197. first_port = last_port;
  198. last_port = tmp;
  199. }
  200. elements = last_port - first_port + 1;
  201. set->dsize = ip_set_elem_len(set, tb, 0, 0);
  202. map = ip_set_alloc(sizeof(*map) + elements * set->dsize);
  203. if (!map)
  204. return -ENOMEM;
  205. map->elements = elements;
  206. map->memsize = bitmap_bytes(0, map->elements);
  207. set->variant = &bitmap_port;
  208. if (!init_map_port(set, map, first_port, last_port)) {
  209. kfree(map);
  210. return -ENOMEM;
  211. }
  212. if (tb[IPSET_ATTR_TIMEOUT]) {
  213. set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
  214. bitmap_port_gc_init(set, bitmap_port_gc);
  215. }
  216. return 0;
  217. }
  218. static struct ip_set_type bitmap_port_type = {
  219. .name = "bitmap:port",
  220. .protocol = IPSET_PROTOCOL,
  221. .features = IPSET_TYPE_PORT,
  222. .dimension = IPSET_DIM_ONE,
  223. .family = NFPROTO_UNSPEC,
  224. .revision_min = IPSET_TYPE_REV_MIN,
  225. .revision_max = IPSET_TYPE_REV_MAX,
  226. .create = bitmap_port_create,
  227. .create_policy = {
  228. [IPSET_ATTR_PORT] = { .type = NLA_U16 },
  229. [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 },
  230. [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
  231. [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
  232. },
  233. .adt_policy = {
  234. [IPSET_ATTR_PORT] = { .type = NLA_U16 },
  235. [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 },
  236. [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
  237. [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
  238. [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
  239. [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
  240. [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING,
  241. .len = IPSET_MAX_COMMENT_SIZE },
  242. [IPSET_ATTR_SKBMARK] = { .type = NLA_U64 },
  243. [IPSET_ATTR_SKBPRIO] = { .type = NLA_U32 },
  244. [IPSET_ATTR_SKBQUEUE] = { .type = NLA_U16 },
  245. },
  246. .me = THIS_MODULE,
  247. };
  248. static int __init
  249. bitmap_port_init(void)
  250. {
  251. return ip_set_type_register(&bitmap_port_type);
  252. }
  253. static void __exit
  254. bitmap_port_fini(void)
  255. {
  256. rcu_barrier();
  257. ip_set_type_unregister(&bitmap_port_type);
  258. }
  259. module_init(bitmap_port_init);
  260. module_exit(bitmap_port_fini);