ebtables-compat: add support for limit extension
PATCH 1/1 ebtables-compat: add support for limit extension
Add support for the ebtables limit extension (match),
Signed-off-by Arturo Borrero Gonzalez <[email protected]>
--- extensions/libebt_limit.c | 179 +++++++++++++++++++++++++++++++++++++++++++++ iptables/xtables-eb.c | 1 2 files changed, 180 insertions(+) create mode 100644 extensions/libebt_limit.c
extensions/libebt_limit.c new file +179 -0
@@ -0,0 +1,179 @@ +/* ebt_limit +* +* Authors: +* Tom Marshall <[email protected]> +* +* Mostly copied from iptables' limit match. +* +* September, 2003 +* +* Translated to use libxtables for ebtables-compat in 2015 by +* Arturo Borrero Gonzalez <[email protected]> +*/ + +#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 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 }, + {"min" ,EBT_LIMIT_SCALE *60 }, + {"sec" ,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 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, + .extra_opts = brlimit_opts, +}; + +void _init (void ) +{ +xtables_register_match (&brlimit_match); +}
iptables/xtables-eb.c +1 -0
@@ -643,6 +643,7 @@ static void ebt_load_match_extensions(void)ebt_load_match ("802_3" );ebt_load_match ("ip" );ebt_load_match ("mark_m" ); +ebt_load_match ("limit" );ebt_load_watcher ("log" ); }
Quoted 1 line · Arturo Borrero Gonzalez
Add support for the ebtables limit extension (match),
Applied, thanks Arturo.