]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge commit 'ba91f4c831f057b81104d1453f99b012c01f9c9e' into thread-next
authorMaria Matejka <mq@ucw.cz>
Tue, 31 Oct 2023 15:54:58 +0000 (16:54 +0100)
committerMaria Matejka <mq@ucw.cz>
Tue, 31 Oct 2023 15:54:58 +0000 (16:54 +0100)
1  2 
filter/filter.c
filter/filter.h
proto/static/static.c

diff --cc filter/filter.c
index 2a6261884c55f8daac4b7a09bed9c08fb25afbfd,396b7333c3a91b50b51981b8b34f913fe824fe6c..fd2c16b13b93eee1f0ab84eae4e297c59e267a2e
@@@ -229,11 -285,38 +222,11 @@@ f_run_args(const struct filter *filter
      .flags = flags,
    };
  
 -  LOG_BUFFER_INIT(filter_state.buf);
 +  f_stack_init(filter_state);
  
    /* Run the interpreter itself */
-   enum filter_return fret = interpret(&filter_state, filter->root, argc, argv, NULL);
+   enum filter_return fret = interpret(&filter_state, filter->root, argc, argv, 0, NULL);
  
 -  if (filter_state.old_rta) {
 -    /*
 -     * Cached rta was modified and filter_state->rte contains now an uncached one,
 -     * sharing some part with the cached one. The cached rta should
 -     * be freed (if rte was originally COW, filter_state->old_rta is a clone
 -     * obtained during rte_cow()).
 -     *
 -     * This also implements the exception mentioned in f_run()
 -     * description. The reason for this is that rta reuses parts of
 -     * filter_state->old_rta, and these may be freed during rta_free(filter_state->old_rta).
 -     * This is not the problem if rte was COW, because original rte
 -     * also holds the same rta.
 -     */
 -    if (!rte_cow) {
 -      /* Cache the new attrs */
 -      (*filter_state.rte)->attrs = rta_lookup((*filter_state.rte)->attrs);
 -
 -      /* Drop cached ea_list pointer */
 -      filter_state.eattrs = NULL;
 -    }
 -
 -    /* Uncache the old attrs and drop the pointer as it is invalid now. */
 -    rta_free(filter_state.old_rta);
 -    filter_state.old_rta = NULL;
 -  }
 -
    /* Process the filter output, log it and return */
    if (fret < F_ACCEPT) {
      if (!(filter_state.flags & FF_SILENT))
   */
  
  enum filter_return
- f_eval_rte(const struct f_line *expr, struct rte *rte, uint argc, const struct f_val *argv, struct f_val *pres)
 -f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, uint resc, struct f_val *resv)
++f_eval_rte(const struct f_line *expr, struct rte *rte, uint argc, const struct f_val *argv, uint resc, struct f_val *resv)
  {
    filter_state = (struct filter_state) {
 -    .stack = &filter_stack,
      .rte = rte,
 -    .pool = tmp_pool,
    };
  
 -  LOG_BUFFER_INIT(filter_state.buf);
 +  f_stack_init(filter_state);
  
-   return interpret(&filter_state, expr, argc, argv, pres);
+   return interpret(&filter_state, expr, argc, argv, resc, resv);
  }
  
  /*
   * f_eval - get a value of a term
   * @expr: filter line containing the term
   * @tmp_pool: long data may get allocated from this pool
-  * @pres: here the output will be stored
+  * @pres: here the output will be stored if requested
   */
  enum filter_return
 -f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres)
 +f_eval(const struct f_line *expr, struct f_val *pres)
  {
 -  filter_state = (struct filter_state) {
 -    .stack = &filter_stack,
 -    .pool = tmp_pool,
 -  };
 +  filter_state = (struct filter_state) {};
  
 -  LOG_BUFFER_INIT(filter_state.buf);
 +  f_stack_init(filter_state);
  
-   enum filter_return fret = interpret(&filter_state, expr, 0, NULL, pres);
+   enum filter_return fret = interpret(&filter_state, expr, 0, NULL, !!pres, pres);
    return fret;
  }
  
diff --cc filter/filter.h
index 121da468652038bea99d8dbf4cebe9f49da246dc,c4b1796dc006e3c3295eac03cce0db28a6b6d69a..8d495e2d8ed651ac5cddc3a830a98639dc036cb1
@@@ -52,19 -51,13 +52,19 @@@ 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_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, uint resc, struct f_val *resv);
 -enum filter_return f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf);
 +enum filter_return f_run(const struct filter *filter, struct rte *rte, int flags);
 +enum filter_return f_run_args(const struct filter *filter, struct rte *rte, uint argc, const struct f_val *argv, int flags);
- enum filter_return f_eval_rte(const struct f_line *expr, struct rte *rte, uint argc, const struct f_val *argv, struct f_val *pres);
++enum filter_return f_eval_rte(const struct f_line *expr, struct rte *rte, uint argc, const struct f_val *argv, uint resc, struct f_val *resv);
 +enum filter_return f_eval_buf(const struct f_line *expr, 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; };
 +struct f_val cf_eval_tmp(const struct f_inst *inst, int type);
 +static inline struct f_val *cf_eval(const struct f_inst *inst, int type)
 +{
 +  struct f_val val = cf_eval_tmp(inst, type);
 +  return lp_val_copy(cfg_mem, &val);
 +}
 +
 +static inline uint cf_eval_int(const struct f_inst *inst) { return cf_eval_tmp(inst, T_INT).val.i; };
  
  const char *filter_name(const struct filter *filter);
  int filter_same(const struct filter *new, const struct filter *old);
index 27b9a26f222a6f7413eca2fb29bf5cae1ea643a9,2d2ac310ca1a9044048f5b8c9b0c7f6eac95b9bd..c43f098cf816c0bd12d353d9045565e69cf61453
@@@ -117,17 -103,28 +117,17 @@@ static_announce_rte(struct static_prot
      return;
  
    /* We skip rta_lookup() here */
 -  rte *e = rte_get_temp(a, src);
 +  src = static_get_source(p, r->index);
 +  rte e0 = { .attrs = ea, .src = src, .net = r->net, }, *e = &e0;
  
 +  /* Evaluate the filter */
    if (r->cmds)
-     f_eval_rte(r->cmds, e, 0, NULL, NULL);
 -  {
 -    /* Create a temporary table node */
 -    e->net = alloca(sizeof(net) + r->net->length);
 -    memset(e->net, 0, sizeof(net) + r->net->length);
 -    net_copy(e->net->n.addr, r->net);
++    f_eval_rte(r->cmds, e, 0, NULL, 0, NULL);
  
 -    /* Evaluate the filter */
 -    f_eval_rte(r->cmds, &e, static_lp, 0, NULL, 0, NULL);
 -
 -    /* Remove the temporary node */
 -    e->net = NULL;
 -  }
 +  rte_update(p->p.main_channel, r->net, e, src);
 +  static_free_source(src, r->index);
  
 -  rte_update2(p->p.main_channel, r->net, e, src);
    r->state = SRS_CLEAN;
 -
 -  if (r->cmds)
 -    lp_flush(static_lp);
 -
    return;
  
  withdraw: