~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to net/netfilter/ipset/ip_set_hash_netport.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
/* Member elements without timeout */
 
44
struct hash_netport4_elem {
 
45
        __be32 ip;
 
46
        __be16 port;
 
47
        u8 proto;
 
48
        u8 cidr;
 
49
};
 
50
 
 
51
/* Member elements with timeout support */
 
52
struct hash_netport4_telem {
 
53
        __be32 ip;
 
54
        __be16 port;
 
55
        u8 proto;
 
56
        u8 cidr;
 
57
        unsigned long timeout;
 
58
};
 
59
 
 
60
static inline bool
 
61
hash_netport4_data_equal(const struct hash_netport4_elem *ip1,
 
62
                         const struct hash_netport4_elem *ip2)
 
63
{
 
64
        return ip1->ip == ip2->ip &&
 
65
               ip1->port == ip2->port &&
 
66
               ip1->proto == ip2->proto &&
 
67
               ip1->cidr == ip2->cidr;
 
68
}
 
69
 
 
70
static inline bool
 
71
hash_netport4_data_isnull(const struct hash_netport4_elem *elem)
 
72
{
 
73
        return elem->proto == 0;
 
74
}
 
75
 
 
76
static inline void
 
77
hash_netport4_data_copy(struct hash_netport4_elem *dst,
 
78
                        const struct hash_netport4_elem *src)
 
79
{
 
80
        dst->ip = src->ip;
 
81
        dst->port = src->port;
 
82
        dst->proto = src->proto;
 
83
        dst->cidr = src->cidr;
 
84
}
 
85
 
 
86
static inline void
 
87
hash_netport4_data_netmask(struct hash_netport4_elem *elem, u8 cidr)
 
88
{
 
89
        elem->ip &= ip_set_netmask(cidr);
 
90
        elem->cidr = cidr;
 
91
}
 
92
 
 
93
static inline void
 
94
hash_netport4_data_zero_out(struct hash_netport4_elem *elem)
 
95
{
 
96
        elem->proto = 0;
 
97
}
 
98
 
 
99
static bool
 
100
hash_netport4_data_list(struct sk_buff *skb,
 
101
                        const struct hash_netport4_elem *data)
 
102
{
 
103
        NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip);
 
104
        NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
 
105
        NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
 
106
        NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
 
107
        return 0;
 
108
 
 
109
nla_put_failure:
 
110
        return 1;
 
111
}
 
112
 
 
113
static bool
 
114
hash_netport4_data_tlist(struct sk_buff *skb,
 
115
                         const struct hash_netport4_elem *data)
 
116
{
 
117
        const struct hash_netport4_telem *tdata =
 
118
                (const struct hash_netport4_telem *)data;
 
119
 
 
120
        NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip);
 
121
        NLA_PUT_NET16(skb, IPSET_ATTR_PORT, tdata->port);
 
122
        NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
 
123
        NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
 
124
        NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
 
125
                      htonl(ip_set_timeout_get(tdata->timeout)));
 
126
 
 
127
        return 0;
 
128
 
 
129
nla_put_failure:
 
130
        return 1;
 
131
}
 
132
 
 
133
#define IP_SET_HASH_WITH_PROTO
 
134
#define IP_SET_HASH_WITH_NETS
 
135
 
 
136
#define PF              4
 
137
#define HOST_MASK       32
 
138
#include <linux/netfilter/ipset/ip_set_ahash.h>
 
139
 
 
140
static int
 
141
hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb,
 
142
                   enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
 
143
{
 
144
        const struct ip_set_hash *h = set->data;
 
145
        ipset_adtfn adtfn = set->variant->adt[adt];
 
146
        struct hash_netport4_elem data = {
 
147
                .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
 
148
        };
 
149
 
 
150
        if (data.cidr == 0)
 
151
                return -EINVAL;
 
152
        if (adt == IPSET_TEST)
 
153
                data.cidr = HOST_MASK;
 
154
 
 
155
        if (!ip_set_get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
 
156
                                 &data.port, &data.proto))
 
157
                return -EINVAL;
 
158
 
 
159
        ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip);
 
160
        data.ip &= ip_set_netmask(data.cidr);
 
161
 
 
162
        return adtfn(set, &data, h->timeout);
 
163
}
 
164
 
 
165
static int
 
166
hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
 
167
                   enum ipset_adt adt, u32 *lineno, u32 flags)
 
