summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/errcode.c4
-rw-r--r--src/ipset.842
-rw-r--r--src/ipset.c22
-rw-r--r--src/ipset_hash_ipport.c6
-rw-r--r--src/ipset_hash_ipportip.c6
-rw-r--r--src/ipset_hash_ipportnet.c101
-rw-r--r--src/ipset_hash_net.c59
-rw-r--r--src/ipset_hash_netport.c82
8 files changed, 287 insertions, 35 deletions
diff --git a/src/errcode.c b/src/errcode.c
index 6370ec7..9d5f226 100644
--- a/src/errcode.c
+++ b/src/errcode.c
@@ -113,6 +113,10 @@ static const struct ipset_errcode_table hash_errcode_table[] = {
"Invalid protocol specified" },
{ IPSET_ERR_MISSING_PROTO, 0,
"Protocol missing, but must be specified" },
+ { IPSET_ERR_HASH_RANGE_UNSUPPORTED, 0,
+ "Range is not supported in the \"net\" component of the element" },
+ { IPSET_ERR_HASH_RANGE, 0,
+ "Invalid range, covers the whole address space" },
{ },
};
diff --git a/src/ipset.8 b/src/ipset.8
index 21750fa..90914f4 100644
--- a/src/ipset.8
+++ b/src/ipset.8
@@ -214,7 +214,7 @@ command follows the syntax
where the current list of the methods are
\fBbitmap\fR, \fBhash\fR, and \fBlist\fR and the possible data types
-are \fBip\fR, \fBmac\fR and \fBport\fR. The dimension of a set
+are \fBip\fR, \fBnet\fR, \fBmac\fR and \fBport\fR. The dimension of a set
is equal to the number of data types in its type name.
When adding, deleting or testing entries in a set, the same comma separated
@@ -409,13 +409,16 @@ Network address with zero prefix size cannot be stored in this type of sets.
.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 := \fIip\fR[/\fIcidr\fR]
+\fIADD\-ENTRY\fR := \fInetaddr\fR
.PP
\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ]
.PP
-\fIDEL\-ENTRY\fR := \fIip\fR[/\fIcidr\fR]
+\fIDEL\-ENTRY\fR := \fInetaddr\fR
.PP
-\fITEST\-ENTRY\fR := \fIip\fR[/\fIcidr\fR]
+\fITEST\-ENTRY\fR := \fInetaddr\fR
+.PP
+where
+\fInetaddr\fR := \fIip\fR[/\fIcidr\fR]
.PP
Optional \fBcreate\fR options:
.TP
@@ -431,6 +434,11 @@ correct value.
\fBmaxelem\fR \fIvalue\fR
The maximal number of elements which can be stored in the set, default 65536.
.PP
+For the \fBinet\fR family one can add or delete multiple entries by specifying
+a range, which is converted internally to network(s) equal to the range:
+.PP
+\fInetaddr\fR := { \fIip\fR[/\fIcidr\fR] | \fIfromaddr\fR\-\fItoaddr\fR }
+.PP
When adding/deleting/testing entries, if the cidr prefix parameter is not specified,
then the host prefix value is assumed. When adding/deleting entries, the exact
element is added/deleted and overlapping elements are not checked by the kernel.
@@ -539,13 +547,16 @@ address with zero prefix size is not accepted either.
.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],[\fIproto\fR:]\fIport\fR
+\fIADD\-ENTRY\fR := \fInetaddr\fR,[\fIproto\fR:]\fIport\fR
.PP
\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ]
.PP
-\fIDEL\-ENTRY\fR := \fIipaddr\fR[/\fIcidr\fR],[\fIproto\fR:]\fIport\fR
+\fIDEL\-ENTRY\fR := \fInetaddr\fR,[\fIproto\fR:]\fIport\fR
.PP
-\fITEST\-ENTRY\fR := \fIipaddr\fR[/\fIcidr\fR],[\fIproto\fR:]\fIport\fR
+\fITEST\-ENTRY\fR := \fInetaddr\fR,[\fIproto\fR:]\fIport\fR
+.PP
+where
+\fInetaddr\fR := \fIip\fR[/\fIcidr\fR]
.PP
Optional \fBcreate\fR options:
.TP
@@ -561,7 +572,8 @@ correct value.
\fBmaxelem\fR \fIvalue\fR
The maximal number of elements which can be stored in the set, default 65536.
.PP
-For the
+For the \fInetaddr\fR part of the elements
+see the description at the \fBhash:net\fR set type. For the
[\fIproto\fR:]\fIport\fR
part of the elements see the description at the
\fBhash:ip,port\fR set type.
@@ -645,18 +657,22 @@ address with zero prefix size cannot be stored either.
.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,[\fIproto\fR:]\fIport\fR,\fIip\fR[/\fIcidr\fR]
+\fIADD\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fInetaddr\fR
.PP
\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ]
.PP
-\fIDEL\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fIip\fR[/\fIcidr\fR]
+\fIDEL\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fInetaddr\fR
.PP
-\fITEST\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fIip\fR[/\fIcidr\fR]
+\fITEST\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fInetaddr\fR
.PP
-For the first \fIipaddr\fR and
+where
+\fInetaddr\fR := \fIip\fR[/\fIcidr\fR]
+.PP
+For the \fIipaddr\fR and
[\fIproto\fR:]\fIport\fR
parts of the elements see the descriptions at the
-\fBhash:ip,port\fR set type.
+\fBhash:ip,port\fR set type. For the \fInetaddr\fR part of the elements
+see the description at the \fBhash:net\fR set type.
.PP
Optional \fBcreate\fR options:
.TP
diff --git a/src/ipset.c b/src/ipset.c
index 05f8ef3..b3569ed 100644
--- a/src/ipset.c
+++ b/src/ipset.c
@@ -39,10 +39,13 @@ extern struct ipset_type ipset_bitmap_ipmac0;
extern struct ipset_type ipset_bitmap_port0;
extern struct ipset_type ipset_hash_ip0;
extern struct ipset_type ipset_hash_net0;
-extern struct ipset_type ipset_hash_netport0;
-extern struct ipset_type ipset_hash_ipport0;
-extern struct ipset_type ipset_hash_ipportip0;
-extern struct ipset_type ipset_hash_ipportnet0;
+extern struct ipset_type ipset_hash_net1;
+extern struct ipset_type ipset_hash_netport1;
+extern struct ipset_type ipset_hash_netport2;
+extern struct ipset_type ipset_hash_ipport1;
+extern struct ipset_type ipset_hash_ipportip1;
+extern struct ipset_type ipset_hash_ipportnet1;
+extern struct ipset_type ipset_hash_ipportnet2;
extern struct ipset_type ipset_list_set0;
enum exittype {
@@ -721,10 +724,13 @@ main(int argc, char *argv[])
ipset_type_add(&ipset_bitmap_port0);
ipset_type_add(&ipset_hash_ip0);
ipset_type_add(&ipset_hash_net0);
- ipset_type_add(&ipset_hash_netport0);
- ipset_type_add(&ipset_hash_ipport0);
- ipset_type_add(&ipset_hash_ipportip0);
- ipset_type_add(&ipset_hash_ipportnet0);
+ ipset_type_add(&ipset_hash_net1);
+ ipset_type_add(&ipset_hash_netport1);
+ ipset_type_add(&ipset_hash_netport2);
+ ipset_type_add(&ipset_hash_ipport1);
+ ipset_type_add(&ipset_hash_ipportip1);
+ ipset_type_add(&ipset_hash_ipportnet1);
+ ipset_type_add(&ipset_hash_ipportnet2);
ipset_type_add(&ipset_list_set0);
/* Initialize session */
diff --git a/src/ipset_hash_ipport.c b/src/ipset_hash_ipport.c
index 3179805..58ea76c 100644
--- a/src/ipset_hash_ipport.c
+++ b/src/ipset_hash_ipport.c
@@ -70,7 +70,7 @@ static const struct ipset_arg hash_ipport_add_args[] = {
{ },
};
-static const char hash_ipport_usage[] =
+static const char hash_ipport1_usage[] =
"create SETNAME hash:ip,port\n"
" [family inet|inet6]\n"
" [hashsize VALUE] [maxelem VALUE]\n"
@@ -85,7 +85,7 @@ static const char hash_ipport_usage[] =
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipport0 = {
+struct ipset_type ipset_hash_ipport1 = {
.name = "hash:ip,port",
.alias = { "ipporthash", NULL },
.revision = 1,
@@ -139,6 +139,6 @@ struct ipset_type ipset_hash_ipport0 = {
| IPSET_FLAG(IPSET_OPT_PROTO),
},
- .usage = hash_ipport_usage,
+ .usage = hash_ipport1_usage,
.usagefn = ipset_port_usage,
};
diff --git a/src/ipset_hash_ipportip.c b/src/ipset_hash_ipportip.c
index 944ee81..2f310ea 100644
--- a/src/ipset_hash_ipportip.c
+++ b/src/ipset_hash_ipportip.c
@@ -70,7 +70,7 @@ static const struct ipset_arg hash_ipportip_add_args[] = {
{ },
};
-static const char hash_ipportip_usage[] =
+static const char hash_ipportip1_usage[] =
"create SETNAME hash:ip,port,ip\n"
" [family inet|inet6]\n"
" [hashsize VALUE] [maxelem VALUE]\n"
@@ -85,7 +85,7 @@ static const char hash_ipportip_usage[] =
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipportip0 = {
+struct ipset_type ipset_hash_ipportip1 = {
.name = "hash:ip,port,ip",
.alias = { "ipportiphash", NULL },
.revision = 1,
@@ -150,6 +150,6 @@ struct ipset_type ipset_hash_ipportip0 = {
| IPSET_FLAG(IPSET_OPT_IP2),
},
- .usage = hash_ipportip_usage,
+ .usage = hash_ipportip1_usage,
.usagefn = ipset_port_usage,
};
diff --git a/src/ipset_hash_ipportnet.c b/src/ipset_hash_ipportnet.c
index bd94d12..c2eece8 100644
--- a/src/ipset_hash_ipportnet.c
+++ b/src/ipset_hash_ipportnet.c
@@ -70,7 +70,7 @@ static const struct ipset_arg hash_ipportnet_add_args[] = {
{ },
};
-static const char hash_ipportnet_usage[] =
+static const char hash_ipportnet1_usage[] =
"create SETNAME hash:ip,port,net\n"
" [family inet|inet6]\n"
" [hashsize VALUE] [maxelem VALUE]\n"
@@ -86,7 +86,7 @@ static const char hash_ipportnet_usage[] =
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipportnet0 = {
+struct ipset_type ipset_hash_ipportnet1 = {
.name = "hash:ip,port,net",
.alias = { "ipportnethash", NULL },
.revision = 1,
@@ -133,6 +133,7 @@ struct ipset_type ipset_hash_ipportnet0 = {
| IPSET_FLAG(IPSET_OPT_MAXELEM)
| IPSET_FLAG(IPSET_OPT_TIMEOUT),
[IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR)
| IPSET_FLAG(IPSET_OPT_IP_TO)
| IPSET_FLAG(IPSET_OPT_PORT)
| IPSET_FLAG(IPSET_OPT_PORT_TO)
@@ -141,6 +142,7 @@ struct ipset_type ipset_hash_ipportnet0 = {
| IPSET_FLAG(IPSET_OPT_CIDR2)
| IPSET_FLAG(IPSET_OPT_TIMEOUT),
[IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR)
| IPSET_FLAG(IPSET_OPT_IP_TO)
| IPSET_FLAG(IPSET_OPT_PORT)
| IPSET_FLAG(IPSET_OPT_PORT_TO)
@@ -154,6 +156,99 @@ struct ipset_type ipset_hash_ipportnet0 = {
| IPSET_FLAG(IPSET_OPT_CIDR2),
},
- .usage = hash_ipportnet_usage,
+ .usage = hash_ipportnet1_usage,
.usagefn = ipset_port_usage,
};
+
+static const char hash_ipportnet2_usage[] =
+"create SETNAME hash:ip,port,net\n"
+" [family inet|inet6]\n"
+" [hashsize VALUE] [maxelem VALUE]\n"
+" [timeout VALUE]\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\n"
+"where depending on the INET family\n"
+" IP are valid IPv4 or IPv6 addresses (or hostnames),\n"
+" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
+" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
+" in both IP components are supported for IPv4.\n"
+" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
+" port range is supported both for IPv4 and IPv6.\n";
+
+struct ipset_type ipset_hash_ipportnet2 = {
+ .name = "hash:ip,port,net",
+ .alias = { "ipportnethash", NULL },
+ .revision = 2,
+ .family = AF_INET46,
+ .dimension = IPSET_DIM_THREE,
+ .elem = {
+ [IPSET_DIM_ONE] = {
+ .parse = ipset_parse_ip4_single6,
+ .print = ipset_print_ip,
+ .opt = IPSET_OPT_IP
+ },
+ [IPSET_DIM_TWO] = {
+ .parse = ipset_parse_proto_port,
+ .print = ipset_print_proto_port,
+ .opt = IPSET_OPT_PORT
+ },
+ [IPSET_DIM_THREE] = {
+ .parse = ipset_parse_ip4_net6,
+ .print = ipset_print_ip,
+ .opt = IPSET_OPT_IP2
+ },
+ },
+ .args = {
+ [IPSET_CREATE] = hash_ipportnet_create_args,
+ [IPSET_ADD] = hash_ipportnet_add_args,
+ },
+ .mandatory = {
+ [IPSET_CREATE] = 0,
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_IP2),
+ [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),
+ },
+ .full = {
+ [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
+ | IPSET_FLAG(IPSET_OPT_MAXELEM)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT),
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR)
+ | IPSET_FLAG(IPSET_OPT_IP_TO)
+ | IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PORT_TO)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_IP2)
+ | IPSET_FLAG(IPSET_OPT_CIDR2)
+ | IPSET_FLAG(IPSET_OPT_IP2_TO)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR)
+ | IPSET_FLAG(IPSET_OPT_IP_TO)
+ | IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PORT_TO)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_IP2)
+ | IPSET_FLAG(IPSET_OPT_CIDR2)
+ | IPSET_FLAG(IPSET_OPT_IP2_TO),
+ [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),
+ },
+
+ .usage = hash_ipportnet2_usage,
+ .usagefn = ipset_port_usage,
+};
+
diff --git a/src/ipset_hash_net.c b/src/ipset_hash_net.c
index e8891c1..9c0a6ca 100644
--- a/src/ipset_hash_net.c
+++ b/src/ipset_hash_net.c
@@ -57,7 +57,7 @@ static const struct ipset_arg hash_net_add_args[] = {
{ },
};
-static const char hash_net_usage[] =
+static const char hash_net0_usage[] =
"create SETNAME hash:net\n"
" [family inet|inet6]\n"
" [hashsize VALUE] [maxelem VALUE]\n"
@@ -105,5 +105,60 @@ struct ipset_type ipset_hash_net0 = {
| IPSET_FLAG(IPSET_OPT_CIDR),
},
- .usage = hash_net_usage,
+ .usage = hash_net0_usage,
};
+
+static const char hash_net1_usage[] =
+"create SETNAME hash:net\n"
+" [family inet|inet6]\n"
+" [hashsize VALUE] [maxelem VALUE]\n"
+" [timeout VALUE]\n"
+"add SETNAME IP[/CIDR]|FROM-TO [timeout VALUE]\n"
+"del SETNAME IP[/CIDR]|FROM-TO\n"
+"test SETNAME IP[/CIDR]\n\n"
+"where depending on the INET family\n"
+" IP is an IPv4 or IPv6 address (or hostname),\n"
+" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
+" IP range is not supported with IPv6.\n";
+
+struct ipset_type ipset_hash_net1 = {
+ .name = "hash:net",
+ .alias = { "nethash", NULL },
+ .revision = 1,
+ .family = AF_INET46,
+ .dimension = IPSET_DIM_ONE,
+ .elem = {
+ [IPSET_DIM_ONE] = {
+ .parse = ipset_parse_ip4_net6,
+ .print = ipset_print_ip,
+ .opt = IPSET_OPT_IP
+ },
+ },
+ .args = {
+ [IPSET_CREATE] = hash_net_create_args,
+ [IPSET_ADD] = hash_net_add_args,
+ },
+ .mandatory = {
+ [IPSET_CREATE] = 0,
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP),
+ [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP),
+ },
+ .full = {
+ [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
+ | IPSET_FLAG(IPSET_OPT_MAXELEM)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT),
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR)
+ | IPSET_FLAG(IPSET_OPT_IP_TO)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR)
+ | IPSET_FLAG(IPSET_OPT_IP_TO),
+ [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR),
+ },
+
+ .usage = hash_net1_usage,
+};
+
diff --git a/src/ipset_hash_netport.c b/src/ipset_hash_netport.c
index 8ca77df..7964319 100644
--- a/src/ipset_hash_netport.c
+++ b/src/ipset_hash_netport.c
@@ -49,7 +49,7 @@ static const struct ipset_arg hash_netport_add_args[] = {
{ },
};
-static const char hash_netport_usage[] =
+static const char hash_netport1_usage[] =
"create SETNAME hash:net,port\n"
" [family inet|inet6]\n"
" [hashsize VALUE] [maxelem VALUE]\n"
@@ -63,7 +63,7 @@ static const char hash_netport_usage[] =
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_netport0 = {
+struct ipset_type ipset_hash_netport1 = {
.name = "hash:net,port",
.alias = { "netporthash", NULL },
.revision = 1,
@@ -118,6 +118,82 @@ struct ipset_type ipset_hash_netport0 = {
| IPSET_FLAG(IPSET_OPT_CIDR),
},
- .usage = hash_netport_usage,
+ .usage = hash_netport1_usage,
+ .usagefn = ipset_port_usage,
+};
+
+static const char hash_netport2_usage[] =
+"create SETNAME hash:net,port\n"
+" [family inet|inet6]\n"
+" [hashsize VALUE] [maxelem VALUE]\n"
+" [timeout VALUE]\n"
+"add SETNAME IP[/CIDR]|FROM-TO,PROTO:PORT [timeout VALUE]\n"
+"del SETNAME IP[/CIDR]|FROM-TO,PROTO:PORT\n"
+"test SETNAME IP[/CIDR],PROTO:PORT\n\n"
+"where depending on the INET family\n"
+" IP is a valid IPv4 or IPv6 address (or hostname),\n"
+" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
+" Adding/deleting multiple elements with IPv4 is supported.\n"
+" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
+" port range is supported both for IPv4 and IPv6.\n";
+
+struct ipset_type ipset_hash_netport2 = {
+ .name = "hash:net,port",
+ .alias = { "netporthash", NULL },
+ .revision = 2,
+ .family = AF_INET46,
+ .dimension = IPSET_DIM_TWO,
+ .elem = {
+ [IPSET_DIM_ONE] = {
+ .parse = ipset_parse_ip4_net6,
+ .print = ipset_print_ip,
+ .opt = IPSET_OPT_IP
+ },
+ [IPSET_DIM_TWO] = {
+ .parse = ipset_parse_proto_port,
+ .print = ipset_print_proto_port,
+ .opt = IPSET_OPT_PORT
+ },
+ },
+ .args = {
+ [IPSET_CREATE] = hash_netport_create_args,
+ [IPSET_ADD] = hash_netport_add_args,
+ },
+ .mandatory = {
+ [IPSET_CREATE] = 0,
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_PORT),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_PORT),
+ [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_PORT),
+ },
+ .full = {
+ [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
+ | IPSET_FLAG(IPSET_OPT_MAXELEM)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT),
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR)
+ | IPSET_FLAG(IPSET_OPT_IP_TO)
+ | IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PORT_TO)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR)
+ | IPSET_FLAG(IPSET_OPT_IP_TO)
+ | IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PORT_TO)
+ | IPSET_FLAG(IPSET_OPT_PROTO),
+ [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR)
+ | IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PROTO),
+ },
+
+ .usage = hash_netport2_usage,
.usagefn = ipset_port_usage,
};