]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter: Pre-evaluation of constant expressions
authorMaria Matejka <mq@ucw.cz>
Tue, 2 Jul 2019 08:45:53 +0000 (10:45 +0200)
committerMaria Matejka <mq@ucw.cz>
Tue, 2 Jul 2019 08:45:53 +0000 (10:45 +0200)
conf/cf-lex.l
filter/Makefile
filter/data.c
filter/data.h
filter/decl.m4
filter/f-inst.c
filter/filter.c
lib/resource.h

index 0aa9273f36a816fd70f8f82ea6f57825a9bed3d2..38250d9068c49c96374894a359dfb4907960781e 100644 (file)
@@ -757,6 +757,7 @@ cf_pop_scope(void)
 {
   conf_this_scope->active = 0;
   conf_this_scope = conf_this_scope->next;
+
   ASSERT(conf_this_scope);
 }
 
index b2f8d96d724cd5ea9f3dc280fa574e497fcc0532..c20625346e9660fff33fe079aa1505bee87e1720 100644 (file)
@@ -3,7 +3,8 @@ obj := $(src-o-files)
 $(all-daemon)
 $(cf-local)
 
-M4FLAGS_FILTERS=$(filter-out -s,$(M4FLAGS))
+#M4FLAGS_FILTERS=$(filter-out -s,$(M4FLAGS))
+M4FLAGS_FILTERS=$(M4FLAGS)
 
 $(o)inst-gen.h: $(s)decl.m4 $(s)f-inst.c $(objdir)/.dir-stamp
        $(M4) $(M4FLAGS_FILTERS) -DTARGET=H -P $^ >$@
index 912e2b00aaf0c726085b31f7f1df02ca83f46ee9..db55070fa08f3fb3409ebbc7924885a444e2e43b 100644 (file)
@@ -514,6 +514,15 @@ val_format(const struct f_val *v, buffer *buf)
   }
 }
 
