]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filters always allocate from tmp_linpool
authorMaria Matejka <mq@ucw.cz>
Sun, 10 Apr 2022 16:55:15 +0000 (18:55 +0200)
committerMaria Matejka <mq@ucw.cz>
Wed, 4 May 2022 13:37:41 +0000 (15:37 +0200)
15 files changed:
conf/confbase.Y
filter/config.Y
filter/data.c
filter/data.h
filter/f-inst.c
filter/filter.c
filter/filter.h
filter/filter_test.c
lib/attrs.h
nest/cmds.c
nest/rt-show.c
nest/rt-table.c
proto/mrt/mrt.c
proto/static/static.c
sysdep/unix/krt.c

index 3fdacb12852c8c3129a0c219547dbeb39f5629e2..a81560dc4faa3678a58c4aec61eb171194dbe6db 100644 (file)
@@ -152,9 +152,9 @@ conf: definition ;
 
 definition:
    DEFINE symbol '=' term ';' {
-     struct f_val *val = cfg_allocz(sizeof(struct f_val));
-     if (f_eval(f_linearize($4), cfg_mem, val) > F_RETURN) cf_error("Runtime error");
-     cf_define_symbol($2, SYM_CONSTANT | val->type, val, val);
+     struct f_val val;
+     if (f_eval(f_linearize($4), &val) > F_RETURN) cf_error("Runtime error");
+     cf_define_symbol($2, SYM_CONSTANT | val.type, val, lp_val_copy(cfg_mem, &val));
    }
  ;
 
index 22981945f4285302e802b3a5a5e4113e0f8f5814..92656f7c47f31221d5de67321c96bac3a4bc9ab2 100644 (file)
@@ -529,7 +529,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), cfg_mem, &($$)) > F_RETURN) cf_error("Runtime error");
+     if (f_eval(f_linearize($2), &($$)) > F_RETURN) cf_error("Runtime error");
      if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type");
    }
  | CF_SYM_KNOWN {
index 381448fa35c9331acb41a62ec5330049c295542f..425dfdd35757b4f3cb40548e68ecbafbb5d39e36 100644 (file)
@@ -602,3 +602,75 @@ val_dump(const struct f_val *v) {
   return val_dump_buffer;
 }
 
+
+struct f_val *
+lp_val_copy(struct linpool *lp, const struct f_val *v)
+{
+  switch (v->type)
+  {
+    case T_VOID:
+    case T_BOOL:
+    case T_INT:
+    case T_IP:
+    case T_PAIR:
+    case T_QUAD:
+    case T_EC:
+    case T_LC:
+    case T_RD:
+    case T_ENUM:
+    case T_PATH_MASK_ITEM:
+      /* These aren't embedded but there is no need to copy them */
+    case T_SET:
+    case T_PREFIX_SET:
+    case T_PATH_MASK:
+    case T_IFACE:
+      {
+       struct f_val *out = lp_alloc(lp, sizeof(*out));
+       *out = *v;
+       return out;
+      }
+
+    case T_NET:
+      {
+       struct {
+         struct f_val val;
+         net_addr net[0];
+       } *out = lp_alloc(lp, sizeof(*out) + v->val.net->length);
+       out->val = *v;
+       out->val.val.net = out->net;
+       net_copy(out->net, v->val.net);
+       return &out->val;
+      }
+
+    case T_STRING:
+      {
+       uint len = strlen(v->val.s);
+       struct {
+         struct f_val val;
+         char buf[0];
+       } *out = lp_alloc(lp, sizeof(*out) + len + 1);
+       out->val = *v;
+       out->val.val.s = out->buf;
+       memcpy(out->buf, v->val.s, len+1);
+       return &out->val;
+      }
+
+    case T_PATH:
+    case T_CLIST:
+    case T_ECLIST:
+    case T_LCLIST:
+      {
+       struct {
+         struct f_val val;
+         struct adata ad;
+       } *out = lp_alloc(lp, sizeof(*out) + v->val.ad->length);
+       out->val = *v;
+       out->val.val.ad = &out->ad;
+       memcpy(&out->ad, v->val.ad, v->val.ad->length);
+       return &out->val;
+      }
+
+    default:
+      bug("Unknown type in value copy: %d", v->type);
+  }
+}
index 9ffa1b61cbfeb158f2bf5dbfbf42cc27dcbbc73d..cba47d6ac5c12ee4b290edcc4667b233a5d0dc50 100644 (file)
@@ -213,6 +213,8 @@ void val_format(const struct f_val *v, buffer *buf);
 char *val_format_str(struct linpool *lp, const struct f_val *v);
 const char *val_dump(const struct f_val *v);
 
+struct f_val *lp_val_copy(struct linpool *lp, const struct f_val *v);
+
 static inline int val_is_ip4(const struct f_val *v)
 { return (v->type == T_IP) && ipa_is_ip4(v->val.ip); }
 int val_in_range(const struct f_val *v1, const struct f_val *v2);
@@ -249,6 +251,6 @@ static inline const struct f_val *f_get_empty(btype t)
   }
 }
 
