aboutsummaryrefslogtreecommitdiffstats
path: root/filter
diff options
context:
space:
mode:
authorAlexander Zubkov <green@qrator.net>2023-08-24 04:45:55 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2023-08-24 04:45:55 +0200
commit0dbcc927260c6da918fa1bd78c86800e41ab05a8 (patch)
treee147628288e204afe717bef47a779cd6c4b92bea /filter
parentfc3547880aafad726509f0514df2d5e0bb140728 (diff)
downloadbird-0dbcc927260c6da918fa1bd78c86800e41ab05a8.tar.gz
Filter: Use more generic approach for intra-config expressions
Replace f_eval_int() function with a type-generic variant: cf_eval(). Implement similar fuction: cf_eval_int() via inline call to cf_eval().
Diffstat (limited to 'filter')
-rw-r--r--filter/config.Y8
-rw-r--r--filter/filter.c22
-rw-r--r--filter/filter.h8
3 files changed, 16 insertions, 22 deletions
diff --git a/filter/config.Y b/filter/config.Y
index e2d133a9..2a298843 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -358,7 +358,7 @@ filter_def:
conf: filter_eval ;
filter_eval:
- EVAL term { f_eval_int(f_linearize($2, 1)); }
+ EVAL term { cf_eval_int($2); }
;
conf: custom_attr ;
@@ -573,7 +573,7 @@ set_atom:
| VPN_RD { $$.type = T_RD; $$.val.ec = $1; }
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
| '(' term ')' {
- if (f_eval(f_linearize($2, 1), cfg_mem, &($$)) > F_RETURN) cf_error("Runtime error");
+ $$ = cf_eval($2, T_VOID);
if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type");
}
| CF_SYM_KNOWN {
@@ -585,13 +585,13 @@ set_atom:
switch_atom:
NUM { $$.type = T_INT; $$.val.i = $1; }
- | '(' term ')' { $$.type = T_INT; $$.val.i = f_eval_int(f_linearize($2, 1)); }
+ | '(' term ')' { $$ = cf_eval($2, T_INT); }
| fipa { $$ = $1; }
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
;
cnum:
- term { $$ = f_eval_int(f_linearize($1, 1)); }
+ term { $$ = cf_eval_int($1); }
pair_item:
'(' cnum ',' cnum ')' { $$ = f_new_pair_item($2, $2, $4, $4); }
diff --git a/filter/filter.c b/filter/filter.c
index 20a380dc..d080cadc 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -373,30 +373,22 @@ f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres)
}
/*
- * f_eval_int - get an integer value of a term
+ * cf_eval - evaluate a value of a term and check its type
* Called internally from the config parser, uses its internal memory pool
* for allocations. Do not call in other cases.
*/
-uint
-f_eval_int(const struct f_line *expr)
+struct f_val
+cf_eval(const struct f_inst *inst, int type)
{
- /* Called independently in parse-time to eval expressions */
- filter_state = (struct filter_state) {
- .stack = &filter_stack,
- .pool = cfg_mem,
- };
-
struct f_val val;
- LOG_BUFFER_INIT(filter_state.buf);
-
- if (interpret(&filter_state, expr, &val) > F_RETURN)
+ if (f_eval(f_linearize(inst, 1), cfg_mem, &val) > F_RETURN)
cf_error("Runtime error while evaluating expression; see log for details");
- if (val.type != T_INT)
- cf_error("Integer expression expected");
+ if (type != T_VOID && val.type != type)
+ cf_error("Expression of type %s expected", f_type_name(type));
- return val.val.i;
+ return val;
}
/*
diff --git a/filter/filter.h b/filter/filter.h
index 26c1037b..91de696c 100644
--- a/filter/filter.h
+++ b/filter/filter.h
@@ -15,6 +15,7 @@
#include "lib/macro.h"
#include "nest/route.h"
#include "nest/attrs.h"
+#include "filter/data.h"
/* Possible return values of filter execution */
enum filter_return {
@@ -40,9 +41,8 @@ static inline const char *filter_return_str(const enum filter_return fret) {
}
}
-struct f_val;
-
/* The filter encapsulating structure to be pointed-to from outside */
+struct f_inst;
struct f_line;
struct filter {
struct symbol *sym;
@@ -53,9 +53,11 @@ struct rte;
enum filter_return f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags);
enum filter_return f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool);
-uint f_eval_int(const struct f_line *expr);
enum filter_return f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf);
+struct f_val cf_eval(const struct f_inst *inst, int type);
+static inline uint cf_eval_int(const struct f_inst *inst) { return cf_eval(inst, T_INT).val.i; };
+
const char *filter_name(const struct filter *filter);
int filter_same(const struct filter *new, const struct filter *old);
int f_same(const struct f_line *f1, const struct f_line *f2);