1 /* Copyright 2007-2013 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
2 * Copyright 2013 Smoothwall Ltd. (vytas.dauksa@smoothwall.net)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 #include <libipset/data.h> /* IPSET_OPT_* */
9 #include <libipset/parse.h> /* parser functions */
10 #include <libipset/print.h> /* printing functions */
11 #include <libipset/types.h> /* prototypes */
13 /* Parse commandline arguments */
14 static const struct ipset_arg hash_ipmark_create_args0[] = {
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 = { "markmask", NULL },
30 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MARKMASK,
31 .parse = ipset_parse_uint32, .print = ipset_print_mark,
33 { .name = { "hashsize", NULL },
34 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
35 .parse = ipset_parse_uint32, .print = ipset_print_number,
37 { .name = { "maxelem", NULL },
38 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
39 .parse = ipset_parse_uint32, .print = ipset_print_number,
41 { .name = { "timeout", NULL },
42 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
43 .parse = ipset_parse_timeout, .print = ipset_print_number,
45 { .name = { "counters", NULL },
46 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS,
47 .parse = ipset_parse_flag, .print = ipset_print_flag,
49 { .name = { "comment", NULL },
50 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_CREATE_COMMENT,
51 .parse = ipset_parse_flag, .print = ipset_print_flag,
53 /* Backward compatibility */
54 { .name = { "probes", NULL },
55 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
56 .parse = ipset_parse_ignored, .print = ipset_print_number,
58 { .name = { "resize", NULL },
59 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE,
60 .parse = ipset_parse_ignored, .print = ipset_print_number,
62 { .name = { "from", NULL },
63 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
64 .parse = ipset_parse_ignored,
66 { .name = { "to", NULL },
67 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO,
68 .parse = ipset_parse_ignored,
70 { .name = { "network", NULL },
71 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
72 .parse = ipset_parse_ignored,
77 static const struct ipset_arg hash_ipmark_add_args0[] = {
78 { .name = { "timeout", NULL },
79 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
80 .parse = ipset_parse_timeout, .print = ipset_print_number,
82 { .name = { "packets", NULL },
83 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS,
84 .parse = ipset_parse_uint64, .print = ipset_print_number,
86 { .name = { "bytes", NULL },
87 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES,
88 .parse = ipset_parse_uint64, .print = ipset_print_number,
90 { .name = { "comment", NULL },
91 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_ADT_COMMENT,
92 .parse = ipset_parse_comment, .print = ipset_print_comment,
97 static const char hash_ipmark_usage0[] =
98 "create SETNAME hash:ip,mark\n"
99 " [family inet|inet6] [markmask VALUE]\n"
100 " [hashsize VALUE] [maxelem VALUE]\n"
101 " [timeout VALUE] [counters] [comment]\n"
102 "add SETNAME IP,MARK [timeout VALUE]\n"
103 " [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
104 "del SETNAME IP,MARK\n"
105 "test SETNAME IP,MARK\n\n"
106 "where depending on the INET family\n"
107 " IP is a valid IPv4 or IPv6 address (or hostname).\n"
108 " Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
109 " is supported for IPv4.\n"
110 " Adding/deleting single mark element\n"
111 " is supported both for IPv4 and IPv6.\n";
113 static struct ipset_type ipset_hash_ipmark0 = {
114 .name = "hash:ip,mark",
115 .alias = { "ipmarkhash", NULL },
117 .family = NFPROTO_IPSET_IPV46,
118 .dimension = IPSET_DIM_TWO,
120 [IPSET_DIM_ONE - 1] = {
121 .parse = ipset_parse_ip4_single6,
122 .print = ipset_print_ip,
125 [IPSET_DIM_TWO - 1] = {
126 .parse = ipset_parse_mark,
127 .print = ipset_print_mark,
128 .opt = IPSET_OPT_MARK
132 [IPSET_CREATE] = hash_ipmark_create_args0,
133 [IPSET_ADD] = hash_ipmark_add_args0,
137 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
138 | IPSET_FLAG(IPSET_OPT_MARK),
139 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
140 | IPSET_FLAG(IPSET_OPT_MARK),
141 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
142 | IPSET_FLAG(IPSET_OPT_MARK),
145 [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_MARKMASK)
146 | IPSET_FLAG(IPSET_OPT_HASHSIZE)
147 | IPSET_FLAG(IPSET_OPT_MAXELEM)
148 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
149 | IPSET_FLAG(IPSET_OPT_COUNTERS)
150 | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT),
151 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
152 | IPSET_FLAG(IPSET_OPT_IP_TO)
153 | IPSET_FLAG(IPSET_OPT_MARK)
154 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
155 | IPSET_FLAG(IPSET_OPT_PACKETS)
156 | IPSET_FLAG(IPSET_OPT_BYTES)
157 | IPSET_FLAG(IPSET_OPT_ADT_COMMENT),
158 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
159 | IPSET_FLAG(IPSET_OPT_IP_TO)
160 | IPSET_FLAG(IPSET_OPT_MARK),
161 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
162 | IPSET_FLAG(IPSET_OPT_MARK),
165 .usage = hash_ipmark_usage0,
166 .description = "initial revision",
169 static const struct ipset_arg hash_ipmark_create_args1[] = {
170 { .name = { "family", NULL },
171 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY,
172 .parse = ipset_parse_family, .print = ipset_print_family,
174 /* Alias: family inet */
175 { .name = { "-4", NULL },
176 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
177 .parse = ipset_parse_family,
179 /* Alias: family inet6 */
180 { .name = { "-6", NULL },
181 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
182 .parse = ipset_parse_family,
184 { .name = { "markmask", NULL },
185 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MARKMASK,
186 .parse = ipset_parse_uint32, .print = ipset_print_mark,
188 { .name = { "hashsize", NULL },
189 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
190 .parse = ipset_parse_uint32, .print = ipset_print_number,
192 { .name = { "maxelem", NULL },
193 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
194 .parse = ipset_parse_uint32, .print = ipset_print_number,
196 { .name = { "timeout", NULL },
197 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
198 .parse = ipset_parse_timeout, .print = ipset_print_number,
200 { .name = { "counters", NULL },
201 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS,
202 .parse = ipset_parse_flag, .print = ipset_print_flag,
204 { .name = { "comment", NULL },
205 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_CREATE_COMMENT,
206 .parse = ipset_parse_flag, .print = ipset_print_flag,
208 { .name = { "forceadd", NULL },
209 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FORCEADD,
210 .parse = ipset_parse_flag, .print = ipset_print_flag,
212 /* Backward compatibility */
213 { .name = { "probes", NULL },
214 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
215 .parse = ipset_parse_ignored, .print = ipset_print_number,
217 { .name = { "resize", NULL },
218 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE,
219 .parse = ipset_parse_ignored, .print = ipset_print_number,
221 { .name = { "from", NULL },
222 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
223 .parse = ipset_parse_ignored,
225 { .name = { "to", NULL },
226 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO,
227 .parse = ipset_parse_ignored,
229 { .name = { "network", NULL },
230 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
231 .parse = ipset_parse_ignored,
236 static const char hash_ipmark_usage1[] =
237 "create SETNAME hash:ip,mark\n"
238 " [family inet|inet6] [markmask VALUE]\n"
239 " [hashsize VALUE] [maxelem VALUE]\n"
240 " [timeout VALUE] [counters] [comment]\n"
242 "add SETNAME IP,MARK [timeout VALUE]\n"
243 " [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
244 "del SETNAME IP,MARK\n"
245 "test SETNAME IP,MARK\n\n"
246 "where depending on the INET family\n"
247 " IP is a valid IPv4 or IPv6 address (or hostname).\n"
248 " Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
249 " is supported for IPv4.\n"
250 " Adding/deleting single mark element\n"
251 " is supported both for IPv4 and IPv6.\n";
253 static struct ipset_type ipset_hash_ipmark1 = {
254 .name = "hash:ip,mark",
255 .alias = { "ipmarkhash", NULL },
257 .family = NFPROTO_IPSET_IPV46,
258 .dimension = IPSET_DIM_TWO,
260 [IPSET_DIM_ONE - 1] = {
261 .parse = ipset_parse_ip4_single6,
262 .print = ipset_print_ip,
265 [IPSET_DIM_TWO - 1] = {
266 .parse = ipset_parse_mark,
267 .print = ipset_print_mark,
268 .opt = IPSET_OPT_MARK
272 [IPSET_CREATE] = hash_ipmark_create_args1,
273 [IPSET_ADD] = hash_ipmark_add_args0,
277 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
278 | IPSET_FLAG(IPSET_OPT_MARK),
279 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
280 | IPSET_FLAG(IPSET_OPT_MARK),
281 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
282 | IPSET_FLAG(IPSET_OPT_MARK),
285 [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_MARKMASK)
286 | IPSET_FLAG(IPSET_OPT_HASHSIZE)
287 | IPSET_FLAG(IPSET_OPT_MAXELEM)
288 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
289 | IPSET_FLAG(IPSET_OPT_COUNTERS)
290 | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
291 | IPSET_FLAG(IPSET_OPT_FORCEADD),
292 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
293 | IPSET_FLAG(IPSET_OPT_IP_TO)
294 | IPSET_FLAG(IPSET_OPT_MARK)
295 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
296 | IPSET_FLAG(IPSET_OPT_PACKETS)
297 | IPSET_FLAG(IPSET_OPT_BYTES)
298 | IPSET_FLAG(IPSET_OPT_ADT_COMMENT),
299 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
300 | IPSET_FLAG(IPSET_OPT_IP_TO)
301 | IPSET_FLAG(IPSET_OPT_MARK),
302 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
303 | IPSET_FLAG(IPSET_OPT_MARK),
306 .usage = hash_ipmark_usage1,
307 .description = "forceadd support"
310 static const struct ipset_arg hash_ipmark_create_args2[] = {
311 { .name = { "family", NULL },
312 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY,
313 .parse = ipset_parse_family, .print = ipset_print_family,
315 /* Alias: family inet */
316 { .name = { "-4", NULL },
317 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
318 .parse = ipset_parse_family,
320 /* Alias: family inet6 */
321 { .name = { "-6", NULL },
322 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
323 .parse = ipset_parse_family,
325 { .name = { "markmask", NULL },
326 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MARKMASK,
327 .parse = ipset_parse_uint32, .print = ipset_print_mark,
329 { .name = { "hashsize", NULL },
330 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
331 .parse = ipset_parse_uint32, .print = ipset_print_number,
333 { .name = { "maxelem", NULL },
334 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
335 .parse = ipset_parse_uint32, .print = ipset_print_number,
337 { .name = { "timeout", NULL },
338 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
339 .parse = ipset_parse_timeout, .print = ipset_print_number,
341 { .name = { "counters", NULL },
342 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS,
343 .parse = ipset_parse_flag, .print = ipset_print_flag,
345 { .name = { "comment", NULL },
346 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_CREATE_COMMENT,
347 .parse = ipset_parse_flag, .print = ipset_print_flag,
349 { .name = { "forceadd", NULL },
350 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FORCEADD,
351 .parse = ipset_parse_flag, .print = ipset_print_flag,
353 { .name = { "skbinfo", NULL },
354 .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_SKBINFO,
355 .parse = ipset_parse_flag, .print = ipset_print_flag,
357 /* Backward compatibility */
358 { .name = { "probes", NULL },
359 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
360 .parse = ipset_parse_ignored, .print = ipset_print_number,
362 { .name = { "resize", NULL },
363 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE,
364 .parse = ipset_parse_ignored, .print = ipset_print_number,
366 { .name = { "from", NULL },
367 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
368 .parse = ipset_parse_ignored,
370 { .name = { "to", NULL },
371 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO,
372 .parse = ipset_parse_ignored,
374 { .name = { "network", NULL },
375 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
376 .parse = ipset_parse_ignored,
381 static const struct ipset_arg hash_ipmark_add_args2[] = {
382 { .name = { "timeout", NULL },
383 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
384 .parse = ipset_parse_timeout, .print = ipset_print_number,
386 { .name = { "packets", NULL },
387 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS,
388 .parse = ipset_parse_uint64, .print = ipset_print_number,
390 { .name = { "bytes", NULL },
391 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES,
392 .parse = ipset_parse_uint64, .print = ipset_print_number,
394 { .name = { "comment", NULL },
395 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_ADT_COMMENT,
396 .parse = ipset_parse_comment, .print = ipset_print_comment,
398 { .name = { "skbmark", NULL },
399 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBMARK,
400 .parse = ipset_parse_skbmark, .print = ipset_print_skbmark,
402 { .name = { "skbprio", NULL },
403 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBPRIO,
404 .parse = ipset_parse_skbprio, .print = ipset_print_skbprio,
406 { .name = { "skbqueue", NULL },
407 .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBQUEUE,
408 .parse = ipset_parse_uint16, .print = ipset_print_number,
414 static const char hash_ipmark_usage2[] =
415 "create SETNAME hash:ip,mark\n"
416 " [family inet|inet6] [markmask VALUE]\n"
417 " [hashsize VALUE] [maxelem VALUE]\n"
418 " [timeout VALUE] [counters] [comment]\n"
419 " [forceadd] [skbinfo]\n"
420 "add SETNAME IP,MARK [timeout VALUE]\n"
421 " [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
422 " [skbmark VALUE] [skbprio VALUE] [skbqueue VALUE]\n"
423 "del SETNAME IP,MARK\n"
424 "test SETNAME IP,MARK\n\n"
425 "where depending on the INET family\n"
426 " IP is a valid IPv4 or IPv6 address (or hostname).\n"
427 " Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
428 " is supported for IPv4.\n"
429 " Adding/deleting single mark element\n"
430 " is supported both for IPv4 and IPv6.\n";
432 static struct ipset_type ipset_hash_ipmark2 = {
433 .name = "hash:ip,mark",
434 .alias = { "ipmarkhash", NULL },
436 .family = NFPROTO_IPSET_IPV46,
437 .dimension = IPSET_DIM_TWO,
439 [IPSET_DIM_ONE - 1] = {
440 .parse = ipset_parse_ip4_single6,
441 .print = ipset_print_ip,
444 [IPSET_DIM_TWO - 1] = {
445 .parse = ipset_parse_mark,
446 .print = ipset_print_mark,
447 .opt = IPSET_OPT_MARK
451 [IPSET_CREATE] = hash_ipmark_create_args2,
452 [IPSET_ADD] = hash_ipmark_add_args2,
456 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
457 | IPSET_FLAG(IPSET_OPT_MARK),
458 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
459 | IPSET_FLAG(IPSET_OPT_MARK),
460 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
461 | IPSET_FLAG(IPSET_OPT_MARK),
464 [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_MARKMASK)
465 | IPSET_FLAG(IPSET_OPT_HASHSIZE)
466 | IPSET_FLAG(IPSET_OPT_MAXELEM)
467 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
468 | IPSET_FLAG(IPSET_OPT_COUNTERS)
469 | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
470 | IPSET_FLAG(IPSET_OPT_FORCEADD)
471 | IPSET_FLAG(IPSET_OPT_SKBINFO),
472 [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
473 | IPSET_FLAG(IPSET_OPT_IP_TO)
474 | IPSET_FLAG(IPSET_OPT_MARK)
475 | IPSET_FLAG(IPSET_OPT_TIMEOUT)
476 | IPSET_FLAG(IPSET_OPT_PACKETS)
477 | IPSET_FLAG(IPSET_OPT_BYTES)
478 | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
479 | IPSET_FLAG(IPSET_OPT_SKBMARK)
480 | IPSET_FLAG(IPSET_OPT_SKBPRIO)
481 | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
482 [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
483 | IPSET_FLAG(IPSET_OPT_IP_TO)
484 | IPSET_FLAG(IPSET_OPT_MARK),
485 [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
486 | IPSET_FLAG(IPSET_OPT_MARK),
489 .usage = hash_ipmark_usage2,
490 .description = "sbkinfo support"
496 ipset_type_add(&ipset_hash_ipmark0);
497 ipset_type_add(&ipset_hash_ipmark1);
498 ipset_type_add(&ipset_hash_ipmark2);