-enum filter_return f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres);
+enum filter_return f_eval(const struct f_line *expr, struct f_val *pres);
 
 #endif
index 7b3db1c72574d733ca4eec962d284f57b2f8c977..3a2554fd1325c29a09e78f7b284cbd9826d9c699 100644 (file)
     DYNAMIC_ATTR;
     ARG_TYPE(1, da.type);
     {
-      struct ea_list *l = lp_alloc(fs->pool, sizeof(struct ea_list) + sizeof(eattr));
+      struct ea_list *l = tmp_alloc(sizeof(struct ea_list) + sizeof(eattr));
 
       l->next = NULL;
       l->flags = EALF_SORTED;
        break;
 
       case T_IP:
-       l->attrs[0].u.ptr = lp_store_adata(fs->pool, &v1.val.ip, sizeof(ip_addr));
+       l->attrs[0].u.ptr = tmp_store_adata(&v1.val.ip, sizeof(ip_addr));
        break;
 
       default:
     ACCESS_EATTRS;
 
     f_rta_cow(fs);
-    ea_unset_attr(fs->eattrs, fs->pool, 1, da.ea_code);
+    ea_unset_attr(fs->eattrs, tmp_linpool, 1, da.ea_code);
   }
 
   INST(FI_LENGTH, 1, 1) {      /* Get length of */
index 8f946f5b0038ef0a9e83b0f61d111ae9264b244f..9bedb9381df28ecef8354c03d7ac4fbb7e334dab 100644 (file)
@@ -82,9 +82,6 @@ struct filter_state {
   /* Cached pointer to ea_list */
   struct ea_list **eattrs;
 
-  /* Linpool for adata allocation */
-  struct linpool *pool;
-
   /* Buffer for log output */
   struct buffer buf;
 
@@ -134,7 +131,7 @@ f_rta_cow(struct filter_state *fs)
    * at the end of f_run()), also the lock of hostentry is inherited (we
    * suppose hostentry is not changed by filters).
    */
-  (*fs->rte)->attrs = rta_do_cow((*fs->rte)->attrs, fs->pool);
+  (*fs->rte)->attrs = rta_do_cow((*fs->rte)->attrs, tmp_linpool);
 
   /* Re-cache the ea_list */
   f_cache_eattrs(fs);
@@ -202,8 +199,8 @@ interpret(struct filter_state *fs, const struct f_line *line, struct f_val *val)
   return F_ERROR; \
 } while(0)
 
-#define falloc(size)  lp_alloc(fs->pool, size)
-#define fpool fs->pool
+#define falloc(size)   tmp_alloc(size)
+#define fpool          tmp_linpool
 
 #define ACCESS_EATTRS do { if (!fs->eattrs) f_cache_eattrs(fs); } while (0)
 
@@ -268,7 +265,7 @@ interpret(struct filter_state *fs, const struct f_line *line, struct f_val *val)
  * modified in place, old cached rta is possibly freed.
  */
 enum filter_return
-f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags)
+f_run(const struct filter *filter, struct rte **rte, int flags)
 {
   if (filter == FILTER_ACCEPT)
     return F_ACCEPT;
@@ -282,7 +279,6 @@ f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, i
   /* Initialize the filter state */
   filter_state = (struct filter_state) {
     .rte = rte,
-    .pool = tmp_pool,
     .flags = flags,
   };
 
@@ -343,11 +339,10 @@ 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)
 {
   filter_state = (struct filter_state) {
     .rte = rte,
-    .pool = tmp_pool,
   };
 
   f_stack_init(filter_state);
@@ -367,11 +362,9 @@ f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool
  * @pres: here the output will be stored
  */
 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) {
-    .pool = tmp_pool,
-  };
+  filter_state = (struct filter_state) {};
 
   f_stack_init(filter_state);
 
