summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extensions/libebt_limit.c205
-rw-r--r--extensions/libxt_limit.c102
-rwxr-xr-xiptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_06
-rwxr-xr-xiptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_04
-rw-r--r--iptables/xtables-eb.c5
5 files changed, 97 insertions, 225 deletions
diff --git a/extensions/libebt_limit.c b/extensions/libebt_limit.c
deleted file mode 100644
index e8da2a15..00000000
--- a/extensions/libebt_limit.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/* ebt_limit
- *
- * Authors:
- * Tom Marshall <tommy@home.tig-grr.com>
- *
- * Mostly copied from iptables' limit match.
- *
- * September, 2003
- *
- * Translated to use libxtables for ebtables-compat in 2015 by
- * Arturo Borrero Gonzalez <arturo@debian.org>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <errno.h>
-#include <xtables.h>
-#include <linux/netfilter_bridge/ebt_limit.h>
-#include "iptables/nft.h"
-#include "iptables/nft-bridge.h"
-
-#define EBT_LIMIT_AVG "3/hour"
-#define EBT_LIMIT_BURST 5
-
-#define FLAG_LIMIT 0x01
-#define FLAG_LIMIT_BURST 0x02
-#define ARG_LIMIT '1'
-#define ARG_LIMIT_BURST '2'
-
-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 void brlimit_print_help(void)
-{
- printf(
-"limit options:\n"
-"--limit avg : max average match rate: default "EBT_LIMIT_AVG"\n"
-" [Packets per second unless followed by \n"
-" /sec /minute /hour /day postfixes]\n"
-"--limit-burst number : number to match in a burst, -1 < number < 10001,\n"
-" default %u\n", EBT_LIMIT_BURST);
-}
-
-static int parse_rate(const char *rate, uint32_t *val)
-{
- const char *delim;
- uint32_t r;
- uint32_t mult = 1; /* Seconds by default. */
-
- delim = strchr(rate, '/');
- if (delim) {
- if (strlen(delim+1) == 0)
- return 0;
-
- if (strncasecmp(delim+1, "second", strlen(delim+1)) == 0)
- mult = 1;
- else if (strncasecmp(delim+1, "minute", strlen(delim+1)) == 0)
- mult = 60;
- else if (strncasecmp(delim+1, "hour", strlen(delim+1)) == 0)
- mult = 60*60;
- else if (strncasecmp(delim+1, "day", strlen(delim+1)) == 0)
- mult = 24*60*60;
- else
- return 0;
- }
- r = atoi(rate);
- if (!r)
- return 0;
-
- /* This would get mapped to infinite (1/day is minimum they
- can specify, so we're ok at that end). */
- if (r / mult > EBT_LIMIT_SCALE)
- return 0;
-
- *val = EBT_LIMIT_SCALE * mult / r;
- return 1;
-}
-
-static void brlimit_init(struct xt_entry_match *match)
-{
- struct ebt_limit_info *r = (struct ebt_limit_info *)match->data;
-
- parse_rate(EBT_LIMIT_AVG, &r->avg);
- r->burst = EBT_LIMIT_BURST;
-}
-
-static int brlimit_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_match **match)
-{
- struct ebt_limit_info *r = (struct ebt_limit_info *)(*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;
-}
-
-struct rates
-{
- const char *name;
- uint32_t mult;
-};
-
-static struct rates g_rates[] =
-{
- { "day", EBT_LIMIT_SCALE*24*60*60 },
- { "hour", EBT_LIMIT_SCALE*60*60 },
- { "minute", EBT_LIMIT_SCALE*60 },
- { "second", EBT_LIMIT_SCALE }
-};
-
-static void print_rate(uint32_t period)
-{
- unsigned int i;
-
- for (i = 1; i < sizeof(g_rates)/sizeof(struct rates); i++)
- if (period > g_rates[i].mult ||
- g_rates[i].mult/period < g_rates[i].mult%period)
- break;
-
- printf("%u/%s ", g_rates[i-1].mult / period, g_rates[i-1].name);
-}
-
-static void brlimit_print(const void *ip, const struct xt_entry_match *match,
- int numeric)
-{
- struct ebt_limit_info *r = (struct ebt_limit_info *)match->data;
-
- printf("--limit ");
- print_rate(r->avg);
- printf("--limit-burst %u ", r->burst);
-}
-
-static void print_rate_xlate(struct xt_xlate *xl, uint32_t period)
-{
- unsigned int i;
-
- for (i = 1; i < sizeof(g_rates)/sizeof(struct rates); i++)
- if (period > g_rates[i].mult ||
- g_rates[i].mult/period < g_rates[i].mult%period)
- break;
-
- xt_xlate_add(xl, "%u/%s ", g_rates[i-1].mult / period, g_rates[i-1].name);
-}
-
-static int brlimit_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct ebt_limit_info *r = (const void *)params->match->data;
-
- xt_xlate_add(xl, "limit rate ");
- print_rate_xlate(xl, r->avg);
- if (r->burst != 0)
- xt_xlate_add(xl, "burst %u packets ", r->burst);
-
- return 1;
-}
-
-static struct xtables_match brlimit_match = {
- .name = "limit",
- .revision = 0,
- .version = XTABLES_VERSION,
- .family = NFPROTO_BRIDGE,
- .size = XT_ALIGN(sizeof(struct ebt_limit_info)),
- .userspacesize = offsetof(struct ebt_limit_info, prev),
- .init = brlimit_init,
- .help = brlimit_print_help,
- .parse = brlimit_parse,
- .print = brlimit_print,
- .xlate = brlimit_xlate,
- .extra_opts = brlimit_opts,
-};
-
-void _init(void)
-{
- xtables_register_match(&brlimit_match);
-}
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));
}
diff --git a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 b/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0
index 1de76840..eeb7d835 100755
--- a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0
+++ b/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0
@@ -84,15 +84,15 @@ DUMP='*filter
-A foo -p IPv6 --ip6-src feed:babe::1 -j ACCEPT
-A foo -p IPv6 --ip6-dst feed:babe::/64 -j ACCEPT
-A foo -p IPv6 --ip6-proto tcp -j ACCEPT
--A foo --limit 100/second --limit-burst 42 -j ACCEPT
+-A foo --limit 100/sec --limit-burst 42 -j ACCEPT
-A foo --log-level notice --log-prefix "" -j CONTINUE
-A foo -j mark --mark-set 0x23 --mark-target ACCEPT
-A foo --nflog-group 1 -j CONTINUE
-A foo --pkttype-type multicast -j ACCEPT
-A foo --stp-type config -j ACCEPT
--A foo --802_3-sap 0x23 --limit 100/second --limit-burst 5 -j ACCEPT
+-A foo --802_3-sap 0x23 --limit 100/sec --limit-burst 5 -j ACCEPT
-A foo --pkttype-type multicast --log-level notice --log-prefix "" -j CONTINUE
--A foo --pkttype-type multicast --limit 100/second --limit-burst 5 -j ACCEPT
+-A foo --pkttype-type multicast --limit 100/sec --limit-burst 5 -j ACCEPT
*nat
:PREROUTING ACCEPT
diff --git a/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0 b/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0
index d82bae54..c8580547 100755
--- a/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0
+++ b/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0
@@ -22,8 +22,8 @@ EXPECT='*filter
:INPUT ACCEPT
:FORWARD ACCEPT
:OUTPUT ACCEPT
--A FORWARD --limit 100/second --limit-burst 42 -j ACCEPT
--A FORWARD --limit 1000/second --limit-burst 5 -j ACCEPT
+-A FORWARD --limit 100/sec --limit-burst 42 -j ACCEPT
+-A FORWARD --limit 1000/sec --limit-burst 5 -j ACCEPT
-A FORWARD --log-level notice --log-prefix "foobar" -j CONTINUE
-A FORWARD --log-level notice --log-prefix "" -j CONTINUE
'
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index 798c027c..a46b9e5a 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -1199,7 +1199,10 @@ print_zero:
/* Is it a match_option? */
for (m = xtables_matches; m; m = m->next) {
- if (m->parse(c - m->option_offset, argv, ebt_check_inverse2(optarg, argc, argv), &m->mflags, NULL, &m->m)) {
+ if (m->parse &&
+ m->parse(c - m->option_offset, argv,
+ ebt_check_inverse2(optarg, argc, argv),
+ &m->mflags, NULL, &m->m)) {
ebt_add_match(m, &cs);
goto check_extension;
}