168
{
 
169
        const struct ip_set_hash *h = set->data;
 
170
        ipset_adtfn adtfn = set->variant->adt[adt];
 
171
        struct hash_netport4_elem data = { .cidr = HOST_MASK };
 
172
        u32 port, port_to;
 
173
        u32 timeout = h->timeout;
 
174
        bool with_ports = false;
 
175
        int ret;
 
176
 
 
177
        if (unlikely(!tb[IPSET_ATTR_IP] ||
 
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
                return -IPSET_ERR_PROTOCOL;
 
182
 
 
183
        if (tb[IPSET_ATTR_LINENO])
 
184
                *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
185
 
 
186
        ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip);
 
187
        if (ret)
 
188
                return ret;
 
189
 
 
190
        if (tb[IPSET_ATTR_CIDR])
 
191
                data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
 
192
        if (!data.cidr)
 
193
                return -IPSET_ERR_INVALID_CIDR;
 
194
        data.ip &= ip_set_netmask(data.cidr);
 
195
 
 
196
        if (tb[IPSET_ATTR_PORT])
 
197
                data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
 
198
        else
 
199
                return -IPSET_ERR_PROTOCOL;
 
200
 
 
201
        if (tb[IPSET_ATTR_PROTO]) {
 
202
                data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
 
203
                with_ports = ip_set_proto_with_ports(data.proto);
 
204
 
 
205
                if (data.proto == 0)
 
206
                        return -IPSET_ERR_INVALID_PROTO;
 
207
        } else
 
208
                return -IPSET_ERR_MISSING_PROTO;
 
209
 
 
210
        if (!(with_ports || data.proto == IPPROTO_ICMP))
 
211
                data.port = 0;
 
212
 
 
213
        if (tb[IPSET_ATTR_TIMEOUT]) {
 
214
                if (!with_timeout(h->timeout))
 
215
                        return -IPSET_ERR_TIMEOUT;
 
216
                timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
 
217
        }
 
218
 
 
219
        if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
 
220
                ret = adtfn(set, &data, timeout);
 
221
                return ip_set_eexist(ret, flags) ? 0 : ret;
 
222
        }
 
223
 
 
224
        port = ntohs(data.port);
 
225
        port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
 
226
        if (port > port_to)
 
227
                swap(port, port_to);
 
228
 
 
229
        for (; port <= port_to; port++) {
 
230
                data.port = htons(port);
 
231
                ret = adtfn(set, &data, timeout);
 
232
 
 
233
                if (ret && !ip_set_eexist(ret, flags))
 
234
                        return ret;
 
235
                else
 
236
                        ret = 0;
 
237
        }
 
238
        return ret;
 
239
}
 
240
 
 
241
static bool
 
242
hash_netport_same_set(const struct ip_set *a, const struct ip_set *b)
 
243
{
 
244
        const struct ip_set_hash *x = a->data;
 
245
        const struct ip_set_hash *y = b->data;
 
246
 
 
247
        /* Resizing changes htable_bits, so we ignore it */
 
248
        return x->maxelem == y->maxelem &&
 
249
               x->timeout == y->timeout;
 
250
}
 
251
 
 
252
/* The type variant functions: IPv6 */
 
253
 
 
254
struct hash_netport6_elem {
 
255
        union nf_inet_addr ip;
 
256
        __be16 port;
 
257
        u8 proto;
 
258
        u8 cidr;
 
259
};
 
260
 
 
261
struct hash_netport6_telem {
 
262
        union nf_inet_addr ip;
 
263
        __be16 port;
 
264
        u8 proto;
 
265
        u8 cidr;
 
266
        unsigned long timeout;
 
267
};
 
268
 
 
269
static inline bool
 
270
hash_netport6_data_equal(const struct hash_netport6_elem *ip1,
 
271
                         const struct hash_netport6_elem *ip2)
 
272
{
 
273
        return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
 
274
               ip1->port == ip2->port &&
 
275
               ip1->proto == ip2->proto &&
 
276
               ip1->cidr == ip2->cidr;
 
277
}
 
278
 
 
279
static inline bool
 
280
hash_netport6_data_isnull(const struct hash_netport6_elem *elem)
 
281
{
 
282
        return elem->proto == 0;
 
283
}
 
284
 
 
285
static inline void
 
286
hash_netport6_data_copy(struct hash_netport6_elem *dst,
 
287
                        const struct hash_netport6_elem *src)
 
288
{
 
289
        memcpy(dst, src, sizeof(*dst));
 
290
}
 
291
 
 
292
static inline void
 
293
hash_netport6_data_zero_out(struct hash_netport6_elem *elem)
 
294
{
 
295
        elem->proto = 0;
 
296
}
 
297
 
 
298
static inline void
 
299
ip6_netmask(union nf_inet_addr *ip, u8 prefix)
 
300
{
 
301
        ip->ip6[0] &= ip_set_netmask6(prefix)[0];
 
302
        ip->ip6[1] &= ip_set_netmask6(prefix)[1];
 
303
        ip->ip6[2] &= ip_set_netmask6(prefix)[2];
 
304
        ip->ip6[3] &= ip_set_netmask6(prefix)[3];
 
305
}
 