@@ -390,9 +383,7 @@ uint
 f_eval_int(const struct f_line *expr)
 {
   /* Called independently in parse-time to eval expressions */
-  filter_state = (struct filter_state) {
-    .pool = cfg_mem,
-  };
+  filter_state = (struct filter_state) {};
 
   f_stack_init(filter_state);
 
@@ -413,10 +404,10 @@ f_eval_int(const struct f_line *expr)
  * f_eval_buf - get a value of a term and print it to the supplied buffer
  */
 enum filter_return
-f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf)
+f_eval_buf(const struct f_line *expr, buffer *buf)
 {
   struct f_val val;
-  enum filter_return fret = f_eval(expr, tmp_pool, &val);
+  enum filter_return fret = f_eval(expr, &val);
   if (fret <= F_RETURN)
     val_format(&val, buf);
   return fret;
index 385f1179d9ca31aa9217757bf23c73382737ce3e..43c0444387469ed03e537a94e50b9e962d83f284 100644 (file)
@@ -51,10 +51,10 @@ 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(const struct filter *filter, struct rte **rte, int flags);
+enum filter_return f_eval_rte(const struct f_line *expr, struct rte **rte);
 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);
+enum filter_return f_eval_buf(const struct f_line *expr, buffer *buf);
 
 const char *filter_name(const struct filter *filter);
 int filter_same(const struct filter *new, const struct filter *old);
index e8e8b7477085f5ebd204cdc1a81a7c227f9d8971..63764964c69b81e66276dde3e0b05fddcf7f2b9b 100644 (file)
@@ -46,7 +46,7 @@ run_function(const void *arg)
   if (t->cmp)
     return t->result == f_same(t->fn, t->cmp);
 
-  enum filter_return fret = f_eval(t->fn, tmp_linpool, NULL);
+  enum filter_return fret = f_eval(t->fn, NULL);
 
   return (fret < F_REJECT);
 }
index fcb7023022e26f13d807452894d0a345d687ef7d..d2638f3f0ed95f12f26e6d06c01406c72e464350 100644 (file)
@@ -37,6 +37,8 @@ lp_store_adata(struct linpool *pool, const void *buf, uint len)
   return ad;
 }
 
+#define tmp_store_adata(buf, len) lp_store_adata(tmp_linpool, buf, len)
+
 static inline int adata_same(const struct adata *a, const struct adata *b)
 { return (a->length == b->length && !memcmp(a->data, b->data, a->length)); }
 
index 3e59cb6fea1871bb120b05dca4e7c18c1b86a088..99a7bbfe95964e87de67f867c69260198f3b6978 100644 (file)
@@ -133,7 +133,7 @@ cmd_eval(const struct f_line *expr)
   buffer buf;
   LOG_BUFFER_INIT(buf);
 
-  if (f_eval_buf(expr, this_cli->parser_pool, &buf) > F_RETURN)
+  if (f_eval_buf(expr, &buf) > F_RETURN)
     {
       cli_msg(8008, "runtime error");
       return;
index 4e0c56022f83e6ed413959a07073a06b180f5e0c..7d02f52ede58c1076955a28b2cca5637348724a1 100644 (file)
@@ -169,7 +169,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
               * command may change the export filter and do not update routes.
               */
              int do_export = (ic > 0) ||
-               (f_run(ec->out_filter, &e, c->show_pool, FF_SILENT) <= F_ACCEPT);
+               (f_run(ec->out_filter, &e, FF_SILENT) <= F_ACCEPT);
 
              if (do_export != (d->export_mode == RSEM_EXPORT))
                goto skip;
@@ -182,7 +182,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
       if (d->show_protocol && (d->show_protocol != e->src->proto))
        goto skip;
 
-      if (f_run(d->filter, &e, c->show_pool, 0) > F_ACCEPT)
+      if (f_run(d->filter, &e, 0) > F_ACCEPT)
        goto skip;
 
       if (d->stats < 2)
index 031e462b5f55d3c766130d00992710bdebc63103..049b7a7f943d76cc60d4c8056856891cafdbeae1 100644 (file)
@@ -713,7 +713,7 @@ rte_trace_out(uint flag, struct channel *c, rte *e, char *msg)
 }
 
 static rte *
