netfilter: ipset: remove unnecessary includes
[linux-flexiantxendom0-3.2.10.git] / net / netfilter / ipset / ip_set_hash_netport.c
1 /* Copyright (C) 2003-2011 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
8 /* Kernel module implementing an IP set type: the hash:net,port type */
9
10 #include <linux/jhash.h>
11 #include <linux/module.h>
12 #include <linux/ip.h>
13 #include <linux/skbuff.h>
14 #include <linux/errno.h>
15 #include <linux/random.h>
16 #include <net/ip.h>
17 #include <net/ipv6.h>
18 #include <net/netlink.h>
19
20 #include <linux/netfilter.h>
21 #include <linux/netfilter/ipset/pfxlen.h>
22 #include <linux/netfilter/ipset/ip_set.h>
23 #include <linux/netfilter/ipset/ip_set_timeout.h>
24 #include <linux/netfilter/ipset/ip_set_getport.h>
25 #include <linux/netfilter/ipset/ip_set_hash.h>
26
27 MODULE_LICENSE("GPL");
28 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
29 MODULE_DESCRIPTION("hash:net,port type of IP sets");
30 MODULE_ALIAS("ip_set_hash:net,port");
31
32 /* Type specific function prefix */
33 #define TYPE            hash_netport
34
35 static bool
36 hash_netport_same_set(const struct ip_set *a, const struct ip_set *b);
37
38 #define hash_netport4_same_set  hash_netport_same_set
39 #define hash_netport6_same_set  hash_netport_same_set
40
41 /* The type variant functions: IPv4 */
42
43 /* Member elements without timeout */
44 struct hash_netport4_elem {
45         __be32 ip;
46         __be16 port;
47         u8 proto;
48         u8 cidr;
49 };
50
51 /* Member elements with timeout support */
52 struct hash_netport4_telem {
53         __be32 ip;
54         __be16 port;
55         u8 proto;
56         u8 cidr;
57         unsigned long timeout;
58 };
59
60 static inline bool
61 hash_netport4_data_equal(const struct hash_netport4_elem *ip1,
62                          const struct hash_netport4_elem *ip2)
63 {
64         return ip1->ip == ip2->ip &&
65                ip1->port == ip2->port &&
66                ip1->proto == ip2->proto &&
67                ip1->cidr == ip2->cidr;
68 }
69
70 static inline bool
71 hash_netport4_data_isnull(const struct hash_netport4_elem *elem)
72 {
73         return elem->proto == 0;
74 }
75
76 static inline void
77 hash_netport4_data_copy(struct hash_netport4_elem *dst,
78                         const struct hash_netport4_elem *src)
79 {
80         dst->ip = src->ip;
81         dst->port = src->port;
82         dst->proto = src->proto;
83         dst->cidr = src->cidr;
84 }
85
86 static inline void
87 hash_netport4_data_netmask(struct hash_netport4_elem *elem, u8 cidr)
88 {
89         elem->ip &= ip_set_netmask(cidr);
90         elem->cidr = cidr;
91 }
92
93 static inline void
94 hash_netport4_data_zero_out(struct hash_netport4_elem *elem)
95 {
96         elem->proto = 0;
97 }
98
99 static bool
100 hash_netport4_data_list(struct sk_buff *skb,
101                         const struct hash_netport4_elem *data)
102 {
103         NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip);
104         NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
105         NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
106         NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
107         return 0;
108
109 nla_put_failure:
110         return 1;
111 }
112
113 static bool
114 hash_netport4_data_tlist(struct sk_buff *skb,
115                          const struct hash_netport4_elem *data)
116 {
117         const struct hash_netport4_telem *tdata =
118                 (const struct hash_netport4_telem *)data;
119
120         NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip);
121         NLA_PUT_NET16(skb, IPSET_ATTR_PORT, tdata->port);
122         NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
123         NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
124         NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
125                       htonl(ip_set_timeout_get(tdata->timeout)));
126
127         return 0;
128
129 nla_put_failure:
130         return 1;
131 }
132
133 #define IP_SET_HASH_WITH_PROTO
134 #define IP_SET_HASH_WITH_NETS
135
136 #define PF              4
137 #define HOST_MASK       32
138 #include <linux/netfilter/ipset/ip_set_ahash.h>
139
140 static int
141 hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb,
142                    enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
143 {
144         const struct ip_set_hash *h = set->data;
145         ipset_adtfn adtfn = set->variant->adt[adt];
146         struct hash_netport4_elem data = {
147                 .cidr = h->nets[0].cidr || HOST_MASK };
148
149         if (data.cidr == 0)
150                 return -EINVAL;
151         if (adt == IPSET_TEST)
152                 data.cidr = HOST_MASK;
153
154         if (!ip_set_get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
155                                  &data.port, &data.proto))
156                 return -EINVAL;
157
158         ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip);
159         data.ip &= ip_set_netmask(data.cidr);
160
161         return adtfn(set, &data, h->timeout);
162 }
163
164 static int
165 hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
166                    enum ipset_adt adt, u32 *lineno, u32 flags)
167 {
168         const struct ip_set_hash *h = set->data;
169         ipset_adtfn adtfn = set->variant->adt[adt];
170         struct hash_netport4_elem data = { .cidr = HOST_MASK };
171         u32 port, port_to;
172         u32 timeout = h->timeout;
173         int ret;
174
175         if (unlikely(!tb[IPSET_ATTR_IP] ||
176                      !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
177                      !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
178                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
179                 return -IPSET_ERR_PROTOCOL;
180
181         if (tb[IPSET_ATTR_LINENO])
182                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
183
184         ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip);
185         if (ret)
186                 return ret;
187
188         if (tb[IPSET_ATTR_CIDR])
189                 data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
190         if (!data.cidr)
191                 return -IPSET_ERR_INVALID_CIDR;
192         data.ip &= ip_set_netmask(data.cidr);
193
194         if (tb[IPSET_ATTR_PORT])
195                 data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
196         else
197                 return -IPSET_ERR_PROTOCOL;
198
199         if (tb[IPSET_ATTR_PROTO]) {
200                 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
201
202                 if (data.proto == 0)
203                         return -IPSET_ERR_INVALID_PROTO;
204         } else
205                 return -IPSET_ERR_MISSING_PROTO;
206
207         switch (data.proto) {
208         case IPPROTO_UDP:
209         case IPPROTO_TCP:
210         case IPPROTO_ICMP:
211                 break;
212         default:
213                 data.port = 0;
214                 break;
215         }
216
217         if (tb[IPSET_ATTR_TIMEOUT]) {
218                 if (!with_timeout(h->timeout))
219                         return -IPSET_ERR_TIMEOUT;
220                 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
221         }
222
223         if (adt == IPSET_TEST ||
224             !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
225             !tb[IPSET_ATTR_PORT_TO]) {
226                 ret = adtfn(set, &data, timeout);
227                 return ip_set_eexist(ret, flags) ? 0 : ret;
228         }
229
230         port = ntohs(data.port);
231         port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
232         if (port > port_to)
233                 swap(port, port_to);
234
235         for (; port <= port_to; port++) {
236                 data.port = htons(port);
237                 ret = adtfn(set, &data, timeout);
238
239                 if (ret && !ip_set_eexist(ret, flags))
240                         return ret;
241                 else
242                         ret = 0;
243         }
244         return ret;
245 }
246
247 static bool
248 hash_netport_same_set(const struct ip_set *a, const struct ip_set *b)
249 {
250         const struct ip_set_hash *x = a->data;
251         const struct ip_set_hash *y = b->data;
252
253         /* Resizing changes htable_bits, so we ignore it */
254         return x->maxelem == y->maxelem &&
255                x->timeout == y->timeout;
256 }
257
258 /* The type variant functions: IPv6 */
259
260 struct hash_netport6_elem {
261         union nf_inet_addr ip;
262         __be16 port;
263         u8 proto;
264         u8 cidr;
265 };
266
267 struct hash_netport6_telem {
268         union nf_inet_addr ip;
269         __be16 port;
270         u8 proto;
271         u8 cidr;
272         unsigned long timeout;
273 };
274
275 static inline bool
276 hash_netport6_data_equal(const struct hash_netport6_elem *ip1,
277                          const struct hash_netport6_elem *ip2)
278 {
279         return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
280                ip1->port == ip2->port &&
281                ip1->proto == ip2->proto &&
282                ip1->cidr == ip2->cidr;
283 }
284
285 static inline bool
286 hash_netport6_data_isnull(const struct hash_netport6_elem *elem)
287 {
288         return elem->proto == 0;
289 }
290
291 static inline void
292 hash_netport6_data_copy(struct hash_netport6_elem *dst,
293                         const struct hash_netport6_elem *src)
294 {
295         memcpy(dst, src, sizeof(*dst));
296 }
297
298 static inline void
299 hash_netport6_data_zero_out(struct hash_netport6_elem *elem)
300 {
301         elem->proto = 0;
302 }
303
304 static inline void
305 ip6_netmask(union nf_inet_addr *ip, u8 prefix)
306 {
307         ip->ip6[0] &= ip_set_netmask6(prefix)[0];
308         ip->ip6[1] &= ip_set_netmask6(prefix)[1];
309         ip->ip6[2] &= ip_set_netmask6(prefix)[2];
310         ip->ip6[3] &= ip_set_netmask6(prefix)[3];
311 }
312
313 static inline void
314 hash_netport6_data_netmask(struct hash_netport6_elem *elem, u8 cidr)
315 {
316         ip6_netmask(&elem->ip, cidr);
317         elem->cidr = cidr;
318 }
319
320 static bool
321 hash_netport6_data_list(struct sk_buff *skb,
322                         const struct hash_netport6_elem *data)
323 {
324         NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip);
325         NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
326         NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
327         NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
328         return 0;
329
330 nla_put_failure:
331         return 1;
332 }
333
334 static bool
335 hash_netport6_data_tlist(struct sk_buff *skb,
336                          const struct hash_netport6_elem *data)
337 {
338         const struct hash_netport6_telem *e =
339                 (const struct hash_netport6_telem *)data;
340
341         NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip);
342         NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
343         NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
344         NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
345         NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
346                       htonl(ip_set_timeout_get(e->timeout)));
347         return 0;
348
349 nla_put_failure:
350         return 1;
351 }
352
353 #undef PF
354 #undef HOST_MASK
355
356 #define PF              6
357 #define HOST_MASK       128
358 #include <linux/netfilter/ipset/ip_set_ahash.h>
359
360 static int
361 hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb,
362                    enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
363 {
364         const struct ip_set_hash *h = set->data;
365         ipset_adtfn adtfn = set->variant->adt[adt];
366         struct hash_netport6_elem data = {
367                 .cidr = h->nets[0].cidr || HOST_MASK };
368
369         if (data.cidr == 0)
370                 return -EINVAL;
371         if (adt == IPSET_TEST)
372                 data.cidr = HOST_MASK;
373
374         if (!ip_set_get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
375                                  &data.port, &data.proto))
376                 return -EINVAL;
377
378         ip6addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
379         ip6_netmask(&data.ip, data.cidr);
380
381         return adtfn(set, &data, h->timeout);
382 }
383
384 static int
385 hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
386                    enum ipset_adt adt, u32 *lineno, u32 flags)
387 {
388         const struct ip_set_hash *h = set->data;
389         ipset_adtfn adtfn = set->variant->adt[adt];
390         struct hash_netport6_elem data = { .cidr = HOST_MASK };
391         u32 port, port_to;
392         u32 timeout = h->timeout;
393         int ret;
394
395         if (unlikely(!tb[IPSET_ATTR_IP] ||
396                      !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
397                      !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
398                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
399                 return -IPSET_ERR_PROTOCOL;
400
401         if (tb[IPSET_ATTR_LINENO])
402                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
403
404         ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
405         if (ret)
406                 return ret;
407
408         if (tb[IPSET_ATTR_CIDR])
409                 data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
410         if (!data.cidr)
411                 return -IPSET_ERR_INVALID_CIDR;
412         ip6_netmask(&data.ip, data.cidr);
413
414         if (tb[IPSET_ATTR_PORT])
415                 data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
416         else
417                 return -IPSET_ERR_PROTOCOL;
418
419         if (tb[IPSET_ATTR_PROTO]) {
420                 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
421
422                 if (data.proto == 0)
423                         return -IPSET_ERR_INVALID_PROTO;
424         } else
425                 return -IPSET_ERR_MISSING_PROTO;
426
427         switch (data.proto) {
428         case IPPROTO_UDP:
429         case IPPROTO_TCP:
430         case IPPROTO_ICMPV6:
431                 break;
432         default:
433                 data.port = 0;
434                 break;
435         }
436
437         if (tb[IPSET_ATTR_TIMEOUT]) {
438                 if (!with_timeout(h->timeout))
439                         return -IPSET_ERR_TIMEOUT;
440                 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
441         }
442
443         if (adt == IPSET_TEST ||
444             !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
445             !tb[IPSET_ATTR_PORT_TO]) {
446                 ret = adtfn(set, &data, timeout);
447                 return ip_set_eexist(ret, flags) ? 0 : ret;
448         }
449
450         port = ntohs(data.port);
451         port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
452         if (port > port_to)
453                 swap(port, port_to);
454
455         for (; port <= port_to; port++) {
456                 data.port = htons(port);
457                 ret = adtfn(set, &data, timeout);
458
459                 if (ret && !ip_set_eexist(ret, flags))
460                         return ret;
461                 else
462                         ret = 0;
463         }
464         return ret;
465 }
466
467 /* Create hash:ip type of sets */
468
469 static int
470 hash_netport_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
471 {
472         struct ip_set_hash *h;
473         u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
474         u8 hbits;
475
476         if (!(set->family == AF_INET || set->family == AF_INET6))
477                 return -IPSET_ERR_INVALID_FAMILY;
478
479         if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
480                      !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
481                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
482                 return -IPSET_ERR_PROTOCOL;
483
484         if (tb[IPSET_ATTR_HASHSIZE]) {
485                 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
486                 if (hashsize < IPSET_MIMINAL_HASHSIZE)
487                         hashsize = IPSET_MIMINAL_HASHSIZE;
488         }
489
490         if (tb[IPSET_ATTR_MAXELEM])
491                 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
492
493         h = kzalloc(sizeof(*h)
494                     + sizeof(struct ip_set_hash_nets)
495                       * (set->family == AF_INET ? 32 : 128), GFP_KERNEL);
496         if (!h)
497                 return -ENOMEM;
498
499         h->maxelem = maxelem;
500         get_random_bytes(&h->initval, sizeof(h->initval));
501         h->timeout = IPSET_NO_TIMEOUT;
502
503         hbits = htable_bits(hashsize);
504         h->table = ip_set_alloc(
505                         sizeof(struct htable)
506                         + jhash_size(hbits) * sizeof(struct hbucket));
507         if (!h->table) {
508                 kfree(h);
509                 return -ENOMEM;
510         }
511         h->table->htable_bits = hbits;
512
513         set->data = h;
514
515         if (tb[IPSET_ATTR_TIMEOUT]) {
516                 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
517
518                 set->variant = set->family == AF_INET
519                         ? &hash_netport4_tvariant : &hash_netport6_tvariant;
520
521                 if (set->family == AF_INET)
522                         hash_netport4_gc_init(set);
523                 else
524                         hash_netport6_gc_init(set);
525         } else {
526                 set->variant = set->family == AF_INET
527                         ? &hash_netport4_variant : &hash_netport6_variant;
528         }
529
530         pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
531                  set->name, jhash_size(h->table->htable_bits),
532                  h->table->htable_bits, h->maxelem, set->data, h->table);
533
534         return 0;
535 }
536
537 static struct ip_set_type hash_netport_type __read_mostly = {
538         .name           = "hash:net,port",
539         .protocol       = IPSET_PROTOCOL,
540         .features       = IPSET_TYPE_IP | IPSET_TYPE_PORT,
541         .dimension      = IPSET_DIM_TWO,
542         .family         = AF_UNSPEC,
543         .revision       = 0,
544         .create         = hash_netport_create,
545         .create_policy  = {
546                 [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
547                 [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
548                 [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
549                 [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
550                 [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
551                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
552         },
553         .adt_policy     = {
554                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
555                 [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
556                 [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
557                 [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
558                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
559                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
560                 [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
561         },
562         .me             = THIS_MODULE,
563 };
564
565 static int __init
566 hash_netport_init(void)
567 {
568         return ip_set_type_register(&hash_netport_type);
569 }
570
571 static void __exit
572 hash_netport_fini(void)
573 {
574         ip_set_type_unregister(&hash_netport_type);
575 }
576
577 module_init(hash_netport_init);
578 module_exit(hash_netport_fini);