diff options
author | Phil Sutter <phil@nwl.cc> | 2018-08-10 17:07:36 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2018-08-16 19:43:47 +0200 |
commit | 02b80972c43d21f899c845c7fcafa4e4fb183312 (patch) | |
tree | 0d977247aed39733663b267fd0667a35966c1028 /extensions/libxt_limit.c | |
parent | 5de8dcf75941c533f2dae8a40bf8b6128b8287f3 (diff) |
ebtables: Merge libebt_limit.c into libxt_limit.c
Both extensions were very similar already, but now that they both are
translated into native nftables code, their actual difference (i.e.
match size) doesn't matter anymore.
This change comes with one caveat: Since ebtables limit match is not in
its own file anymore, match preloading automatically also loads the
NFPROTO_UNSPEC limit match. This is not a problem per se since match
lookup will prefer the family-specific one, but when parsing unknown
options, a match without 'parse' callback is encountered. Therefore
do_commandeb() has to check existence of that callback prior to
dereferencing it.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'extensions/libxt_limit.c')
-rw-r--r-- | extensions/libxt_limit.c | 102 |
1 files changed, 88 insertions, 14 deletions
diff --git a/extensions/libxt_limit.c b/extensions/libxt_limit.c index c8ddca87..124bda29 100644 --- a/extensions/libxt_limit.c +++ b/extensions/libxt_limit.c @@ -6,6 +6,8 @@ #define _BSD_SOURCE 1 #define _DEFAULT_SOURCE 1 #define _ISOC99_SOURCE 1 +#include <errno.h> +#include <getopt.h> #include <math.h> #include <stdio.h> #include <string.h> @@ -13,6 +15,8 @@ #include <xtables.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter/xt_limit.h> +#include "iptables/nft.h" +#include "iptables/nft-bridge.h" #define XT_LIMIT_AVG "3/hour" #define XT_LIMIT_BURST 5 @@ -191,22 +195,92 @@ static int limit_xlate(struct xt_xlate *xl, return 1; } -static struct xtables_match limit_match = { - .family = NFPROTO_UNSPEC, - .name = "limit", - .version = XTABLES_VERSION, - .size = XT_ALIGN(sizeof(struct xt_rateinfo)), - .userspacesize = offsetof(struct xt_rateinfo, prev), - .help = limit_help, - .init = limit_init, - .x6_parse = limit_parse, - .print = limit_print, - .save = limit_save, - .x6_options = limit_opts, - .xlate = limit_xlate, +#define FLAG_LIMIT 0x01 +#define FLAG_LIMIT_BURST 0x02 +#define ARG_LIMIT '1' +#define ARG_LIMIT_BURST '2' + +static int brlimit_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_match **match) +{ + struct xt_rateinfo *r = (struct xt_rateinfo *)(*match)->data; + uintmax_t num; + + switch (c) { + case ARG_LIMIT: + EBT_CHECK_OPTION(flags, FLAG_LIMIT); + if (invert) + xtables_error(PARAMETER_PROBLEM, + "Unexpected `!' after --limit"); + if (!parse_rate(optarg, &r->avg)) + xtables_error(PARAMETER_PROBLEM, + "bad rate `%s'", optarg); + break; + case ARG_LIMIT_BURST: + EBT_CHECK_OPTION(flags, FLAG_LIMIT_BURST); + if (invert) + xtables_error(PARAMETER_PROBLEM, + "Unexpected `!' after --limit-burst"); + if (!xtables_strtoul(optarg, NULL, &num, 0, 10000)) + xtables_error(PARAMETER_PROBLEM, + "bad --limit-burst `%s'", optarg); + r->burst = num; + break; + default: + return 0; + } + + return 1; +} + +static void brlimit_print(const void *ip, const struct xt_entry_match *match, + int numeric) +{ + const struct xt_rateinfo *r = (struct xt_rateinfo *)match->data; + + printf("--limit"); + print_rate(r->avg); + printf(" --limit-burst %u ", r->burst); +} + +static const struct option brlimit_opts[] = +{ + { .name = "limit", .has_arg = true, .val = ARG_LIMIT }, + { .name = "limit-burst",.has_arg = true, .val = ARG_LIMIT_BURST }, + XT_GETOPT_TABLEEND, +}; + +static struct xtables_match limit_match[] = { + { + .family = NFPROTO_UNSPEC, + .name = "limit", + .version = XTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_rateinfo)), + .userspacesize = offsetof(struct xt_rateinfo, prev), + .help = limit_help, + .init = limit_init, + .x6_parse = limit_parse, + .print = limit_print, + .save = limit_save, + .x6_options = limit_opts, + .xlate = limit_xlate, + }, + { + .family = NFPROTO_BRIDGE, + .name = "limit", + .version = XTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_rateinfo)), + .userspacesize = offsetof(struct xt_rateinfo, prev), + .help = limit_help, + .init = limit_init, + .parse = brlimit_parse, + .print = brlimit_print, + .extra_opts = brlimit_opts, + .xlate = limit_xlate, + }, }; void _init(void) { - xtables_register_match(&limit_match); + xtables_register_matches(limit_match, ARRAY_SIZE(limit_match)); } |