]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
ebtables: Merge libebt_limit.c into libxt_limit.c
authorPhil Sutter <phil@nwl.cc>
Fri, 10 Aug 2018 15:07:36 +0000 (17:07 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 16 Aug 2018 17:43:47 +0000 (19:43 +0200)
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>
extensions/libebt_limit.c [deleted file]
extensions/libxt_limit.c
iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0
iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0
iptables/xtables-eb.c

diff --git a/extensions/libebt_limit.c b/extensions/libebt_limit.c
deleted file mode 100644 (file)
index e8da2a1..0000000
+++ /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);
-}
index c8ddca8778400991868f6100382215e24e67a459..124bda2902eb7b8201ff74cbbeadf185cb14be23 100644 (file)
@@ -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));
 }
index 1de76840a8432819cd428168bb4e954c9be12c76..eeb7d83574e9dc4ef49d48a0dcf6d5263cd2f1dd 100755 (executable)
@@ -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
index d82bae549212f3250731f8a4d46e50d5fb648325..c858054764d7085f6ede730daf1be95aa56e56d9 100755 (executable)
@@ -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
 '
index 798c027c134ac4ed5bc502383ed02ba7533aeae5..a46b9e5a9113b5196e6cfe14355466e95e9c478b 100644 (file)
@@ -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;
                                }