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