9 #include <linux/netfilter/x_tables.h>
10 #include <linux/netfilter/xt_RATEEST.h>
12 /* hack to pass raw values to final_check */
13 static struct xt_rateest_target_info
*RATEEST_info
;
14 static unsigned int interval
;
15 static unsigned int ewma_log
;
21 "RATEEST target options:\n"
22 " --rateest-name name Rate estimator name\n"
23 " --rateest-interval sec Rate measurement interval in seconds\n"
24 " --rateest-ewmalog value Rate measurement averaging time constant\n");
27 enum RATEEST_options
{
33 static const struct option RATEEST_opts
[] = {
34 { "rateest-name", 1, NULL
, RATEEST_OPT_NAME
},
35 { "rateest-interval", 1, NULL
, RATEEST_OPT_INTERVAL
},
36 { "rateest-ewmalog", 1, NULL
, RATEEST_OPT_EWMALOG
},
40 /* Copied from iproute */
41 #define TIME_UNITS_PER_SEC 1000000
44 RATEEST_get_time(unsigned int *time
, const char *str
)
54 if (strcasecmp(p
, "s") == 0 || strcasecmp(p
, "sec")==0 ||
55 strcasecmp(p
, "secs")==0)
56 t
*= TIME_UNITS_PER_SEC
;
57 else if (strcasecmp(p
, "ms") == 0 || strcasecmp(p
, "msec")==0 ||
58 strcasecmp(p
, "msecs") == 0)
59 t
*= TIME_UNITS_PER_SEC
/1000;
60 else if (strcasecmp(p
, "us") == 0 || strcasecmp(p
, "usec")==0 ||
61 strcasecmp(p
, "usecs") == 0)
62 t
*= TIME_UNITS_PER_SEC
/1000000;
72 RATEEST_print_time(unsigned int time
)
76 if (tmp
>= TIME_UNITS_PER_SEC
)
77 printf("%.1fs ", tmp
/TIME_UNITS_PER_SEC
);
78 else if (tmp
>= TIME_UNITS_PER_SEC
/1000)
79 printf("%.1fms ", tmp
/(TIME_UNITS_PER_SEC
/1000));
81 printf("%uus ", time
);
85 RATEEST_init(struct xt_entry_target
*target
)
92 RATEEST_parse(int c
, char **argv
, int invert
, unsigned int *flags
,
93 const void *entry
, struct xt_entry_target
**target
)
95 struct xt_rateest_target_info
*info
= (void *)(*target
)->data
;
100 case RATEEST_OPT_NAME
:
101 if (*flags
& (1 << c
))
102 xtables_error(PARAMETER_PROBLEM
,
103 "RATEEST: can't specify --rateest-name twice");
106 strncpy(info
->name
, optarg
, sizeof(info
->name
) - 1);
109 case RATEEST_OPT_INTERVAL
:
110 if (*flags
& (1 << c
))
111 xtables_error(PARAMETER_PROBLEM
,
112 "RATEEST: can't specify --rateest-interval twice");
115 if (RATEEST_get_time(&interval
, optarg
) < 0)
116 xtables_error(PARAMETER_PROBLEM
,
117 "RATEEST: bad interval value `%s'", optarg
);
121 case RATEEST_OPT_EWMALOG
:
122 if (*flags
& (1 << c
))
123 xtables_error(PARAMETER_PROBLEM
,
124 "RATEEST: can't specify --rateest-ewmalog twice");
127 if (RATEEST_get_time(&ewma_log
, optarg
) < 0)
128 xtables_error(PARAMETER_PROBLEM
,
129 "RATEEST: bad ewmalog value `%s'", optarg
);
141 RATEEST_final_check(unsigned int flags
)
143 struct xt_rateest_target_info
*info
= RATEEST_info
;
145 if (!(flags
& (1 << RATEEST_OPT_NAME
)))
146 xtables_error(PARAMETER_PROBLEM
, "RATEEST: no name specified");
147 if (!(flags
& (1 << RATEEST_OPT_INTERVAL
)))
148 xtables_error(PARAMETER_PROBLEM
, "RATEEST: no interval specified");
149 if (!(flags
& (1 << RATEEST_OPT_EWMALOG
)))
150 xtables_error(PARAMETER_PROBLEM
, "RATEEST: no ewmalog specified");
152 for (info
->interval
= 0; info
->interval
<= 5; info
->interval
++) {
153 if (interval
<= (1 << info
->interval
) * (TIME_UNITS_PER_SEC
/ 4))
157 if (info
->interval
> 5)
158 xtables_error(PARAMETER_PROBLEM
,
159 "RATEEST: interval value is too large");
162 for (info
->ewma_log
= 1; info
->ewma_log
< 32; info
->ewma_log
++) {
163 double w
= 1.0 - 1.0 / (1 << info
->ewma_log
);
164 if (interval
/ (-log(w
)) > ewma_log
)
169 if (info
->ewma_log
== 0 || info
->ewma_log
>= 31)
170 xtables_error(PARAMETER_PROBLEM
,
171 "RATEEST: ewmalog value is out of range");
175 __RATEEST_print(const struct xt_entry_target
*target
, const char *prefix
)
177 const struct xt_rateest_target_info
*info
= (const void *)target
->data
;
178 unsigned int local_interval
;
179 unsigned int local_ewma_log
;
181 local_interval
= (TIME_UNITS_PER_SEC
<< (info
->interval
+ 2)) / 4;
182 local_ewma_log
= local_interval
* (1 << (info
->ewma_log
));
184 printf("%sname %s ", prefix
, info
->name
);
185 printf("%sinterval ", prefix
);
186 RATEEST_print_time(local_interval
);
187 printf("%sewmalog ", prefix
);
188 RATEEST_print_time(local_ewma_log
);
192 RATEEST_print(const void *ip
, const struct xt_entry_target
*target
,
195 __RATEEST_print(target
, "");
199 RATEEST_save(const void *ip
, const struct xt_entry_target
*target
)
201 __RATEEST_print(target
, "--rateest-");
204 static struct xtables_target rateest_tg_reg
= {
207 .version
= XTABLES_VERSION
,
208 .size
= XT_ALIGN(sizeof(struct xt_rateest_target_info
)),
209 .userspacesize
= XT_ALIGN(sizeof(struct xt_rateest_target_info
)),
210 .help
= RATEEST_help
,
211 .init
= RATEEST_init
,
212 .parse
= RATEEST_parse
,
213 .final_check
= RATEEST_final_check
,
214 .print
= RATEEST_print
,
215 .save
= RATEEST_save
,
216 .extra_opts
= RATEEST_opts
,
221 xtables_register_target(&rateest_tg_reg
);