Merge branch 'for-arm' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal...
[firefly-linux-kernel-4.4.55.git] / net / netfilter / ipset / ip_set_hash_net.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 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_hash.h>
25
26 MODULE_LICENSE("GPL");
27 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
28 MODULE_DESCRIPTION("hash:net type of IP sets");
29 MODULE_ALIAS("ip_set_hash:net");
30
31 /* Type specific function prefix */
32 #define TYPE            hash_net
33
34 static bool
35 hash_net_same_set(const struct ip_set *a, const struct ip_set *b);
36
37 #define hash_net4_same_set      hash_net_same_set
38 #define hash_net6_same_set      hash_net_same_set
39
40 /* The type variant functions: IPv4 */
41
42 /* Member elements without timeout */
43 struct hash_net4_elem {
44         __be32 ip;
45         u16 padding0;
46         u8 nomatch;
47         u8 cidr;
48 };
49
50 /* Member elements with timeout support */
51 struct hash_net4_telem {
52         __be32 ip;
53         u16 padding0;
54         u8 nomatch;
55         u8 cidr;
56         unsigned long timeout;
57 };
58
59 static inline bool
60 hash_net4_data_equal(const struct hash_net4_elem *ip1,
61                      const struct hash_net4_elem *ip2,
62                      u32 *multi)
63 {
64         return ip1->ip == ip2->ip &&
65                ip1->cidr == ip2->cidr;
66 }
67
68 static inline bool
69 hash_net4_data_isnull(const struct hash_net4_elem *elem)
70 {
71         return elem->cidr == 0;
72 }
73
74 static inline void
75 hash_net4_data_copy(struct hash_net4_elem *dst,
76                     const struct hash_net4_elem *src)
77 {
78         dst->ip = src->ip;
79         dst->cidr = src->cidr;
80         dst->nomatch = src->nomatch;
81 }
82
83 static inline void
84 hash_net4_data_flags(struct hash_net4_elem *dst, u32 flags)
85 {
86         dst->nomatch = flags & IPSET_FLAG_NOMATCH;
87 }
88
89 static inline bool
90 hash_net4_data_match(const struct hash_net4_elem *elem)
91 {
92         return !elem->nomatch;
93 }
94
95 static inline void
96 hash_net4_data_netmask(struct hash_net4_elem *elem, u8 cidr)
97 {
98         elem->ip &= ip_set_netmask(cidr);
99         elem->cidr = cidr;
100 }
101
102 /* Zero CIDR values cannot be stored */
103 static inline void
104 hash_net4_data_zero_out(struct hash_net4_elem *elem)
105 {
106         elem->cidr = 0;
107 }
108
109 static bool
110 hash_net4_data_list(struct sk_buff *skb, const struct hash_net4_elem *data)
111 {
112         u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
113
114         if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
115             nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
116             (flags &&
117              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
118                 goto nla_put_failure;
119         return 0;
120
121 nla_put_failure:
122         return 1;
123 }
124
125 static bool
126 hash_net4_data_tlist(struct sk_buff *skb, const struct hash_net4_elem *data)
127 {
128         const struct hash_net4_telem *tdata =
129                 (const struct hash_net4_telem *)data;
130         u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
131
132         if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
133             nla_put_u8(skb, IPSET_ATTR_CIDR, tdata->cidr) ||
134             nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
135                           htonl(ip_set_timeout_get(tdata->timeout))) ||
136             (flags &&
137              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
138                 goto nla_put_failure;
139         return 0;
140
141 nla_put_failure:
142         return 1;
143 }
144
145 #define IP_SET_HASH_WITH_NETS
146
147 #define PF              4
148 #define HOST_MASK       32
149 #include <linux/netfilter/ipset/ip_set_ahash.h>
150
151 static inline void
152 hash_net4_data_next(struct ip_set_hash *h,
153                     const struct hash_net4_elem *d)
154 {
155         h->next.ip = ntohl(d->ip);
156 }
157
158 static int
159 hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb,
160                const struct xt_action_param *par,
161                enum ipset_adt adt, const struct ip_set_adt_opt *opt)
162 {
163         const struct ip_set_hash *h = set->data;
164         ipset_adtfn adtfn = set->variant->adt[adt];
165         struct hash_net4_elem data = {
166                 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
167         };
168
169         if (data.cidr == 0)
170                 return -EINVAL;
171         if (adt == IPSET_TEST)
172                 data.cidr = HOST_MASK;
173
174         ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip);
175         data.ip &= ip_set_netmask(data.cidr);
176
177         return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
178 }
179
180 static int
181 hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
182                enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
183 {
184         const struct ip_set_hash *h = set->data;
185         ipset_adtfn adtfn = set->variant->adt[adt];
186         struct hash_net4_elem data = { .cidr = HOST_MASK };
187         u32 timeout = h->timeout;
188         u32 ip = 0, ip_to, last;
189         int ret;
190
191         if (unlikely(!tb[IPSET_ATTR_IP] ||
192                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
193                      !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
194                 return -IPSET_ERR_PROTOCOL;
195
196         if (tb[IPSET_ATTR_LINENO])
197                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
198
199         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
200         if (ret)
201                 return ret;
202
203         if (tb[IPSET_ATTR_CIDR]) {
204                 data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
205                 if (!data.cidr || data.cidr > HOST_MASK)
206                         return -IPSET_ERR_INVALID_CIDR;
207         }
208
209         if (tb[IPSET_ATTR_TIMEOUT]) {
210                 if (!with_timeout(h->timeout))
211                         return -IPSET_ERR_TIMEOUT;
212                 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
213         }
214
215         if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) {
216                 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
217                 if (cadt_flags & IPSET_FLAG_NOMATCH)
218                         flags |= (cadt_flags << 16);
219         }
220
221         if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) {
222                 data.ip = htonl(ip & ip_set_hostmask(data.cidr));
223                 ret = adtfn(set, &data, timeout, flags);
224                 return ip_set_eexist(ret, flags) ? 0 : ret;
225         }
226
227         ip_to = ip;
228         if (tb[IPSET_ATTR_IP_TO]) {
229                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
230                 if (ret)
231                         return ret;
232                 if (ip_to < ip)
233                         swap(ip, ip_to);
234                 if (ip + UINT_MAX == ip_to)
235                         return -IPSET_ERR_HASH_RANGE;
236         }
237         if (retried)
238                 ip = h->next.ip;
239         while (!after(ip, ip_to)) {
240                 data.ip = htonl(ip);
241                 last = ip_set_range_to_cidr(ip, ip_to, &data.cidr);
242                 ret = adtfn(set, &data, timeout, flags);
243                 if (ret && !ip_set_eexist(ret, flags))
244                         return ret;
245                 else
246                         ret = 0;
247                 ip = last + 1;
248         }
249         return ret;
250 }
251
252 static bool
253 hash_net_same_set(const struct ip_set *a, const struct ip_set *b)
254 {
255         const struct ip_set_hash *x = a->data;
256         const struct ip_set_hash *y = b->data;
257
258         /* Resizing changes htable_bits, so we ignore it */
259         return x->maxelem == y->maxelem &&
260                x->timeout == y->timeout;
261 }
262
263 /* The type variant functions: IPv6 */
264
265 struct hash_net6_elem {
266         union nf_inet_addr ip;
267         u16 padding0;
268         u8 nomatch;
269         u8 cidr;
270 };
271
272 struct hash_net6_telem {
273         union nf_inet_addr ip;
274         u16 padding0;
275         u8 nomatch;
276         u8 cidr;
277         unsigned long timeout;
278 };
279
280 static inline bool
281 hash_net6_data_equal(const struct hash_net6_elem *ip1,
282                      const struct hash_net6_elem *ip2,
283                      u32 *multi)
284 {
285         return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
286                ip1->cidr == ip2->cidr;
287 }
288
289 static inline bool
290 hash_net6_data_isnull(const struct hash_net6_elem *elem)
291 {
292         return elem->cidr == 0;
293 }
294
295 static inline void
296 hash_net6_data_copy(struct hash_net6_elem *dst,
297                     const struct hash_net6_elem *src)
298 {
299         dst->ip.in6 = src->ip.in6;
300         dst->cidr = src->cidr;
301         dst->nomatch = src->nomatch;
302 }
303
304 static inline void
305 hash_net6_data_flags(struct hash_net6_elem *dst, u32 flags)
306 {
307         dst->nomatch = flags & IPSET_FLAG_NOMATCH;
308 }
309
310 static inline bool
311 hash_net6_data_match(const struct hash_net6_elem *elem)
312 {
313         return !elem->nomatch;
314 }
315
316 static inline void
317 hash_net6_data_zero_out(struct hash_net6_elem *elem)
318 {
319         elem->cidr = 0;
320 }
321
322 static inline void
323 ip6_netmask(union nf_inet_addr *ip, u8 prefix)
324 {
325         ip->ip6[0] &= ip_set_netmask6(prefix)[0];
326         ip->ip6[1] &= ip_set_netmask6(prefix)[1];
327         ip->ip6[2] &= ip_set_netmask6(prefix)[2];
328         ip->ip6[3] &= ip_set_netmask6(prefix)[3];
329 }
330
331 static inline void
332 hash_net6_data_netmask(struct hash_net6_elem *elem, u8 cidr)
333 {
334         ip6_netmask(&elem->ip, cidr);
335         elem->cidr = cidr;
336 }
337
338 static bool
339 hash_net6_data_list(struct sk_buff *skb, const struct hash_net6_elem *data)
340 {
341         u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
342
343         if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
344             nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
345             (flags &&
346              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
347                 goto nla_put_failure;
348         return 0;
349
350 nla_put_failure:
351         return 1;
352 }
353
354 static bool
355 hash_net6_data_tlist(struct sk_buff *skb, const struct hash_net6_elem *data)
356 {
357         const struct hash_net6_telem *e =
358                 (const struct hash_net6_telem *)data;
359         u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
360
361         if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
362             nla_put_u8(skb, IPSET_ATTR_CIDR, e->cidr) ||
363             nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
364                           htonl(ip_set_timeout_get(e->timeout))) ||
365             (flags &&
366              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
367                 goto nla_put_failure;
368         return 0;
369
370 nla_put_failure:
371         return 1;
372 }
373
374 #undef PF
375 #undef HOST_MASK
376
377 #define PF              6
378 #define HOST_MASK       128
379 #include <linux/netfilter/ipset/ip_set_ahash.h>
380
381 static inline void
382 hash_net6_data_next(struct ip_set_hash *h,
383                     const struct hash_net6_elem *d)
384 {
385 }
386
387 static int
388 hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb,
389                const struct xt_action_param *par,
390                enum ipset_adt adt, const struct ip_set_adt_opt *opt)
391 {
392         const struct ip_set_hash *h = set->data;
393         ipset_adtfn adtfn = set->variant->adt[adt];
394         struct hash_net6_elem data = {
395                 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
396         };
397
398         if (data.cidr == 0)
399                 return -EINVAL;
400         if (adt == IPSET_TEST)
401                 data.cidr = HOST_MASK;
402
403         ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
404         ip6_netmask(&data.ip, data.cidr);
405
406         return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
407 }
408
409 static int
410 hash_net6_uadt(struct ip_set *set, struct nlattr *tb[],
411                enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
412 {
413         const struct ip_set_hash *h = set->data;
414         ipset_adtfn adtfn = set->variant->adt[adt];
415         struct hash_net6_elem data = { .cidr = HOST_MASK };
416         u32 timeout = h->timeout;
417         int ret;
418
419         if (unlikely(!tb[IPSET_ATTR_IP] ||
420                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
421                      !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
422                 return -IPSET_ERR_PROTOCOL;
423         if (unlikely(tb[IPSET_ATTR_IP_TO]))
424                 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED;
425
426         if (tb[IPSET_ATTR_LINENO])
427                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
428
429         ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
430         if (ret)
431                 return ret;
432
433         if (tb[IPSET_ATTR_CIDR])
434                 data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
435
436         if (!data.cidr || data.cidr > HOST_MASK)
437                 return -IPSET_ERR_INVALID_CIDR;
438
439         ip6_netmask(&data.ip, data.cidr);
440
441         if (tb[IPSET_ATTR_TIMEOUT]) {
442                 if (!with_timeout(h->timeout))
443                         return -IPSET_ERR_TIMEOUT;
444                 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
445         }
446
447         if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) {
448                 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
449                 if (cadt_flags & IPSET_FLAG_NOMATCH)
450                         flags |= (cadt_flags << 16);
451         }
452
453         ret = adtfn(set, &data, timeout, flags);
454
455         return ip_set_eexist(ret, flags) ? 0 : ret;
456 }
457
458 /* Create hash:ip type of sets */
459
460 static int
461 hash_net_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
462 {
463         u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
464         struct ip_set_hash *h;
465         u8 hbits;
466         size_t hsize;
467
468         if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
469                 return -IPSET_ERR_INVALID_FAMILY;
470
471         if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
472                      !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
473                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
474                 return -IPSET_ERR_PROTOCOL;
475
476         if (tb[IPSET_ATTR_HASHSIZE]) {
477                 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
478                 if (hashsize < IPSET_MIMINAL_HASHSIZE)
479                         hashsize = IPSET_MIMINAL_HASHSIZE;
480         }
481
482         if (tb[IPSET_ATTR_MAXELEM])
483                 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
484
485         h = kzalloc(sizeof(*h)
486                     + sizeof(struct ip_set_hash_nets)
487                       * (set->family == NFPROTO_IPV4 ? 32 : 128), GFP_KERNEL);
488         if (!h)
489                 return -ENOMEM;
490
491         h->maxelem = maxelem;
492         get_random_bytes(&h->initval, sizeof(h->initval));
493         h->timeout = IPSET_NO_TIMEOUT;
494
495         hbits = htable_bits(hashsize);
496         hsize = htable_size(hbits);
497         if (hsize == 0) {
498                 kfree(h);
499                 return -ENOMEM;
500         }
501         h->table = ip_set_alloc(hsize);
502         if (!h->table) {
503                 kfree(h);
504                 return -ENOMEM;
505         }
506         h->table->htable_bits = hbits;
507
508         set->data = h;
509
510         if (tb[IPSET_ATTR_TIMEOUT]) {
511                 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
512
513                 set->variant = set->family == NFPROTO_IPV4
514                         ? &hash_net4_tvariant : &hash_net6_tvariant;
515
516                 if (set->family == NFPROTO_IPV4)
517                         hash_net4_gc_init(set);
518                 else
519                         hash_net6_gc_init(set);
520         } else {
521                 set->variant = set->family == NFPROTO_IPV4
522                         ? &hash_net4_variant : &hash_net6_variant;
523         }
524
525         pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
526                  set->name, jhash_size(h->table->htable_bits),
527                  h->table->htable_bits, h->maxelem, set->data, h->table);
528
529         return 0;
530 }
531
532 static struct ip_set_type hash_net_type __read_mostly = {
533         .name           = "hash:net",
534         .protocol       = IPSET_PROTOCOL,
535         .features       = IPSET_TYPE_IP,
536         .dimension      = IPSET_DIM_ONE,
537         .family         = NFPROTO_UNSPEC,
538         .revision_min   = 0,
539         /*              = 1        Range as input support for IPv4 added */
540         .revision_max   = 2,    /* nomatch flag support added */
541         .create         = hash_net_create,
542         .create_policy  = {
543                 [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
544                 [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
545                 [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
546                 [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
547                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
548         },
549         .adt_policy     = {
550                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
551                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
552                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
553                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
554                 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
555         },
556         .me             = THIS_MODULE,
557 };
558
559 static int __init
560 hash_net_init(void)
561 {
562         return ip_set_type_register(&hash_net_type);
563 }
564
565 static void __exit
566 hash_net_fini(void)
567 {
568         ip_set_type_unregister(&hash_net_type);
569 }
570
571 module_init(hash_net_init);
572 module_exit(hash_net_fini);