From 020936c8c3375e1efe44a3087c891a4b2cbfe044 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Tue, 22 Jun 2010 10:49:41 +0200 Subject: ipset 5: last new feature added - the hash types can now store protocol together port, not only port - lots of fixes everywhere: parser, error reporting, manpage The last bits on the todo list before announcing ipset 5: - recheck all the error messages - add possibly more tests - polish manpage --- src/errcode.c | 6 ++- src/ipset.8 | 96 ++++++++++++++++++++++++++++++---------------- src/ipset.c | 31 +++++++++------ src/ipset_hash_ipport.c | 24 ++++++++---- src/ipset_hash_ipportip.c | 20 +++++++--- src/ipset_hash_ipportnet.c | 20 +++++++--- 6 files changed, 132 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/errcode.c b/src/errcode.c index c30ecb6..ae0d8c8 100644 --- a/src/errcode.c +++ b/src/errcode.c @@ -102,6 +102,10 @@ static const struct ipset_errcode_table hash_errcode_table[] = { "Hash is full, cannot add more elements" }, { IPSET_ERR_HASH_ELEM, 0, "Null-valued element, cannot be stored in a hash type of set" }, + { IPSET_ERR_INVALID_PROTO, 0, + "Invalid protocol specified" }, + { IPSET_ERR_MISSING_PROTO, 0, + "Protocol missing, but must be specified" }, { }, }; @@ -144,7 +148,7 @@ ipset_errcode(struct ipset_session *session, enum ipset_cmd cmd, int errcode) if (errcode >= IPSET_ERR_TYPE_SPECIFIC) { const struct ipset_type *type; - type = ipset_session_data_get(session, IPSET_OPT_TYPE); + type = ipset_saved_type(session); if (type) { if (MATCH_TYPENAME(type->name, "bitmap:")) table = bitmap_errcode_table; diff --git a/src/ipset.8 b/src/ipset.8 index 661d1b4..5b9e4ad 100644 --- a/src/ipset.8 +++ b/src/ipset.8 @@ -112,12 +112,12 @@ If the set has got reference(s), nothing is done and no set destroyed. \fBlist\fP [ \fISETNAME\fP ] List the header data and the entries for the specified set, or for all sets if none is given. The -\fB\-\-resolve\fP +\fB\-resolve\fP option can be used to force name lookups (which may be slow). When the -\fB\-\-sorted\fP +\fB\-sorted\fP option is given, the entries are listed sorted (if the given set type supports the operation). The option -\fB\-\-output\fR +\fB\-output\fR can be used to control the format of the listing: \fBplain\fR, \fBsave\fR or \fBxml\fR. The default is @@ -231,7 +231,7 @@ to 65536 entries. .PP \fIDEL\-ENTRY\fR := { \fIipaddr\fR | \fIfromaddr\fR\-\fItoaddr\fR | \fIipaddr\fR/\fIcidr\fR } .PP -\fITEST\-ENTRY\fR := { \fIipaddr\fR } +\fITEST\-ENTRY\fR := \fIipaddr\fR .PP Mandatory \fBcreate\fR options: .TP @@ -262,13 +262,13 @@ The \fBbitmap:ip,mac\fR set type uses a memory range to store IPv4 and a MAC add .PP \fICREATE\-OPTIONS\fR := \fBrange\fP \fIfrom\-ip\fP\-\fIto\-ip\fR|\fIip\fR/\fIcidr\fR [ \fBtimeout\fR \fIvalue\fR ] .PP -\fIADD\-ENTRY\fR := { \fIipaddr\fR[,\fImac\-addr\fR] } +\fIADD\-ENTRY\fR := \fIipaddr\fR[,\fImac\-addr\fR] .PP \fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] .PP -\fIDEL\-ENTRY\fR := { \fIipaddr\fR[,\fImac\-addr\fR] } +\fIDEL\-ENTRY\fR := \fIipaddr\fR[,\fImac\-addr\fR] .PP -\fITEST\-ENTRY\fR := { \fIipaddr\fR[,\fImac\-addr\fR] } +\fITEST\-ENTRY\fR := \fIipaddr\fR[,\fImac\-addr\fR] .PP Mandatory options to use when creating a \fBbitmap:ip,mac\fR type of set: .TP @@ -307,7 +307,7 @@ and such a set can store up to 65536 ports. .PP \fIDEL\-ENTRY\fR := {\fIport\fR | \fIfrom\-port\fR\-\fIto\-port\fR } .PP -\fITEST\-ENTRY\fR := { \fIport\fR } +\fITEST\-ENTRY\fR := \fIport\fR .PP Mandatory options to use when creating a \fBbitmap:port\fR type of set: .TP @@ -328,13 +328,13 @@ if that is exhausted, the doubling of the hash is performed. .PP \fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR|\fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBnetmask\fP \fIcidr\fP ] [ \fBtimeout\fR \fIvalue\fR ] .PP -\fIADD\-ENTRY\fR := { \fIipaddr\fR } +\fIADD\-ENTRY\fR := \fIipaddr\fR .PP \fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] .PP -\fIDEL\-ENTRY\fR := { \fIipaddr\fR } +\fIDEL\-ENTRY\fR := \fIipaddr\fR .PP -\fITEST\-ENTRY\fR := { \fIipaddr\fR } +\fITEST\-ENTRY\fR := \fIipaddr\fR .PP For the \fBinet\fR family one can add or delete multiple entries by specifying a range or a network: @@ -378,13 +378,13 @@ if that is exhausted, the doubling of the hash is performed. .PP \fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR|\fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] .PP -\fIADD\-ENTRY\fR := { \fIipaddr\fR[/\fIcidr\fR] } +\fIADD\-ENTRY\fR := \fIipaddr\fR[/\fIcidr\fR] .PP \fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] .PP -\fIDEL\-ENTRY\fR := { \fIipaddr\fR[/\fIcidr\fR] } +\fIDEL\-ENTRY\fR := \fIipaddr\fR[/\fIcidr\fR] .PP -\fITEST\-ENTRY\fR := { \fIipaddr\fR[/\fIcidr\fR] } +\fITEST\-ENTRY\fR := \fIipaddr\fR[/\fIcidr\fR] .PP Optional \fBcreate\fR options: .TP @@ -427,15 +427,15 @@ The \fBhash:ip,port\fR set type uses a hash to store IP address and port pairs. In order to avoid clashes in the hash a limited number of chaining, and then if that is exhausted, the doubling of the hash is performed. .PP -\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR|\fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] +\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR|\fBinet6\fR } ] | [ \fBproto\fR \fIvalue\fR ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] .PP -\fIADD\-ENTRY\fR := { \fIipaddr\fR,\fIport\fR } +\fIADD\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR .PP \fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] .PP -\fIDEL\-ENTRY\fR := { \fIipaddr\fR,\fIport\fR } +\fIDEL\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR .PP -\fITEST\-ENTRY\fR := { \fIipaddr\fR,\fIport\fR } +\fITEST\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR .PP Optional \fBcreate\fR options: .TP @@ -443,6 +443,12 @@ Optional \fBcreate\fR options: The protocol family of the IP addresses to be stored in the set. The default is \fBinet\fR, i.e IPv4. .TP +\fBproto\fR \fIvalue\fR +The default protocol for the port to be stored in the set. If no protocol is specified, +then TCP/UDP ports are assumed as backward compatibility. The default protocol +also defines which kind of ports are to be added to the set when the \fBSET\fR +target is used. +.TP \fBhashsize\fR \fIvalue\fR The initial hash size for the set, default is 1024. The hash size must be a power of two, the kernel automatically rounds up non power of two hash sizes to the first @@ -451,30 +457,37 @@ correct value. \fBmaxelem\fR \fIvalue\fR The maximal number of elements which can be stored in the set, default 65536. .PP -The \fBhash:ip,port\fR type of sets require two \fBsrc\fR/\fBdst\fR parameters of -the \fBset\fR match and \fBSET\fR target kernel modules. +When adding, deleting, testing entries the port value is interpreted +for TCP and UDP only, for other protocols the port value currently is ignored and +zeroed out, but must be specified. The \fBhash:ip,port\fR type of sets require +two \fBsrc\fR/\fBdst\fR parameters of the \fBset\fR match and \fBSET\fR +target kernel modules. .PP Examples: .IP -ipset create foo hash:ip,port +ipset create foo hash:ip,port proto tcp .IP ipset add foo 192.168.1.1,80 .IP +ipset add foo 192.168.1.1,udp:53 +.IP +ipset add foo 192.168.1.1,ospf:0 +.IP ipset test foo 192.168.1.1,80 .SS hash:ip,port,ip The \fBhash:ip,port,ip\fR set type uses a hash to store IP address, port and IP address triples. In order to avoid clashes in the hash a limited number of chaining, and then if that is exhausted, the doubling of the hash is performed. .PP -\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR|\fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] +\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR|\fBinet6\fR } ] | [ \fBproto\fR \fIvalue\fR ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] .PP -\fIADD\-ENTRY\fR := { \fIipaddr\fR,\fIport\fR,\fIipaddr\fR } +\fIADD\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fIipaddr\fR .PP \fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] .PP -\fIDEL\-ENTRY\fR := { \fIipaddr\fR,\fIport\fR,\fIipaddr\fR } +\fIDEL\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fIipaddr\fR .PP -\fITEST\-ENTRY\fR := { \fIipaddr\fR,\fIport\fR,\fIipaddr\fR } +\fITEST\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fIipaddr\fR .PP Optional \fBcreate\fR options: .TP @@ -482,6 +495,12 @@ Optional \fBcreate\fR options: The protocol family of the IP addresses to be stored in the set. The default is \fBinet\fR, i.e IPv4. .TP +\fBproto\fR \fIvalue\fR +The default protocol for the port to be stored in the set. If no protocol is specified, +then TCP/UDP ports are assumed as backward compatibility. The default protocol +also defines which kind of ports are to be added to the set when the \fBSET\fR +target is used. +.TP \fBhashsize\fR \fIvalue\fR The initial hash size for the set, default is 1024. The hash size must be a power of two, the kernel automatically rounds up non power of two hash sizes to the first @@ -490,8 +509,11 @@ correct value. \fBmaxelem\fR \fIvalue\fR The maximal number of elements which can be stored in the set, default 65536. .PP -The \fBhash:ip,port,ip\fR type of sets require three \fBsrc\fR/\fBdst\fR parameters of -the \fBset\fR match and \fBSET\fR target kernel modules. +When adding, deleting, testing entries the port value is interpreted +for TCP and UDP only, for other protocols the port value currently is ignored and +zeroed out, but must be specified. The \fBhash:ip,port,ip\fR type of sets require +three \fBsrc\fR/\fBdst\fR parameters of the \fBset\fR match and \fBSET\fR +target kernel modules. .PP Examples: .IP @@ -499,22 +521,22 @@ ipset create foo hash:ip,port,ip .IP ipset add foo 192.168.1.1,80,10.0.0.1 .IP -ipset test foo 192.168.1.1,80,10.0.0.1 +ipset test foo 192.168.1.1,udp:53,10.0.0.1 .SS hash:ip,port,net The \fBhash:ip,port,net\fR set type uses a hash to store IP address, port and IP network triples. In order to avoid clashes in the hash a limited number of chaining, and then if that is exhausted, the doubling of the hash is performed. .PP -\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR|\fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] +\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR|\fBinet6\fR } ] | [ \fBproto\fR \fIvalue\fR ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] .PP -\fIADD\-ENTRY\fR := { \fIipaddr\fR,\fIport\fR,\fIipaddr\fR[/\fIcidr\fR] } +\fIADD\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fIipaddr\fR[/\fIcidr\fR] .PP \fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] .PP -\fIDEL\-ENTRY\fR := { \fIipaddr\fR,\fIport\fR,\fIipaddr\fR[/\fIcidr\fR] } +\fIDEL\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fIipaddr\fR[/\fIcidr\fR] .PP -\fITEST\-ENTRY\fR := { \fIipaddr\fR,\fIport\fR,\fIipaddr\fR[/\fIcidr\fR] } +\fITEST\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fIipaddr\fR[/\fIcidr\fR] .PP Optional \fBcreate\fR options: .TP @@ -522,6 +544,12 @@ Optional \fBcreate\fR options: The protocol family of the IP addresses to be stored in the set. The default is \fBinet\fR, i.e IPv4. .TP +\fBproto\fR \fIvalue\fR +The default protocol for the port to be stored in the set. If no protocol is specified, +then TCP/UDP ports are assumed as backward compatibility. The default protocol +also defines which kind of ports are to be added to the set when the \fBSET\fR +target is used. +.TP \fBhashsize\fR \fIvalue\fR The initial hash size for the set, default is 1024. The hash size must be a power of two, the kernel automatically rounds up non power of two hash sizes to the first @@ -531,7 +559,9 @@ correct value. The maximal number of elements which can be stored in the set, default 65536. .PP When adding/deleting/testing entries, if the cidr parameter is not specified, -then the host cidr value is assumed. +then the host cidr value is assumed. The port value is interpreted +for TCP and UDP only, for other protocols the port value currently is ignored and +zeroed out, but must be specified. .PP From the \fBset\fR netfilter match point of view a triple will be in a \fBhash:ip,port,net\fR type of set (when the first IP and the port match) if the second IP belongs to any of the netblocks added to the set. diff --git a/src/ipset.c b/src/ipset.c index 69fcd09..c613b24 100644 --- a/src/ipset.c +++ b/src/ipset.c @@ -202,7 +202,7 @@ restore(char *argv0) } static int -call_parser(int argc, char *argv[], const struct ipset_arg *args) +call_parser(int *argc, char *argv[], const struct ipset_arg *args) { int i = 1, ret = 0; const struct ipset_arg *arg; @@ -212,8 +212,8 @@ call_parser(int argc, char *argv[], const struct ipset_arg *args) if (!args) goto done; for (arg = args; arg->opt; arg++) { - for (i = 1; i < argc; ) { - D("argc: %u, i: %u: %s vs %s", argc, i, argv[i], arg->name[0]); + for (i = 1; i < *argc; ) { + D("argc: %u, i: %u: %s vs %s", *argc, i, argv[i], arg->name[0]); if (!(ipset_match_option(argv[i], arg->name))) { i++; continue; @@ -221,24 +221,24 @@ call_parser(int argc, char *argv[], const struct ipset_arg *args) optstr = argv[i]; /* Shift off matched option */ D("match %s", arg->name[0]); - ipset_shift_argv(&argc, argv, i); - D("argc: %u, i: %u", argc, i); + ipset_shift_argv(argc, argv, i); + D("argc: %u, i: %u", *argc, i); switch (arg->has_arg) { case IPSET_MANDATORY_ARG: - if (i + 1 > argc) + if (i + 1 > *argc) return exit_error(PARAMETER_PROBLEM, "Missing mandatory argument of option `%s'", arg->name[0]); /* Fall through */ case IPSET_OPTIONAL_ARG: - if (i + 1 <= argc) { + if (i + 1 <= *argc) { ret = ipset_call_parser(session, arg->parse, optstr, arg->opt, argv[i]); if (ret < 0) return ret; - ipset_shift_argv(&argc, argv, i); + ipset_shift_argv(argc, argv, i); break; } /* Fall through */ @@ -253,7 +253,7 @@ call_parser(int argc, char *argv[], const struct ipset_arg *args) } } done: - if (i < argc) + if (i < *argc) return exit_error(PARAMETER_PROBLEM, "Unknown argument: `%s'", argv[i]); @@ -458,6 +458,9 @@ parse_commandline(int argc, char *argv[]) } return exit_error(NO_PROBLEM, NULL); } + if (argc > 1) + return exit_error(PARAMETER_PROBLEM, + "No command specified: unknown argument %s", argv[1]); return exit_error(PARAMETER_PROBLEM, "No command specified."); case IPSET_CMD_VERSION: printf("%s v%s.\n", program_name, program_version); @@ -522,7 +525,7 @@ parse_commandline(int argc, char *argv[]) return handle_error(); /* Parse create options */ - ret = call_parser(argc, argv, type->args[IPSET_CREATE]); + ret = call_parser(&argc, argv, type->args[IPSET_CREATE]); if (ret < 0) return handle_error(); else if (ret) @@ -557,6 +560,9 @@ parse_commandline(int argc, char *argv[]) case IPSET_CMD_RESTORE: /* Restore mode */ + if (argc > 1) + return exit_error(PARAMETER_PROBLEM, + "Unknown argument %s", argv[1]); return restore(argv[0]); case IPSET_CMD_ADD: case IPSET_CMD_DEL: @@ -576,7 +582,7 @@ parse_commandline(int argc, char *argv[]) return handle_error(); /* Parse additional ADT options */ - ret = call_parser(argc, argv, type->args[cmd2cmd(cmd)]); + ret = call_parser(&argc, argv, type->args[cmd2cmd(cmd)]); if (ret < 0) return handle_error(); else if (ret) @@ -590,6 +596,9 @@ parse_commandline(int argc, char *argv[]) break; } + if (argc > 1) + return exit_error(PARAMETER_PROBLEM, + "Unknown argument %s", argv[1]); ret = ipset_cmd(session, cmd, restore_line); D("ret %d", ret); /* Special case for TEST and non-quiet mode */ diff --git a/src/ipset_hash_ipport.c b/src/ipset_hash_ipport.c index 4a9b8cf..94a8cc6 100644 --- a/src/ipset_hash_ipport.c +++ b/src/ipset_hash_ipport.c @@ -37,6 +37,10 @@ static const struct ipset_arg hash_ipport_create_args[] = { .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, .parse = ipset_parse_uint32, .print = ipset_print_number, }, + { .name = { "proto", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROTO, + .parse = ipset_parse_proto, .print = ipset_print_proto, + }, /* Backward compatibility */ { .name = { "probes", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES, @@ -71,12 +75,12 @@ static const struct ipset_arg hash_ipport_add_args[] = { static const char hash_ipport_usage[] = "create SETNAME hash:ip,port\n" -" [family inet|inet6]\n" +" [family inet|inet6] [proto PROTO]\n" " [hashsize VALUE] [maxelem VALUE]\n" " [timeout VALUE]\n" -"add SETNAME IP,PORT [timeout VALUE]\n" -"del SETNAME IP,PORT\n" -"test SETNAME IP,PORT\n"; +"add SETNAME IP,[PROTO:]PORT [timeout VALUE]\n" +"del SETNAME IP,[PROTO:]PORT\n" +"test SETNAME IP,[PROTO:]PORT\n"; struct ipset_type ipset_hash_ipport0 = { .name = "hash:ip,port", @@ -91,8 +95,8 @@ struct ipset_type ipset_hash_ipport0 = { .opt = IPSET_OPT_IP }, [IPSET_DIM_TWO] = { - .parse = ipset_parse_single_port, - .print = ipset_print_port, + .parse = ipset_parse_proto_port, + .print = ipset_print_proto_port, .opt = IPSET_OPT_PORT }, }, @@ -112,14 +116,18 @@ struct ipset_type ipset_hash_ipport0 = { .full = { [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) | IPSET_FLAG(IPSET_OPT_MAXELEM) + | IPSET_FLAG(IPSET_OPT_PROTO) | IPSET_FLAG(IPSET_OPT_TIMEOUT), [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO) | IPSET_FLAG(IPSET_OPT_TIMEOUT), [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT), + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO), [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT), + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO), }, .usage = hash_ipport_usage, diff --git a/src/ipset_hash_ipportip.c b/src/ipset_hash_ipportip.c index 299e362..dc121e4 100644 --- a/src/ipset_hash_ipportip.c +++ b/src/ipset_hash_ipportip.c @@ -37,6 +37,10 @@ static const struct ipset_arg hash_ipportip_create_args[] = { .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, .parse = ipset_parse_uint32, .print = ipset_print_number, }, + { .name = { "proto", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROTO, + .parse = ipset_parse_proto, .print = ipset_print_proto, + }, /* Backward compatibility */ { .name = { "probes", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES, @@ -71,12 +75,12 @@ static const struct ipset_arg hash_ipportip_add_args[] = { static const char hash_ipportip_usage[] = "create SETNAME hash:ip,port,ip\n" -" [family inet|inet6]\n" +" [family inet|inet6] [proto PROTO]\n" " [hashsize VALUE] [maxelem VALUE]\n" " [timeout VALUE]\n" -"add SETNAME IP,PORT,IP [timeout VALUE]\n" -"del SETNAME IP,PORT,IP\n" -"test SETNAME IP,PORT,IP\n"; +"add SETNAME IP,[PROTO:]PORT,IP [timeout VALUE]\n" +"del SETNAME IP,[PROTO:]PORT,IP\n" +"test SETNAME IP,[PROTO:]PORT,IP\n"; struct ipset_type ipset_hash_ipportip0 = { .name = "hash:ip,port,ip", @@ -91,8 +95,8 @@ struct ipset_type ipset_hash_ipportip0 = { .opt = IPSET_OPT_IP }, [IPSET_DIM_TWO] = { - .parse = ipset_parse_single_port, - .print = ipset_print_port, + .parse = ipset_parse_proto_port, + .print = ipset_print_proto_port, .opt = IPSET_OPT_PORT }, [IPSET_DIM_THREE] = { @@ -120,16 +124,20 @@ struct ipset_type ipset_hash_ipportip0 = { .full = { [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) | IPSET_FLAG(IPSET_OPT_MAXELEM) + | IPSET_FLAG(IPSET_OPT_PROTO) | IPSET_FLAG(IPSET_OPT_TIMEOUT), [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO) | IPSET_FLAG(IPSET_OPT_IP2) | IPSET_FLAG(IPSET_OPT_TIMEOUT), [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO) | IPSET_FLAG(IPSET_OPT_IP2), [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO) | IPSET_FLAG(IPSET_OPT_IP2), }, diff --git a/src/ipset_hash_ipportnet.c b/src/ipset_hash_ipportnet.c index 13a0487..a668c5e 100644 --- a/src/ipset_hash_ipportnet.c +++ b/src/ipset_hash_ipportnet.c @@ -37,6 +37,10 @@ static const struct ipset_arg hash_ipportnet_create_args[] = { .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, .parse = ipset_parse_uint32, .print = ipset_print_number, }, + { .name = { "proto", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROTO, + .parse = ipset_parse_proto, .print = ipset_print_proto, + }, /* Backward compatibility */ { .name = { "probes", NULL }, .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES, @@ -71,12 +75,12 @@ static const struct ipset_arg hash_ipportnet_add_args[] = { static const char hash_ipportnet_usage[] = "create SETNAME hash:ip,port,net\n" -" [family inet|inet6]\n" +" [family inet|inet6] [proto PROTO]\n" " [hashsize VALUE] [maxelem VALUE]\n" " [timeout VALUE]\n" -"add SETNAME IP,PORT,IP[/CIDR] [timeout VALUE]\n" -"del SETNAME IP,PORT,IP[/CIDR]\n" -"test SETNAME IP,PORT,IP[/CIDR]\n"; +"add SETNAME IP,[PROTO:]PORT,IP[/CIDR] [timeout VALUE]\n" +"del SETNAME IP,[PROTO:]PORT,IP[/CIDR]\n" +"test SETNAME IP,[PROTO:]PORT,IP[/CIDR]\n"; struct ipset_type ipset_hash_ipportnet0 = { .name = "hash:ip,port,net", @@ -91,8 +95,8 @@ struct ipset_type ipset_hash_ipportnet0 = { .opt = IPSET_OPT_IP }, [IPSET_DIM_TWO] = { - .parse = ipset_parse_single_port, - .print = ipset_print_port, + .parse = ipset_parse_proto_port, + .print = ipset_print_proto_port, .opt = IPSET_OPT_PORT }, [IPSET_DIM_THREE] = { @@ -120,18 +124,22 @@ struct ipset_type ipset_hash_ipportnet0 = { .full = { [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) | IPSET_FLAG(IPSET_OPT_MAXELEM) + | IPSET_FLAG(IPSET_OPT_PROTO) | IPSET_FLAG(IPSET_OPT_TIMEOUT), [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO) | IPSET_FLAG(IPSET_OPT_IP2) | IPSET_FLAG(IPSET_OPT_CIDR2) | IPSET_FLAG(IPSET_OPT_TIMEOUT), [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO) | IPSET_FLAG(IPSET_OPT_IP2) | IPSET_FLAG(IPSET_OPT_CIDR2), [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO) | IPSET_FLAG(IPSET_OPT_IP2) | IPSET_FLAG(IPSET_OPT_CIDR2), }, -- cgit v1.2.3