summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-04-17 11:38:18 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-04-17 11:38:18 +0200
commite39f367d905670e39e6f08d2b73c715a6d0b4bfb (patch)
treec8c481c0861d32d51001e45432bb59fe8fe96c3f /extensions
parent316ae9d2f1996caea4cf221201accb8c2087a154 (diff)
SET target revision 2 added
The new revision of the SET target supports the following new operations - specifying the timeout value of the entry to be added - flag to instruct the kernel that if the entry already exists then reset the timeout value to the specified one (or to the default from the set definition)
Diffstat (limited to 'extensions')
-rw-r--r--extensions/libxt_SET.c207
-rw-r--r--extensions/libxt_SET.man8
-rw-r--r--extensions/libxt_set.c52
3 files changed, 210 insertions, 57 deletions
diff --git a/extensions/libxt_SET.c b/extensions/libxt_SET.c
index 2f915bcd..51c0cec6 100644
--- a/extensions/libxt_SET.c
+++ b/extensions/libxt_SET.c
@@ -21,8 +21,10 @@
#include <linux/netfilter/xt_set.h>
#include "libxt_set.h"
+/* Revision 0 */
+
static void
-set_target_help(void)
+set_target_help_v0(void)
{
printf("SET target options:\n"
" --add-set name flags\n"
@@ -32,14 +34,14 @@ set_target_help(void)
" 'src' and 'dst' specifications.\n");
}
-static const struct option set_target_opts[] = {
+static const struct option set_target_opts_v0[] = {
{.name = "add-set", .has_arg = true, .val = '1'},
{.name = "del-set", .has_arg = true, .val = '2'},
XT_GETOPT_TABLEEND,
};
static void
-set_target_check(unsigned int flags)
+set_target_check_v0(unsigned int flags)
{
if (!flags)
xtables_error(PARAMETER_PROBLEM,
@@ -144,20 +146,29 @@ set_target_save_v0(const void *ip, const struct xt_entry_target *target)
print_target_v0("--del-set", &info->del_set);
}
+/* Revision 1 */
+
+#define set_target_help_v1 set_target_help_v0
+
static void
-set_target_init(struct xt_entry_target *target)
+set_target_init_v1(struct xt_entry_target *target)
{
- struct xt_set_info_target *info =
- (struct xt_set_info_target *) target->data;
+ struct xt_set_info_target_v1 *info =
+ (struct xt_set_info_target_v1 *) target->data;
info->add_set.index =
info->del_set.index = IPSET_INVALID_ID;
}
+#define SET_TARGET_ADD 0x1
+#define SET_TARGET_DEL 0x2
+#define SET_TARGET_EXIST 0x4
+#define SET_TARGET_TIMEOUT 0x8
+
static void
-parse_target(char **argv, int invert, unsigned int *flags,
- struct xt_set_info *info, const char *what)
+parse_target(char **argv, int invert, struct xt_set_info *info,
+ const char *what)
{
if (info->dim)
xtables_error(PARAMETER_PROBLEM,
@@ -180,30 +191,30 @@ parse_target(char **argv, int invert, unsigned int *flags,
get_set_byname(optarg, info);
parse_dirs(argv[optind], info);
optind++;
-
- *flags = 1;
}
static int
-set_target_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_target **target)
+set_target_parse_v1(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_target **target)
{
- struct xt_set_info_target *myinfo =
- (struct xt_set_info_target *) (*target)->data;
+ struct xt_set_info_target_v1 *myinfo =
+ (struct xt_set_info_target_v1 *) (*target)->data;
switch (c) {
case '1': /* --add-set <set> <flags> */
- parse_target(argv, invert, flags,
- &myinfo->add_set, "add-set");
+ parse_target(argv, invert, &myinfo->add_set, "add-set");
+ *flags |= SET_TARGET_ADD;
break;
case '2': /* --del-set <set>[:<flags>] <flags> */
- parse_target(argv, invert, flags,
- &myinfo->del_set, "del-set");
+ parse_target(argv, invert, &myinfo->del_set, "del-set");
+ *flags |= SET_TARGET_DEL;
break;
}
return 1;
}
+#define set_target_check_v1 set_target_check_v0
+
static void
print_target(const char *prefix, const struct xt_set_info *info)
{
@@ -222,21 +233,132 @@ print_target(const char *prefix, const struct xt_set_info *info)
}
static void
-set_target_print(const void *ip, const struct xt_entry_target *target,
- int numeric)
+set_target_print_v1(const void *ip, const struct xt_entry_target *target,
+ int numeric)
+{
+ const struct xt_set_info_target_v1 *info = (const void *)target->data;
+
+ print_target("add-set", &info->add_set);
+ print_target("del-set", &info->del_set);
+}
+
+static void
+set_target_save_v1(const void *ip, const struct xt_entry_target *target)
+{
+ const struct xt_set_info_target_v1 *info = (const void *)target->data;
+
+ print_target("--add-set", &info->add_set);
+ print_target("--del-set", &info->del_set);
+}
+
+#define set_target_opts_v1 set_target_opts_v0
+
+/* Revision 2 */
+
+static void
+set_target_help_v2(void)
+{
+ printf("SET target options:\n"
+ " --add-set name flags [--exist] [--timeout n]\n"
+ " --del-set name flags\n"
+ " add/del src/dst IP/port from/to named sets,\n"
+ " where flags are the comma separated list of\n"
+ " 'src' and 'dst' specifications.\n");
+}
+
+static const struct option set_target_opts_v2[] = {
+ {.name = "add-set", .has_arg = true, .val = '1'},
+ {.name = "del-set", .has_arg = true, .val = '2'},
+ {.name = "exist", .has_arg = false, .val = '3'},
+ {.name = "timeout", .has_arg = true, .val = '4'},
+ XT_GETOPT_TABLEEND,
+};
+
+static void
+set_target_check_v2(unsigned int flags)
+{
+ if (!(flags & (SET_TARGET_ADD|SET_TARGET_DEL)))
+ xtables_error(PARAMETER_PROBLEM,
+ "You must specify either `--add-set' or `--del-set'");
+ if (!(flags & SET_TARGET_ADD)) {
+ if (flags & SET_TARGET_EXIST)
+ xtables_error(PARAMETER_PROBLEM,
+ "Flag `--exist' can be used with `--add-set' only");
+ if (flags & SET_TARGET_TIMEOUT)
+ xtables_error(PARAMETER_PROBLEM,
+ "Option `--timeout' can be used with `--add-set' only");
+ }
+}
+
+
+static void
+set_target_init_v2(struct xt_entry_target *target)
{
- const struct xt_set_info_target *info = (const void *)target->data;
+ struct xt_set_info_target_v2 *info =
+ (struct xt_set_info_target_v2 *) target->data;
+
+ info->add_set.index =
+ info->del_set.index = IPSET_INVALID_ID;
+ info->timeout = UINT32_MAX;
+}
+
+static int
+set_target_parse_v2(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_target **target)
+{
+ struct xt_set_info_target_v2 *myinfo =
+ (struct xt_set_info_target_v2 *) (*target)->data;
+ unsigned int timeout;
+
+ switch (c) {
+ case '1': /* --add-set <set> <flags> */
+ parse_target(argv, invert, &myinfo->add_set, "add-set");
+ *flags |= SET_TARGET_ADD;
+ break;
+ case '2': /* --del-set <set>[:<flags>] <flags> */
+ parse_target(argv, invert, &myinfo->del_set, "del-set");
+ *flags |= SET_TARGET_DEL;
+ break;
+ case '3':
+ myinfo->flags |= IPSET_FLAG_EXIST;
+ *flags |= SET_TARGET_EXIST;
+ break;
+ case '4':
+ if (!xtables_strtoui(optarg, NULL, &timeout, 0, UINT32_MAX - 1))
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid value for option --timeout "
+ "or out of range 0-%u", UINT32_MAX - 1);
+ myinfo->timeout = timeout;
+ *flags |= SET_TARGET_TIMEOUT;
+ break;
+ }
+ return 1;
+}
+
+static void
+set_target_print_v2(const void *ip, const struct xt_entry_target *target,
+ int numeric)
+{
+ const struct xt_set_info_target_v2 *info = (const void *)target->data;
print_target("add-set", &info->add_set);
+ if (info->flags & IPSET_FLAG_EXIST)
+ printf(" exist");
+ if (info->timeout != UINT32_MAX)
+ printf(" timeout %u", info->timeout);
print_target("del-set", &info->del_set);
}
static void
-set_target_save(const void *ip, const struct xt_entry_target *target)
+set_target_save_v2(const void *ip, const struct xt_entry_target *target)
{
- const struct xt_set_info_target *info = (const void *)target->data;
+ const struct xt_set_info_target_v2 *info = (const void *)target->data;
print_target("--add-set", &info->add_set);
+ if (info->flags & IPSET_FLAG_EXIST)
+ printf(" --exist");
+ if (info->timeout != UINT32_MAX)
+ printf(" --timeout %u", info->timeout);
print_target("--del-set", &info->del_set);
}
@@ -248,28 +370,43 @@ static struct xtables_target set_tg_reg[] = {
.family = NFPROTO_IPV4,
.size = XT_ALIGN(sizeof(struct xt_set_info_target_v0)),
.userspacesize = XT_ALIGN(sizeof(struct xt_set_info_target_v0)),
- .help = set_target_help,
+ .help = set_target_help_v0,
.init = set_target_init_v0,
.parse = set_target_parse_v0,
- .final_check = set_target_check,
+ .final_check = set_target_check_v0,
.print = set_target_print_v0,
.save = set_target_save_v0,
- .extra_opts = set_target_opts,
+ .extra_opts = set_target_opts_v0,
},
{
.name = "SET",
.revision = 1,
.version = XTABLES_VERSION,
.family = NFPROTO_UNSPEC,
- .size = XT_ALIGN(sizeof(struct xt_set_info_target)),
- .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_target)),
- .help = set_target_help,
- .init = set_target_init,
- .parse = set_target_parse,
- .final_check = set_target_check,
- .print = set_target_print,
- .save = set_target_save,
- .extra_opts = set_target_opts,
+ .size = XT_ALIGN(sizeof(struct xt_set_info_target_v1)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_target_v1)),
+ .help = set_target_help_v1,
+ .init = set_target_init_v1,
+ .parse = set_target_parse_v1,
+ .final_check = set_target_check_v1,
+ .print = set_target_print_v1,
+ .save = set_target_save_v1,
+ .extra_opts = set_target_opts_v1,
+ },
+ {
+ .name = "SET",
+ .revision = 2,
+ .version = XTABLES_VERSION,
+ .family = NFPROTO_UNSPEC,
+ .size = XT_ALIGN(sizeof(struct xt_set_info_target_v2)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_target_v2)),
+ .help = set_target_help_v2,
+ .init = set_target_init_v2,
+ .parse = set_target_parse_v2,
+ .final_check = set_target_check_v2,
+ .print = set_target_print_v2,
+ .save = set_target_save_v2,
+ .extra_opts = set_target_opts_v2,
},
};
diff --git a/extensions/libxt_SET.man b/extensions/libxt_SET.man
index ea80c2a1..739be414 100644
--- a/extensions/libxt_SET.man
+++ b/extensions/libxt_SET.man
@@ -12,6 +12,14 @@ where flags are
and/or
.BR "dst"
specifications and there can be no more than six of them.
+.TP
+\fB\-\-timeout\fP \fIvalue\fP
+when adding entry, the timeout value to use instead of the default
+one from the set definition
+.TP
+\fB\-\-exist\fP
+when adding entry if it already exists, reset the timeout value
+to the specified one or to the default from the set definition
.PP
Use of -j SET requires that ipset kernel support is provided. As standard
kernels do not ship this currently, the ipset or Xtables-addons package needs
diff --git a/extensions/libxt_set.c b/extensions/libxt_set.c
index 78bf7c10..da722c73 100644
--- a/extensions/libxt_set.c
+++ b/extensions/libxt_set.c
@@ -22,8 +22,10 @@
#include <linux/netfilter/xt_set.h>
#include "libxt_set.h"
+/* Revision 0 */
+
static void
-set_help(void)
+set_help_v0(void)
{
printf("set match options:\n"
" [!] --match-set name flags\n"
@@ -32,14 +34,14 @@ set_help(void)
" 'src' and 'dst' specifications.\n");
}
-static const struct option set_opts[] = {
+static const struct option set_opts_v0[] = {
{.name = "match-set", .has_arg = true, .val = '1'},
{.name = "set", .has_arg = true, .val = '2'},
XT_GETOPT_TABLEEND,
};
static void
-set_check(unsigned int flags)
+set_check_v0(unsigned int flags)
{
if (!flags)
xtables_error(PARAMETER_PROBLEM,
@@ -127,12 +129,18 @@ set_save_v0(const void *ip, const struct xt_entry_match *match)
print_match_v0("--match-set", &info->match_set);
}
+/* Revision 1 */
+
+#define set_help_v1 set_help_v0
+#define set_opts_v1 set_opts_v0
+#define set_check_v1 set_check_v0
+
static int
-set_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_match **match)
+set_parse_v1(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_match **match)
{
- struct xt_set_info_match *myinfo =
- (struct xt_set_info_match *) (*match)->data;
+ 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) {
@@ -191,17 +199,17 @@ print_match(const char *prefix, const struct xt_set_info *info)
/* Prints out the matchinfo. */
static void
-set_print(const void *ip, const struct xt_entry_match *match, int numeric)
+set_print_v1(const void *ip, const struct xt_entry_match *match, int numeric)
{
- const struct xt_set_info_match *info = (const void *)match->data;
+ const struct xt_set_info_match_v1 *info = (const void *)match->data;
print_match("match-set", &info->match_set);
}
static void
-set_save(const void *ip, const struct xt_entry_match *match)
+set_save_v1(const void *ip, const struct xt_entry_match *match)
{
- const struct xt_set_info_match *info = (const void *)match->data;
+ const struct xt_set_info_match_v1 *info = (const void *)match->data;
print_match("--match-set", &info->match_set);
}
@@ -214,26 +222,26 @@ static struct xtables_match set_mt_reg[] = {
.family = NFPROTO_IPV4,
.size = XT_ALIGN(sizeof(struct xt_set_info_match_v0)),
.userspacesize = XT_ALIGN(sizeof(struct xt_set_info_match_v0)),
- .help = set_help,
+ .help = set_help_v0,
.parse = set_parse_v0,
- .final_check = set_check,
+ .final_check = set_check_v0,
.print = set_print_v0,
.save = set_save_v0,
- .extra_opts = set_opts,
+ .extra_opts = set_opts_v0,
},
{
.name = "set",
.revision = 1,
.version = XTABLES_VERSION,
.family = NFPROTO_UNSPEC,
- .size = XT_ALIGN(sizeof(struct xt_set_info_match)),
- .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_match)),
- .help = set_help,
- .parse = set_parse,
- .final_check = set_check,
- .print = set_print,
- .save = set_save,
- .extra_opts = set_opts,
+ .size = XT_ALIGN(sizeof(struct xt_set_info_match_v1)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_match_v1)),
+ .help = set_help_v1,
+ .parse = set_parse_v1,
+ .final_check = set_check_v1,
+ .print = set_print_v1,
+ .save = set_save_v1,
+ .extra_opts = set_opts_v1,
},
};