]> granicus.if.org Git - ipset/commitdiff
libipset: Add userspace support of the skbinfo extension of the hash set types.
authorAnton Danilov <littlesmilingcloud@gmail.com>
Thu, 28 Aug 2014 06:11:33 +0000 (10:11 +0400)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Sun, 14 Sep 2014 18:36:51 +0000 (20:36 +0200)
Add userspace part for support of new revisions of the hash set types
with the skbinfo extension.

Signed-off-by: Anton Danilov <littlesmilingcloud@gmail.com>
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
lib/ipset_hash_ip.c
lib/ipset_hash_ipmark.c
lib/ipset_hash_ipport.c
lib/ipset_hash_ipportip.c
lib/ipset_hash_ipportnet.c
lib/ipset_hash_net.c
lib/ipset_hash_netiface.c
lib/ipset_hash_netnet.c
lib/ipset_hash_netport.c
lib/ipset_hash_netportnet.c

index b09536e380ff38f0db232c0d2c995fee3733eeea..2bff34fc6a0d112980f6c38f3840c8178f3faba4 100644 (file)
@@ -505,6 +505,170 @@ static struct ipset_type ipset_hash_ip3 = {
        .description = "forceadd support",
 };
 
+/* Parse commandline arguments */
+static const struct ipset_arg hash_ip_create_args4[] = {
+       { .name = { "family", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,          .print = ipset_print_family,
+       },
+       /* Alias: family inet */
+       { .name = { "-4", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       /* Alias: family inet6 */
+       { .name = { "-6", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       { .name = { "hashsize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_HASHSIZE,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "maxelem", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_MAXELEM,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "netmask", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_NETMASK,
+         .parse = ipset_parse_netmask,         .print = ipset_print_number,
+       },
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "counters", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_COUNTERS,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_CREATE_COMMENT,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "forceadd", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FORCEADD,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "skbinfo", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_SKBINFO,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       /* Ignored options: backward compatibilty */
+       { .name = { "probes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PROBES,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "resize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_RESIZE,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "gc", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_GC,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { },
+};
+
+static const struct ipset_arg hash_ip_add_args4[] = {
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "packets", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PACKETS,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "bytes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_BYTES,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_ADT_COMMENT,
+         .parse = ipset_parse_comment,         .print = ipset_print_comment,
+       },
+       { .name = { "skbmark", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBMARK,
+         .parse = ipset_parse_skbmark,         .print = ipset_print_skbmark,
+       },
+       { .name = { "skbprio", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBPRIO,
+         .parse = ipset_parse_skbprio,         .print = ipset_print_skbprio,
+       },
+       { .name = { "skbqueue", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBQUEUE,
+         .parse = ipset_parse_uint16,          .print = ipset_print_number,
+       },
+       { },
+};
+
+
+static const char hash_ip_usage4[] =
+"create SETNAME hash:ip\n"
+"              [family inet|inet6]\n"
+"               [hashsize VALUE] [maxelem VALUE]\n"
+"               [netmask CIDR] [timeout VALUE]\n"
+"               [counters] [comment] [forceadd] [skbinfo]\n"
+"add    SETNAME IP [timeout VALUE]\n"
+"               [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
+"              [skbmark VALUE] [skbprio VALUE] [skbqueue VALUE]\n"
+"del    SETNAME IP\n"
+"test   SETNAME IP\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 in IP/CIDR or FROM-TO form\n"
+"      is supported for IPv4.\n";
+
+static struct ipset_type ipset_hash_ip4 = {
+       .name = "hash:ip",
+       .alias = { "iphash", NULL },
+       .revision = 4,
+       .family = NFPROTO_IPSET_IPV46,
+       .dimension = IPSET_DIM_ONE,
+       .elem = {
+               [IPSET_DIM_ONE - 1] = {
+                       .parse = ipset_parse_ip4_single6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP
+               },
+       },
+       .args = {
+               [IPSET_CREATE] = hash_ip_create_args4,
+               [IPSET_ADD] = hash_ip_add_args4,
+       },
+       .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_NETMASK)
+                       | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+                       | IPSET_FLAG(IPSET_OPT_COUNTERS)
+                       | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_FORCEADD)
+                       | IPSET_FLAG(IPSET_OPT_SKBINFO),
+               [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_IP_TO)
+                       | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+                       | IPSET_FLAG(IPSET_OPT_PACKETS)
+                       | IPSET_FLAG(IPSET_OPT_BYTES)
+                       | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_SKBMARK)
+                       | IPSET_FLAG(IPSET_OPT_SKBPRIO)
+                       | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
+               [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_IP_TO),
+               [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP),
+       },
+
+       .usage = hash_ip_usage4,
+       .description = "skbinfo support",
+};
+
 void _init(void);
 void _init(void)
 {
@@ -512,4 +676,5 @@ void _init(void)
        ipset_type_add(&ipset_hash_ip1);
        ipset_type_add(&ipset_hash_ip2);
        ipset_type_add(&ipset_hash_ip3);
+       ipset_type_add(&ipset_hash_ip4);
 }
index 1bfd65fe2e75221e8518692c582c8e36daa4b768..8e1a596e7c2d7b4b1c73b4fc4bb19fcf263c5fca 100644 (file)
@@ -307,9 +307,193 @@ static struct ipset_type ipset_hash_ipmark1 = {
        .description = "forceadd support"
 };
 
+static const struct ipset_arg hash_ipmark_create_args2[] = {
+       { .name = { "family", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,          .print = ipset_print_family,
+       },
+       /* Alias: family inet */
+       { .name = { "-4", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       /* Alias: family inet6 */
+       { .name = { "-6", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       { .name = { "markmask", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_MARKMASK,
+         .parse = ipset_parse_uint32,          .print = ipset_print_mark,
+       },
+       { .name = { "hashsize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_HASHSIZE,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "maxelem", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_MAXELEM,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "counters", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_COUNTERS,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_CREATE_COMMENT,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "forceadd", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FORCEADD,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "skbinfo", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_SKBINFO,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       /* Backward compatibility */
+       { .name = { "probes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PROBES,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "resize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_RESIZE,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "from", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP,
+         .parse = ipset_parse_ignored,
+       },
+       { .name = { "to", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP_TO,
+         .parse = ipset_parse_ignored,
+       },
+       { .name = { "network", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP,
+         .parse = ipset_parse_ignored,
+       },
+       { },
+};
+
+static const struct ipset_arg hash_ipmark_add_args2[] = {
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "packets", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PACKETS,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "bytes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_BYTES,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_ADT_COMMENT,
+         .parse = ipset_parse_comment,         .print = ipset_print_comment,
+       },
+       { .name = { "skbmark", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBMARK,
+         .parse = ipset_parse_skbmark,         .print = ipset_print_skbmark,
+       },
+       { .name = { "skbprio", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBPRIO,
+         .parse = ipset_parse_skbprio,         .print = ipset_print_skbprio,
+       },
+       { .name = { "skbqueue", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBQUEUE,
+         .parse = ipset_parse_uint16,          .print = ipset_print_number,
+       },
+       { },
+};
+
+
+static const char hash_ipmark_usage2[] =
+"create SETNAME hash:ip,mark\n"
+"              [family inet|inet6] [markmask VALUE]\n"
+"               [hashsize VALUE] [maxelem VALUE]\n"
+"               [timeout VALUE] [counters] [comment]\n"
+"              [forceadd] [skbinfo]\n"
+"add    SETNAME IP,MARK [timeout VALUE]\n"
+"               [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
+"              [skbmark VALUE] [skbprio VALUE] [skbqueue VALUE]\n"
+"del    SETNAME IP,MARK\n"
+"test   SETNAME IP,MARK\n\n"
+"where depending on the INET family\n"
+"      IP is a valid IPv4 or IPv6 address (or hostname).\n"
+"      Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
+"      is supported for IPv4.\n"
+"      Adding/deleting single mark element\n"
+"      is supported both for IPv4 and IPv6.\n";
+
+static struct ipset_type ipset_hash_ipmark2 = {
+       .name = "hash:ip,mark",
+       .alias = { "ipmarkhash", NULL },
+       .revision = 2,
+       .family = NFPROTO_IPSET_IPV46,
+       .dimension = IPSET_DIM_TWO,
+       .elem = {
+               [IPSET_DIM_ONE - 1] = {
+                       .parse = ipset_parse_ip4_single6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP
+               },
+               [IPSET_DIM_TWO - 1] = {
+                       .parse = ipset_parse_mark,
+                       .print = ipset_print_mark,
+                       .opt = IPSET_OPT_MARK
+               },
+       },
+       .args = {
+               [IPSET_CREATE] = hash_ipmark_create_args2,
+               [IPSET_ADD] = hash_ipmark_add_args2,
+       },
+       .mandatory = {
+               [IPSET_CREATE] = 0,
+               [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_MARK),
+               [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_MARK),
+               [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_MARK),
+       },
+       .full = {
+               [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_MARKMASK)
+                       | IPSET_FLAG(IPSET_OPT_HASHSIZE)
+                       | IPSET_FLAG(IPSET_OPT_MAXELEM)
+                       | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+                       | IPSET_FLAG(IPSET_OPT_COUNTERS)
+                       | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_FORCEADD)
+                       | IPSET_FLAG(IPSET_OPT_SKBINFO),
+               [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_IP_TO)
+                       | IPSET_FLAG(IPSET_OPT_MARK)
+                       | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+                       | IPSET_FLAG(IPSET_OPT_PACKETS)
+                       | IPSET_FLAG(IPSET_OPT_BYTES)
+                       | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_SKBMARK)
+                       | IPSET_FLAG(IPSET_OPT_SKBPRIO)
+                       | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
+               [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_IP_TO)
+                       | IPSET_FLAG(IPSET_OPT_MARK),
+               [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_MARK),
+       },
+
+       .usage = hash_ipmark_usage2,
+       .description = "sbkinfo support"
+};
+
 void _init(void);
 void _init(void)
 {
        ipset_type_add(&ipset_hash_ipmark0);
        ipset_type_add(&ipset_hash_ipmark1);
+       ipset_type_add(&ipset_hash_ipmark2);
 }
index 919376d393589ea25ab87f89ac207b41d696e248..21669220f377536d857e147a928024d4d82f75dd 100644 (file)
@@ -600,6 +600,193 @@ static struct ipset_type ipset_hash_ipport4 = {
        .description = "forceadd support",
 };
 
+/* Parse commandline arguments */
+static const struct ipset_arg hash_ipport_create_args5[] = {
+       { .name = { "family", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,          .print = ipset_print_family,
+       },
+       /* Alias: family inet */
+       { .name = { "-4", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       /* Alias: family inet6 */
+       { .name = { "-6", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       { .name = { "hashsize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_HASHSIZE,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "maxelem", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_MAXELEM,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "counters", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_COUNTERS,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_CREATE_COMMENT,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "forceadd", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FORCEADD,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "skbinfo", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_SKBINFO,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       /* Backward compatibility */
+       { .name = { "probes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PROBES,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "resize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_RESIZE,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "from", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP,
+         .parse = ipset_parse_ignored,
+       },
+       { .name = { "to", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP_TO,
+         .parse = ipset_parse_ignored,
+       },
+       { .name = { "network", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP,
+         .parse = ipset_parse_ignored,
+       },
+       { },
+};
+
+static const struct ipset_arg hash_ipport_add_args5[] = {
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "packets", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PACKETS,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "bytes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_BYTES,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_ADT_COMMENT,
+         .parse = ipset_parse_comment,         .print = ipset_print_comment,
+       },
+       { .name = { "skbmark", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBMARK,
+         .parse = ipset_parse_skbmark,         .print = ipset_print_skbmark,
+       },
+       { .name = { "skbprio", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBPRIO,
+         .parse = ipset_parse_skbprio,         .print = ipset_print_skbprio,
+       },
+       { .name = { "skbqueue", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBQUEUE,
+         .parse = ipset_parse_uint16,          .print = ipset_print_number,
+       },
+       { },
+};
+
+static const char hash_ipport_usage5[] =
+"create SETNAME hash:ip,port\n"
+"              [family inet|inet6]\n"
+"               [hashsize VALUE] [maxelem VALUE]\n"
+"               [timeout VALUE] [counters] [comment]\n"
+"              [forceadd] [skbinfo]\n"
+"add    SETNAME IP,PROTO:PORT [timeout VALUE]\n"
+"               [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
+"              [skbmark VALUE] [skbprio VALUE] [skbqueue VALUE]\n"
+"del    SETNAME IP,PROTO:PORT\n"
+"test   SETNAME IP,PROTO:PORT\n\n"
+"where depending on the INET family\n"
+"      IP is a valid IPv4 or IPv6 address (or hostname).\n"
+"      Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
+"      is supported for IPv4.\n"
+"      Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
+"      port range is supported both for IPv4 and IPv6.\n";
+
+static struct ipset_type ipset_hash_ipport5 = {
+       .name = "hash:ip,port",
+       .alias = { "ipporthash", NULL },
+       .revision = 5,
+       .family = NFPROTO_IPSET_IPV46,
+       .dimension = IPSET_DIM_TWO,
+       .elem = {
+               [IPSET_DIM_ONE - 1] = {
+                       .parse = ipset_parse_ip4_single6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP
+               },
+               [IPSET_DIM_TWO - 1] = {
+                       .parse = ipset_parse_proto_port,
+                       .print = ipset_print_proto_port,
+                       .opt = IPSET_OPT_PORT
+               },
+       },
+       .args = {
+               [IPSET_CREATE] = hash_ipport_create_args5,
+               [IPSET_ADD] = hash_ipport_add_args5,
+       },
+       .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_FLAG(IPSET_OPT_COUNTERS)
+                       | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_FORCEADD)
+                       | IPSET_FLAG(IPSET_OPT_SKBINFO),
+               [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+                       | 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_FLAG(IPSET_OPT_PACKETS)
+                       | IPSET_FLAG(IPSET_OPT_BYTES)
+                       | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_SKBMARK)
+                       | IPSET_FLAG(IPSET_OPT_SKBPRIO)
+                       | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
+               [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+                       | 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_PORT)
+                       | IPSET_FLAG(IPSET_OPT_PROTO),
+       },
+
+       .usage = hash_ipport_usage5,
+       .usagefn = ipset_port_usage,
+       .description = "skbinfo support",
+};
+
 void _init(void);
 void _init(void)
 {
@@ -607,4 +794,5 @@ void _init(void)
        ipset_type_add(&ipset_hash_ipport2);
        ipset_type_add(&ipset_hash_ipport3);
        ipset_type_add(&ipset_hash_ipport4);
+       ipset_type_add(&ipset_hash_ipport5);
 }
index 748f08376f3bee1304084f179470d0e6ca717026..5eeb24515e228a52e4d5fde9ae51200753577914 100644 (file)
@@ -644,6 +644,204 @@ static struct ipset_type ipset_hash_ipportip4 = {
        .description = "forceadd support",
 };
 
+/* Parse commandline arguments */
+static const struct ipset_arg hash_ipportip_create_args5[] = {
+       { .name = { "family", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,          .print = ipset_print_family,
+       },
+       /* Alias: family inet */
+       { .name = { "-4", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       /* Alias: family inet6 */
+       { .name = { "-6", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       { .name = { "hashsize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_HASHSIZE,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "maxelem", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_MAXELEM,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "counters", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_COUNTERS,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_CREATE_COMMENT,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "forceadd", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FORCEADD,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "skbinfo", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_SKBINFO,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       /* Backward compatibility */
+       { .name = { "probes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PROBES,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "resize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_RESIZE,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "from", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP,
+         .parse = ipset_parse_ignored,
+       },
+       { .name = { "to", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP_TO,
+         .parse = ipset_parse_ignored,
+       },
+       { .name = { "network", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP,
+         .parse = ipset_parse_ignored,
+       },
+       { },
+};
+
+static const struct ipset_arg hash_ipportip_add_args5[] = {
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "packets", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PACKETS,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "bytes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_BYTES,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_ADT_COMMENT,
+         .parse = ipset_parse_comment,         .print = ipset_print_comment,
+       },
+       { .name = { "skbmark", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBMARK,
+         .parse = ipset_parse_skbmark,         .print = ipset_print_skbmark,
+       },
+       { .name = { "skbprio", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBPRIO,
+         .parse = ipset_parse_skbprio,         .print = ipset_print_skbprio,
+       },
+       { .name = { "skbqueue", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBQUEUE,
+         .parse = ipset_parse_uint16,          .print = ipset_print_number,
+       },
+       { },
+};
+
+static const char hash_ipportip_usage5[] =
+"create SETNAME hash:ip,port,ip\n"
+"              [family inet|inet6]\n"
+"               [hashsize VALUE] [maxelem VALUE]\n"
+"               [timeout VALUE] [counters] [comment]\n"
+"              [forceadd] [skbinfo]\n"
+"add    SETNAME IP,PROTO:PORT,IP [timeout VALUE]\n"
+"               [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
+"              [skbmark VALUE] [skbprio VALUE] [skbqueue VALUE]\n"
+"del    SETNAME IP,PROTO:PORT,IP\n"
+"test   SETNAME IP,PROTO:PORT,IP\n\n"
+"where depending on the INET family\n"
+"      IP is a valid IPv4 or IPv6 address (or hostname).\n"
+"      Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
+"      in the first IP component is supported for IPv4.\n"
+"      Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
+"      port range is supported both for IPv4 and IPv6.\n";
+
+static struct ipset_type ipset_hash_ipportip5 = {
+       .name = "hash:ip,port,ip",
+       .alias = { "ipportiphash", NULL },
+       .revision = 5,
+       .family = NFPROTO_IPSET_IPV46,
+       .dimension = IPSET_DIM_THREE,
+       .elem = {
+               [IPSET_DIM_ONE - 1] = {
+                       .parse = ipset_parse_ip4_single6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP
+               },
+               [IPSET_DIM_TWO - 1] = {
+                       .parse = ipset_parse_proto_port,
+                       .print = ipset_print_proto_port,
+                       .opt = IPSET_OPT_PORT
+               },
+               [IPSET_DIM_THREE - 1] = {
+                       .parse = ipset_parse_single_ip,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP2
+               },
+       },
+       .args = {
+               [IPSET_CREATE] = hash_ipportip_create_args5,
+               [IPSET_ADD] = hash_ipportip_add_args5,
+       },
+       .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_FLAG(IPSET_OPT_COUNTERS)
+                       | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_FORCEADD)
+                       | IPSET_FLAG(IPSET_OPT_SKBINFO),
+               [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+                       | 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_TIMEOUT)
+                       | IPSET_FLAG(IPSET_OPT_PACKETS)
+                       | IPSET_FLAG(IPSET_OPT_BYTES)
+                       | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_SKBMARK)
+                       | IPSET_FLAG(IPSET_OPT_SKBPRIO)
+                       | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
+               [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+                       | 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_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_PORT)
+                       | IPSET_FLAG(IPSET_OPT_PROTO)
+                       | IPSET_FLAG(IPSET_OPT_IP2),
+       },
+
+       .usage = hash_ipportip_usage5,
+       .usagefn = ipset_port_usage,
+       .description = "skbinfo support",
+};
+
 void _init(void);
 void _init(void)
 {
@@ -651,4 +849,5 @@ void _init(void)
        ipset_type_add(&ipset_hash_ipportip2);
        ipset_type_add(&ipset_hash_ipportip3);
        ipset_type_add(&ipset_hash_ipportip4);
+       ipset_type_add(&ipset_hash_ipportip5);
 }
index 82339c1bff993664c9cfbd5c6b3b13757b288608..bd394de27598f1b8eae15edfbd689ce1b0dea71a 100644 (file)
@@ -906,6 +906,219 @@ static struct ipset_type ipset_hash_ipportnet6 = {
        .description = "forceadd support",
 };
 
+/* Parse commandline arguments */
+static const struct ipset_arg hash_ipportnet_create_args7[] = {
+       { .name = { "family", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,          .print = ipset_print_family,
+       },
+       /* Alias: family inet */
+       { .name = { "-4", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       /* Alias: family inet6 */
+       { .name = { "-6", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       { .name = { "hashsize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_HASHSIZE,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "maxelem", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_MAXELEM,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "counters", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_COUNTERS,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_CREATE_COMMENT,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "forceadd", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FORCEADD,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "skbinfo", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_SKBINFO,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       /* Backward compatibility */
+       { .name = { "probes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PROBES,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "resize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_RESIZE,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "from", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP,
+         .parse = ipset_parse_ignored,
+       },
+       { .name = { "to", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP_TO,
+         .parse = ipset_parse_ignored,
+       },
+       { .name = { "network", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP,
+         .parse = ipset_parse_ignored,
+       },
+       { },
+};
+
+static const struct ipset_arg hash_ipportnet_add_args7[] = {
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "nomatch", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_NOMATCH,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "packets", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PACKETS,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "bytes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_BYTES,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_ADT_COMMENT,
+         .parse = ipset_parse_comment,         .print = ipset_print_comment,
+       },
+       { .name = { "skbmark", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBMARK,
+         .parse = ipset_parse_skbmark,         .print = ipset_print_skbmark,
+       },
+       { .name = { "skbprio", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBPRIO,
+         .parse = ipset_parse_skbprio,         .print = ipset_print_skbprio,
+       },
+       { .name = { "skbqueue", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBQUEUE,
+         .parse = ipset_parse_uint16,          .print = ipset_print_number,
+       },
+       { },
+};
+
+static const char hash_ipportnet_usage7[] =
+"create SETNAME hash:ip,port,net\n"
+"              [family inet|inet6]\n"
+"               [hashsize VALUE] [maxelem VALUE]\n"
+"               [timeout VALUE] [counters] [comment]\n"
+"              [forceadd] [skbinfo]\n"
+"add    SETNAME IP,PROTO:PORT,IP[/CIDR] [timeout VALUE] [nomatch]\n"
+"               [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
+"              [skbmark VALUE] [skbprio VALUE] [skbqueue 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";
+
+static struct ipset_type ipset_hash_ipportnet7 = {
+       .name = "hash:ip,port,net",
+       .alias = { "ipportnethash", NULL },
+       .revision = 7,
+       .family = NFPROTO_IPSET_IPV46,
+       .dimension = IPSET_DIM_THREE,
+       .elem = {
+               [IPSET_DIM_ONE - 1] = {
+                       .parse = ipset_parse_ip4_single6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP
+               },
+               [IPSET_DIM_TWO - 1] = {
+                       .parse = ipset_parse_proto_port,
+                       .print = ipset_print_proto_port,
+                       .opt = IPSET_OPT_PORT
+               },
+               [IPSET_DIM_THREE - 1] = {
+                       .parse = ipset_parse_ip4_net6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP2
+               },
+       },
+       .args = {
+               [IPSET_CREATE] = hash_ipportnet_create_args6,
+               [IPSET_ADD] = hash_ipportnet_add_args5,
+               [IPSET_TEST] = hash_ipportnet_test_args5,
+       },
+       .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_FLAG(IPSET_OPT_COUNTERS)
+                       | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_FORCEADD)
+                       | IPSET_FLAG(IPSET_OPT_SKBINFO),
+               [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_FLAG(IPSET_OPT_NOMATCH)
+                       | IPSET_FLAG(IPSET_OPT_PACKETS)
+                       | IPSET_FLAG(IPSET_OPT_BYTES)
+                       | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_SKBMARK)
+                       | IPSET_FLAG(IPSET_OPT_SKBPRIO)
+                       | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
+               [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)
+                       | IPSET_FLAG(IPSET_OPT_NOMATCH),
+       },
+
+       .usage = hash_ipportnet_usage7,
+       .usagefn = ipset_port_usage,
+       .description = "skbinfo support",
+};
+
 void _init(void);
 void _init(void)
 {
@@ -915,4 +1128,5 @@ void _init(void)
        ipset_type_add(&ipset_hash_ipportnet4);
        ipset_type_add(&ipset_hash_ipportnet5);
        ipset_type_add(&ipset_hash_ipportnet6);
+       ipset_type_add(&ipset_hash_ipportnet7);
 }
index 1110a226b0716eed747a489bbf0561a26c5805cd..0dd5578159c945448c7bccd58e8b9d835df827c1 100644 (file)
@@ -628,6 +628,171 @@ static struct ipset_type ipset_hash_net5 = {
        .description = "forceadd support",
 };
 
+/* Parse commandline arguments */
+static const struct ipset_arg hash_net_create_args6[] = {
+       { .name = { "family", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,          .print = ipset_print_family,
+       },
+       /* Alias: family inet */
+       { .name = { "-4", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       /* Alias: family inet6 */
+       { .name = { "-6", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       { .name = { "hashsize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_HASHSIZE,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "maxelem", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_MAXELEM,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "counters", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_COUNTERS,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_CREATE_COMMENT,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "forceadd", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FORCEADD,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "skbinfo", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_SKBINFO,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       /* Ignored options: backward compatibilty */
+       { .name = { "probes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PROBES,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "resize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_RESIZE,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { },
+};
+
+
+static const struct ipset_arg hash_net_add_args6[] = {
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "nomatch", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_NOMATCH,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "packets", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PACKETS,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "bytes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_BYTES,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_ADT_COMMENT,
+         .parse = ipset_parse_comment,         .print = ipset_print_comment,
+       },
+       { .name = { "skbmark", NULL },
+         . has_arg = IPSET_MANDATORY_ARG,      .opt = IPSET_OPT_SKBMARK,
+         .parse = ipset_parse_skbmark,         .print = ipset_print_skbmark,
+       },
+       { .name = { "skbprio", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBPRIO,
+         .parse = ipset_parse_skbprio,         .print = ipset_print_skbprio,
+       },
+       { .name = { "skbqueue", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBQUEUE,
+         .parse = ipset_parse_uint16,          .print = ipset_print_number,
+       },
+       { },
+};
+
+
+static const char hash_net_usage6[] =
+"create SETNAME hash:net\n"
+"              [family inet|inet6]\n"
+"               [hashsize VALUE] [maxelem VALUE]\n"
+"               [timeout VALUE] [counters] [comment]\n"
+"              [skbinfo] [forceadd]\n"
+"add    SETNAME IP[/CIDR]|FROM-TO [timeout VALUE] [nomatch]\n"
+"               [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
+"              [skbmark VALUE/VALUE] [skbprio VALUE] [skbqueue 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";
+
+static struct ipset_type ipset_hash_net6 = {
+       .name = "hash:net",
+       .alias = { "nethash", NULL },
+       .revision = 6,
+       .family = NFPROTO_IPSET_IPV46,
+       .dimension = IPSET_DIM_ONE,
+       .elem = {
+               [IPSET_DIM_ONE - 1] = {
+                       .parse = ipset_parse_ip4_net6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP
+               },
+       },
+       .args = {
+               [IPSET_CREATE] = hash_net_create_args6,
+               [IPSET_ADD] = hash_net_add_args6,
+               [IPSET_TEST] = hash_net_test_args4,
+       },
+       .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_FLAG(IPSET_OPT_COUNTERS)
+                       | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_FORCEADD)
+                       | IPSET_FLAG(IPSET_OPT_SKBINFO),
+               [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_CIDR)
+                       | IPSET_FLAG(IPSET_OPT_IP_TO)
+                       | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+                       | IPSET_FLAG(IPSET_OPT_NOMATCH)
+                       | IPSET_FLAG(IPSET_OPT_PACKETS)
+                       | IPSET_FLAG(IPSET_OPT_BYTES)
+                       | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_SKBMARK)
+                       | IPSET_FLAG(IPSET_OPT_SKBPRIO)
+                       | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
+               [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)
+                       | IPSET_FLAG(IPSET_OPT_NOMATCH),
+       },
+
+       .usage = hash_net_usage6,
+       .description = "skbinfo support",
+};
+
 void _init(void);
 void _init(void)
 {
@@ -637,4 +802,5 @@ void _init(void)
        ipset_type_add(&ipset_hash_net3);
        ipset_type_add(&ipset_hash_net4);
        ipset_type_add(&ipset_hash_net5);
+       ipset_type_add(&ipset_hash_net6);
 }
index 4efc57a2c63ca31e35d1dc2d68bdebd24b277d06..abf286c647e5420bdad1e0c340e6b73f3624d5a1 100644 (file)
@@ -674,6 +674,175 @@ static struct ipset_type ipset_hash_netiface5 = {
        .description = "forceadd support",
 };
 
+/* Parse commandline arguments */
+static const struct ipset_arg hash_netiface_create_args6[] = {
+       { .name = { "family", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,          .print = ipset_print_family,
+       },
+       /* Alias: family inet */
+       { .name = { "-4", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       /* Alias: family inet6 */
+       { .name = { "-6", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       { .name = { "hashsize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_HASHSIZE,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "maxelem", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_MAXELEM,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "counters", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_COUNTERS,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_CREATE_COMMENT,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "forceadd", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FORCEADD,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "skbinfo", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_SKBINFO,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { },
+};
+
+static const struct ipset_arg hash_netiface_add_args6[] = {
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "nomatch", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_NOMATCH,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "packets", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PACKETS,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "bytes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_BYTES,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_ADT_COMMENT,
+         .parse = ipset_parse_comment,         .print = ipset_print_comment,
+       },
+       { .name = { "skbmark", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBMARK,
+         .parse = ipset_parse_skbmark,         .print = ipset_print_skbmark,
+       },
+       { .name = { "skbprio", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBPRIO,
+         .parse = ipset_parse_skbprio,         .print = ipset_print_skbprio,
+       },
+       { .name = { "skbqueue", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBQUEUE,
+         .parse = ipset_parse_uint16,          .print = ipset_print_number,
+       },
+       { },
+};
+
+static const char hash_netiface_usage6[] =
+"create SETNAME hash:net,iface\n"
+"              [family inet|inet6]\n"
+"               [hashsize VALUE] [maxelem VALUE]\n"
+"               [timeout VALUE] [counters] [comment]\n"
+"              [forceadd] [skbinfo]\n"
+"add    SETNAME IP[/CIDR]|FROM-TO,[physdev:]IFACE [timeout VALUE] [nomatch]\n"
+"               [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
+"              [skbmark VALUE] [skbprip VALUE] [skbqueue VALUE]\n"
+"del    SETNAME IP[/CIDR]|FROM-TO,[physdev:]IFACE\n"
+"test   SETNAME IP[/CIDR],[physdev:]IFACE\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";
+
+static struct ipset_type ipset_hash_netiface6 = {
+       .name = "hash:net,iface",
+       .alias = { "netifacehash", NULL },
+       .revision = 6,
+       .family = NFPROTO_IPSET_IPV46,
+       .dimension = IPSET_DIM_TWO,
+       .elem = {
+               [IPSET_DIM_ONE - 1] = {
+                       .parse = ipset_parse_ip4_net6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP
+               },
+               [IPSET_DIM_TWO - 1] = {
+                       .parse = ipset_parse_iface,
+                       .print = ipset_print_iface,
+                       .opt = IPSET_OPT_IFACE
+               },
+       },
+       .args = {
+               [IPSET_CREATE] = hash_netiface_create_args6,
+               [IPSET_ADD] = hash_netiface_add_args6,
+               [IPSET_TEST] = hash_netiface_test_args4,
+       },
+       .mandatory = {
+               [IPSET_CREATE] = 0,
+               [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_IFACE),
+               [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_IFACE),
+               [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_IFACE),
+       },
+       .full = {
+               [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
+                       | IPSET_FLAG(IPSET_OPT_MAXELEM)
+                       | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+                       | IPSET_FLAG(IPSET_OPT_COUNTERS)
+                       | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_FORCEADD)
+                       | IPSET_FLAG(IPSET_OPT_SKBINFO),
+               [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_CIDR)
+                       | IPSET_FLAG(IPSET_OPT_IP_TO)
+                       | IPSET_FLAG(IPSET_OPT_IFACE)
+                       | IPSET_FLAG(IPSET_OPT_PHYSDEV)
+                       | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+                       | IPSET_FLAG(IPSET_OPT_NOMATCH)
+                       | IPSET_FLAG(IPSET_OPT_PACKETS)
+                       | IPSET_FLAG(IPSET_OPT_BYTES)
+                       | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_SKBMARK)
+                       | IPSET_FLAG(IPSET_OPT_SKBPRIO)
+                       | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
+               [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_CIDR)
+                       | IPSET_FLAG(IPSET_OPT_IP_TO)
+                       | IPSET_FLAG(IPSET_OPT_IFACE)
+                       | IPSET_FLAG(IPSET_OPT_PHYSDEV),
+               [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_CIDR)
+                       | IPSET_FLAG(IPSET_OPT_IP_TO)
+                       | IPSET_FLAG(IPSET_OPT_IFACE)
+                       | IPSET_FLAG(IPSET_OPT_PHYSDEV)
+                       | IPSET_FLAG(IPSET_OPT_NOMATCH),
+       },
+
+       .usage = hash_netiface_usage6,
+       .description = "skbinfo support",
+};
+
 void _init(void);
 void _init(void)
 {
@@ -683,4 +852,5 @@ void _init(void)
        ipset_type_add(&ipset_hash_netiface3);
        ipset_type_add(&ipset_hash_netiface4);
        ipset_type_add(&ipset_hash_netiface5);
+       ipset_type_add(&ipset_hash_netiface6);
 }
index 5378d116d763fa432cacbcaef36e33188b166b8d..b0d4954af899440777ce5df9129dac8bcc1d5e4f 100644 (file)
@@ -285,9 +285,179 @@ static struct ipset_type ipset_hash_netnet1 = {
        .description = "forceadd support",
 };
 
+/* Parse commandline arguments */
+static const struct ipset_arg hash_netnet_create_args2[] = {
+       { .name = { "family", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,          .print = ipset_print_family,
+       },
+       /* Alias: family inet */
+       { .name = { "-4", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       /* Alias: family inet6 */
+       { .name = { "-6", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       { .name = { "hashsize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_HASHSIZE,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "maxelem", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_MAXELEM,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "counters", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_COUNTERS,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_CREATE_COMMENT,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "forceadd", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FORCEADD,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "skbinfo", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_SKBINFO,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { },
+};
+
+static const struct ipset_arg hash_netnet_add_args2[] = {
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "nomatch", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_NOMATCH,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "packets", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PACKETS,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "bytes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_BYTES,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_ADT_COMMENT,
+         .parse = ipset_parse_comment,         .print = ipset_print_comment,
+       },
+       { .name = { "skbmark", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBMARK,
+         .parse = ipset_parse_skbmark,         .print = ipset_print_skbmark,
+       },
+       { .name = { "skbprio", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBPRIO,
+         .parse = ipset_parse_skbprio,         .print = ipset_print_skbprio,
+       },
+       { .name = { "skbqueue", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBQUEUE,
+         .parse = ipset_parse_uint16,          .print = ipset_print_number,
+       },
+       { },
+};
+
+static const char hash_netnet_usage2[] =
+"create SETNAME hash:net,net\n"
+"              [family inet|inet6]\n"
+"               [hashsize VALUE] [maxelem VALUE]\n"
+"               [timeout VALUE] [counters] [forceadd] [skbinfo]\n"
+"add    SETNAME IP[/CIDR]|FROM-TO,IP[/CIDR]|FROM-TO [timeout VALUE] [nomatch]\n"
+"               [packets VALUE] [bytes VALUE]\n"
+"              [skbmark VALUE] [skbprio VALUE] [skbqueue VALUE]\n"
+"del    SETNAME IP[/CIDR]|FROM-TO,IP[/CIDR]|FROM-TO\n"
+"test   SETNAME IP[/CIDR],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";
+
+static struct ipset_type ipset_hash_netnet2 = {
+       .name = "hash:net,net",
+       .alias = { "netnethash", NULL },
+       .revision = 2,
+       .family = NFPROTO_IPSET_IPV46,
+       .dimension = IPSET_DIM_TWO,
+       .elem = {
+               [IPSET_DIM_ONE - 1] = {
+                       .parse = ipset_parse_ip4_net6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP
+               },
+               [IPSET_DIM_TWO - 1] = {
+                       .parse = ipset_parse_ip4_net6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP2
+               },
+       },
+       .args = {
+               [IPSET_CREATE] = hash_netnet_create_args2,
+               [IPSET_ADD] = hash_netnet_add_args2,
+               [IPSET_TEST] = hash_netnet_test_args0,
+       },
+       .mandatory = {
+               [IPSET_CREATE] = 0,
+               [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_IP2),
+               [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_IP2),
+               [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_IP2),
+       },
+       .full = {
+               [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
+                       | IPSET_FLAG(IPSET_OPT_MAXELEM)
+                       | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+                       | IPSET_FLAG(IPSET_OPT_COUNTERS)
+                       | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_FORCEADD)
+                       | IPSET_FLAG(IPSET_OPT_SKBINFO),
+               [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_CIDR)
+                       | IPSET_FLAG(IPSET_OPT_IP_TO)
+                       | IPSET_FLAG(IPSET_OPT_IP2)
+                       | IPSET_FLAG(IPSET_OPT_CIDR2)
+                       | IPSET_FLAG(IPSET_OPT_IP2_TO)
+                       | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+                       | IPSET_FLAG(IPSET_OPT_NOMATCH)
+                       | IPSET_FLAG(IPSET_OPT_PACKETS)
+                       | IPSET_FLAG(IPSET_OPT_BYTES)
+                       | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_SKBMARK)
+                       | IPSET_FLAG(IPSET_OPT_SKBPRIO)
+                       | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
+               [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_CIDR)
+                       | IPSET_FLAG(IPSET_OPT_IP_TO)
+                       | 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_CIDR)
+                       | IPSET_FLAG(IPSET_OPT_IP2)
+                       | IPSET_FLAG(IPSET_OPT_CIDR2)
+                       | IPSET_FLAG(IPSET_OPT_NOMATCH),
+       },
+
+       .usage = hash_netnet_usage2,
+       .description = "skbinfo support",
+};
+
 void _init(void);
 void _init(void)
 {
        ipset_type_add(&ipset_hash_netnet0);
        ipset_type_add(&ipset_hash_netnet1);
+       ipset_type_add(&ipset_hash_netnet2);
 }
index dbcbe977594d19c80dfb232bf29013e8491c97d3..b99654187cfa6525e5d0657242e1e6ce9d2ead05 100644 (file)
@@ -725,6 +725,182 @@ static struct ipset_type ipset_hash_netport6 = {
        .description = "forceadd support",
 };
 
+/* Parse commandline arguments */
+static const struct ipset_arg hash_netport_create_args7[] = {
+       { .name = { "family", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,          .print = ipset_print_family,
+       },
+       /* Alias: family inet */
+       { .name = { "-4", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       /* Alias: family inet6 */
+       { .name = { "-6", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       { .name = { "hashsize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_HASHSIZE,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "maxelem", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_MAXELEM,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "counters", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_COUNTERS,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_CREATE_COMMENT,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "forceadd", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FORCEADD,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "skbinfo", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_SKBINFO,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { },
+};
+
+static const struct ipset_arg hash_netport_add_args7[] = {
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "nomatch", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_NOMATCH,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "packets", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PACKETS,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "bytes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_BYTES,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_ADT_COMMENT,
+         .parse = ipset_parse_comment,         .print = ipset_print_comment,
+       },
+       { .name = { "skbmark", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBMARK,
+         .parse = ipset_parse_skbmark,         .print = ipset_print_skbmark,
+       },
+       { .name = { "skbprio", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBPRIO,
+         .parse = ipset_parse_skbprio,         .print = ipset_print_skbprio,
+       },
+       { .name = { "skbqueue", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBQUEUE,
+         .parse = ipset_parse_uint16,          .print = ipset_print_number,
+       },
+       { },
+};
+
+static const char hash_netport_usage7[] =
+"create SETNAME hash:net,port\n"
+"              [family inet|inet6]\n"
+"               [hashsize VALUE] [maxelem VALUE]\n"
+"               [timeout VALUE] [counters] [comment]\n"
+"              [forceadd] [skbinfo]\n"
+"add    SETNAME IP[/CIDR]|FROM-TO,PROTO:PORT [timeout VALUE] [nomatch]\n"
+"               [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
+"              [skbmark VALUE] [skbprio VALUE] [skbqueue 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";
+
+static struct ipset_type ipset_hash_netport7 = {
+       .name = "hash:net,port",
+       .alias = { "netporthash", NULL },
+       .revision = 7,
+       .family = NFPROTO_IPSET_IPV46,
+       .dimension = IPSET_DIM_TWO,
+       .elem = {
+               [IPSET_DIM_ONE - 1] = {
+                       .parse = ipset_parse_ip4_net6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP
+               },
+               [IPSET_DIM_TWO - 1] = {
+                       .parse = ipset_parse_proto_port,
+                       .print = ipset_print_proto_port,
+                       .opt = IPSET_OPT_PORT
+               },
+       },
+       .args = {
+               [IPSET_CREATE] = hash_netport_create_args7,
+               [IPSET_ADD] = hash_netport_add_args7,
+               [IPSET_TEST] = hash_netport_test_args5,
+       },
+       .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_FLAG(IPSET_OPT_COUNTERS)
+                       | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_FORCEADD)
+                       | IPSET_FLAG(IPSET_OPT_SKBINFO),
+               [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_FLAG(IPSET_OPT_NOMATCH)
+                       | IPSET_FLAG(IPSET_OPT_PACKETS)
+                       | IPSET_FLAG(IPSET_OPT_BYTES)
+                       | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_SKBMARK)
+                       | IPSET_FLAG(IPSET_OPT_SKBPRIO)
+                       | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
+               [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)
+                       | IPSET_FLAG(IPSET_OPT_NOMATCH),
+       },
+
+       .usage = hash_netport_usage7,
+       .usagefn = ipset_port_usage,
+       .description = "skbinfo support",
+};
+
 void _init(void);
 void _init(void)
 {
@@ -734,4 +910,5 @@ void _init(void)
        ipset_type_add(&ipset_hash_netport4);
        ipset_type_add(&ipset_hash_netport5);
        ipset_type_add(&ipset_hash_netport6);
+       ipset_type_add(&ipset_hash_netport7);
 }
index 07299b77b86efe9e59757148eaba0485f0e45878..c2146638b8835c2029f34334c98d70721923d9a5 100644 (file)
@@ -332,9 +332,203 @@ static struct ipset_type ipset_hash_netportnet1 = {
        .description = "forceadd support",
 };
 
+/* Parse commandline arguments */
+static const struct ipset_arg hash_netportnet_create_args2[] = {
+       { .name = { "family", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,          .print = ipset_print_family,
+       },
+       /* Alias: family inet */
+       { .name = { "-4", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       /* Alias: family inet6 */
+       { .name = { "-6", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FAMILY,
+         .parse = ipset_parse_family,
+       },
+       { .name = { "hashsize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_HASHSIZE,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "maxelem", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_MAXELEM,
+         .parse = ipset_parse_uint32,          .print = ipset_print_number,
+       },
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "counters", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_COUNTERS,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_CREATE_COMMENT,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "forceadd", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_FORCEADD,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "skbinfo", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_SKBINFO,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { },
+};
+
+static const struct ipset_arg hash_netportnet_add_args2[] = {
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "nomatch", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_NOMATCH,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "packets", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PACKETS,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "bytes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_BYTES,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_ADT_COMMENT,
+         .parse = ipset_parse_comment,         .print = ipset_print_comment,
+       },
+       { .name = { "skbmark", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBMARK,
+         .parse = ipset_parse_skbmark,         .print = ipset_print_skbmark,
+       },
+       { .name = { "skbprio", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBPRIO,
+         .parse = ipset_parse_skbprio,         .print = ipset_print_skbprio,
+       },
+       { .name = { "skbqueue", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_SKBQUEUE,
+         .parse = ipset_parse_uint16,          .print = ipset_print_number,
+       },
+       { },
+};
+
+static const char hash_netportnet_usage2[] =
+"create SETNAME hash:net,port,net\n"
+"              [family inet|inet6]\n"
+"               [hashsize VALUE] [maxelem VALUE]\n"
+"               [timeout VALUE] [counters] [comment]\n"
+"              [forceadd] [skbinfo]\n"
+"add    SETNAME IP[/CIDR],PROTO:PORT,IP[/CIDR] [timeout VALUE] [nomatch]\n"
+"               [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
+"              [skbmark VALUE] [skbprio VALUE] [skbqueue VALUE]\n"
+"del    SETNAME IP[/CIDR],PROTO:PORT,IP[/CIDR]\n"
+"test   SETNAME IP[/CIDR],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";
+
+static struct ipset_type ipset_hash_netportnet2 = {
+       .name = "hash:net,port,net",
+       .alias = { "netportnethash", NULL },
+       .revision = 2,
+       .family = NFPROTO_IPSET_IPV46,
+       .dimension = IPSET_DIM_THREE,
+       .elem = {
+               [IPSET_DIM_ONE - 1] = {
+                       .parse = ipset_parse_ip4_net6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP
+               },
+               [IPSET_DIM_TWO - 1] = {
+                       .parse = ipset_parse_proto_port,
+                       .print = ipset_print_proto_port,
+                       .opt = IPSET_OPT_PORT
+               },
+               [IPSET_DIM_THREE - 1] = {
+                       .parse = ipset_parse_ip4_net6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP2
+               },
+       },
+       .args = {
+               [IPSET_CREATE] = hash_netportnet_create_args2,
+               [IPSET_ADD] = hash_netportnet_add_args2,
+               [IPSET_TEST] = hash_netportnet_test_args0,
+       },
+       .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_FLAG(IPSET_OPT_COUNTERS)
+                       | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_FORCEADD)
+                       | IPSET_FLAG(IPSET_OPT_SKBINFO),
+               [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_FLAG(IPSET_OPT_NOMATCH)
+                       | IPSET_FLAG(IPSET_OPT_PACKETS)
+                       | IPSET_FLAG(IPSET_OPT_BYTES)
+                       | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
+                       | IPSET_FLAG(IPSET_OPT_SKBMARK)
+                       | IPSET_FLAG(IPSET_OPT_SKBPRIO)
+                       | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
+               [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_CIDR)
+                       | IPSET_FLAG(IPSET_OPT_PORT)
+                       | IPSET_FLAG(IPSET_OPT_PROTO)
+                       | IPSET_FLAG(IPSET_OPT_IP2)
+                       | IPSET_FLAG(IPSET_OPT_CIDR2)
+                       | IPSET_FLAG(IPSET_OPT_NOMATCH),
+       },
+
+       .usage = hash_netportnet_usage2,
+       .usagefn = ipset_port_usage,
+       .description = "skbinfo support",
+};
+
 void _init(void);
 void _init(void)
 {
        ipset_type_add(&ipset_hash_netportnet0);
        ipset_type_add(&ipset_hash_netportnet1);
+       ipset_type_add(&ipset_hash_netportnet2);
 }