306
 
 
307
static inline void
 
308
hash_netport6_data_netmask(struct hash_netport6_elem *elem, u8 cidr)
 
309
{
 
310
        ip6_netmask(&elem->ip, cidr);
 
311
        elem->cidr = cidr;
 
312
}
 
313
 
 
314
static bool
 
315
hash_netport6_data_list(struct sk_buff *skb,
 
316
                        const struct hash_netport6_elem *data)
 
317
{
 
318
        NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip);
 
319
        NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
 
320
        NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
 
321
        NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
 
322
        return 0;
 
323
 
 
324
nla_put_failure:
 
325
        return 1;
 
326
}
 
327
 
 
328
static bool
 
329
hash_netport6_data_tlist(struct sk_buff *skb,
 
330
                         const struct hash_netport6_elem *data)
 
331
{
 
332
        const struct hash_netport6_telem *e =
 
333
                (const struct hash_netport6_telem *)data;
 
334
 
 
335
        NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip);
 
336
        NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
 
337
        NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
 
338
        NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
 
339
        NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
 
340
                      htonl(ip_set_timeout_get(e->timeout)));
 
341
        return 0;
 
342
 
 
343
nla_put_failure:
 
344
        return 1;
 
345
}
 
346
 
 
347
#undef PF
 
348
#undef HOST_MASK
 
349
 
 
350
#define PF              6
 
351
#define HOST_MASK       128
 
352
#include <linux/netfilter/ipset/ip_set_ahash.h>
 
353
 
 
354
static int
 
355
hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb,
 
356
                   enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
 
357
{
 
358
        const struct ip_set_hash *h = set->data;
 
359
        ipset_adtfn adtfn = set->variant->adt[adt];
 
360
        struct hash_netport6_elem data = {
 
361
                .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
 
362
        };
 
363
 
 
364
        if (data.cidr == 0)
 
365
                return -EINVAL;
 
366
        if (adt == IPSET_TEST)
 
367
                data.cidr = HOST_MASK;
 
368
 
 
369
        if (!ip_set_get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
 
370
                                 &data.port, &data.proto))
 
371
                return -EINVAL;
 
372
 
 
373
        ip6addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
 
374
        ip6_netmask(&data.ip, data.cidr);
 
375
 
 
376
        return adtfn(set, &data, h->timeout);
 
377
}
 
378
 
 
379
static int
 
380
hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
 
381
                   enum ipset_adt adt, u32 *lineno, u32 flags)
 
