1 /* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
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.
7 #include <libipset/data.h> /* IPSET_OPT_* */
8 #include <libipset/parse.h> /* parser functions */
9 #include <libipset/print.h> /* printing functions */
10 #include <libipset/ui.h> /* ipset_port_usage */
11 #include <libipset/types.h> /* prototypes */
13 /* Parse commandline arguments */
14 static const struct ipset_arg hash_ipport_create_args1[] = {
15 { .name = { "family", NULL },
16 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY,
17 .parse = ipset_parse_family, .print = ipset_print_family,
19 /* Alias: family inet */
20 { .name = { "-4", NULL },
21 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
22 .parse = ipset_parse_family,
24 /* Alias: family inet6 */
25 { .name = { "-6", NULL },
26 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
27 .parse = ipset_parse_family,
29 { .name = { "hashsize", NULL },
30 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
31 .parse = ipset_parse_uint32, .print = ipset_print_number,
33 { .name = { "maxelem", NULL },
34 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
35 .parse = ipset_parse_uint32, .print = ipset_print_number,
37 { .name = { "timeout", NULL },
38 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
39 .parse = ipset_parse_timeout, .print = ipset_print_number,
41 /* Backward compatibility */
42 { .name = { "probes", NULL },
43 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
44 .parse = ipset_parse_ignored, .print = ipset_print_number,
46 { .name = { "resize", NULL },
47 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE,
48 .parse = ipset_parse_ignored, .print = ipset_print_number,
50 { .name = { "from", NULL },
51 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
52 .parse = ipset_parse_ignored,
54 { .name = { "to", NULL },
55 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO,
56 .parse = ipset_parse_ignored,
58 { .name = { "network", NULL },
59 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
60 .parse = ipset_parse_ignored,
65 static const struct ipset_arg hash_ipport_add_args1[] = {
66 { .name = { "timeout", NULL },
67 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
68 .parse = ipset_parse_timeout, .print = ipset_print_number,
73 static const char hash_ipport_usage1[] =
74 "create SETNAME hash:ip,port\n"
75 " [family inet|inet6]\n"
76 " [hashsize VALUE] [maxelem VALUE]\n"
78 "add SETNAME IP,PROTO:PORT [timeout VALUE]\n"
79 "del SETNAME IP,PROTO:PORT\n"
80 "test SETNAME IP,PROTO:PORT\n\n"
81 "where depending on the INET family\n"
82 " IP is a valid IPv4 or IPv6 address (or hostname).\n"
83 " Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
84 " is supported for IPv4.\n"
85 " Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
86 " port range is supported both for IPv4 and IPv6.\n";
88 static struct ipset_type ipset_hash_ipport1 = {
89 .name = "hash:ip,port",
90 .alias = { "ipporthash", NULL },
92 .family = NFPROTO_IPSET_IPV46,
93 .dimension = IPSET_DIM_TWO,
95 [IPSET_DIM_ONE - 1] = {
96 .parse = ipset_parse_ip4_single6,
97 .print = ipset_print_ip,
100 [IPSET_DIM_TWO - 1] = {
101 .parse = ipset_parse_proto_port,
102 .print = ipset_print_proto_port,
103 .opt = IPSET_OPT_PORT
107 [IPSET_CREATE] = hash_ipport_create_args1,
108 [IPSET_ADD] = hash_ipport_add_args1,
112 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
113 | IPSET_FLAG(IPSET_OPT_PROTO)
114 | IPSET_FLAG(IPSET_OPT_PORT),
115 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
116 | IPSET_FLAG(IPSET_OPT_PROTO)
117 | IPSET_FLAG(IPSET_OPT_PORT),
118 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
119 | IPSET_FLAG(IPSET_OPT_PROTO)
120 | IPSET_FLAG(IPSET_OPT_PORT),
123 [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
124 | IPSET_FLAG(IPSET_OPT_MAXELEM)
125 | IPSET_FLAG(IPSET_OPT_TIMEOUT),
126 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
127 | IPSET_FLAG(IPSET_OPT_IP_TO)
128 | IPSET_FLAG(IPSET_OPT_PORT)
129 | IPSET_FLAG(IPSET_OPT_PORT_TO)
130 | IPSET_FLAG(IPSET_OPT_PROTO)
131 | IPSET_FLAG(IPSET_OPT_TIMEOUT),
132 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
133 | IPSET_FLAG(IPSET_OPT_IP_TO)
134 | IPSET_FLAG(IPSET_OPT_PORT)
135 | IPSET_FLAG(IPSET_OPT_PORT_TO)
136 | IPSET_FLAG(IPSET_OPT_PROTO),
137 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
138 | IPSET_FLAG(IPSET_OPT_PORT)
139 | IPSET_FLAG(IPSET_OPT_PROTO),
142 .usage = hash_ipport_usage1,
143 .usagefn = ipset_port_usage,
144 .description = "SCTP and UDPLITE support",
147 /* Parse commandline arguments */
148 static const struct ipset_arg hash_ipport_create_args2[] = {
149 { .name = { "family", NULL },
150 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY,
151 .parse = ipset_parse_family, .print = ipset_print_family,
153 /* Alias: family inet */
154 { .name = { "-4", NULL },
155 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
156 .parse = ipset_parse_family,
158 /* Alias: family inet6 */
159 { .name = { "-6", NULL },
160 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
161 .parse = ipset_parse_family,
163 { .name = { "hashsize", NULL },
164 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
165 .parse = ipset_parse_uint32, .print = ipset_print_number,
167 { .name = { "maxelem", NULL },
168 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
169 .parse = ipset_parse_uint32, .print = ipset_print_number,
171 { .name = { "timeout", NULL },
172 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
173 .parse = ipset_parse_timeout, .print = ipset_print_number,
175 { .name = { "counters", NULL },
176 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS,
177 .parse = ipset_parse_flag, .print = ipset_print_flag,
179 /* Backward compatibility */
180 { .name = { "probes", NULL },
181 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
182 .parse = ipset_parse_ignored, .print = ipset_print_number,
184 { .name = { "resize", NULL },
185 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE,
186 .parse = ipset_parse_ignored, .print = ipset_print_number,
188 { .name = { "from", NULL },
189 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
190 .parse = ipset_parse_ignored,
192 { .name = { "to", NULL },
193 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO,
194 .parse = ipset_parse_ignored,
196 { .name = { "network", NULL },
197 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
198 .parse = ipset_parse_ignored,
203 static const struct ipset_arg hash_ipport_add_args2[] = {
204 { .name = { "timeout", NULL },
205 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
206 .parse = ipset_parse_timeout, .print = ipset_print_number,
208 { .name = { "packets", NULL },
209 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS,
210 .parse = ipset_parse_uint64, .print = ipset_print_number,
212 { .name = { "bytes", NULL },
213 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES,
214 .parse = ipset_parse_uint64, .print = ipset_print_number,
219 static const char hash_ipport_usage2[] =
220 "create SETNAME hash:ip,port\n"
221 " [family inet|inet6]\n"
222 " [hashsize VALUE] [maxelem VALUE]\n"
223 " [timeout VALUE] [counters]\n"
224 "add SETNAME IP,PROTO:PORT [timeout VALUE]\n"
225 " [packets VALUE] [bytes VALUE]\n"
226 "del SETNAME IP,PROTO:PORT\n"
227 "test SETNAME IP,PROTO:PORT\n\n"
228 "where depending on the INET family\n"
229 " IP is a valid IPv4 or IPv6 address (or hostname).\n"
230 " Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
231 " is supported for IPv4.\n"
232 " Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
233 " port range is supported both for IPv4 and IPv6.\n";
235 static struct ipset_type ipset_hash_ipport2 = {
236 .name = "hash:ip,port",
237 .alias = { "ipporthash", NULL },
239 .family = NFPROTO_IPSET_IPV46,
240 .dimension = IPSET_DIM_TWO,
242 [IPSET_DIM_ONE - 1] = {
243 .parse = ipset_parse_ip4_single6,
244 .print = ipset_print_ip,
247 [IPSET_DIM_TWO - 1] = {
248 .parse = ipset_parse_proto_port,
249 .print = ipset_print_proto_port,
250 .opt = IPSET_OPT_PORT
254 [IPSET_CREATE] = hash_ipport_create_args2,
255 [IPSET_ADD] = hash_ipport_add_args2,
259 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
260 | IPSET_FLAG(IPSET_OPT_PROTO)
261 | IPSET_FLAG(IPSET_OPT_PORT),
262 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
263 | IPSET_FLAG(IPSET_OPT_PROTO)
264 | IPSET_FLAG(IPSET_OPT_PORT),
265 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
266 | IPSET_FLAG(IPSET_OPT_PROTO)
267 | IPSET_FLAG(IPSET_OPT_PORT),
270 [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
271 | IPSET_FLAG(IPSET_OPT_MAXELEM)
272 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
273 | IPSET_FLAG(IPSET_OPT_COUNTERS),
274 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
275 | IPSET_FLAG(IPSET_OPT_IP_TO)
276 | IPSET_FLAG(IPSET_OPT_PORT)
277 | IPSET_FLAG(IPSET_OPT_PORT_TO)
278 | IPSET_FLAG(IPSET_OPT_PROTO)
279 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
280 | IPSET_FLAG(IPSET_OPT_PACKETS)
281 | IPSET_FLAG(IPSET_OPT_BYTES),
282 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
283 | IPSET_FLAG(IPSET_OPT_IP_TO)
284 | IPSET_FLAG(IPSET_OPT_PORT)
285 | IPSET_FLAG(IPSET_OPT_PORT_TO)
286 | IPSET_FLAG(IPSET_OPT_PROTO),
287 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
288 | IPSET_FLAG(IPSET_OPT_PORT)
289 | IPSET_FLAG(IPSET_OPT_PROTO),
292 .usage = hash_ipport_usage2,
293 .usagefn = ipset_port_usage,
294 .description = "counters support",
297 /* Parse commandline arguments */
298 static const struct ipset_arg hash_ipport_create_args3[] = {
299 { .name = { "family", NULL },
300 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY,
301 .parse = ipset_parse_family, .print = ipset_print_family,
303 /* Alias: family inet */
304 { .name = { "-4", NULL },
305 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
306 .parse = ipset_parse_family,
308 /* Alias: family inet6 */
309 { .name = { "-6", NULL },
310 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
311 .parse = ipset_parse_family,
313 { .name = { "hashsize", NULL },
314 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
315 .parse = ipset_parse_uint32, .print = ipset_print_number,
317 { .name = { "maxelem", NULL },
318 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
319 .parse = ipset_parse_uint32, .print = ipset_print_number,
321 { .name = { "timeout", NULL },
322 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
323 .parse = ipset_parse_timeout, .print = ipset_print_number,
325 { .name = { "counters", NULL },
326 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS,
327 .parse = ipset_parse_flag, .print = ipset_print_flag,
329 { .name = { "comment", NULL },
330 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_CREATE_COMMENT,
331 .parse = ipset_parse_flag, .print = ipset_print_flag,
333 /* Backward compatibility */
334 { .name = { "probes", NULL },
335 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
336 .parse = ipset_parse_ignored, .print = ipset_print_number,
338 { .name = { "resize", NULL },
339 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE,
340 .parse = ipset_parse_ignored, .print = ipset_print_number,
342 { .name = { "from", NULL },
343 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
344 .parse = ipset_parse_ignored,
346 { .name = { "to", NULL },
347 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO,
348 .parse = ipset_parse_ignored,
350 { .name = { "network", NULL },
351 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
352 .parse = ipset_parse_ignored,
357 static const struct ipset_arg hash_ipport_add_args3[] = {
358 { .name = { "timeout", NULL },
359 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
360 .parse = ipset_parse_timeout, .print = ipset_print_number,
362 { .name = { "packets", NULL },
363 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS,
364 .parse = ipset_parse_uint64, .print = ipset_print_number,
366 { .name = { "bytes", NULL },
367 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES,
368 .parse = ipset_parse_uint64, .print = ipset_print_number,
370 { .name = { "comment", NULL },
371 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_ADT_COMMENT,
372 .parse = ipset_parse_comment, .print = ipset_print_comment,
377 static const char hash_ipport_usage3[] =
378 "create SETNAME hash:ip,port\n"
379 " [family inet|inet6]\n"
380 " [hashsize VALUE] [maxelem VALUE]\n"
381 " [timeout VALUE] [counters] [comment]\n"
382 "add SETNAME IP,PROTO:PORT [timeout VALUE]\n"
383 " [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
384 "del SETNAME IP,PROTO:PORT\n"
385 "test SETNAME IP,PROTO:PORT\n\n"
386 "where depending on the INET family\n"
387 " IP is a valid IPv4 or IPv6 address (or hostname).\n"
388 " Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
389 " is supported for IPv4.\n"
390 " Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
391 " port range is supported both for IPv4 and IPv6.\n";
393 static struct ipset_type ipset_hash_ipport3 = {
394 .name = "hash:ip,port",
395 .alias = { "ipporthash", NULL },
397 .family = NFPROTO_IPSET_IPV46,
398 .dimension = IPSET_DIM_TWO,
400 [IPSET_DIM_ONE - 1] = {
401 .parse = ipset_parse_ip4_single6,
402 .print = ipset_print_ip,
405 [IPSET_DIM_TWO - 1] = {
406 .parse = ipset_parse_proto_port,
407 .print = ipset_print_proto_port,
408 .opt = IPSET_OPT_PORT
412 [IPSET_CREATE] = hash_ipport_create_args3,
413 [IPSET_ADD] = hash_ipport_add_args3,
417 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
418 | IPSET_FLAG(IPSET_OPT_PROTO)
419 | IPSET_FLAG(IPSET_OPT_PORT),
420 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
421 | IPSET_FLAG(IPSET_OPT_PROTO)
422 | IPSET_FLAG(IPSET_OPT_PORT),
423 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
424 | IPSET_FLAG(IPSET_OPT_PROTO)
425 | IPSET_FLAG(IPSET_OPT_PORT),
428 [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
429 | IPSET_FLAG(IPSET_OPT_MAXELEM)
430 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
431 | IPSET_FLAG(IPSET_OPT_COUNTERS)
432 | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT),
433 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
434 | IPSET_FLAG(IPSET_OPT_IP_TO)
435 | IPSET_FLAG(IPSET_OPT_PORT)
436 | IPSET_FLAG(IPSET_OPT_PORT_TO)
437 | IPSET_FLAG(IPSET_OPT_PROTO)
438 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
439 | IPSET_FLAG(IPSET_OPT_PACKETS)
440 | IPSET_FLAG(IPSET_OPT_BYTES)
441 | IPSET_FLAG(IPSET_OPT_ADT_COMMENT),
442 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
443 | IPSET_FLAG(IPSET_OPT_IP_TO)
444 | IPSET_FLAG(IPSET_OPT_PORT)
445 | IPSET_FLAG(IPSET_OPT_PORT_TO)
446 | IPSET_FLAG(IPSET_OPT_PROTO),
447 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
448 | IPSET_FLAG(IPSET_OPT_PORT)
449 | IPSET_FLAG(IPSET_OPT_PROTO),
452 .usage = hash_ipport_usage3,
453 .usagefn = ipset_port_usage,
454 .description = "comment support",
457 /* Parse commandline arguments */
458 static const struct ipset_arg hash_ipport_create_args4[] = {
459 { .name = { "family", NULL },
460 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY,
461 .parse = ipset_parse_family, .print = ipset_print_family,
463 /* Alias: family inet */
464 { .name = { "-4", NULL },
465 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
466 .parse = ipset_parse_family,
468 /* Alias: family inet6 */
469 { .name = { "-6", NULL },
470 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
471 .parse = ipset_parse_family,
473 { .name = { "hashsize", NULL },
474 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
475 .parse = ipset_parse_uint32, .print = ipset_print_number,
477 { .name = { "maxelem", NULL },
478 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
479 .parse = ipset_parse_uint32, .print = ipset_print_number,
481 { .name = { "timeout", NULL },
482 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
483 .parse = ipset_parse_timeout, .print = ipset_print_number,
485 { .name = { "counters", NULL },
486 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS,
487 .parse = ipset_parse_flag, .print = ipset_print_flag,
489 { .name = { "comment", NULL },
490 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_CREATE_COMMENT,
491 .parse = ipset_parse_flag, .print = ipset_print_flag,
493 { .name = { "forceadd", NULL },
494 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FORCEADD,
495 .parse = ipset_parse_flag, .print = ipset_print_flag,
497 /* Backward compatibility */
498 { .name = { "probes", NULL },
499 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
500 .parse = ipset_parse_ignored, .print = ipset_print_number,
502 { .name = { "resize", NULL },
503 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE,
504 .parse = ipset_parse_ignored, .print = ipset_print_number,
506 { .name = { "from", NULL },
507 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
508 .parse = ipset_parse_ignored,
510 { .name = { "to", NULL },
511 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO,
512 .parse = ipset_parse_ignored,
514 { .name = { "network", NULL },
515 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
516 .parse = ipset_parse_ignored,
521 static const char hash_ipport_usage4[] =
522 "create SETNAME hash:ip,port\n"
523 " [family inet|inet6]\n"
524 " [hashsize VALUE] [maxelem VALUE]\n"
525 " [timeout VALUE] [counters] [comment]\n"
527 "add SETNAME IP,PROTO:PORT [timeout VALUE]\n"
528 " [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
529 "del SETNAME IP,PROTO:PORT\n"
530 "test SETNAME IP,PROTO:PORT\n\n"
531 "where depending on the INET family\n"
532 " IP is a valid IPv4 or IPv6 address (or hostname).\n"
533 " Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
534 " is supported for IPv4.\n"
535 " Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
536 " port range is supported both for IPv4 and IPv6.\n";
538 static struct ipset_type ipset_hash_ipport4 = {
539 .name = "hash:ip,port",
540 .alias = { "ipporthash", NULL },
542 .family = NFPROTO_IPSET_IPV46,
543 .dimension = IPSET_DIM_TWO,
545 [IPSET_DIM_ONE - 1] = {
546 .parse = ipset_parse_ip4_single6,
547 .print = ipset_print_ip,
550 [IPSET_DIM_TWO - 1] = {
551 .parse = ipset_parse_proto_port,
552 .print = ipset_print_proto_port,
553 .opt = IPSET_OPT_PORT
557 [IPSET_CREATE] = hash_ipport_create_args4,
558 [IPSET_ADD] = hash_ipport_add_args3,
562 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
563 | IPSET_FLAG(IPSET_OPT_PROTO)
564 | IPSET_FLAG(IPSET_OPT_PORT),
565 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
566 | IPSET_FLAG(IPSET_OPT_PROTO)
567 | IPSET_FLAG(IPSET_OPT_PORT),
568 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
569 | IPSET_FLAG(IPSET_OPT_PROTO)
570 | IPSET_FLAG(IPSET_OPT_PORT),
573 [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
574 | IPSET_FLAG(IPSET_OPT_MAXELEM)
575 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
576 | IPSET_FLAG(IPSET_OPT_COUNTERS)
577 | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
578 | IPSET_FLAG(IPSET_OPT_FORCEADD),
579 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
580 | IPSET_FLAG(IPSET_OPT_IP_TO)
581 | IPSET_FLAG(IPSET_OPT_PORT)
582 | IPSET_FLAG(IPSET_OPT_PORT_TO)
583 | IPSET_FLAG(IPSET_OPT_PROTO)
584 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
585 | IPSET_FLAG(IPSET_OPT_PACKETS)
586 | IPSET_FLAG(IPSET_OPT_BYTES)
587 | IPSET_FLAG(IPSET_OPT_ADT_COMMENT),
588 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
589 | IPSET_FLAG(IPSET_OPT_IP_TO)
590 | IPSET_FLAG(IPSET_OPT_PORT)
591 | IPSET_FLAG(IPSET_OPT_PORT_TO)
592 | IPSET_FLAG(IPSET_OPT_PROTO),
593 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
594 | IPSET_FLAG(IPSET_OPT_PORT)
595 | IPSET_FLAG(IPSET_OPT_PROTO),
598 .usage = hash_ipport_usage4,
599 .usagefn = ipset_port_usage,
600 .description = "forceadd support",
603 /* Parse commandline arguments */
604 static const struct ipset_arg hash_ipport_create_args5[] = {
605 { .name = { "family", NULL },
606 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY,
607 .parse = ipset_parse_family, .print = ipset_print_family,
609 /* Alias: family inet */
610 { .name = { "-4", NULL },
611 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
612 .parse = ipset_parse_family,
614 /* Alias: family inet6 */
615 { .name = { "-6", NULL },
616 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
617 .parse = ipset_parse_family,
619 { .name = { "hashsize", NULL },
620 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
621 .parse = ipset_parse_uint32, .print = ipset_print_number,
623 { .name = { "maxelem", NULL },
624 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
625 .parse = ipset_parse_uint32, .print = ipset_print_number,
627 { .name = { "timeout", NULL },
628 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
629 .parse = ipset_parse_timeout, .print = ipset_print_number,
631 { .name = { "counters", NULL },
632 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS,
633 .parse = ipset_parse_flag, .print = ipset_print_flag,
635 { .name = { "comment", NULL },
636 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_CREATE_COMMENT,
637 .parse = ipset_parse_flag, .print = ipset_print_flag,
639 { .name = { "forceadd", NULL },
640 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FORCEADD,
641 .parse = ipset_parse_flag, .print = ipset_print_flag,
643 { .name = { "skbinfo", NULL },
644 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_SKBINFO,
645 .parse = ipset_parse_flag, .print = ipset_print_flag,
647 /* Backward compatibility */
648 { .name = { "probes", NULL },
649 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
650 .parse = ipset_parse_ignored, .print = ipset_print_number,
652 { .name = { "resize", NULL },
653 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE,
654 .parse = ipset_parse_ignored, .print = ipset_print_number,
656 { .name = { "from", NULL },
657 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
658 .parse = ipset_parse_ignored,
660 { .name = { "to", NULL },
661 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO,
662 .parse = ipset_parse_ignored,
664 { .name = { "network", NULL },
665 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
666 .parse = ipset_parse_ignored,
671 static const struct ipset_arg hash_ipport_add_args5[] = {
672 { .name = { "timeout", NULL },
673 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
674 .parse = ipset_parse_timeout, .print = ipset_print_number,
676 { .name = { "packets", NULL },
677 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS,
678 .parse = ipset_parse_uint64, .print = ipset_print_number,
680 { .name = { "bytes", NULL },
681 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES,
682 .parse = ipset_parse_uint64, .print = ipset_print_number,
684 { .name = { "comment", NULL },
685 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_ADT_COMMENT,
686 .parse = ipset_parse_comment, .print = ipset_print_comment,
688 { .name = { "skbmark", NULL },
689 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBMARK,
690 .parse = ipset_parse_skbmark, .print = ipset_print_skbmark,
692 { .name = { "skbprio", NULL },
693 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBPRIO,
694 .parse = ipset_parse_skbprio, .print = ipset_print_skbprio,
696 { .name = { "skbqueue", NULL },
697 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBQUEUE,
698 .parse = ipset_parse_uint16, .print = ipset_print_number,
703 static const char hash_ipport_usage5[] =
704 "create SETNAME hash:ip,port\n"
705 " [family inet|inet6]\n"
706 " [hashsize VALUE] [maxelem VALUE]\n"
707 " [timeout VALUE] [counters] [comment]\n"
708 " [forceadd] [skbinfo]\n"
709 "add SETNAME IP,PROTO:PORT [timeout VALUE]\n"
710 " [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
711 " [skbmark VALUE] [skbprio VALUE] [skbqueue VALUE]\n"
712 "del SETNAME IP,PROTO:PORT\n"
713 "test SETNAME IP,PROTO:PORT\n\n"
714 "where depending on the INET family\n"
715 " IP is a valid IPv4 or IPv6 address (or hostname).\n"
716 " Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
717 " is supported for IPv4.\n"
718 " Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
719 " port range is supported both for IPv4 and IPv6.\n";
721 static struct ipset_type ipset_hash_ipport5 = {
722 .name = "hash:ip,port",
723 .alias = { "ipporthash", NULL },
725 .family = NFPROTO_IPSET_IPV46,
726 .dimension = IPSET_DIM_TWO,
728 [IPSET_DIM_ONE - 1] = {
729 .parse = ipset_parse_ip4_single6,
730 .print = ipset_print_ip,
733 [IPSET_DIM_TWO - 1] = {
734 .parse = ipset_parse_proto_port,
735 .print = ipset_print_proto_port,
736 .opt = IPSET_OPT_PORT
740 [IPSET_CREATE] = hash_ipport_create_args5,
741 [IPSET_ADD] = hash_ipport_add_args5,
745 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
746 | IPSET_FLAG(IPSET_OPT_PROTO)
747 | IPSET_FLAG(IPSET_OPT_PORT),
748 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
749 | IPSET_FLAG(IPSET_OPT_PROTO)
750 | IPSET_FLAG(IPSET_OPT_PORT),
751 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
752 | IPSET_FLAG(IPSET_OPT_PROTO)
753 | IPSET_FLAG(IPSET_OPT_PORT),
756 [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
757 | IPSET_FLAG(IPSET_OPT_MAXELEM)
758 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
759 | IPSET_FLAG(IPSET_OPT_COUNTERS)
760 | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
761 | IPSET_FLAG(IPSET_OPT_FORCEADD)
762 | IPSET_FLAG(IPSET_OPT_SKBINFO),
763 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
764 | IPSET_FLAG(IPSET_OPT_IP_TO)
765 | IPSET_FLAG(IPSET_OPT_PORT)
766 | IPSET_FLAG(IPSET_OPT_PORT_TO)
767 | IPSET_FLAG(IPSET_OPT_PROTO)
768 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
769 | IPSET_FLAG(IPSET_OPT_PACKETS)
770 | IPSET_FLAG(IPSET_OPT_BYTES)
771 | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
772 | IPSET_FLAG(IPSET_OPT_SKBMARK)
773 | IPSET_FLAG(IPSET_OPT_SKBPRIO)
774 | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
775 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
776 | IPSET_FLAG(IPSET_OPT_IP_TO)
777 | IPSET_FLAG(IPSET_OPT_PORT)
778 | IPSET_FLAG(IPSET_OPT_PORT_TO)
779 | IPSET_FLAG(IPSET_OPT_PROTO),
780 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
781 | IPSET_FLAG(IPSET_OPT_PORT)
782 | IPSET_FLAG(IPSET_OPT_PROTO),
785 .usage = hash_ipport_usage5,
786 .usagefn = ipset_port_usage,
787 .description = "skbinfo support",
793 ipset_type_add(&ipset_hash_ipport1);
794 ipset_type_add(&ipset_hash_ipport2);
795 ipset_type_add(&ipset_hash_ipport3);
796 ipset_type_add(&ipset_hash_ipport4);
797 ipset_type_add(&ipset_hash_ipport5);