netfilter: ipset: use unified from/to address masking and check the usage
[pandora-kernel.git] / net / netfilter / ipset / ip_set_hash_ip.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 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_hash.h>
26
27 MODULE_LICENSE("GPL");
28 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
29 MODULE_DESCRIPTION("hash:ip type of IP sets");
30 MODULE_ALIAS("ip_set_hash:ip");
31
32 /* Type specific function prefix */
33 #define TYPE            hash_ip
34
35 static bool
36 hash_ip_same_set(const struct ip_set *a, const struct ip_set *b);
37
38 #define hash_ip4_same_set       hash_ip_same_set
39 #define hash_ip6_same_set       hash_ip_same_set
40
41 /* The type variant functions: IPv4 */
42
43 /* Member elements without timeout */
44 struct hash_ip4_elem {
45         __be32 ip;
46 };
47
48 /* Member elements with timeout support */
49 struct hash_ip4_telem {
50         __be32 ip;
51         unsigned long timeout;
52 };
53
54 static inline bool
55 hash_ip4_data_equal(const struct hash_ip4_elem *ip1,
56                     const struct hash_ip4_elem *ip2)
57 {
58         return ip1->ip == ip2->ip;
59 }
60
61 static inline bool
62 hash_ip4_data_isnull(const struct hash_ip4_elem *elem)
63 {
64         return elem->ip == 0;
65 }
66
67 static inline void
68 hash_ip4_data_copy(struct hash_ip4_elem *dst, const struct hash_ip4_elem *src)
69 {
70         dst->ip = src->ip;
71 }
72
73 /* Zero valued IP addresses cannot be stored */
74 static inline void
75 hash_ip4_data_zero_out(struct hash_ip4_elem *elem)
76 {
77         elem->ip = 0;
78 }
79
80 static inline bool
81 hash_ip4_data_list(struct sk_buff *skb, const struct hash_ip4_elem *data)
82 {
83         NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip);
84         return 0;
85
86 nla_put_failure:
87         return 1;
88 }
89
90 static bool
91 hash_ip4_data_tlist(struct sk_buff *skb, const struct hash_ip4_elem *data)
92 {
93         const struct hash_ip4_telem *tdata =
94                 (const struct hash_ip4_telem *)data;
95
96         NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip);
97         NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
98                       htonl(ip_set_timeout_get(tdata->timeout)));
99
100         return 0;
101
102 nla_put_failure:
103         return 1;
104 }
105
106 #define IP_SET_HASH_WITH_NETMASK
107 #define PF              4
108 #define HOST_MASK       32
109 #include <linux/netfilter/ipset/ip_set_ahash.h>
110
111 static inline void
112 hash_ip4_data_next(struct ip_set_hash *h, const struct hash_ip4_elem *d)
113 {
114         h->next.ip = ntohl(d->ip);
115 }
116
117 static int
118 hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb,
119               enum ipset_adt adt, const struct ip_set_adt_opt *opt)
120 {
121         const struct ip_set_hash *h = set->data;
122         ipset_adtfn adtfn = set->variant->adt[adt];
123         __be32 ip;
124
125         ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip);
126         ip &= ip_set_netmask(h->netmask);
127         if (ip == 0)
128                 return -EINVAL;
129
130         return adtfn(set, &ip, opt_timeout(opt, h), opt->cmdflags);
131 }
132
133 static int
134 hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
135               enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
136 {
137         const struct ip_set_hash *h = set->data;
138         ipset_adtfn adtfn = set->variant->adt[adt];
139         u32 ip, ip_to, hosts, timeout = h->timeout;
140         __be32 nip;
141         int ret = 0;
142
143         if (unlikely(!tb[IPSET_ATTR_IP] ||
144                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
145                 return -IPSET_ERR_PROTOCOL;
146
147         if (tb[IPSET_ATTR_LINENO])
148                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
149
150         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
151         if (ret)
152                 return ret;
153
154         ip &= ip_set_hostmask(h->netmask);
155
156         if (tb[IPSET_ATTR_TIMEOUT]) {
157                 if (!with_timeout(h->timeout))
158                         return -IPSET_ERR_TIMEOUT;
159                 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
160         }
161
162         if (adt == IPSET_TEST) {
163                 nip = htonl(ip);
164                 if (nip == 0)
165                         return -IPSET_ERR_HASH_ELEM;
166                 return adtfn(set, &nip, timeout, flags);
167         }
168
169         if (tb[IPSET_ATTR_IP_TO]) {
170                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
171                 if (ret)
172                         return ret;
173                 if (ip > ip_to)
174                         swap(ip, ip_to);
175         } else if (tb[IPSET_ATTR_CIDR]) {
176                 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
177
178                 if (cidr > 32)
179                         return -IPSET_ERR_INVALID_CIDR;
180                 ip_set_mask_from_to(ip, ip_to, cidr);
181         } else
182                 ip_to = ip;
183
184         hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1);
185
186         if (retried)
187                 ip = h->next.ip;
188         for (; !before(ip_to, ip); ip += hosts) {
189                 nip = htonl(ip);
190                 if (nip == 0)
191                         return -IPSET_ERR_HASH_ELEM;
192                 ret = adtfn(set, &nip, timeout, flags);
193
194                 if (ret && !ip_set_eexist(ret, flags))
195                         return ret;
196                 else
197                         ret = 0;
198         }
199         return ret;
200 }
201
202 static bool
203 hash_ip_same_set(const struct ip_set *a, const struct ip_set *b)
204 {
205         const struct ip_set_hash *x = a->data;
206         const struct ip_set_hash *y = b->data;
207
208         /* Resizing changes htable_bits, so we ignore it */
209         return x->maxelem == y->maxelem &&
210                x->timeout == y->timeout &&
211                x->netmask == y->netmask;
212 }
213
214 /* The type variant functions: IPv6 */
215
216 struct hash_ip6_elem {
217         union nf_inet_addr ip;
218 };
219
220 struct hash_ip6_telem {
221         union nf_inet_addr ip;
222         unsigned long timeout;
223 };
224
225 static inline bool
226 hash_ip6_data_equal(const struct hash_ip6_elem *ip1,
227                     const struct hash_ip6_elem *ip2)
228 {
229         return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0;
230 }
231
232 static inline bool
233 hash_ip6_data_isnull(const struct hash_ip6_elem *elem)
234 {
235         return ipv6_addr_any(&elem->ip.in6);
236 }
237
238 static inline void
239 hash_ip6_data_copy(struct hash_ip6_elem *dst, const struct hash_ip6_elem *src)
240 {
241         ipv6_addr_copy(&dst->ip.in6, &src->ip.in6);
242 }
243
244 static inline void
245 hash_ip6_data_zero_out(struct hash_ip6_elem *elem)
246 {
247         ipv6_addr_set(&elem->ip.in6, 0, 0, 0, 0);
248 }
249
250 static inline void
251 ip6_netmask(union nf_inet_addr *ip, u8 prefix)
252 {
253         ip->ip6[0] &= ip_set_netmask6(prefix)[0];
254         ip->ip6[1] &= ip_set_netmask6(prefix)[1];
255         ip->ip6[2] &= ip_set_netmask6(prefix)[2];
256         ip->ip6[3] &= ip_set_netmask6(prefix)[3];
257 }
258
259 static bool
260 hash_ip6_data_list(struct sk_buff *skb, const struct hash_ip6_elem *data)
261 {
262         NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip);
263         return 0;
264
265 nla_put_failure:
266         return 1;
267 }
268
269 static bool
270 hash_ip6_data_tlist(struct sk_buff *skb, const struct hash_ip6_elem *data)
271 {
272         const struct hash_ip6_telem *e =
273                 (const struct hash_ip6_telem *)data;
274
275         NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip);
276         NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
277                       htonl(ip_set_timeout_get(e->timeout)));
278         return 0;
279
280 nla_put_failure:
281         return 1;
282 }
283
284 #undef PF
285 #undef HOST_MASK
286
287 #define PF              6
288 #define HOST_MASK       128
289 #include <linux/netfilter/ipset/ip_set_ahash.h>
290
291 static inline void
292 hash_ip6_data_next(struct ip_set_hash *h, const struct hash_ip6_elem *d)
293 {
294 }
295
296 static int
297 hash_ip6_kadt(struct ip_set *set, const struct sk_buff *skb,
298               enum ipset_adt adt, const struct ip_set_adt_opt *opt)
299 {
300         const struct ip_set_hash *h = set->data;
301         ipset_adtfn adtfn = set->variant->adt[adt];
302         union nf_inet_addr ip;
303
304         ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip.in6);
305         ip6_netmask(&ip, h->netmask);
306         if (ipv6_addr_any(&ip.in6))
307                 return -EINVAL;
308
309         return adtfn(set, &ip, opt_timeout(opt, h), opt->cmdflags);
310 }
311
312 static const struct nla_policy hash_ip6_adt_policy[IPSET_ATTR_ADT_MAX + 1] = {
313         [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
314         [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
315         [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
316 };
317
318 static int
319 hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[],
320               enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
321 {
322         const struct ip_set_hash *h = set->data;
323         ipset_adtfn adtfn = set->variant->adt[adt];
324         union nf_inet_addr ip;
325         u32 timeout = h->timeout;
326         int ret;
327
328         if (unlikely(!tb[IPSET_ATTR_IP] ||
329                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
330                      tb[IPSET_ATTR_IP_TO] ||
331                      tb[IPSET_ATTR_CIDR]))
332                 return -IPSET_ERR_PROTOCOL;
333
334         if (tb[IPSET_ATTR_LINENO])
335                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
336
337         ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &ip);
338         if (ret)
339                 return ret;
340
341         ip6_netmask(&ip, h->netmask);
342         if (ipv6_addr_any(&ip.in6))
343                 return -IPSET_ERR_HASH_ELEM;
344
345         if (tb[IPSET_ATTR_TIMEOUT]) {
346                 if (!with_timeout(h->timeout))
347                         return -IPSET_ERR_TIMEOUT;
348                 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
349         }
350
351         ret = adtfn(set, &ip, timeout, flags);
352
353         return ip_set_eexist(ret, flags) ? 0 : ret;
354 }
355
356 /* Create hash:ip type of sets */
357
358 static int
359 hash_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
360 {
361         u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
362         u8 netmask, hbits;
363         struct ip_set_hash *h;
364
365         if (!(set->family == AF_INET || set->family == AF_INET6))
366                 return -IPSET_ERR_INVALID_FAMILY;
367         netmask = set->family == AF_INET ? 32 : 128;
368         pr_debug("Create set %s with family %s\n",
369                  set->name, set->family == AF_INET ? "inet" : "inet6");
370
371         if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
372                      !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
373                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
374                 return -IPSET_ERR_PROTOCOL;
375
376         if (tb[IPSET_ATTR_HASHSIZE]) {
377                 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
378                 if (hashsize < IPSET_MIMINAL_HASHSIZE)
379                         hashsize = IPSET_MIMINAL_HASHSIZE;
380         }
381
382         if (tb[IPSET_ATTR_MAXELEM])
383                 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
384
385         if (tb[IPSET_ATTR_NETMASK]) {
386                 netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]);
387
388                 if ((set->family == AF_INET && netmask > 32) ||
389                     (set->family == AF_INET6 && netmask > 128) ||
390                     netmask == 0)
391                         return -IPSET_ERR_INVALID_NETMASK;
392         }
393
394         h = kzalloc(sizeof(*h), GFP_KERNEL);
395         if (!h)
396                 return -ENOMEM;
397
398         h->maxelem = maxelem;
399         h->netmask = netmask;
400         get_random_bytes(&h->initval, sizeof(h->initval));
401         h->timeout = IPSET_NO_TIMEOUT;
402
403         hbits = htable_bits(hashsize);
404         h->table = ip_set_alloc(
405                         sizeof(struct htable)
406                         + jhash_size(hbits) * sizeof(struct hbucket));
407         if (!h->table) {
408                 kfree(h);
409                 return -ENOMEM;
410         }
411         h->table->htable_bits = hbits;
412
413         set->data = h;
414
415         if (tb[IPSET_ATTR_TIMEOUT]) {
416                 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
417
418                 set->variant = set->family == AF_INET
419                         ? &hash_ip4_tvariant : &hash_ip6_tvariant;
420
421                 if (set->family == AF_INET)
422                         hash_ip4_gc_init(set);
423                 else
424                         hash_ip6_gc_init(set);
425         } else {
426                 set->variant = set->family == AF_INET
427                         ? &hash_ip4_variant : &hash_ip6_variant;
428         }
429
430         pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
431                  set->name, jhash_size(h->table->htable_bits),
432                  h->table->htable_bits, h->maxelem, set->data, h->table);
433
434         return 0;
435 }
436
437 static struct ip_set_type hash_ip_type __read_mostly = {
438         .name           = "hash:ip",
439         .protocol       = IPSET_PROTOCOL,
440         .features       = IPSET_TYPE_IP,
441         .dimension      = IPSET_DIM_ONE,
442         .family         = AF_UNSPEC,
443         .revision_min   = 0,
444         .revision_max   = 0,
445         .create         = hash_ip_create,
446         .create_policy  = {
447                 [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
448                 [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
449                 [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
450                 [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
451                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
452                 [IPSET_ATTR_NETMASK]    = { .type = NLA_U8  },
453         },
454         .adt_policy     = {
455                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
456                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
457                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
458                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
459                 [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
460         },
461         .me             = THIS_MODULE,
462 };
463
464 static int __init
465 hash_ip_init(void)
466 {
467         return ip_set_type_register(&hash_ip_type);
468 }
469
470 static void __exit
471 hash_ip_fini(void)
472 {
473         ip_set_type_unregister(&hash_ip_type);
474 }
475
476 module_init(hash_ip_init);
477 module_exit(hash_ip_fini);