382
{
 
383
        const struct ip_set_hash *h = set->data;
 
384
        ipset_adtfn adtfn = set->variant->adt[adt];
 
385
        struct hash_netport6_elem data = { .cidr = HOST_MASK };
 
386
        u32 port, port_to;
 
387
        u32 timeout = h->timeout;
 
388
        bool with_ports = false;
 
389
        int ret;
 
390
 
 
391
        if (unlikely(!tb[IPSET_ATTR_IP] ||
 
392
                     !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
 
393
                     !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
 
394
                     !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
 
395
                return -IPSET_ERR_PROTOCOL;
 
396
 
 
397
        if (tb[IPSET_ATTR_LINENO])
 
398
                *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
399
 
 
400
        ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
 
401
        if (ret)
 
402
                return ret;
 
403
 
 
404
        if (tb[IPSET_ATTR_CIDR])
 
405
                data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
 
406
        if (!data.cidr)
 
407
                return -IPSET_ERR_INVALID_CIDR;
 
408
        ip6_netmask(&data.ip, data.cidr);
 
409
 
 
410
        if (tb[IPSET_ATTR_PORT])
 
411
                data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
 
412
        else
 
413
                return -IPSET_ERR_PROTOCOL;
 
414
 
 
415
        if (tb[IPSET_ATTR_PROTO]) {
 
416
                data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
 
417
                with_ports = ip_set_proto_with_ports(data.proto);
 
418
 
 
419
                if (data.proto == 0)
 
420
                        return -IPSET_ERR_INVALID_PROTO;
 
421
        } else
 
422
                return -IPSET_ERR_MISSING_PROTO;
 
423
 
 
424
        if (!(with_ports || data.proto == IPPROTO_ICMPV6))
 
425
                data.port = 0;
 
426
 
 
427
        if (tb[IPSET_ATTR_TIMEOUT]) {
 
428
                if (!with_timeout(h->timeout))
 
429
                        return -IPSET_ERR_TIMEOUT;
 
430
                timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
 
431
        }
 
432
 
 
433
        if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
 
434
                ret = adtfn(set, &data, timeout);
 
435
                return ip_set_eexist(ret, flags) ? 0 : ret;
 
436
        }
 
437
 
 
438
        port = ntohs(data.port);
 
439
        port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
 
440
        if (port > port_to)
 
441
                swap(port, port_to);
 
442
 
 
443
        for (; port <= port_to; port++) {
 
444
                data.port = htons(port);
 
445
                ret = adtfn(set, &data, timeout);
 
446
 
 
447
                if (ret && !ip_set_eexist(ret, flags))
 
448
                        return ret;
 
449
                else
 
450
                        ret = 0;
 
451
        }
 
452
        return ret;
 
453
}
 
454
 
 
455
/* Create hash:ip type of sets */
 
456
 
 
457
static int
 
458
hash_netport_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 
459
{
 
460
        struct ip_set_hash *h;
 
461
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
 
462
        u8 hbits;
 
463
 
 
464
        if (!(set->family == AF_INET || set->family == AF_INET6))
 
465
                return -IPSET_ERR_INVALID_FAMILY;
 
466
 
 
467
        if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
 
468
                     !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
 
469
                     !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
 
470
                return -IPSET_ERR_PROTOCOL;
 
471
 
 
472
        if (tb[IPSET_ATTR_HASHSIZE]) {
 
473
                hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
 
474
                if (hashsize < IPSET_MIMINAL_HASHSIZE)
 
475
                        hashsize = IPSET_MIMINAL_HASHSIZE;
 
476
        }
 
477
 
 
478
        if (tb[IPSET_ATTR_MAXELEM])
 
479
                maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
 
480
 
 
481
        h = kzalloc(sizeof(*h)
 
482
                    + sizeof(struct ip_set_hash_nets)
 
483
                      * (set->family == AF_INET ? 32 : 128), GFP_KERNEL);
 
484
        if (!h)
 
485
                return -ENOMEM;
 
486
 
 
487
        h->maxelem = maxelem;
 
488
        get_random_bytes(&h->initval, sizeof(h->initval));
 
489
        h->timeout = IPSET_NO_TIMEOUT;
 
490
 
 
491
        hbits = htable_bits(hashsize);
 
492
        h->table = ip_set_alloc(
 
493
                        sizeof(struct htable)
 
494
                        + jhash_size(hbits) * sizeof(struct hbucket));
 
495
        if (!h->table) {
 
496
                kfree(h);
 
497
                return -ENOMEM;
 
498
        }
 
499
        h->table->htable_bits = hbits;
 
500
 
 
501
        set->data = h;
 
502
 
 
503
        if (tb[IPSET_ATTR_TIMEOUT]) {
 
504
                h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
 
505
 
 
506
                set->variant = set->family == AF_INET
 
507
                        ? &hash_netport4_tvariant : &hash_netport6_tvariant;
 
508
 
 
509
                if (set->family == AF_INET)
 
510
                        hash_netport4_gc_init(set);
 
511
                else
 
512
                        hash_netport6_gc_init(set);
 
513
        } else {
 
514
                set->variant = set->family == AF_INET
 
515
                        ? &hash_netport4_variant : &hash_netport6_variant;
 
516
        }
 
517
 
 
518
        pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
 
519
                 set->name, jhash_size(h->table->htable_bits),
 
520
                 h->table->htable_bits, h->maxelem, set->data, h->table);
 
521
 
 
522
        return 0;
 
523
}
 
524
 
 
525
static struct ip_set_type hash_netport_type __read_mostly = {
 
526
        .name           = "hash:net,port",
 
527
        .protocol       = IPSET_PROTOCOL,
 
528
        .features       = IPSET_TYPE_IP | IPSET_TYPE_PORT,
 
529
        .dimension      = IPSET_DIM_TWO,
 
530
        .family         = AF_UNSPEC,
 
531
        .revision       = 1,
 
532
        .create         = hash_netport_create,
 
533
        .create_policy  = {
 
534
                [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
 
535
                [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
 
536
                [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
 
537
                [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
 
538
                [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
 
539
                [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
 
540
        },
 
541
        .adt_policy     = {
 
542
                [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
 
543
                [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
 
544
                [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
 
545
                [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
 
546
                [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
 
547
                [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
 
548
                [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
 
549
        },
 
550
        .me             = THIS_MODULE,
 
551
};
 
552
 
 
553
static int __init
 
554
hash_netport_init(void)
 
555
{
 
556
        return ip_set_type_register(&hash_netport_type);
 
557
}
 
558
 
 
559
static void __exit
 
560
hash_netport_fini(void)
 
561
{
 
562
        ip_set_type_unregister(&hash_netport_type);
 
563
}
 
564
 
 
565
module_init(hash_netport_init);
 
566
module_exit(hash_netport_fini);