Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / net / netfilter / ipset / ip_set_hash_ipportnet.c
1 /* Copyright (C) 2003-2013 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,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 #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_getport.h>
25 #include <linux/netfilter/ipset/ip_set_hash.h>
26
27 #define IPSET_TYPE_REV_MIN      0
28 /*                              1    SCTP and UDPLITE support added */
29 /*                              2    Range as input support for IPv4 added */
30 /*                              3    nomatch flag support added */
31 /*                              4    Counters support added */
32 /*                              5    Comments support added */
33 /*                              6    Forceadd support added */
34 #define IPSET_TYPE_REV_MAX      7 /* skbinfo support added */
35
36 MODULE_LICENSE("GPL");
37 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
38 IP_SET_MODULE_DESC("hash:ip,port,net", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
39 MODULE_ALIAS("ip_set_hash:ip,port,net");
40
41 /* Type specific function prefix */
42 #define HTYPE           hash_ipportnet
43
44 /* We squeeze the "nomatch" flag into cidr: we don't support cidr == 0
45  * However this way we have to store internally cidr - 1,
46  * dancing back and forth.
47  */
48 #define IP_SET_HASH_WITH_NETS_PACKED
49 #define IP_SET_HASH_WITH_PROTO
50 #define IP_SET_HASH_WITH_NETS
51
52 /* IPv4 variant */
53
54 /* Member elements */
55 struct hash_ipportnet4_elem {
56         __be32 ip;
57         __be32 ip2;
58         __be16 port;
59         u8 cidr:7;
60         u8 nomatch:1;
61         u8 proto;
62 };
63
64 /* Common functions */
65
66 static inline bool
67 hash_ipportnet4_data_equal(const struct hash_ipportnet4_elem *ip1,
68                            const struct hash_ipportnet4_elem *ip2,
69                            u32 *multi)
70 {
71         return ip1->ip == ip2->ip &&
72                ip1->ip2 == ip2->ip2 &&
73                ip1->cidr == ip2->cidr &&
74                ip1->port == ip2->port &&
75                ip1->proto == ip2->proto;
76 }
77
78 static inline int
79 hash_ipportnet4_do_data_match(const struct hash_ipportnet4_elem *elem)
80 {
81         return elem->nomatch ? -ENOTEMPTY : 1;
82 }
83
84 static inline void
85 hash_ipportnet4_data_set_flags(struct hash_ipportnet4_elem *elem, u32 flags)
86 {
87         elem->nomatch = !!((flags >> 16) & IPSET_FLAG_NOMATCH);
88 }
89
90 static inline void
91 hash_ipportnet4_data_reset_flags(struct hash_ipportnet4_elem *elem, u8 *flags)
92 {
93         swap(*flags, elem->nomatch);
94 }
95
96 static inline void
97 hash_ipportnet4_data_netmask(struct hash_ipportnet4_elem *elem, u8 cidr)
98 {
99         elem->ip2 &= ip_set_netmask(cidr);
100         elem->cidr = cidr - 1;
101 }
102
103 static bool
104 hash_ipportnet4_data_list(struct sk_buff *skb,
105                           const struct hash_ipportnet4_elem *data)
106 {
107         u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
108
109         if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
110             nla_put_ipaddr4(skb, IPSET_ATTR_IP2, data->ip2) ||
111             nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
112             nla_put_u8(skb, IPSET_ATTR_CIDR2, data->cidr + 1) ||
113             nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
114             (flags &&
115              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
116                 goto nla_put_failure;
117         return 0;
118
119 nla_put_failure:
120         return 1;
121 }
122
123 static inline void
124 hash_ipportnet4_data_next(struct hash_ipportnet4_elem *next,
125                           const struct hash_ipportnet4_elem *d)
126 {
127         next->ip = d->ip;
128         next->port = d->port;
129         next->ip2 = d->ip2;
130 }
131
132 #define MTYPE           hash_ipportnet4
133 #define PF              4
134 #define HOST_MASK       32
135 #include "ip_set_hash_gen.h"
136
137 static int
138 hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
139                      const struct xt_action_param *par,
140                      enum ipset_adt adt, struct ip_set_adt_opt *opt)
141 {
142         const struct hash_ipportnet *h = set->data;
143         ipset_adtfn adtfn = set->variant->adt[adt];
144         struct hash_ipportnet4_elem e = {
145                 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK) - 1,
146         };
147         struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
148
149         if (adt == IPSET_TEST)
150                 e.cidr = HOST_MASK - 1;
151
152         if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
153                                  &e.port, &e.proto))
154                 return -EINVAL;
155
156         ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
157         ip4addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &e.ip2);
158         e.ip2 &= ip_set_netmask(e.cidr + 1);
159
160         return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
161 }
162
163 static int
164 hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
165                      enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
166 {
167         const struct hash_ipportnet *h = set->data;
168         ipset_adtfn adtfn = set->variant->adt[adt];
169         struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 };
170         struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
171         u32 ip = 0, ip_to = 0, p = 0, port, port_to;
172         u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2;
173         bool with_ports = false;
174         u8 cidr;
175         int ret;
176
177         if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
178                      !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
179                      !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
180                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
181                      !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
182                      !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
183                      !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
184                      !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBMARK) ||
185                      !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBPRIO) ||
186                      !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBQUEUE)))
187                 return -IPSET_ERR_PROTOCOL;
188
189         if (tb[IPSET_ATTR_LINENO])
190                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
191
192         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) ||
193               ip_set_get_extensions(set, tb, &ext);
194         if (ret)
195                 return ret;
196
197         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2], &ip2_from);
198         if (ret)
199                 return ret;
200
201         if (tb[IPSET_ATTR_CIDR2]) {
202                 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
203                 if (!cidr || cidr > HOST_MASK)
204                         return -IPSET_ERR_INVALID_CIDR;
205                 e.cidr = cidr - 1;
206         }
207
208         if (tb[IPSET_ATTR_PORT])
209                 e.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
210         else
211                 return -IPSET_ERR_PROTOCOL;
212
213         if (tb[IPSET_ATTR_PROTO]) {
214                 e.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
215                 with_ports = ip_set_proto_with_ports(e.proto);
216
217                 if (e.proto == 0)
218                         return -IPSET_ERR_INVALID_PROTO;
219         } else
220                 return -IPSET_ERR_MISSING_PROTO;
221
222         if (!(with_ports || e.proto == IPPROTO_ICMP))
223                 e.port = 0;
224
225         if (tb[IPSET_ATTR_CADT_FLAGS]) {
226                 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
227                 if (cadt_flags & IPSET_FLAG_NOMATCH)
228                         flags |= (IPSET_FLAG_NOMATCH << 16);
229         }
230
231         with_ports = with_ports && tb[IPSET_ATTR_PORT_TO];
232         if (adt == IPSET_TEST ||
233             !(tb[IPSET_ATTR_CIDR] || tb[IPSET_ATTR_IP_TO] || with_ports ||
234               tb[IPSET_ATTR_IP2_TO])) {
235                 e.ip = htonl(ip);
236                 e.ip2 = htonl(ip2_from & ip_set_hostmask(e.cidr + 1));
237                 ret = adtfn(set, &e, &ext, &ext, flags);
238                 return ip_set_enomatch(ret, flags, adt, set) ? -ret :
239                        ip_set_eexist(ret, flags) ? 0 : ret;
240         }
241
242         ip_to = ip;
243         if (tb[IPSET_ATTR_IP_TO]) {
244                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
245                 if (ret)
246                         return ret;
247                 if (ip > ip_to)
248                         swap(ip, ip_to);
249         } else if (tb[IPSET_ATTR_CIDR]) {
250                 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
251
252                 if (!cidr || cidr > 32)
253                         return -IPSET_ERR_INVALID_CIDR;
254                 ip_set_mask_from_to(ip, ip_to, cidr);
255         }
256
257         port_to = port = ntohs(e.port);
258         if (tb[IPSET_ATTR_PORT_TO]) {
259                 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
260                 if (port > port_to)
261                         swap(port, port_to);
262         }
263
264         ip2_to = ip2_from;
265         if (tb[IPSET_ATTR_IP2_TO]) {
266                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to);
267                 if (ret)
268                         return ret;
269                 if (ip2_from > ip2_to)
270                         swap(ip2_from, ip2_to);
271                 if (ip2_from + UINT_MAX == ip2_to)
272                         return -IPSET_ERR_HASH_RANGE;
273         } else
274                 ip_set_mask_from_to(ip2_from, ip2_to, e.cidr + 1);
275
276         if (retried)
277                 ip = ntohl(h->next.ip);
278         for (; !before(ip_to, ip); ip++) {
279                 e.ip = htonl(ip);
280                 p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
281                                                        : port;
282                 for (; p <= port_to; p++) {
283                         e.port = htons(p);
284                         ip2 = retried &&
285                               ip == ntohl(h->next.ip) &&
286                               p == ntohs(h->next.port)
287                                 ? ntohl(h->next.ip2) : ip2_from;
288                         while (!after(ip2, ip2_to)) {
289                                 e.ip2 = htonl(ip2);
290                                 ip2_last = ip_set_range_to_cidr(ip2, ip2_to,
291                                                                 &cidr);
292                                 e.cidr = cidr - 1;
293                                 ret = adtfn(set, &e, &ext, &ext, flags);
294
295                                 if (ret && !ip_set_eexist(ret, flags))
296                                         return ret;
297                                 else
298                                         ret = 0;
299                                 ip2 = ip2_last + 1;
300                         }
301                 }
302         }
303         return ret;
304 }
305
306 /* IPv6 variant */
307
308 struct hash_ipportnet6_elem {
309         union nf_inet_addr ip;
310         union nf_inet_addr ip2;
311         __be16 port;
312         u8 cidr:7;
313         u8 nomatch:1;
314         u8 proto;
315 };
316
317 /* Common functions */
318
319 static inline bool
320 hash_ipportnet6_data_equal(const struct hash_ipportnet6_elem *ip1,
321                            const struct hash_ipportnet6_elem *ip2,
322                            u32 *multi)
323 {
324         return ipv6_addr_equal(&ip1->ip.in6, &ip2->ip.in6) &&
325                ipv6_addr_equal(&ip1->ip2.in6, &ip2->ip2.in6) &&
326                ip1->cidr == ip2->cidr &&
327                ip1->port == ip2->port &&
328                ip1->proto == ip2->proto;
329 }
330
331 static inline int
332 hash_ipportnet6_do_data_match(const struct hash_ipportnet6_elem *elem)
333 {
334         return elem->nomatch ? -ENOTEMPTY : 1;
335 }
336
337 static inline void
338 hash_ipportnet6_data_set_flags(struct hash_ipportnet6_elem *elem, u32 flags)
339 {
340         elem->nomatch = !!((flags >> 16) & IPSET_FLAG_NOMATCH);
341 }
342
343 static inline void
344 hash_ipportnet6_data_reset_flags(struct hash_ipportnet6_elem *elem, u8 *flags)
345 {
346         swap(*flags, elem->nomatch);
347 }
348
349 static inline void
350 hash_ipportnet6_data_netmask(struct hash_ipportnet6_elem *elem, u8 cidr)
351 {
352         ip6_netmask(&elem->ip2, cidr);
353         elem->cidr = cidr - 1;
354 }
355
356 static bool
357 hash_ipportnet6_data_list(struct sk_buff *skb,
358                           const struct hash_ipportnet6_elem *data)
359 {
360         u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
361
362         if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
363             nla_put_ipaddr6(skb, IPSET_ATTR_IP2, &data->ip2.in6) ||
364             nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
365             nla_put_u8(skb, IPSET_ATTR_CIDR2, data->cidr + 1) ||
366             nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
367             (flags &&
368              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
369                 goto nla_put_failure;
370         return 0;
371
372 nla_put_failure:
373         return 1;
374 }
375
376 static inline void
377 hash_ipportnet6_data_next(struct hash_ipportnet4_elem *next,
378                           const struct hash_ipportnet6_elem *d)
379 {
380         next->port = d->port;
381 }
382
383 #undef MTYPE
384 #undef PF
385 #undef HOST_MASK
386
387 #define MTYPE           hash_ipportnet6
388 #define PF              6
389 #define HOST_MASK       128
390 #define IP_SET_EMIT_CREATE
391 #include "ip_set_hash_gen.h"
392
393 static int
394 hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
395                      const struct xt_action_param *par,
396                      enum ipset_adt adt, struct ip_set_adt_opt *opt)
397 {
398         const struct hash_ipportnet *h = set->data;
399         ipset_adtfn adtfn = set->variant->adt[adt];
400         struct hash_ipportnet6_elem e = {
401                 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK) - 1,
402         };
403         struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
404
405         if (adt == IPSET_TEST)
406                 e.cidr = HOST_MASK - 1;
407
408         if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
409                                  &e.port, &e.proto))
410                 return -EINVAL;
411
412         ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
413         ip6addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &e.ip2.in6);
414         ip6_netmask(&e.ip2, e.cidr + 1);
415
416         return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
417 }
418
419 static int
420 hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
421                      enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
422 {
423         const struct hash_ipportnet *h = set->data;
424         ipset_adtfn adtfn = set->variant->adt[adt];
425         struct hash_ipportnet6_elem e = { .cidr = HOST_MASK - 1 };
426         struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
427         u32 port, port_to;
428         bool with_ports = false;
429         u8 cidr;
430         int ret;
431
432         if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
433                      !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
434                      !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
435                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
436                      !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
437                      !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
438                      !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
439                      !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBMARK) ||
440                      !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBPRIO) ||
441                      !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBQUEUE) ||
442                      tb[IPSET_ATTR_IP_TO] ||
443                      tb[IPSET_ATTR_CIDR]))
444                 return -IPSET_ERR_PROTOCOL;
445         if (unlikely(tb[IPSET_ATTR_IP_TO]))
446                 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED;
447
448         if (tb[IPSET_ATTR_LINENO])
449                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
450
451         ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
452               ip_set_get_extensions(set, tb, &ext);
453         if (ret)
454                 return ret;
455
456         ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &e.ip2);
457         if (ret)
458                 return ret;
459
460         if (tb[IPSET_ATTR_CIDR2]) {
461                 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
462                 if (!cidr || cidr > HOST_MASK)
463                         return -IPSET_ERR_INVALID_CIDR;
464                 e.cidr = cidr - 1;
465         }
466
467         ip6_netmask(&e.ip2, e.cidr + 1);
468
469         if (tb[IPSET_ATTR_PORT])
470                 e.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
471         else
472                 return -IPSET_ERR_PROTOCOL;
473
474         if (tb[IPSET_ATTR_PROTO]) {
475                 e.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
476                 with_ports = ip_set_proto_with_ports(e.proto);
477
478                 if (e.proto == 0)
479                         return -IPSET_ERR_INVALID_PROTO;
480         } else
481                 return -IPSET_ERR_MISSING_PROTO;
482
483         if (!(with_ports || e.proto == IPPROTO_ICMPV6))
484                 e.port = 0;
485
486         if (tb[IPSET_ATTR_CADT_FLAGS]) {
487                 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
488                 if (cadt_flags & IPSET_FLAG_NOMATCH)
489                         flags |= (IPSET_FLAG_NOMATCH << 16);
490         }
491
492         if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
493                 ret = adtfn(set, &e, &ext, &ext, flags);
494                 return ip_set_enomatch(ret, flags, adt, set) ? -ret :
495                        ip_set_eexist(ret, flags) ? 0 : ret;
496         }
497
498         port = ntohs(e.port);
499         port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
500         if (port > port_to)
501                 swap(port, port_to);
502
503         if (retried)
504                 port = ntohs(h->next.port);
505         for (; port <= port_to; port++) {
506                 e.port = htons(port);
507                 ret = adtfn(set, &e, &ext, &ext, flags);
508
509                 if (ret && !ip_set_eexist(ret, flags))
510                         return ret;
511                 else
512                         ret = 0;
513         }
514         return ret;
515 }
516
517 static struct ip_set_type hash_ipportnet_type __read_mostly = {
518         .name           = "hash:ip,port,net",
519         .protocol       = IPSET_PROTOCOL,
520         .features       = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2 |
521                           IPSET_TYPE_NOMATCH,
522         .dimension      = IPSET_DIM_THREE,
523         .family         = NFPROTO_UNSPEC,
524         .revision_min   = IPSET_TYPE_REV_MIN,
525         .revision_max   = IPSET_TYPE_REV_MAX,
526         .create         = hash_ipportnet_create,
527         .create_policy  = {
528                 [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
529                 [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
530                 [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
531                 [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
532                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
533                 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
534         },
535         .adt_policy     = {
536                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
537                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
538                 [IPSET_ATTR_IP2]        = { .type = NLA_NESTED },
539                 [IPSET_ATTR_IP2_TO]     = { .type = NLA_NESTED },
540                 [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
541                 [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
542                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
543                 [IPSET_ATTR_CIDR2]      = { .type = NLA_U8 },
544                 [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
545                 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
546                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
547                 [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
548                 [IPSET_ATTR_BYTES]      = { .type = NLA_U64 },
549                 [IPSET_ATTR_PACKETS]    = { .type = NLA_U64 },
550                 [IPSET_ATTR_COMMENT]    = { .type = NLA_NUL_STRING },
551                 [IPSET_ATTR_SKBMARK]    = { .type = NLA_U64 },
552                 [IPSET_ATTR_SKBPRIO]    = { .type = NLA_U32 },
553                 [IPSET_ATTR_SKBQUEUE]   = { .type = NLA_U16 },
554         },
555         .me             = THIS_MODULE,
556 };
557
558 static int __init
559 hash_ipportnet_init(void)
560 {
561         return ip_set_type_register(&hash_ipportnet_type);
562 }
563
564 static void __exit
565 hash_ipportnet_fini(void)
566 {
567         ip_set_type_unregister(&hash_ipportnet_type);
568 }
569
570 module_init(hash_ipportnet_init);
571 module_exit(hash_ipportnet_fini);