]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter: predefined variables for specific blocks
authorMaria Matejka <mq@ucw.cz>
Mon, 30 Oct 2023 09:44:45 +0000 (10:44 +0100)
committerMaria Matejka <mq@ucw.cz>
Mon, 30 Oct 2023 12:10:37 +0000 (13:10 +0100)
This is a split-commit of the neighboring aggregator branch
with a bit improved lvalue handling, to have easier merge into v3.

filter/config.Y
filter/filter.c
filter/filter.h
proto/static/static.c

index 4e1f6359f9f685c1fdbd4abda85c0311542331cb..873e4035587965ad509ef764941caa7d00f4bd82 100644 (file)
@@ -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
index 65fb92a4122a2b1cd987c7ed57c9d0c3a4ee4c47..4c0f6f12f990127f056782c444ab088f1e2557a5 100644 (file)
@@ -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;
 }
 
index 91de696cfd7be9a6a42e853f45e80be510a605d4..18ff0874f56f35ddb9175d31263959ad56199cfa 100644 (file)
@@ -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);
index bb93305ed2fcc89d2d5ac8be316522be28b9d516..cf7a476843aca4d409863e54a42206e9f3a8405d 100644 (file)
@@ -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;