]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
New set match revision with --return-nomatch flag support
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Fri, 21 Sep 2012 18:42:15 +0000 (20:42 +0200)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Fri, 21 Sep 2012 18:42:15 +0000 (20:42 +0200)
extensions/libxt_set.c
extensions/libxt_set.man
include/linux/netfilter/ipset/ip_set.h

index 77e3f07e226a69fa70f99724bf256a29bdb50705..e0111568d3c8f07ccedbb4d803cdc23029cdb35d 100644 (file)
@@ -205,6 +205,90 @@ set_save_v1(const void *ip, const struct xt_entry_match *match)
        print_match("--match-set", &info->match_set);
 }
 
+/* Revision 2 */
+static void
+set_help_v2(void)
+{
+       printf("set match options:\n"
+              " [!] --match-set name flags [--return-nomatch]\n"
+              "                 'name' is the set name from to match,\n" 
+              "                 'flags' are the comma separated list of\n"
+              "                 'src' and 'dst' specifications.\n");
+}
+
+static const struct option set_opts_v2[] = {
+       {.name = "match-set",           .has_arg = true,        .val = '1'},
+       {.name = "set",                 .has_arg = true,        .val = '2'},
+       {.name = "return-nomatch",      .has_arg = false,       .val = '3'},
+       XT_GETOPT_TABLEEND,
+};
+
+static int
+set_parse_v2(int c, char **argv, int invert, unsigned int *flags,
+            const void *entry, struct xt_entry_match **match)
+{
+       struct xt_set_info_match_v1 *myinfo = 
+               (struct xt_set_info_match_v1 *) (*match)->data;
+       struct xt_set_info *info = &myinfo->match_set;
+
+       switch (c) {
+       case '3':
+               info->flags |= IPSET_RETURN_NOMATCH;
+               break;
+       case '2':
+               fprintf(stderr,
+                       "--set option deprecated, please use --match-set\n");
+       case '1':               /* --match-set <set> <flag>[,<flag> */
+               if (info->dim)
+                       xtables_error(PARAMETER_PROBLEM,
+                                     "--match-set can be specified only once");
+               if (invert)
+                       info->flags |= IPSET_INV_MATCH;
+
+               if (!argv[optind]
+                   || argv[optind][0] == '-'
+                   || argv[optind][0] == '!')
+                       xtables_error(PARAMETER_PROBLEM,
+                                     "--match-set requires two args.");
+
+               if (strlen(optarg) > IPSET_MAXNAMELEN - 1)
+                       xtables_error(PARAMETER_PROBLEM,
+                                     "setname `%s' too long, max %d characters.",
+                                     optarg, IPSET_MAXNAMELEN - 1);
+
+               get_set_byname(optarg, info);
+               parse_dirs(argv[optind], info);
+               DEBUGP("parse: set index %u\n", info->index);
+               optind++;
+               
+               *flags = 1;
+               break;
+       }
+
+       return 1;
+}
+
+/* Prints out the matchinfo. */
+static void
+set_print_v2(const void *ip, const struct xt_entry_match *match, int numeric)
+{
+       const struct xt_set_info_match_v1 *info = (const void *)match->data;
+
+       print_match("match-set", &info->match_set);
+       if (info->match_set.flags & IPSET_RETURN_NOMATCH)
+               printf(" return-nomatch");
+}
+
+static void
+set_save_v2(const void *ip, const struct xt_entry_match *match)
+{
+       const struct xt_set_info_match_v1 *info = (const void *)match->data;
+
+       print_match("--match-set", &info->match_set);
+       if (info->match_set.flags & IPSET_RETURN_NOMATCH)
+               printf(" --return-nomatch");
+}
+
 static struct xtables_match set_mt_reg[] = {
        {
                .name           = "set",
@@ -234,6 +318,20 @@ static struct xtables_match set_mt_reg[] = {
                .save           = set_save_v1,
                .extra_opts     = set_opts_v0,
        },
+       {
+               .name           = "set",
+               .revision       = 2,
+               .version        = XTABLES_VERSION,
+               .family         = NFPROTO_UNSPEC,
+               .size           = XT_ALIGN(sizeof(struct xt_set_info_match_v1)),
+               .userspacesize  = XT_ALIGN(sizeof(struct xt_set_info_match_v1)),
+               .help           = set_help_v2,
+               .parse          = set_parse_v2,
+               .final_check    = set_check_v0,
+               .print          = set_print_v2,
+               .save           = set_save_v2,
+               .extra_opts     = set_opts_v2,
+       },
 };
 
 void _init(void)
index 1ad908593f15f65185e2863798b689192f3dddb2..ac60f14817f8304e1532e7832782a57ab3e6e48d 100644 (file)
@@ -14,6 +14,12 @@ address and destination port pair can be found in the specified set. If
 the set type of the specified set is single dimension (for example ipmap),
 then the command will match packets for which the source address can be
 found in the specified set. 
+.TP
+\fB\-\-return\-\-nomatch\fP
+If the \fB\-\-return\-\-nomatch\fP option is specified and the set type
+supports the \fBnomatch\fP flag, then the matching is reversed: a match
+with an element flagged with \fBnomatch\fP returns \fBtrue\fP, while a
+match with a plain element returns \fBfalse\fP.
 .PP
 The option \fB\-\-match\-set\fP can be replaced by \fB\-\-set\fP if that does 
 not clash with an option of other extensions.
index 79cb0779dd3263df58d6900f3f637ce44f6371c8..fff191d65e3666b7b0abd1bddd75a61da75f711f 100644 (file)
@@ -186,6 +186,7 @@ enum ip_set_dim {
         * If changed, new revision of iptables match/target is required.
         */
        IPSET_DIM_MAX = 6,
+       IPSET_BIT_RETURN_NOMATCH = 7,
 };
 
 /* Option flags for kernel operations */
@@ -194,6 +195,7 @@ enum ip_set_kopt {
        IPSET_DIM_ONE_SRC = (1 << IPSET_DIM_ONE),
        IPSET_DIM_TWO_SRC = (1 << IPSET_DIM_TWO),
        IPSET_DIM_THREE_SRC = (1 << IPSET_DIM_THREE),
+       IPSET_RETURN_NOMATCH = (1 << IPSET_BIT_RETURN_NOMATCH),
 };