+char *
+val_format_str(struct linpool *lp, const struct f_val *v) {
+  buffer b;
+  LOG_BUFFER_INIT(b);
+  val_format(v, &b);
+  return lp_strdup(lp, b.start);
+}
+
+
 static char val_dump_buffer[1024];
 const char *
 val_dump(const struct f_val *v) {
index 6973008ffca924ebda7feec8ee0044cc6c3bdd01..083595f4c2937da059e902adcb096b8320a8546c 100644 (file)
@@ -119,7 +119,7 @@ enum f_lval_type {
 struct f_lval {
   enum f_lval_type type;
   union {
-    const struct symbol *sym;
+    struct symbol *sym;
     struct f_dynamic_attr da;
     struct f_static_attr sa;
   };
@@ -169,6 +169,7 @@ void trie_format(const struct f_trie *t, buffer *buf);
 int val_same(const struct f_val *v1, const struct f_val *v2);
 int val_compare(const struct f_val *v1, const struct f_val *v2);
 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);
 
 static inline int val_is_ip4(const struct f_val *v)
index 786fee31f98bd36991f2507d000b3a845f92785a..cc06948593687a0c182898f77e4a8f86d6c95f2c 100644 (file)
@@ -53,7 +53,12 @@ m4_define(FID_LINE_IN, `m4_divert(107)')
 m4_define(FID_INTERPRET_BODY, `m4_divert(108)')
 
 m4_define(FID_ALL, `FID_INTERPRET_BODY');
-m4_define(FID_HIC, `m4_ifelse(TARGET, [[H]], $1, TARGET, [[I]], $2, TARGET, [[C]], $3)')
+m4_define(FID_HIC, `m4_ifelse(TARGET, [[H]], [[$1]], TARGET, [[I]], [[$2]], TARGET, [[C]], [[$3]])')
+
+m4_define(FID_INTERPRET_EXEC, `FID_HIC(,[[FID_INTERPRET_BODY()]],[[m4_divert(-1)]])')
+m4_define(FID_INTERPRET_NEW,  `FID_HIC(,[[m4_divert(-1)]],[[FID_INTERPRET_BODY()]])')
+m4_define(NEVER_CONSTANT, `m4_define([[INST_NEVER_CONSTANT]])')
+m4_define(FID_IFCONST, `m4_ifdef([[INST_NEVER_CONSTANT]],[[$2]],[[$1]])')
 
 m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[
 FID_ENUM
@@ -72,26 +77,29 @@ FID_NEW
 FID_HIC(
 [[
 struct f_inst *f_new_inst_]]INST_NAME()[[(enum f_instruction_code fi_code
-[[m4_undivert(102)]]
+m4_undivert(102)
 );]],
 [[
   case INST_NAME():
   #define whati (&(what->i_]]INST_NAME()[[))
   m4_ifelse(m4_eval(INST_INVAL() > 0), 1, [[if (fstk->vcnt < INST_INVAL()) runtime("Stack underflow"); fstk->vcnt -= INST_INVAL(); ]])
-  [[m4_undivert(108)]]
+  m4_undivert(108)
   #undef whati
   break;
 ]],
 [[
 struct f_inst *f_new_inst_]]INST_NAME()[[(enum f_instruction_code fi_code
-[[m4_undivert(102)]]
+m4_undivert(102)
 )
   {
     struct f_inst *what = fi_new(fi_code);
+    FID_IFCONST([[uint constargs = 1;]])
   #define whati (&(what->i_]]INST_NAME()[[))
-  [[m4_undivert(103)]]
+  m4_undivert(103)
+    FID_IFCONST([[if (!constargs)]])
+      return what;
+    FID_IFCONST([[m4_undivert(108)]])
   #undef whati
-    return what;
   }
 ]])
 
@@ -130,13 +138,14 @@ m4_undivert(106)
 #undef f1
 #undef f2
 break;
-
+m4_divert(-1)FID_FLUSH(101,200)
 ]])')
 
 m4_define(INST, `m4_dnl
 INST_FLUSH()m4_dnl
 m4_define([[INST_NAME]], [[$1]])m4_dnl
 m4_define([[INST_INVAL]], [[$2]])m4_dnl
+m4_undefine([[INST_NEVER_CONSTANT]])m4_dnl
 FID_ALL() m4_dnl
 ')
 
@@ -149,22 +158,18 @@ FID_NEW_ARGS
 , $1 $2
 FID_NEW_BODY
 whati->$2 = $2;
-m4_ifelse($3,,,[[
 FID_LINEARIZE_BODY
-item->$3 = whati->$2;
-]])
-m4_ifelse($4,,,[[
+item->$2 = whati->$2;
+m4_ifelse($3,,,[[
 FID_SAME_BODY
-if ($4) return 0;
+if ($3) return 0;
 ]])
-m4_ifelse($5,,,[[
+m4_ifelse($4,,,[[
 FID_DUMP_BODY
-debug("%s$5\n", INDENT, $6);
-]])
-m4_ifelse($7,,,[[
-FID_INTERPRET_BODY
-$7
+debug("%s$4\n", INDENT, $5);
 ]])
+FID_INTERPRET_EXEC
+const $1 $2 = whati->$2
 FID_ALL')
 
 m4_define(ARG_ANY, `
@@ -174,34 +179,39 @@ FID_NEW_ARGS
 , struct f_inst * f$1
 FID_NEW_BODY
 whati->f$1 = f$1;
-for (const struct f_inst *child = f$1; child; child = child->next) what->size += child->size;
+for (const struct f_inst *child = f$1; child; child = child->next) {
+  what->size += child->size;
+FID_IFCONST([[
+  if (child->fi_code != FI_CONSTANT)
+    constargs = 0;
+]])
+}
 FID_LINEARIZE_BODY
-pos = linearize(dest, whati->f$1, pos);m4_dnl
+pos = linearize(dest, whati->f$1, pos);
 FID_ALL()')
 
 m4_define(ARG, `ARG_ANY($1)
-FID_INTERPRET_BODY
+FID_INTERPRET_EXEC()
 if (v$1.type != $2) runtime("Argument $1 of instruction %s must be of type $2, got 0x%02x", f_instruction_name(what->fi_code), v$1.type)m4_dnl
 FID_ALL()')
 
-m4_define(LINEX, `FID_INTERPRET_BODY
-do {
+m4_define(LINEX, `FID_INTERPRET_EXEC()LINEX_($1)FID_INTERPRET_NEW()return $1 FID_ALL()')
+m4_define(LINEX_, `do {
   fstk->estk[fstk->ecnt].pos = 0;
   fstk->estk[fstk->ecnt].line = $1;
   fstk->estk[fstk->ecnt].ventry = fstk->vcnt;
   fstk->estk[fstk->ecnt].vbase = fstk->estk[fstk->ecnt-1].vbase;
   fstk->estk[fstk->ecnt].emask = 0;
   fstk->ecnt++;
-} while (0)m4_dnl
-FID_ALL()')
+} while (0)')
 
 m4_define(LINE, `
 FID_LINE_IN
 const struct f_line * fl$1;
 FID_STRUCT_IN
-const struct f_inst * f$1;
+struct f_inst * f$1;
 FID_NEW_ARGS
-, const struct f_inst * f$1
+, struct f_inst * f$1
 FID_NEW_BODY
 whati->f$1 = f$1;
 FID_DUMP_BODY
@@ -210,23 +220,25 @@ FID_LINEARIZE_BODY
 item->fl$1 = f_linearize(whati->f$1);
 FID_SAME_BODY
 if (!f_same(f1->fl$1, f2->fl$1)) return 0;
-FID_INTERPRET_BODY
+FID_INTERPRET_EXEC
 do { if (whati->fl$1) {
-  LINEX(whati->fl$1);
-} } while(0)m4_dnl
+  LINEX_(whati->fl$1);
+} } while(0)
+FID_INTERPRET_NEW
+return whati->f$1
 FID_ALL()')
 
 m4_define(RESULT, `RESULT_VAL([[ (struct f_val) { .type = $1, .val.$2 = $3 } ]])')
-m4_define(RESULT_VAL, `FID_INTERPRET_BODY()do { res = $1; fstk->vcnt++; } while (0)FID_ALL()')
+m4_define(RESULT_VAL, `FID_HIC(, [[do { res = $1; fstk->vcnt++; } while (0)]],
+[[return fi_constant(what, $1)]])')
 m4_define(RESULT_VOID, `RESULT_VAL([[ (struct f_val) { .type = T_VOID } ]])')
 
-m4_define(SYMBOL, `FID_MEMBER(const struct symbol *, sym, sym,
-[[strcmp(f1->sym->name, f2->sym->name) || (f1->sym->class != f2->sym->class)]], symbol %s, item->sym->name, const struct symbol *sym = whati->sym)')
-m4_define(FRET, `')
-m4_define(ECS, `FID_MEMBER(enum ec_subtype, ecs, ecs, f1->ecs != f2->ecs, ec subtype %s, ec_subtype_str(item->ecs), enum ec_subtype ecs = whati->ecs)')
-m4_define(RTC, `FID_MEMBER(const struct rtable_config *, rtc, rtc, [[strcmp(f1->rtc->name, f2->rtc->name)]], route table %s, item->rtc->name, struct rtable *table = whati->rtc->table)')
-m4_define(STATIC_ATTR, `FID_MEMBER(struct f_static_attr, sa, sa, f1->sa.sa_code != f2->sa.sa_code,,, struct f_static_attr sa = whati->sa)')
-m4_define(DYNAMIC_ATTR, `FID_MEMBER(struct f_dynamic_attr, da, da, f1->da.ea_code != f2->da.ea_code,,, struct f_dynamic_attr da = whati->da)')
+m4_define(SYMBOL, `FID_MEMBER(struct symbol *, sym, 
+[[strcmp(f1->sym->name, f2->sym->name) || (f1->sym->class != f2->sym->class)]], symbol %s, item->sym->name)')
+m4_define(RTC, `FID_MEMBER(struct rtable_config *, rtc, [[strcmp(f1->rtc->name, f2->rtc->name)]], route table %s, item->rtc->name)')
+m4_define(STATIC_ATTR, `FID_MEMBER(struct f_static_attr, sa, f1->sa.sa_code != f2->sa.sa_code,,)')
+m4_define(DYNAMIC_ATTR, `FID_MEMBER(struct f_dynamic_attr, da, f1->da.ea_code != f2->da.ea_code,,)')
+m4_define(ACCESS_RTE, `NEVER_CONSTANT()')
 
 m4_define(FID_WR_PUT_LIST)
 m4_define(FID_WR_PUT_ALSO, `m4_define([[FID_WR_PUT_LIST]],FID_WR_PUT_LIST()[[FID_WR_DPUT(]]FID_WR_DIDX[[)FID_WR_DPUT(]]$1[[)]])m4_define([[FID_WR_DIDX]],m4_eval(FID_WR_DIDX+1))m4_divert(FID_WR_DIDX)')
@@ -267,8 +279,25 @@ fi_new(enum f_instruction_code fi_code)
   return what;
 }
 
+static inline struct f_inst *
+fi_constant(struct f_inst *what, struct f_val val)
+{
+  what->fi_code = FI_CONSTANT;
+  what->i_FI_CONSTANT.val = val;
+  return what;
+}
+
+#define v1 whati->f1->i_FI_CONSTANT.val
+#define v2 whati->f2->i_FI_CONSTANT.val
+#define v3 whati->f3->i_FI_CONSTANT.val
+#define runtime(fmt, ...) cf_error("filter preevaluation, line %d: " fmt, ifs->lino, ##__VA_ARGS__)
+#define fpool cfg_mem
+#define falloc(size) cfg_alloc(size)
 /* Instruction constructors */
 FID_WR_PUT(3)
+#undef v1
+#undef v2
+#undef v3
 
 /* Line dumpers */
 #define INDENT (((const char *) f_dump_line_indent_str) + sizeof(f_dump_line_indent_str) - (indent) - 1)
@@ -387,9 +416,9 @@ FID_WR_PUT(3)
 m4_divert(-1)
 m4_changequote(`,')
 
-m4_define(FID_CLEANUP, `m4_ifelse($1,$2,,[[m4_undivert($1)FID_CLEANUP(m4_eval($1+1),$2)]])')
+m4_define(FID_FLUSH, `m4_ifelse($1,$2,,[[m4_undivert($1)FID_FLUSH(m4_eval($1+1),$2)]])')
 m4_define(FID_WR_DPUT, `m4_undivert($1)')
 
-m4_m4wrap(`INST_FLUSH()m4_divert(0)FID_WR_PUT_LIST()m4_divert(-1)FID_CLEANUP(1,200)')
+m4_m4wrap(`INST_FLUSH()m4_divert(0)FID_WR_PUT_LIST()m4_divert(-1)FID_FLUSH(1,200)')
 
 m4_changequote([[,]])
index a70a4a921a42128d26f632c2fa83b335f8a48d2d..edc9779408d90f049a6d4075b704aafbde60d006 100644 (file)
  *
  *     m4_dnl    FID_MEMBER(                           custom instruction member
  *     m4_dnl      C type,                             for storage in structs
- *     m4_dnl      name in f_inst,                     how the member is named before linearization
- *     m4_dnl      name in f_line_item,                how the member is named afterwards
+ *     m4_dnl      name,                               how the member is named
  *     m4_dnl      comparator for same(),              if different, this should be TRUE (CAVEAT)
  *     m4_dnl      dump format string                  debug -> format string for bvsnprintf
  *     m4_dnl      dump format args                    appropriate args
- *     m4_dnl      interpreter body                    how to deal with this on execution
  *     m4_dnl    )
  *
  *     m4_dnl    RESULT(type, union-field, value);     putting this on value stack
     ARG_ANY(1);
     ARG(2, T_INT);
 
-    FID_MEMBER(enum ec_subtype, ecs, ecs, f1->ecs != f2->ecs, ec subtype %s, ec_subtype_str(item->ecs), enum ec_subtype ecs = whati->ecs);
+    FID_MEMBER(enum ec_subtype, ecs, f1->ecs != f2->ecs, ec subtype %s, ec_subtype_str(item->ecs));
 
     int check, ipv4_used;
     u32 key, val;
 
   INST(FI_PATHMASK_CONSTRUCT, 0, 1) {
     ARG_ANY(1);
-    FID_MEMBER(uint, count, count, f1->count != f2->count, number of items %u, item->count);
+    FID_MEMBER(uint, count, f1->count != f2->count, number of items %u, item->count);
 
     FID_NEW_BODY
       uint len = 0;
-      uint dyn = 0;
-      for (const struct f_inst *tt = f1; tt; tt = tt->next, len++)
-       if (tt->fi_code != FI_CONSTANT)
-         dyn++;
+      for (const struct f_inst *tt = f1; tt; tt = tt->next, len++);
 
       whati->count = len;
+      struct f_inst **items;
+      if (constargs) {
+       items = alloca(len * sizeof(struct f_inst *));
+       for (uint i=0; f1; i++) {
+         items[i] = f1;
+         f1 = f1->next;
+         items[i]->next = 0;
+       }
+       whati->f1 = NULL;
+      }
     FID_ALL
 
+    FID_INTERPRET_EXEC
     if (fstk->vcnt < whati->count) /* TODO: make this check systematic */
       runtime("Construction of BGP path mask from %u elements must have at least that number of elements", whati->count);
 
-    struct f_path_mask *pm = lp_alloc(fs->pool, sizeof(struct f_path_mask) + whati->count * sizeof(struct f_path_mask_item));
+#define pv fstk->vstk[fstk->vcnt - count + i]
+
+    FID_INTERPRET_NEW
+#define pv items[i]->i_FI_CONSTANT.val
+
+    FID_INTERPRET_BODY
+    struct f_path_mask *pm = falloc(sizeof(struct f_path_mask) + whati->count * sizeof(struct f_path_mask_item));
     for (uint i=0; i<whati->count; i++) {
-#define pv fstk->vstk[fstk->vcnt - whati->count + i]
       switch (pv.type) {
        case T_PATH_MASK_ITEM:
          pm->item[i] = pv.val.pmi;
       }
     }
 
-    fstk->vcnt -= whati->count;
-    pm->len = whati->count;
+    FID_INTERPRET_EXEC
+      fstk->vcnt -= whati->count;
+    FID_ALL
 
+    pm->len = whati->count;
     RESULT(T_PATH_MASK, path_mask, pm);
   }
 
 
   /* Set to indirect value prepared in v1 */
   INST(FI_VAR_SET, 1, 0) {
+    NEVER_CONSTANT;
     ARG_ANY(1);
     SYMBOL;
+
     if ((sym->class != (SYM_VARIABLE | v1.type)) && (v1.type != T_VOID))
     {
       /* IP->Quad implicit conversion */
 
   INST(FI_VAR_GET, 0, 1) {
     SYMBOL;
+    NEVER_CONSTANT;
     RESULT_VAL(fstk->vstk[curline.vbase + sym->offset]);
   }
 
     FID_MEMBER(
       struct f_val,
       val,
-      val,
       [[ !val_same(&(f1->val), &(f2->val)) ]],
       value %s,
       val_dump(&(item->val))
     );
 
-    RESULT_VAL(whati->val);
+    RESULT_VAL(val);
   }
   INST(FI_PRINT, 1, 0) {
+    NEVER_CONSTANT;
     ARG_ANY(1);
     val_format(&(v1), &fs->buf);
   }
   INST(FI_CONDITION, 1, 0) {
     ARG(1, T_BOOL);
-    if (res.val.i)
+    if (v1.val.i)
       LINE(2,0);
     else
       LINE(3,1);
   }
   INST(FI_PRINT_AND_DIE, 0, 0) {
+    NEVER_CONSTANT;
     FID_LINEARIZE_BODY
     {
       uint opos = pos;
     }
     FID_ALL
 
-    FID_MEMBER(enum filter_return, fret, fret, f1->fret != f2->fret, %s, filter_return_str(item->fret), enum filter_return fret = whati->fret);
+    FID_MEMBER(enum filter_return, fret, f1->fret != f2->fret, %s, filter_return_str(item->fret));
 
     if ((fret == F_NOP || (fret != F_NONL && (what->flags & FIF_PRINTED))) &&
        !(fs->flags & FF_SILENT))
       runtime( "SADR expected" );
 
     net_addr_ip6_sadr *net = (void *) v1.val.net;
-    net_addr *src = lp_alloc(fs->pool, sizeof(net_addr_ip6));
+    net_addr *src = falloc(sizeof(net_addr_ip6));
     net_fill_ip6(src, net->src_prefix, net->src_pxlen);
 
     RESULT(T_NET, net, src);
   }
 
   INST(FI_RETURN, 1, 1) {
+    NEVER_CONSTANT;
     /* Acquire the return value */
     ARG_ANY(1);
     uint retpos = fstk->vcnt;
   }
 
   INST(FI_CALL, 0, 1) {
+    NEVER_CONSTANT;
     SYMBOL;
 
     /* Push the body on stack */
   }
 
   INST(FI_DROP_RESULT, 1, 0) {
+    NEVER_CONSTANT;
     ARG_ANY(1);
   }
 
   INST(FI_SWITCH, 1, 0) {
     ARG_ANY(1);
 
-    FID_MEMBER(const struct f_tree *, tree, tree, [[!same_tree(f1->tree, f2->tree)]], tree %p, item->tree, const struct f_tree *tree = whati->tree);
+    FID_MEMBER(struct f_tree *, tree, [[!same_tree(f1->tree, f2->tree)]], tree %p, item->tree);
 
     const struct f_tree *t = find_tree(tree, &v1);
     if (!t) {
       t = find_tree(tree, &v1);
       if (!t) {
        debug( "No else statement?\n");
-       break;
+       FID_HIC(,break,return NULL);
       }
     }
     /* It is actually possible to have t->data NULL */
   INST(FI_PATH_PREPEND, 2, 1) {        /* Path prepend */
     ARG(1, T_PATH);
     ARG(2, T_INT);
-    RESULT(T_PATH, ad, [[ as_path_prepend(fs->pool, v1.val.ad, v2.val.i) ]]);
+    RESULT(T_PATH, ad, [[ as_path_prepend(fpool, v1.val.ad, v2.val.i) ]]);
   }
 
   INST(FI_CLIST_ADD, 2, 1) {   /* (Extended) Community list add */
       struct f_val dummy;
 
       if ((v2.type == T_PAIR) || (v2.type == T_QUAD))
-       RESULT(T_CLIST, ad, [[ int_set_add(fs->pool, v1.val.ad, v2.val.i) ]]);
+       RESULT(T_CLIST, ad, [[ int_set_add(fpool, v1.val.ad, v2.val.i) ]]);
       /* IP->Quad implicit conversion */
       else if (val_is_ip4(&v2))
-       RESULT(T_CLIST, ad, [[ int_set_add(fs->pool, v1.val.ad, ipa_to_u32(v2.val.ip)) ]]);
+       RESULT(T_CLIST, ad, [[ int_set_add(fpool, v1.val.ad, ipa_to_u32(v2.val.ip)) ]]);
       else if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy))
        runtime("Can't add set");
       else if (v2.type == T_CLIST)
-       RESULT(T_CLIST, ad, [[ int_set_union(fs->pool, v1.val.ad, v2.val.ad) ]]);
+       RESULT(T_CLIST, ad, [[ int_set_union(fpool, v1.val.ad, v2.val.ad) ]]);
       else
        runtime("Can't add non-pair");
     }
       if ((v2.type == T_SET) && eclist_set_type(v2.val.t))
        runtime("Can't add set");
       else if (v2.type == T_ECLIST)
-       RESULT(T_ECLIST, ad, [[ ec_set_union(fs->pool, v1.val.ad, v2.val.ad) ]]);
+       RESULT(T_ECLIST, ad, [[ ec_set_union(fpool, v1.val.ad, v2.val.ad) ]]);
       else if (v2.type != T_EC)
        runtime("Can't add non-ec");
       else
-       RESULT(T_ECLIST, ad, [[ ec_set_add(fs->pool, v1.val.ad, v2.val.ec) ]]);
+       RESULT(T_ECLIST, ad, [[ ec_set_add(fpool, v1.val.ad, v2.val.ec) ]]);
     }
 
     else if (v1.type == T_LCLIST)
       if ((v2.type == T_SET) && lclist_set_type(v2.val.t))
        runtime("Can't add set");
       else if (v2.type == T_LCLIST)
-       RESULT(T_LCLIST, ad, [[ lc_set_union(fs->pool, v1.val.ad, v2.val.ad) ]]);
+       RESULT(T_LCLIST, ad, [[ lc_set_union(fpool, v1.val.ad, v2.val.ad) ]]);
       else if (v2.type != T_LC)
        runtime("Can't add non-lc");
       else
-       RESULT(T_LCLIST, ad, [[ lc_set_add(fs->pool, v1.val.ad, v2.val.lc) ]]);
+       RESULT(T_LCLIST, ad, [[ lc_set_add(fpool, v1.val.ad, v2.val.lc) ]]);
 
     }
 
       else
        runtime("Can't delete non-integer (set)");
 
-      RESULT(T_PATH, ad, [[ as_path_filter(fs->pool, v1.val.ad, set, key, 0) ]]);
+      RESULT(T_PATH, ad, [[ as_path_filter(fpool, v1.val.ad, set, key, 0) ]]);
     }
 
     else if (v1.type == T_CLIST)
       struct f_val dummy;
 
       if ((v2.type == T_PAIR) || (v2.type == T_QUAD))
-       RESULT(T_CLIST, ad, [[ int_set_del(fs->pool, v1.val.ad, v2.val.i) ]]);
+       RESULT(T_CLIST, ad, [[ int_set_del(fpool, v1.val.ad, v2.val.i) ]]);
       /* IP->Quad implicit conversion */
       else if (val_is_ip4(&v2))
-       RESULT(T_CLIST, ad, [[ int_set_del(fs->pool, v1.val.ad, ipa_to_u32(v2.val.ip)) ]]);
+       RESULT(T_CLIST, ad, [[ int_set_del(fpool, v1.val.ad, ipa_to_u32(v2.val.ip)) ]]);
       else if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy) || (v2.type == T_CLIST))
-       RESULT(T_CLIST, ad, [[ clist_filter(fs->pool, v1.val.ad, &v2, 0) ]]);
+       RESULT(T_CLIST, ad, [[ clist_filter(fpool, v1.val.ad, &v2, 0) ]]);
       else
        runtime("Can't delete non-pair");
     }
     {
       /* v2.val is either EC or EC-set */
       if ((v2.type == T_SET) && eclist_set_type(v2.val.t) || (v2.type == T_ECLIST))
-       RESULT(T_ECLIST, ad, [[ eclist_filter(fs->pool, v1.val.ad, &v2, 0) ]]);
+       RESULT(T_ECLIST, ad, [[ eclist_filter(fpool, v1.val.ad, &v2, 0) ]]);
       else if (v2.type != T_EC)
        runtime("Can't delete non-ec");
       else
-       RESULT(T_ECLIST, ad, [[ ec_set_del(fs->pool, v1.val.ad, v2.val.ec) ]]);
+       RESULT(T_ECLIST, ad, [[ ec_set_del(fpool, v1.val.ad, v2.val.ec) ]]);
     }
 
     else if (v1.type == T_LCLIST)
     {
       /* v2.val is either LC or LC-set */
       if ((v2.type == T_SET) && lclist_set_type(v2.val.t) || (v2.type == T_LCLIST))
-       RESULT(T_LCLIST, ad, [[ lclist_filter(fs->pool, v1.val.ad, &v2, 0) ]]);
+       RESULT(T_LCLIST, ad, [[ lclist_filter(fpool, v1.val.ad, &v2, 0) ]]);
       else if (v2.type != T_LC)
        runtime("Can't delete non-lc");
       else
-       RESULT(T_LCLIST, ad, [[ lc_set_del(fs->pool, v1.val.ad, v2.val.lc) ]]);
+       RESULT(T_LCLIST, ad, [[ lc_set_del(fpool, v1.val.ad, v2.val.lc) ]]);
     }
 
     else
       u32 key = 0;
 
       if ((v2.type == T_SET) && (v2.val.t->from.type == T_INT))
-       RESULT(T_PATH, ad, [[ as_path_filter(fs->pool, v1.val.ad, v2.val.t, key, 1) ]]);
+       RESULT(T_PATH, ad, [[ as_path_filter(fpool, v1.val.ad, v2.val.t, key, 1) ]]);
       else
        runtime("Can't filter integer");
     }
       struct f_val dummy;
 
       if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy) || (v2.type == T_CLIST))
-       RESULT(T_CLIST, ad, [[ clist_filter(fs->pool, v1.val.ad, &v2, 1) ]]);
+       RESULT(T_CLIST, ad, [[ clist_filter(fpool, v1.val.ad, &v2, 1) ]]);
       else
        runtime("Can't filter pair");
     }
     {
       /* v2.val is either EC or EC-set */
       if ((v2.type == T_SET) && eclist_set_type(v2.val.t) || (v2.type == T_ECLIST))
-       RESULT(T_ECLIST, ad, [[ eclist_filter(fs->pool, v1.val.ad, &v2, 1) ]]);
+       RESULT(T_ECLIST, ad, [[ eclist_filter(fpool, v1.val.ad, &v2, 1) ]]);
       else
        runtime("Can't filter ec");
     }
     {
       /* v2.val is either LC or LC-set */
       if ((v2.type == T_SET) && lclist_set_type(v2.val.t) || (v2.type == T_LCLIST))
-       RESULT(T_LCLIST, ad, [[ lclist_filter(fs->pool, v1.val.ad, &v2, 1) ]]);
+       RESULT(T_LCLIST, ad, [[ lclist_filter(fpool, v1.val.ad, &v2, 1) ]]);
       else
        runtime("Can't filter lc");
     }
   }
 
   INST(FI_ROA_CHECK_IMPLICIT, 0, 1) {  /* ROA Check */
+    NEVER_CONSTANT;
     RTC(1);
+    struct rtable *table = rtc->table;
     ACCESS_RTE;
     ACCESS_EATTRS;
     const net_addr *net = (*fs->rte)->net->n.addr;
   }
 
   INST(FI_ROA_CHECK_EXPLICIT, 2, 1) {  /* ROA Check */
+    NEVER_CONSTANT;
     ARG(1, T_NET);
     ARG(2, T_INT);
     RTC(3);
+    struct rtable *table = rtc->table;
 
     u32 as = v2.val.i;
 
 
   INST(FI_FORMAT, 1, 0) {      /* Format */
     ARG_ANY(1);
-    RESULT(T_STRING, s, val_format_str(fs, &v1));
+    RESULT(T_STRING, s, val_format_str(fpool, &v1));
   }
 
   INST(FI_ASSERT, 1, 0) {      /* Birdtest Assert */
+    NEVER_CONSTANT;
     ARG(1, T_BOOL);
-    FID_MEMBER(const char *, s, s, [[strcmp(f1->s, f2->s)]], string \"%s\", item->s);
+    FID_MEMBER(char *, s, [[strcmp(f1->s, f2->s)]], string \"%s\", item->s);
+
+    ASSERT(s);
 
     if (!bt_assert_hook)
       runtime("No bt_assert hook registered, can't assert");
 
-    bt_assert_hook(res.val.i, what);
+    bt_assert_hook(v1.val.i, what);
   }
index ee29522e4994e6c4178873df28e4fd8f1ddb5fb2..ed0b21bc26e51ae4525eea5561855711767aed36 100644 (file)
@@ -150,14 +150,6 @@ f_rta_cow(struct filter_state *fs)
   f_cache_eattrs(fs);
 }
 
-static char *
-val_format_str(struct filter_state *fs, struct f_val *v) {
-  buffer b;
-  LOG_BUFFER_INIT(b);
-  val_format(v, &b);
-  return lp_strdup(fs->pool, b.start);
-}
-
 static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS;
 
 /**
@@ -215,6 +207,9 @@ 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 ACCESS_RTE do { if (!fs->rte) runtime("No route to access"); } while (0)
 #define ACCESS_EATTRS do { if (!fs->eattrs) f_cache_eattrs(fs); } while (0)
 
@@ -224,6 +219,8 @@ interpret(struct filter_state *fs, const struct f_line *line, struct f_val *val)
 #undef v2
 #undef v3
 #undef runtime
+#undef falloc
+#undef fpool
 #undef ACCESS_RTE
 #undef ACCESS_EATTRS
       }
index d9d4bb8f10e265e07e107b174561fdc55f09a8bd..ad17d9ed45be5da41017935639124ae988c838bd 100644 (file)
@@ -101,9 +101,13 @@ void buffer_realloc(void **buf, unsigned *size, unsigned need, unsigned item_siz
  */
 #define DMALLOC_DISABLE
 #include <dmalloc.h>
-#define xmalloc(size) _xmalloc_leap(__FILE__, __LINE__, size)
-#define xrealloc(size) _xrealloc_leap(__FILE__, __LINE__, size)
-#define xfree(ptr) _xfree_leap(__FILE__, __LINE__, ptr)
+#define xmalloc(size) \
+  dmalloc_malloc(__FILE__, __LINE__, (size), DMALLOC_FUNC_MALLOC, 0, 1)
+#define xrealloc(ptr, size) \
+  dmalloc_realloc(__FILE__, __LINE__, (ptr), (size), DMALLOC_FUNC_REALLOC, 1)
+#define xfree(ptr) \
+  dmalloc_free(__FILE__, __LINE__, (ptr), DMALLOC_FUNC_FREE)
+
 #else
 /*
  * Unfortunately, several libraries we might want to link to define