Merge tag 'tty-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
[platform/adaptation/renesas_rcar/renesas_kernel.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 #define REVISION_MIN    0
28 /*                      1    SCTP and UDPLITE support added */
29 /*                      2    Range as input support for IPv4 added */
30 #define REVISION_MAX    3 /* nomatch flag support added */
31
32 MODULE_LICENSE("GPL");
33 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
34 IP_SET_MODULE_DESC("hash:net,port", REVISION_MIN, REVISION_MAX);
35 MODULE_ALIAS("ip_set_hash:net,port");
36
37 /* Type specific function prefix */
38 #define TYPE            hash_netport
39
40 static bool
41 hash_netport_same_set(const struct ip_set *a, const struct ip_set *b);
42
43 #define hash_netport4_same_set  hash_netport_same_set
44 #define hash_netport6_same_set  hash_netport_same_set
45
46 /* The type variant functions: IPv4 */
47
48 /* We squeeze the "nomatch" flag into cidr: we don't support cidr == 0
49  * However this way we have to store internally cidr - 1,
50  * dancing back and forth.
51  */
52 #define IP_SET_HASH_WITH_NETS_PACKED
53
54 /* Member elements without timeout */
55 struct hash_netport4_elem {
56         __be32 ip;
57         __be16 port;
58         u8 proto;
59         u8 cidr:7;
60         u8 nomatch:1;
61 };
62
63 /* Member elements with timeout support */
64 struct hash_netport4_telem {
65         __be32 ip;
66         __be16 port;
67         u8 proto;
68         u8 cidr:7;
69         u8 nomatch:1;
70         unsigned long timeout;
71 };
72
73 static inline bool
74 hash_netport4_data_equal(const struct hash_netport4_elem *ip1,
75                          const struct hash_netport4_elem *ip2,
76                          u32 *multi)
77 {
78         return ip1->ip == ip2->ip &&
79                ip1->port == ip2->port &&
80                ip1->proto == ip2->proto &&
81                ip1->cidr == ip2->cidr;
82 }
83
84 static inline bool
85 hash_netport4_data_isnull(const struct hash_netport4_elem *elem)
86 {
87         return elem->proto == 0;
88 }
89
90 static inline void
91 hash_netport4_data_copy(struct hash_netport4_elem *dst,
92                         const struct hash_netport4_elem *src)
93 {
94         dst->ip = src->ip;
95         dst->port = src->port;
96         dst->proto = src->proto;
97         dst->cidr = src->cidr;
98         dst->nomatch = src->nomatch;
99 }
100
101 static inline void
102 hash_netport4_data_flags(struct hash_netport4_elem *dst, u32 flags)
103 {
104         dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
105 }
106
107 static inline void
108 hash_netport4_data_reset_flags(struct hash_netport4_elem *dst, u32 *flags)
109 {
110         if (dst->nomatch) {
111                 *flags = IPSET_FLAG_NOMATCH;
112                 dst->nomatch = 0;
113         }
114 }
115
116 static inline int
117 hash_netport4_data_match(const struct hash_netport4_elem *elem)
118 {
119         return elem->nomatch ? -ENOTEMPTY : 1;
120 }
121
122 static inline void
123 hash_netport4_data_netmask(struct hash_netport4_elem *elem, u8 cidr)
124 {
125         elem->ip &= ip_set_netmask(cidr);
126         elem->cidr = cidr - 1;
127 }
128
129 static inline void
130 hash_netport4_data_zero_out(struct hash_netport4_elem *elem)
131 {
132         elem->proto = 0;
133 }
134
135 static bool
136 hash_netport4_data_list(struct sk_buff *skb,
137                         const struct hash_netport4_elem *data)
138 {
139         u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
140
141         if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
142             nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
143             nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr + 1) ||
144             nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
145             (flags &&
146              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
147                 goto nla_put_failure;
148         return 0;
149
150 nla_put_failure:
151         return 1;
152 }
153
154 static bool
155 hash_netport4_data_tlist(struct sk_buff *skb,
156                          const struct hash_netport4_elem *data)
157 {
158         const struct hash_netport4_telem *tdata =
159                 (const struct hash_netport4_telem *)data;
160         u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
161
162         if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
163             nla_put_net16(skb, IPSET_ATTR_PORT, tdata->port) ||
164             nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr + 1) ||
165             nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
166             nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
167                           htonl(ip_set_timeout_get(tdata->timeout))) ||
168             (flags &&
169              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
170                 goto nla_put_failure;
171         return 0;
172
173 nla_put_failure:
174         return 1;
175 }
176
177 #define IP_SET_HASH_WITH_PROTO
178 #define IP_SET_HASH_WITH_NETS
179
180 #define PF              4
181 #define HOST_MASK       32
182 #include <linux/netfilter/ipset/ip_set_ahash.h>
183
184 static inline void
185 hash_netport4_data_next(struct ip_set_hash *h,
186                         const struct hash_netport4_elem *d)
187 {
188         h->next.ip = d->ip;
189         h->next.port = d->port;
190 }
191
192 static int
193 hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb,
194                    const struct xt_action_param *par,
195                    enum ipset_adt adt, const struct ip_set_adt_opt *opt)
196 {
197         const struct ip_set_hash *h = set->data;
198         ipset_adtfn adtfn = set->variant->adt[adt];
199         struct hash_netport4_elem data = {
200                 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1
201         };
202
203         if (adt == IPSET_TEST)
204                 data.cidr = HOST_MASK - 1;
205
206         if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
207                                  &data.port, &data.proto))
208                 return -EINVAL;
209
210         ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip);
211         data.ip &= ip_set_netmask(data.cidr + 1);
212
213         return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
214 }
215
216 static int
217 hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
218                    enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
219 {
220         const struct ip_set_hash *h = set->data;
221         ipset_adtfn adtfn = set->variant->adt[adt];
222         struct hash_netport4_elem data = { .cidr = HOST_MASK - 1 };
223         u32 port, port_to, p = 0, ip = 0, ip_to, last;
224         u32 timeout = h->timeout;
225         bool with_ports = false;
226         u8 cidr;
227         int ret;
228
229         if (unlikely(!tb[IPSET_ATTR_IP] ||
230                      !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
231                      !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
232                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
233                      !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
234                 return -IPSET_ERR_PROTOCOL;
235
236         if (tb[IPSET_ATTR_LINENO])
237                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
238
239         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
240         if (ret)
241                 return ret;
242
243         if (tb[IPSET_ATTR_CIDR]) {
244                 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
245                 if (!cidr || cidr > HOST_MASK)
246                         return -IPSET_ERR_INVALID_CIDR;
247                 data.cidr = cidr - 1;
248         }
249
250         if (tb[IPSET_ATTR_PORT])
251                 data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
252         else
253                 return -IPSET_ERR_PROTOCOL;
254
255         if (tb[IPSET_ATTR_PROTO]) {
256                 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
257                 with_ports = ip_set_proto_with_ports(data.proto);
258
259                 if (data.proto == 0)
260                         return -IPSET_ERR_INVALID_PROTO;
261         } else
262                 return -IPSET_ERR_MISSING_PROTO;
263
264         if (!(with_ports || data.proto == IPPROTO_ICMP))
265                 data.port = 0;
266
267         if (tb[IPSET_ATTR_TIMEOUT]) {
268                 if (!with_timeout(h->timeout))
269                         return -IPSET_ERR_TIMEOUT;
270                 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
271         }
272
273         with_ports = with_ports && tb[IPSET_ATTR_PORT_TO];
274
275         if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) {
276                 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
277                 if (cadt_flags & IPSET_FLAG_NOMATCH)
278                         flags |= (cadt_flags << 16);
279         }
280
281         if (adt == IPSET_TEST || !(with_ports || tb[IPSET_ATTR_IP_TO])) {
282                 data.ip = htonl(ip & ip_set_hostmask(data.cidr + 1));
283                 ret = adtfn(set, &data, timeout, flags);
284                 return ip_set_eexist(ret, flags) ? 0 : ret;
285         }
286
287         port = port_to = ntohs(data.port);
288         if (tb[IPSET_ATTR_PORT_TO]) {
289                 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
290                 if (port_to < port)
291                         swap(port, port_to);
292         }
293         if (tb[IPSET_ATTR_IP_TO]) {
294                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
295                 if (ret)
296                         return ret;
297                 if (ip_to < ip)
298                         swap(ip, ip_to);
299                 if (ip + UINT_MAX == ip_to)
300                         return -IPSET_ERR_HASH_RANGE;
301         } else {
302                 ip_set_mask_from_to(ip, ip_to, data.cidr + 1);
303         }
304
305         if (retried)
306                 ip = ntohl(h->next.ip);
307         while (!after(ip, ip_to)) {
308                 data.ip = htonl(ip);
309                 last = ip_set_range_to_cidr(ip, ip_to, &cidr);
310                 data.cidr = cidr - 1;
311                 p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
312                                                        : port;
313                 for (; p <= port_to; p++) {
314                         data.port = htons(p);
315                         ret = adtfn(set, &data, timeout, flags);
316
317                         if (ret && !ip_set_eexist(ret, flags))
318                                 return ret;
319                         else
320                                 ret = 0;
321                 }
322                 ip = last + 1;
323         }
324         return ret;
325 }
326
327 static bool
328 hash_netport_same_set(const struct ip_set *a, const struct ip_set *b)
329 {
330         const struct ip_set_hash *x = a->data;
331         const struct ip_set_hash *y = b->data;
332
333         /* Resizing changes htable_bits, so we ignore it */
334         return x->maxelem == y->maxelem &&
335                x->timeout == y->timeout;
336 }
337
338 /* The type variant functions: IPv6 */
339
340 struct hash_netport6_elem {
341         union nf_inet_addr ip;
342         __be16 port;
343         u8 proto;
344         u8 cidr:7;
345         u8 nomatch:1;
346 };
347
348 struct hash_netport6_telem {
349         union nf_inet_addr ip;
350         __be16 port;
351         u8 proto;
352         u8 cidr:7;
353         u8 nomatch:1;
354         unsigned long timeout;
355 };
356
357 static inline bool
358 hash_netport6_data_equal(const struct hash_netport6_elem *ip1,
359                          const struct hash_netport6_elem *ip2,
360                          u32 *multi)
361 {
362         return ipv6_addr_equal(&ip1->ip.in6, &ip2->ip.in6) &&
363                ip1->port == ip2->port &&
364                ip1->proto == ip2->proto &&
365                ip1->cidr == ip2->cidr;
366 }
367
368 static inline bool
369 hash_netport6_data_isnull(const struct hash_netport6_elem *elem)
370 {
371         return elem->proto == 0;
372 }
373
374 static inline void
375 hash_netport6_data_copy(struct hash_netport6_elem *dst,
376                         const struct hash_netport6_elem *src)
377 {
378         memcpy(dst, src, sizeof(*dst));
379 }
380
381 static inline void
382 hash_netport6_data_flags(struct hash_netport6_elem *dst, u32 flags)
383 {
384         dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
385 }
386
387 static inline void
388 hash_netport6_data_reset_flags(struct hash_netport6_elem *dst, u32 *flags)
389 {
390         if (dst->nomatch) {
391                 *flags = IPSET_FLAG_NOMATCH;
392                 dst->nomatch = 0;
393         }
394 }
395
396 static inline int
397 hash_netport6_data_match(const struct hash_netport6_elem *elem)
398 {
399         return elem->nomatch ? -ENOTEMPTY : 1;
400 }
401
402 static inline void
403 hash_netport6_data_zero_out(struct hash_netport6_elem *elem)
404 {
405         elem->proto = 0;
406 }
407
408 static inline void
409 ip6_netmask(union nf_inet_addr *ip, u8 prefix)
410 {
411         ip->ip6[0] &= ip_set_netmask6(prefix)[0];
412         ip->ip6[1] &= ip_set_netmask6(prefix)[1];
413         ip->ip6[2] &= ip_set_netmask6(prefix)[2];
414         ip->ip6[3] &= ip_set_netmask6(prefix)[3];
415 }
416
417 static inline void
418 hash_netport6_data_netmask(struct hash_netport6_elem *elem, u8 cidr)
419 {
420         ip6_netmask(&elem->ip, cidr);
421         elem->cidr = cidr - 1;
422 }
423
424 static bool
425 hash_netport6_data_list(struct sk_buff *skb,
426                         const struct hash_netport6_elem *data)
427 {
428         u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
429
430         if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
431             nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
432             nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr + 1) ||
433             nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
434             (flags &&
435              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
436                 goto nla_put_failure;
437         return 0;
438
439 nla_put_failure:
440         return 1;
441 }
442
443 static bool
444 hash_netport6_data_tlist(struct sk_buff *skb,
445                          const struct hash_netport6_elem *data)
446 {
447         const struct hash_netport6_telem *e =
448                 (const struct hash_netport6_telem *)data;
449         u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
450
451         if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
452             nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
453             nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr + 1) ||
454             nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
455             nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
456                           htonl(ip_set_timeout_get(e->timeout))) ||
457             (flags &&
458              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
459                 goto nla_put_failure;
460         return 0;
461
462 nla_put_failure:
463         return 1;
464 }
465
466 #undef PF
467 #undef HOST_MASK
468
469 #define PF              6
470 #define HOST_MASK       128
471 #include <linux/netfilter/ipset/ip_set_ahash.h>
472
473 static inline void
474 hash_netport6_data_next(struct ip_set_hash *h,
475                         const struct hash_netport6_elem *d)
476 {
477         h->next.port = d->port;
478 }
479
480 static int
481 hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb,
482                    const struct xt_action_param *par,
483                    enum ipset_adt adt, const struct ip_set_adt_opt *opt)
484 {
485         const struct ip_set_hash *h = set->data;
486         ipset_adtfn adtfn = set->variant->adt[adt];
487         struct hash_netport6_elem data = {
488                 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1,
489         };
490
491         if (adt == IPSET_TEST)
492                 data.cidr = HOST_MASK - 1;
493
494         if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
495                                  &data.port, &data.proto))
496                 return -EINVAL;
497
498         ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
499         ip6_netmask(&data.ip, data.cidr + 1);
500
501         return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
502 }
503
504 static int
505 hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
506                    enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
507 {
508         const struct ip_set_hash *h = set->data;
509         ipset_adtfn adtfn = set->variant->adt[adt];
510         struct hash_netport6_elem data = { .cidr = HOST_MASK  - 1 };
511         u32 port, port_to;
512         u32 timeout = h->timeout;
513         bool with_ports = false;
514         u8 cidr;
515         int ret;
516
517         if (unlikely(!tb[IPSET_ATTR_IP] ||
518                      !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
519                      !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
520                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
521                      !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
522                 return -IPSET_ERR_PROTOCOL;
523         if (unlikely(tb[IPSET_ATTR_IP_TO]))
524                 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED;
525
526         if (tb[IPSET_ATTR_LINENO])
527                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
528
529         ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
530         if (ret)
531                 return ret;
532
533         if (tb[IPSET_ATTR_CIDR]) {
534                 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
535                 if (!cidr || cidr > HOST_MASK)
536                         return -IPSET_ERR_INVALID_CIDR;
537                 data.cidr = cidr - 1;
538         }
539         ip6_netmask(&data.ip, data.cidr + 1);
540
541         if (tb[IPSET_ATTR_PORT])
542                 data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
543         else
544                 return -IPSET_ERR_PROTOCOL;
545
546         if (tb[IPSET_ATTR_PROTO]) {
547                 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
548                 with_ports = ip_set_proto_with_ports(data.proto);
549
550                 if (data.proto == 0)
551                         return -IPSET_ERR_INVALID_PROTO;
552         } else
553                 return -IPSET_ERR_MISSING_PROTO;
554
555         if (!(with_ports || data.proto == IPPROTO_ICMPV6))
556                 data.port = 0;
557
558         if (tb[IPSET_ATTR_TIMEOUT]) {
559                 if (!with_timeout(h->timeout))
560                         return -IPSET_ERR_TIMEOUT;
561                 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
562         }
563
564         if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) {
565                 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
566                 if (cadt_flags & IPSET_FLAG_NOMATCH)
567                         flags |= (cadt_flags << 16);
568         }
569
570         if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
571                 ret = adtfn(set, &data, timeout, flags);
572                 return ip_set_eexist(ret, flags) ? 0 : ret;
573         }
574
575         port = ntohs(data.port);
576         port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
577         if (port > port_to)
578                 swap(port, port_to);
579
580         if (retried)
581                 port = ntohs(h->next.port);
582         for (; port <= port_to; port++) {
583                 data.port = htons(port);
584                 ret = adtfn(set, &data, timeout, flags);
585
586                 if (ret && !ip_set_eexist(ret, flags))
587                         return ret;
588                 else
589                         ret = 0;
590         }
591         return ret;
592 }
593
594 /* Create hash:ip type of sets */
595
596 static int
597 hash_netport_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
598 {
599         struct ip_set_hash *h;
600         u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
601         u8 hbits;
602         size_t hsize;
603
604         if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
605                 return -IPSET_ERR_INVALID_FAMILY;
606
607         if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
608                      !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
609                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
610                 return -IPSET_ERR_PROTOCOL;
611
612         if (tb[IPSET_ATTR_HASHSIZE]) {
613                 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
614                 if (hashsize < IPSET_MIMINAL_HASHSIZE)
615                         hashsize = IPSET_MIMINAL_HASHSIZE;
616         }
617
618         if (tb[IPSET_ATTR_MAXELEM])
619                 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
620
621         h = kzalloc(sizeof(*h)
622                     + sizeof(struct ip_set_hash_nets)
623                       * (set->family == NFPROTO_IPV4 ? 32 : 128), GFP_KERNEL);
624         if (!h)
625                 return -ENOMEM;
626
627         h->maxelem = maxelem;
628         get_random_bytes(&h->initval, sizeof(h->initval));
629         h->timeout = IPSET_NO_TIMEOUT;
630
631         hbits = htable_bits(hashsize);
632         hsize = htable_size(hbits);
633         if (hsize == 0) {
634                 kfree(h);
635                 return -ENOMEM;
636         }
637         h->table = ip_set_alloc(hsize);
638         if (!h->table) {
639                 kfree(h);
640                 return -ENOMEM;
641         }
642         h->table->htable_bits = hbits;
643
644         set->data = h;
645
646         if (tb[IPSET_ATTR_TIMEOUT]) {
647                 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
648
649                 set->variant = set->family == NFPROTO_IPV4
650                         ? &hash_netport4_tvariant : &hash_netport6_tvariant;
651
652                 if (set->family == NFPROTO_IPV4)
653                         hash_netport4_gc_init(set);
654                 else
655                         hash_netport6_gc_init(set);
656         } else {
657                 set->variant = set->family == NFPROTO_IPV4
658                         ? &hash_netport4_variant : &hash_netport6_variant;
659         }
660
661         pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
662                  set->name, jhash_size(h->table->htable_bits),
663                  h->table->htable_bits, h->maxelem, set->data, h->table);
664
665         return 0;
666 }
667
668 static struct ip_set_type hash_netport_type __read_mostly = {
669         .name           = "hash:net,port",
670         .protocol       = IPSET_PROTOCOL,
671         .features       = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_NOMATCH,
672         .dimension      = IPSET_DIM_TWO,
673         .family         = NFPROTO_UNSPEC,
674         .revision_min   = REVISION_MIN,
675         .revision_max   = REVISION_MAX,
676         .create         = hash_netport_create,
677         .create_policy  = {
678                 [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
679                 [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
680                 [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
681                 [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
682                 [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
683                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
684         },
685         .adt_policy     = {
686                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
687                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
688                 [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
689                 [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
690                 [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
691                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
692                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
693                 [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
694                 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
695         },
696         .me             = THIS_MODULE,
697 };
698
699 static int __init
700 hash_netport_init(void)
701 {
702         return ip_set_type_register(&hash_netport_type);
703 }
704
705 static void __exit
706 hash_netport_fini(void)
707 {
708         ip_set_type_unregister(&hash_netport_type);
709 }
710
711 module_init(hash_netport_init);
712 module_exit(hash_netport_fini);