mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
Filter: predefined variables for specific blocks
This is a split-commit of the neighboring aggregator branch with a bit improved lvalue handling, to have easier merge into v3.
This commit is contained in:
parent
f0187d713c
commit
407eb388b7
@ -106,6 +106,10 @@ f_new_var(struct sym_scope *s)
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* Macro for top-level pre-defined variables. */
|
||||
#define f_predefined_variable(conf_, name_, type_) \
|
||||
cf_define_symbol(conf_, cf_get_symbol(conf_, name_), SYM_VARIABLE | type_, offset, f_new_var(conf_->current_scope))
|
||||
|
||||
/*
|
||||
* Sets and their items are during parsing handled as lists, linked
|
||||
* through left ptr. The first item in a list also contains a pointer
|
||||
|
@ -87,6 +87,9 @@ struct filter_state {
|
||||
/* Linpool for adata allocation */
|
||||
struct linpool *pool;
|
||||
|
||||
/* Additional external values provided to the filter */
|
||||
const struct f_val *val;
|
||||
|
||||
/* Buffer for log output */
|
||||
struct buffer buf;
|
||||
|
||||
@ -157,18 +160,20 @@ static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS;
|
||||
* TWOARGS macro to get both of them evaluated.
|
||||
*/
|
||||
static enum filter_return
|
||||
interpret(struct filter_state *fs, const struct f_line *line, struct f_val *val)
|
||||
interpret(struct filter_state *fs, const struct f_line *line, uint argc, const struct f_val *argv, struct f_val *val)
|
||||
{
|
||||
/* No arguments allowed */
|
||||
ASSERT(line->args == 0);
|
||||
/* Check of appropriate number of arguments */
|
||||
ASSERT(line->args == argc);
|
||||
|
||||
/* Initialize the filter stack */
|
||||
struct filter_stack *fstk = fs->stack;
|
||||
|
||||
fstk->vcnt = line->vars;
|
||||
memset(fstk->vstk, 0, sizeof(struct f_val) * line->vars);
|
||||
/* Set the arguments and top-level variables */
|
||||
fstk->vcnt = line->vars + line->args;
|
||||
memcpy(fstk->vstk, argv, sizeof(struct f_val) * line->args);
|
||||
memset(fstk->vstk + argc, 0, sizeof(struct f_val) * line->vars);
|
||||
|
||||
/* The same as with the value stack. Not resetting the stack for performance reasons. */
|
||||
/* The same as with the value stack. Not resetting the stack completely for performance reasons. */
|
||||
fstk->ecnt = 1;
|
||||
fstk->estk[0].line = line;
|
||||
fstk->estk[0].pos = 0;
|
||||
@ -271,6 +276,12 @@ f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, i
|
||||
if (filter == FILTER_REJECT)
|
||||
return F_REJECT;
|
||||
|
||||
return f_run_args(filter, rte, tmp_pool, 0, NULL, flags);
|
||||
}
|
||||
|
||||
enum filter_return
|
||||
f_run_args(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, int flags)
|
||||
{
|
||||
int rte_cow = ((*rte)->flags & REF_COW);
|
||||
DBG( "Running filter `%s'...", filter->name );
|
||||
|
||||
@ -285,7 +296,7 @@ f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, i
|
||||
LOG_BUFFER_INIT(filter_state.buf);
|
||||
|
||||
/* Run the interpreter itself */
|
||||
enum filter_return fret = interpret(&filter_state, filter->root, NULL);
|
||||
enum filter_return fret = interpret(&filter_state, filter->root, argc, argv, NULL);
|
||||
|
||||
if (filter_state.old_rta) {
|
||||
/*
|
||||
@ -337,7 +348,7 @@ f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, i
|
||||
*/
|
||||
|
||||
enum filter_return
|
||||
f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool)
|
||||
f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, struct f_val *pres)
|
||||
{
|
||||
filter_state = (struct filter_state) {
|
||||
.stack = &filter_stack,
|
||||
@ -347,10 +358,7 @@ f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool
|
||||
|
||||
LOG_BUFFER_INIT(filter_state.buf);
|
||||
|
||||
ASSERT(!((*rte)->flags & REF_COW));
|
||||
ASSERT(!rta_is_cached((*rte)->attrs));
|
||||
|
||||
return interpret(&filter_state, expr, NULL);
|
||||
return interpret(&filter_state, expr, argc, argv, pres);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -369,7 +377,7 @@ f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres)
|
||||
|
||||
LOG_BUFFER_INIT(filter_state.buf);
|
||||
|
||||
enum filter_return fret = interpret(&filter_state, expr, pres);
|
||||
enum filter_return fret = interpret(&filter_state, expr, 0, NULL, pres);
|
||||
return fret;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,8 @@ struct filter {
|
||||
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);
|
||||
enum filter_return f_run_args(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, int flags);
|
||||
enum filter_return f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, struct f_val *pres);
|
||||
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);
|
||||
|
@ -113,7 +113,7 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
|
||||
net_copy(e->net->n.addr, r->net);
|
||||
|
||||
/* Evaluate the filter */
|
||||
f_eval_rte(r->cmds, &e, static_lp);
|
||||
f_eval_rte(r->cmds, &e, static_lp, 0, NULL, NULL);
|
||||
|
||||
/* Remove the temporary node */
|
||||
e->net = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user