-export_filter_(struct channel *c, rte *rt0, rte **rt_free, linpool *pool, int silent)
+export_filter(struct channel *c, rte *rt0, rte **rt_free, int silent)
 {
   struct proto *p = c->proto;
   const struct filter *filter = c->out_filter;
@@ -743,7 +743,7 @@ export_filter_(struct channel *c, rte *rt0, rte **rt_free, linpool *pool, int si
     }
 
   v = filter && ((filter == FILTER_REJECT) ||
-                (f_run(filter, &rt, pool,
+                (f_run(filter, &rt,
                        (silent ? FF_SILENT : 0)) > F_ACCEPT));
   if (v)
     {
@@ -767,12 +767,6 @@ export_filter_(struct channel *c, rte *rt0, rte **rt_free, linpool *pool, int si
   return NULL;
 }
 
-static inline rte *
-export_filter(struct channel *c, rte *rt0, rte **rt_free, int silent)
-{
-  return export_filter_(c, rt0, rt_free, rte_update_pool, silent);
-}
-
 static void
 do_rt_notify(struct channel *c, net *net, rte *new, rte *old, int refeed)
 {
@@ -963,7 +957,7 @@ rt_export_merged(struct channel *c, net *net, rte **rt_free, linpool *pool, int
   if (!rte_is_valid(best0))
     return NULL;
 
-  best = export_filter_(c, best0, rt_free, pool, silent);
+  best = export_filter(c, best0, rt_free, silent);
 
   if (!best || !rte_is_reachable(best))
     return best;
@@ -973,7 +967,7 @@ rt_export_merged(struct channel *c, net *net, rte **rt_free, linpool *pool, int
     if (!rte_mergable(best0, rt0))
       continue;
 
-    rt = export_filter_(c, rt0, &tmp, pool, 1);
+    rt = export_filter(c, rt0, &tmp, 1);
 
     if (!rt)
       continue;
@@ -1592,7 +1586,7 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
        }
       else if (filter)
        {
-         int fr = f_run(filter, &new, rte_update_pool, 0);
+         int fr = f_run(filter, &new, 0);
          if (fr > F_ACCEPT)
          {
            stats->imp_updates_filtered++;
@@ -1696,7 +1690,7 @@ rt_examine(rtable *t, net_addr *a, struct proto *p, const struct filter *filter)
   /* Rest is stripped down export_filter() */
   int v = p->preexport ? p->preexport(p, rt) : 0;
   if (v == RIC_PROCESS)
-    v = (f_run(filter, &rt, rte_update_pool, FF_SILENT) <= F_ACCEPT);
+    v = (f_run(filter, &rt, FF_SILENT) <= F_ACCEPT);
 
   /* Discard temporary rte */
   if (rt != n->routes)
index 760cfa737b3d6f5c719a534ccc5aab0a3af757a2..c595f2987e36cedfd1694024503d5fffb5aeab48 100644 (file)
@@ -525,7 +525,7 @@ mrt_rib_table_dump(struct mrt_table_dump_state *s, net *n, int add_path)
       continue;
     }
 
-    if (f_run(s->filter, &rt, s->linpool, 0) <= F_ACCEPT)
+    if (f_run(s->filter, &rt, 0) <= F_ACCEPT)
       mrt_rib_table_entry(s, rt);
 
     if (rt != rt0)
index 3a0d92577313258555fec0c2ae0356840080727c..42febcd42e736d78480b879472d4d8d0ed21e5f2 100644 (file)
@@ -47,8 +47,6 @@
 
 #include "static.h"
 
-static linpool *static_lp;
-
 static inline struct rte_src * static_get_source(struct static_proto *p, uint i)
 { return i ? rt_get_source(&p->p, i) : p->p.main_source; }
 
@@ -114,7 +112,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);
 
     /* Remove the temporary node */
     e->net = NULL;
@@ -122,10 +120,6 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
 
   rte_update2(p->p.main_channel, r->net, e, src);
   r->state = SRS_CLEAN;
-
-  if (r->cmds)
-    lp_flush(static_lp);
-
   return;
 
 withdraw:
@@ -485,9 +479,6 @@ static_start(struct proto *P)
   struct static_config *cf = (void *) P->cf;
   struct static_route *r;
 
-  if (!static_lp)
-    static_lp = lp_new(&root_pool);
-
   if (p->igp_table_ip4)
     rt_lock_table(p->igp_table_ip4);
 
index 671e91fe18d7ee183cd49540b9fdab38dded1594..0ebc4fb33b14843e0b3960165da7c003d1bfe7d3 100644 (file)
@@ -589,7 +589,7 @@ krt_export_net(struct krt_proto *p, net *net, rte **rt_free)
   if (filter == FILTER_ACCEPT)
     goto accept;
 
-  if (f_run(filter, &rt, krt_filter_lp, FF_SILENT) > F_ACCEPT)
+  if (f_run(filter, &rt, FF_SILENT) > F_ACCEPT)
     goto reject;