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