summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
Diffstat (limited to 'filter')
-rw-r--r--filter/Makefile12
-rw-r--r--filter/config.Y24
-rw-r--r--filter/data.h (renamed from filter/f-util.h)38
-rw-r--r--filter/decl.m4128
-rw-r--r--filter/f-inst.c36
-rw-r--r--filter/f-inst.h131
-rw-r--r--filter/f-util.c19
-rw-r--r--filter/filter.c86
-rw-r--r--filter/filter_test.c2
-rw-r--r--filter/interpret.m47
-rw-r--r--filter/line-size.m441
-rw-r--r--filter/new.m478
-rw-r--r--filter/struct.m473
-rw-r--r--filter/tree.c2
-rw-r--r--filter/tree_test.c2
-rw-r--r--filter/trie.c2
-rw-r--r--filter/trie_test.c2
17 files changed, 279 insertions, 404 deletions
diff --git a/filter/Makefile b/filter/Makefile
index 15f2c3d0..f5f50045 100644
--- a/filter/Makefile
+++ b/filter/Makefile
@@ -1,13 +1,10 @@
-src := filter.c f-util.c tree.c trie.c f-inst-new.c
+src := filter.c f-util.c tree.c trie.c
obj := $(src-o-files)
$(all-daemon)
$(cf-local)
M4FLAGS_FILTERS=$(filter-out -s,$(M4FLAGS))
-$(o)f-inst-line-size.c: $(s)line-size.m4 $(s)f-inst.c $(objdir)/.dir-stamp
- $(M4) $(M4FLAGS_FILTERS) -P $^ >$@
-
$(o)f-inst-postfixify.c: $(s)postfixify.m4 $(s)f-inst.c $(objdir)/.dir-stamp
$(M4) $(M4FLAGS_FILTERS) -P $^ >$@
@@ -17,16 +14,13 @@ $(o)f-inst-interpret.c: $(s)interpret.m4 $(s)f-inst.c $(objdir)/.dir-stamp
$(o)f-inst-same.c: $(s)same.m4 $(s)f-inst.c $(objdir)/.dir-stamp
$(M4) $(M4FLAGS_FILTERS) -P $^ >$@
-$(o)f-inst-struct.h: $(s)struct.m4 $(s)f-inst.c $(objdir)/.dir-stamp
- $(M4) $(M4FLAGS_FILTERS) -P $^ >$@
-
-$(o)f-inst-new.c: $(s)new.m4 $(s)f-inst.c $(objdir)/.dir-stamp
+$(o)f-inst-decl.h: $(s)decl.m4 $(s)f-inst.c $(objdir)/.dir-stamp
$(M4) $(M4FLAGS_FILTERS) -P $^ >$@
$(o)f-inst-dump.c: $(s)dump.m4 $(s)f-inst.c $(objdir)/.dir-stamp
$(M4) $(M4FLAGS_FILTERS) -P $^ >$@
-$(o)filter.o: $(o)f-inst-interpret.c $(o)f-inst-line-size.c $(o)f-inst-postfixify.c $(o)f-inst-same.c $(o)f-inst-dump.c $(o)f-inst-struct.h
+$(o)filter.o: $(o)f-inst-interpret.c $(o)f-inst-postfixify.c $(o)f-inst-same.c $(o)f-inst-dump.c $(o)f-inst-decl.h
tests_src := tree_test.c filter_test.c trie_test.c
tests_targets := $(tests_targets) $(tests-target-files)
diff --git a/filter/config.Y b/filter/config.Y
index 31ceb3f5..42624f44 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -11,7 +11,7 @@
CF_HDR
#include "filter/f-inst.h"
-#include "filter/f-util.h"
+#include "filter/data.h"
CF_DEFINES
@@ -418,7 +418,7 @@ assert_assign(struct f_lval *lval, struct f_inst *expr, const char *start, const
}
checker = f_new_inst(FI_EQ, expr, getter);
- f_inst_next(setter, checker);
+ setter->next = checker;
return assert_done(setter, start, end);
}
@@ -550,7 +550,7 @@ one_decl:
decls: /* EMPTY */ { $$ = NULL; }
| one_decl ';' decls {
$$ = $1;
- f_inst_next($$, $3);
+ $$->next = $3;
}
;
@@ -559,7 +559,7 @@ declsn: one_decl { $$.inst = $1; $$.count = 1; }
| one_decl ';' declsn {
$$ = $3;
$$.count++;
- f_inst_next($$.inst, $1);
+ $$.inst->next = $1;
}
;
@@ -640,7 +640,7 @@ cmds: /* EMPTY */ { $$ = NULL; }
;
cmds_int: cmd { $$[0] = $$[1] = $1; }
- | cmds_int cmd { $$[1] = $2; f_inst_next($1[1], $2); $$[0] = $1[0]; }
+ | cmds_int cmd { $$[1] = $2; $1[1]->next = $2; $$[0] = $1[0]; }
;
block:
@@ -803,11 +803,11 @@ bgp_path:
;
bgp_path_tail:
- NUM bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .asn = $1, .kind = PM_ASN, }, }); f_inst_next($$, $2); }
- | NUM DDOT NUM bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .from = $1, .to = $3, .kind = PM_ASN_RANGE }, }); f_inst_next($$, $4); }
- | '*' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_ASTERISK }, }); f_inst_next($$, $2); }
- | '?' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_QUESTION }, }); f_inst_next($$, $2); }
- | bgp_path_expr bgp_path_tail { $$ = $1; f_inst_next($$, $2); }
+ NUM bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .asn = $1, .kind = PM_ASN, }, }); $$->next = $2; }
+ | NUM DDOT NUM bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .from = $1, .to = $3, .kind = PM_ASN_RANGE }, }); $$->next = $4; }
+ | '*' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_ASTERISK }, }); $$->next = $2; }
+ | '?' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_QUESTION }, }); $$->next = $2; }
+ | bgp_path_expr bgp_path_tail { $$ = $1; $$->next = $2; }
| { $$ = NULL; }
;
@@ -946,7 +946,7 @@ print_list: /* EMPTY */ { $$ = NULL; }
| print_one { $$ = $1; }
| print_one ',' print_list {
if ($1) {
- f_inst_next($1, $3);
+ $1->next = $3;
$$ = $1;
} else $$ = $3;
}
@@ -957,7 +957,7 @@ var_listn: term {
}
| term ',' var_listn {
$$ = $1;
- f_inst_next($$, $3);
+ $$->next = $3;
}
;
diff --git a/filter/f-util.h b/filter/data.h
index a7d77bbd..58db3e44 100644
--- a/filter/f-util.h
+++ b/filter/data.h
@@ -1,5 +1,5 @@
/*
- * BIRD Internet Routing Daemon -- Filter utils
+ * BIRD Internet Routing Daemon -- Dynamic data structures
*
* (c) 1999 Pavel Machek <pavel@ucw.cz>
* (c) 2018--2019 Maria Matejka <mq@jmq.cz>
@@ -7,14 +7,10 @@
* Can be freely distributed and used under the terms of the GNU GPL.
*/
-#ifndef _BIRD_F_UTIL_H_
-#define _BIRD_F_UTIL_H_
+#ifndef _BIRD_FILTER_DATA_H_
+#define _BIRD_FILTER_DATA_H_
-/* IP prefix range structure */
-struct f_prefix {
- net_addr net; /* The matching prefix must match this net */
- u8 lo, hi; /* And its length must fit between lo and hi */
-};
+#include "nest/bird.h"
/* Type numbers must be in 0..0xff range */
#define T_MASK 0xff
@@ -84,8 +80,6 @@ struct f_val {
} val;
};
-#define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val));
-
/* Dynamic attribute definition (eattrs) */
struct f_dynamic_attr {
u8 type; /* EA type (EAF_*) */
@@ -113,6 +107,30 @@ struct f_static_attr {
int readonly:1; /* Don't allow writing */
};
+/* Filter l-value type */
+enum f_lval_type {
+ F_LVAL_VARIABLE,
+ F_LVAL_PREFERENCE,
+ F_LVAL_SA,
+ F_LVAL_EA,
+};
+
+/* Filter l-value */
+struct f_lval {
+ enum f_lval_type type;
+ union {
+ const struct symbol *sym;
+ struct f_dynamic_attr da;
+ struct f_static_attr sa;
+ };
+};
+
+/* IP prefix range structure */
+struct f_prefix {
+ net_addr net; /* The matching prefix must match this net */
+ u8 lo, hi; /* And its length must fit between lo and hi */
+};
+
struct f_tree {
struct f_tree *left, *right;
struct f_val from, to;
diff --git a/filter/decl.m4 b/filter/decl.m4
new file mode 100644
index 00000000..bdbb3e27
--- /dev/null
+++ b/filter/decl.m4
@@ -0,0 +1,128 @@
+m4_divert(-1)m4_dnl
+#
+# BIRD -- Construction of per-instruction structures
+#
+# (c) 2018 Maria Matejka <mq@jmq.cz>
+#
+# Can be freely distributed and used under the terms of the GNU GPL.
+#
+#
+# Global Diversions:
+# 4 enum fi_code
+# 1 struct f_inst_FI_...
+# 2 union in struct f_inst
+# 3 constructors
+#
+# Per-inst Diversions:
+# 11 content of struct f_inst_FI_...
+# 12 constructor arguments
+# 13 constructor body
+
+# Flush the completed instruction
+
+m4_define(FID_END, `m4_divert(-1)')
+
+m4_define(FID_ZONE, `m4_divert($1) /* $2 for INST_NAME() */')
+m4_define(FID_STRUCT, `FID_ZONE(1, Per-instruction structure)')
+m4_define(FID_UNION, `FID_ZONE(2, Union member)')
+m4_define(FID_NEW, `FID_ZONE(3, Constructor)')
+m4_define(FID_ENUM, `FID_ZONE(4, Code enum)')
+
+m4_define(FID_STRUCT_IN, `m4_divert(101)')
+m4_define(FID_NEW_ARGS, `m4_divert(102)')
+m4_define(FID_NEW_BODY, `m4_divert(103)')
+
+m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[
+FID_ENUM
+INST_NAME(),
+FID_STRUCT
+struct f_inst_[[]]INST_NAME() {
+m4_undivert(101)
+};
+FID_UNION
+struct f_inst_[[]]INST_NAME() i_[[]]INST_NAME();
+FID_NEW
+static inline struct f_inst *f_new_inst_]]INST_NAME()[[(enum f_instruction_code fi_code
+m4_undivert(102)
+) {
+ struct f_inst *what_ = cfg_allocz(sizeof(struct f_inst));
+ what_->fi_code = fi_code;
+ what_->lineno = ifs->lino;
+ what_->size = 1;
+ struct f_inst_[[]]INST_NAME() *what UNUSED = &(what_->i_[[]]INST_NAME());
+m4_undivert(103)
+ return what_;
+}
+FID_END
+]])')
+
+m4_define(INST, `INST_FLUSH()m4_define([[INST_NAME]], [[$1]])')
+
+m4_define(FID_MEMBER, `m4_dnl
+FID_STRUCT_IN
+$1 $2;
+FID_NEW_ARGS
+, $1 $2
+FID_NEW_BODY
+what->$2 = $2;
+FID_END')
+
+m4_define(ARG, `FID_MEMBER(const struct f_inst *, f$1)
+FID_NEW_BODY
+for (const struct f_inst *child = f$1; child; child = child->next) what_->size += child->size;
+FID_END')
+m4_define(ARG_ANY, `FID_MEMBER(const struct f_inst *, f$1)
+FID_NEW_BODY
+for (const struct f_inst *child = f$1; child; child = child->next) what_->size += child->size;
+FID_END')
+m4_define(LINE, `FID_MEMBER(const struct f_inst *, f$1)')
+m4_define(LINEP, `FID_STRUCT_IN
+const struct f_line *fl$1;
+FID_END')
+m4_define(SYMBOL, `FID_MEMBER(const struct symbol *, sym)')
+m4_define(VALI, `FID_MEMBER(struct f_val, vali)')
+m4_define(VALP, `FID_MEMBER(const struct f_val *, valp)')
+m4_define(VAR, `m4_dnl
+FID_STRUCT_IN
+const struct f_val *valp;
+const struct symbol *sym;
+FID_NEW_ARGS
+, const struct symbol *sym
+FID_NEW_BODY
+what->valp = (what->sym = sym)->def;
+FID_END')
+m4_define(FRET, `FID_MEMBER(enum filter_return, fret)')
+m4_define(ECS, `FID_MEMBER(enum ec_subtype, ecs)')
+m4_define(RTC, `FID_MEMBER(const struct rtable_config *, rtc)')
+m4_define(STATIC_ATTR, `FID_MEMBER(struct f_static_attr, sa)')
+m4_define(DYNAMIC_ATTR, `FID_MEMBER(struct f_dynamic_attr, da)')
+m4_define(COUNT, `FID_MEMBER(uint, count)')
+m4_define(TREE, `FID_MEMBER(const struct f_tree *, tree)')
+m4_define(STRING, `FID_MEMBER(const char *, s)')
+
+m4_m4wrap(`
+INST_FLUSH()
+m4_divert(0)
+/* Filter instruction codes */
+enum f_instruction_code {
+m4_undivert(4)
+};
+
+/* Per-instruction structures */
+m4_undivert(1)
+
+struct f_inst {
+ const struct f_inst *next; /* Next instruction */
+ enum f_instruction_code fi_code; /* Instruction code */
+ int size; /* How many instructions are underneath */
+ int lineno; /* Line number */
+ union {
+ m4_undivert(2)
+ };
+};
+
+/* Instruction constructors */
+m4_undivert(3)
+')
+
+m4_changequote([[,]])
diff --git a/filter/f-inst.c b/filter/f-inst.c
index 0dd9f9f6..afb895c5 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -109,15 +109,15 @@
ARG_ANY(1);
COUNT(2);
- NEW(, [[
- 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++;
+ 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++;
- WHAT().count = len;
- ]]);
+ what->count = len;
+ FID_END
if (vstk.cnt < what->count) /* TODO: make this check systematic */
runtime("Construction of BGP path mask from %u elements must have at least that number of elements", what->count);
@@ -719,17 +719,17 @@
/* Then push the arguments */
LINE(1,1);
- NEW(, [[
- if (sym->class != SYM_FUNCTION)
- cf_error("You can't call something which is not a function. Really.");
+ FID_NEW_BODY
+ if (sym->class != SYM_FUNCTION)
+ cf_error("You can't call something which is not a function. Really.");
- uint count = 0;
- for (const struct f_inst *inst = f1; inst; inst = inst->next)
- count++;
-
- if (count != sym->aux2)
- cf_error("Function %s takes %u arguments, got %u.", sym->name, sym->aux2, count);
- ]]);
+ uint count = 0;
+ for (const struct f_inst *inst = f1; inst; inst = inst->next)
+ count++;
+
+ if (count != sym->aux2)
+ cf_error("Function %s takes %u arguments, got %u.", sym->name, sym->aux2, count);
+ FID_END
}
INST(FI_DROP_RESULT, 1, 0) {
diff --git a/filter/f-inst.h b/filter/f-inst.h
index 63124aa1..1423e685 100644
--- a/filter/f-inst.h
+++ b/filter/f-inst.h
@@ -10,137 +10,21 @@
#ifndef _BIRD_F_INST_H_
#define _BIRD_F_INST_H_
+#include "nest/bird.h"
+#include "conf/conf.h"
#include "filter/filter.h"
-#include "filter/f-util.h"
+#include "filter/data.h"
-/* Filter l-value type */
-enum f_lval_type {
- F_LVAL_VARIABLE,
- F_LVAL_PREFERENCE,
- F_LVAL_SA,
- F_LVAL_EA,
-};
-
-/* Filter l-value */
-struct f_lval {
- enum f_lval_type type;
- union {
- const struct symbol *sym;
- struct f_dynamic_attr da;
- struct f_static_attr sa;
- };
-};
+/* Include generated filter instruction declarations */
+#include "filter/f-inst-decl.h"
-/* Filter instruction declarations */
-#define FI__LIST \
- F(FI_NOP) \
- F(FI_ADD, ARG, ARG) \
- F(FI_SUBTRACT, ARG, ARG) \
- F(FI_MULTIPLY, ARG, ARG) \
- F(FI_DIVIDE, ARG, ARG) \
- F(FI_AND, ARG, LINE) \
- F(FI_OR, ARG, LINE) \
- F(FI_PAIR_CONSTRUCT, ARG, ARG) \
- F(FI_EC_CONSTRUCT, ARG, ARG, ECS) \
- F(FI_LC_CONSTRUCT, ARG, ARG, ARG) \
- F(FI_PATHMASK_CONSTRUCT, ARG, COUNT) \
- F(FI_NEQ, ARG, ARG) \
- F(FI_EQ, ARG, ARG) \
- F(FI_LT, ARG, ARG) \
- F(FI_LTE, ARG, ARG) \
- F(FI_NOT, ARG) \
- F(FI_MATCH, ARG, ARG) \
- F(FI_NOT_MATCH, ARG, ARG) \
- F(FI_DEFINED, ARG) \
- F(FI_TYPE, ARG) \
- F(FI_IS_V4, ARG) \
- F(FI_SET, ARG, SYMBOL) \
- F(FI_CONSTANT, VALI) \
- F(FI_VARIABLE, SYMBOL) \
- F(FI_CONSTANT_INDIRECT, VALP) \
- F(FI_PRINT, ARG) \
- F(FI_CONDITION, ARG, LINE, LINE) \
- F(FI_PRINT_AND_DIE, ARG, FRET) \
- F(FI_RTA_GET, SA) \
- F(FI_RTA_SET, ARG, SA) \
- F(FI_EA_GET, EA) \
- F(FI_EA_SET, ARG, EA) \
- F(FI_EA_UNSET, EA) \
- F(FI_PREF_GET) \
- F(FI_PREF_SET, ARG) \
- F(FI_LENGTH, ARG) \
- F(FI_ROA_MAXLEN, ARG) \
- F(FI_ROA_ASN, ARG) \
- F(FI_SADR_SRC, ARG) \
- F(FI_IP, ARG) \
- F(FI_ROUTE_DISTINGUISHER, ARG) \
- F(FI_AS_PATH_FIRST, ARG) \
- F(FI_AS_PATH_LAST, ARG) \
- F(FI_AS_PATH_LAST_NAG, ARG) \
- F(FI_RETURN, ARG) \
- F(FI_CALL, SYMBOL, LINE) \
- F(FI_DROP_RESULT, ARG) \
- F(FI_SWITCH, ARG, TREE) \
- F(FI_IP_MASK, ARG, ARG) \
- F(FI_PATH_PREPEND, ARG, ARG) \
- F(FI_CLIST_ADD, ARG, ARG) \
- F(FI_CLIST_DEL, ARG, ARG) \
- F(FI_CLIST_FILTER, ARG, ARG) \
- F(FI_ROA_CHECK_IMPLICIT, RTC) \
- F(FI_ROA_CHECK_EXPLICIT, ARG, ARG, RTC) \
- F(FI_FORMAT, ARG) \
- F(FI_ASSERT, ARG, STRING)
-
-/* The enum itself */
-enum f_instruction_code {
-#define F(c, ...) c,
-FI__LIST
-#undef F
- FI__MAX,
-} PACKED;
+#define f_new_inst(...) MACRO_CONCAT_AFTER(f_new_inst_, MACRO_FIRST(__VA_ARGS__))(__VA_ARGS__)
/* Convert the instruction back to the enum name */
const char *f_instruction_name(enum f_instruction_code fi);
-struct f_inst;
-void f_inst_next(struct f_inst *first, const struct f_inst *append);
struct f_inst *f_clear_local_vars(struct f_inst *decls);
-#define FIA(x) , FIA_##x
-#define FIA_ARG const struct f_inst *
-#define FIA_LINE const struct f_inst *
-#define FIA_COUNT uint
-#define FIA_SYMBOL const struct symbol *
-#define FIA_VALI struct f_val
-#define FIA_VALP const struct f_val *
-#define FIA_FRET enum filter_return
-#define FIA_ECS enum ec_subtype
-#define FIA_SA struct f_static_attr
-#define FIA_EA struct f_dynamic_attr
-#define FIA_RTC const struct rtable_config *
-#define FIA_TREE const struct f_tree *
-#define FIA_STRING const char *
-#define F(c, ...) \
- struct f_inst *f_new_inst_##c(enum f_instruction_code MACRO_IFELSE(MACRO_ISLAST(__VA_ARGS__))()(MACRO_FOREACH(FIA, __VA_ARGS__)));
-FI__LIST
-#undef F
-#undef FIA_ARG
-#undef FIA_LINE
-#undef FIA_LINEP
-#undef FIA_COUNT
-#undef FIA_SYMBOL
-#undef FIA_VALI
-#undef FIA_VALP
-#undef FIA_FRET
-#undef FIA_ECS
-#undef FIA_SA
-#undef FIA_EA
-#undef FIA_RTC
-#undef FIA_STRING
-#undef FIA
-
-#define f_new_inst(...) MACRO_CONCAT_AFTER(f_new_inst_, MACRO_FIRST(__VA_ARGS__))(__VA_ARGS__)
-
/* Flags for instructions */
enum f_instruction_flags {
FIF_PRINTED = 1, /* FI_PRINT_AND_DIE: message put in buffer */
@@ -202,7 +86,4 @@ struct f_bt_test_suite {
const char *dsc; /* Description */
};
-/* Include the auto-generated structures */
-#include "filter/f-inst-struct.h"
-
#endif
diff --git a/filter/f-util.c b/filter/f-util.c
index eb948fa0..82aaa385 100644
--- a/filter/f-util.c
+++ b/filter/f-util.c
@@ -17,22 +17,6 @@
#define P(a,b) ((a<<8) | b)
-static const char * const f_instruction_name_str[] = {
-#define F(c,...) \
- [c] = #c,
-FI__LIST
-#undef F
-};
-
-const char *
-f_instruction_name(enum f_instruction_code fi)
-{
- if (fi < FI__MAX)
- return f_instruction_name_str[fi];
- else
- bug("Got unknown instruction code: %d", fi);
-}
-
char *
filter_name(struct filter *filter)
{
@@ -56,18 +40,21 @@ struct filter *f_new_where(const struct f_inst *where)
struct f_inst acc = {
.fi_code = FI_PRINT_AND_DIE,
.lineno = ifs->lino,
+ .size = 1,
.i_FI_PRINT_AND_DIE = { .fret = F_ACCEPT, },
};
struct f_inst rej = {
.fi_code = FI_PRINT_AND_DIE,
.lineno = ifs->lino,
+ .size = 1,
.i_FI_PRINT_AND_DIE = { .fret = F_REJECT, },
};
struct f_inst i = {
.fi_code = FI_CONDITION,
.lineno = ifs->lino,
+ .size = 3,
.i_FI_CONDITION = {
.f1 = where,
.f2 = &acc,
diff --git a/filter/filter.c b/filter/filter.c
index ff702f2b..0cb56fe4 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -48,7 +48,7 @@
#include "conf/conf.h"
#include "filter/filter.h"
#include "filter/f-inst.h"
-#include "filter/f-util.h"
+#include "filter/data.h"
#define CMP_ERROR 999
@@ -64,6 +64,75 @@ struct filter_state {
void (*bt_assert_hook)(int result, const struct f_line_item *assert);
+static const char * const f_instruction_name_str[] = {
+ /* TODO: Make this better */
+ [FI_ADD] = "FI_ADD",
+ [FI_SUBTRACT] = "FI_SUBTRACT",
+ [FI_MULTIPLY] = "FI_MULTIPLY",
+ [FI_DIVIDE] = "FI_DIVIDE",
+ [FI_AND] = "FI_AND",
+ [FI_OR] = "FI_OR",
+ [FI_PAIR_CONSTRUCT] = "FI_PAIR_CONSTRUCT",
+ [FI_EC_CONSTRUCT] = "FI_EC_CONSTRUCT",
+ [FI_LC_CONSTRUCT] = "FI_LC_CONSTRUCT",
+ [FI_PATHMASK_CONSTRUCT] = "FI_PATHMASK_CONSTRUCT",
+ [FI_NEQ] = "FI_NEQ",
+ [FI_EQ] = "FI_EQ",
+ [FI_LT] = "FI_LT",
+ [FI_LTE] = "FI_LTE",
+ [FI_NOT] = "FI_NOT",
+ [FI_MATCH] = "FI_MATCH",
+ [FI_NOT_MATCH] = "FI_NOT_MATCH",
+ [FI_DEFINED] = "FI_DEFINED",
+ [FI_TYPE] = "FI_TYPE",
+ [FI_IS_V4] = "FI_IS_V4",
+ [FI_SET] = "FI_SET",
+ [FI_CONSTANT] = "FI_CONSTANT",
+ [FI_VARIABLE] = "FI_VARIABLE",
+ [FI_CONSTANT_INDIRECT] = "FI_CONSTANT_INDIRECT",
+ [FI_PRINT] = "FI_PRINT",
+ [FI_CONDITION] = "FI_CONDITION",
+ [FI_PRINT_AND_DIE] = "FI_PRINT_AND_DIE",
+ [FI_RTA_GET] = "FI_RTA_GET",
+ [FI_RTA_SET] = "FI_RTA_SET",
+ [FI_EA_GET] = "FI_EA_GET",
+ [FI_EA_SET] = "FI_EA_SET",
+ [FI_EA_UNSET] = "FI_EA_UNSET",
+ [FI_PREF_GET] = "FI_PREF_GET",
+ [FI_PREF_SET] = "FI_PREF_SET",
+ [FI_LENGTH] = "FI_LENGTH",
+ [FI_SADR_SRC] = "FI_SADR_SRC",
+ [FI_ROA_MAXLEN] = "FI_ROA_MAXLEN",
+ [FI_ROA_ASN] = "FI_ROA_ASN",
+ [FI_IP] = "FI_IP",
+ [FI_ROUTE_DISTINGUISHER] = "FI_ROUTE_DISTINGUISHER",
+ [FI_AS_PATH_FIRST] = "FI_AS_PATH_FIRST",
+ [FI_AS_PATH_LAST] = "FI_AS_PATH_LAST",
+ [FI_AS_PATH_LAST_NAG] = "FI_AS_PATH_LAST_NAG",
+ [FI_RETURN] = "FI_RETURN",
+ [FI_CALL] = "FI_CALL",
+ [FI_DROP_RESULT] = "FI_DROP_RESULT",
+ [FI_SWITCH] = "FI_SWITCH",
+ [FI_IP_MASK] = "FI_IP_MASK",
+ [FI_PATH_PREPEND] = "FI_PATH_PREPEND",
+ [FI_CLIST_ADD] = "FI_CLIST_ADD",
+ [FI_CLIST_DEL] = "FI_CLIST_DEL",
+ [FI_CLIST_FILTER] = "FI_CLIST_FILTER",
+ [FI_ROA_CHECK_IMPLICIT] = "FI_ROA_CHECK_IMPLICIT",
+ [FI_ROA_CHECK_EXPLICIT] = "FI_ROA_CHECK_EXPLICIT",
+ [FI_FORMAT] = "FI_FORMAT",
+ [FI_ASSERT] = "FI_ASSERT",
+};
+
+const char *
+f_instruction_name(enum f_instruction_code fi)
+{
+ if (fi < (sizeof(f_instruction_name_str) / sizeof(f_instruction_name_str[0])))
+ return f_instruction_name_str[fi];
+ else
+ bug("Got unknown instruction code: %d", fi);
+}
+
/* Special undef value for paths and clists */
static inline int
undef_value(struct f_val v)
@@ -615,18 +684,6 @@ val_format_str(struct filter_state *fs, struct f_val *v) {
static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS;
-static uint
-inst_line_size(const struct f_inst *what_)
-{
- uint cnt = 0;
- for ( ; what_; what_ = what_->next) {
- switch (what_->fi_code) {
-#include "filter/f-inst-line-size.c"
- }
- }
- return cnt;
-}
-
#define INDENT (((const char *) f_dump_line_indent_str) + sizeof(f_dump_line_indent_str) - (indent) - 1)
static const char f_dump_line_indent_str[] = " ";
@@ -685,7 +742,8 @@ f_postfixify_concat(const struct f_inst * const inst[], uint count)
{
uint len = 0;
for (uint i=0; i<count; i++)
- len += inst_line_size(inst[i]);
+ for (const struct f_inst *what = inst[i]; what; what = what->next)
+ len += what->size;
struct f_line *out = cfg_allocz(sizeof(struct f_line) + sizeof(struct f_line_item)*len);
diff --git a/filter/filter_test.c b/filter/filter_test.c
index a02f0832..edd73ac8 100644
--- a/filter/filter_test.c
+++ b/filter/filter_test.c
@@ -17,7 +17,7 @@
#include "test/bt-utils.h"
#include "filter/filter.h"
-#include "filter/f-util.h"
+#include "filter/data.h"
#include "filter/f-inst.h"
#include "conf/conf.h"
diff --git a/filter/interpret.m4 b/filter/interpret.m4
index dfd5c6a7..e32b3a76 100644
--- a/filter/interpret.m4
+++ b/filter/interpret.m4
@@ -63,10 +63,11 @@ m4_define(TREE, `')
m4_define(STRING, `')
m4_define(COUNT, `')
m4_define(POSTFIXIFY, `')
-m4_define(LINE_SIZE, `')
m4_define(SAME, `')
-m4_define(STRUCT, `')
-m4_define(NEW, `')
+m4_define(FID_STRUCT_IN, `m4_divert(-1)')
+m4_define(FID_NEW_ARGS, `m4_divert(-1)')
+m4_define(FID_NEW_BODY, `m4_divert(-1)')
+m4_define(FID_END, `m4_divert(2)')
m4_m4wrap(`
INST_FLUSH()
diff --git a/filter/line-size.m4 b/filter/line-size.m4
deleted file mode 100644
index 051d3b90..00000000
--- a/filter/line-size.m4
+++ /dev/null
@@ -1,41 +0,0 @@
-m4_divert(-1)m4_dnl
-#
-# BIRD -- Line size counting
-#
-# (c) 2018 Maria Matejka <mq@jmq.cz>
-#
-# Can be freely distributed and used under the terms of the GNU GPL.
-#
-
-# Common aliases
-m4_define(DNL, `m4_dnl')
-
-m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[
-m4_divert(1)
-case INST_NAME():
-cnt += 1;
-#define what ((const struct f_inst_]]INST_NAME()[[ *) &(what_->i_]]INST_NAME()[[))
-m4_undivert(2)
-#undef what
-break;
-m4_divert(-1)
-]])')
-m4_define(INST, `INST_FLUSH()m4_define([[INST_NAME]], [[$1]])')
-
-m4_define(ARG, `m4_divert(2)cnt += inst_line_size(what->f$1);
-m4_divert(-1)')
-m4_define(ARG_T, `m4_divert(2)cnt += inst_line_size(what->f$1);
-m4_divert(-1)')
-m4_define(ARG_ANY, `m4_divert(2)cnt += inst_line_size(what->f$1);
-m4_divert(-1)')
-m4_define(LINE_SIZE, `m4_divert(2)$1m4_divert(-1)')
-
-m4_m4wrap(`
-INST_FLUSH()
-m4_divert(0)DNL
-m4_undivert(1)
-
-default: bug( "Unknown instruction %d (%c)", what_->fi_code, what_->fi_code & 0xff);
-')
-
-m4_changequote([[,]])
diff --git a/filter/new.m4 b/filter/new.m4
deleted file mode 100644
index 38295e5c..00000000
--- a/filter/new.m4
+++ /dev/null
@@ -1,78 +0,0 @@
-m4_divert(-1)m4_dnl
-#
-# BIRD -- Construction of per-instruction structures
-#
-# (c) 2018 Maria Matejka <mq@jmq.cz>
-#
-# Can be freely distributed and used under the terms of the GNU GPL.
-#
-#
-# Diversions:
-# 1 for prepared output
-# 2 for function arguments
-# 3 for function body
-
-# Common aliases
-m4_define(DNL, `m4_dnl')
-
-m4_define(FNSTOP, `m4_divert(-1)')
-m4_define(FNOUT, `m4_divert(1)')
-m4_define(FNARG, `m4_divert(2)')
-m4_define(FNBODY, `m4_divert(3)')
-
-m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[
-FNOUT()DNL
-struct f_inst *f_new_inst_]]INST_NAME()[[(enum f_instruction_code fi_code
-m4_undivert(2)
-) {
- struct f_inst *what = cfg_allocz(sizeof(struct f_inst));
- what->fi_code = fi_code;
- what->lineno = ifs->lino;
-m4_undivert(3)
- return what;
-}
-FNSTOP()
-]]DNL
-)')
-
-m4_define(INST, `INST_FLUSH()m4_define([[INST_NAME]], [[$1]])')
-
-m4_define(WHAT, `what->i_[[]]INST_NAME()')
-
-m4_define(FNMETAARG, `FNARG(), $1 $2
-FNBODY() WHAT().$2 = $2;
-FNSTOP()')
-m4_define(ARG, `FNMETAARG(const struct f_inst *, f$1)')
-m4_define(ARG_ANY, `FNMETAARG(const struct f_inst *, f$1)')
-m4_define(LINE, `FNMETAARG(const struct f_inst *, f$1)')
-m4_define(SYMBOL, `FNMETAARG(const struct symbol *, sym)')
-m4_define(VALI, `FNMETAARG(struct f_val, vali)')
-m4_define(VALP, `FNMETAARG(const struct f_val *, valp)')
-m4_define(VAR, `FNARG(), const struct symbol * sym
-FNBODY() WHAT().valp = (WHAT().sym = sym)->def;
-FNSTOP()')
-m4_define(FRET, `FNMETAARG(enum filter_return, fret)')
-m4_define(ECS, `FNMETAARG(enum ec_subtype, ecs)')
-m4_define(RTC, `FNMETAARG(const struct rtable_config *, rtc)')
-m4_define(STATIC_ATTR, `FNMETAARG(struct f_static_attr, sa)')
-m4_define(DYNAMIC_ATTR, `FNMETAARG(struct f_dynamic_attr, da)')
-m4_define(COUNT, `FNMETAARG(uint, count)')
-m4_define(TREE, `FNMETAARG(const struct f_tree *, tree)')
-m4_define(STRING, `FNMETAARG(const char *, s)')
-m4_define(NEW, `FNARG()$1
-FNBODY()$2
-FNSTOP()')
-
-m4_m4wrap(`
-INST_FLUSH()
-m4_divert(0)
-#include "nest/bird.h"
-#include "conf/conf.h"
-#include "filter/filter.h"
-#include "filter/f-inst.h"
-
-m4_undivert(1)
-
-')
-
-m4_changequote([[,]])
diff --git a/filter/struct.m4 b/filter/struct.m4
deleted file mode 100644
index 7af28cfd..00000000
--- a/filter/struct.m4
+++ /dev/null
@@ -1,73 +0,0 @@
-m4_divert(-1)m4_dnl
-#
-# BIRD -- Definition of per-instruction structures
-#
-# (c) 2018 Maria Matejka <mq@jmq.cz>
-#
-# Can be freely distributed and used under the terms of the GNU GPL.
-#
-
-# Common aliases
-m4_define(DNL, `m4_dnl')
-
-m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[
-m4_divert(1)
-struct f_inst_[[]]INST_NAME() {
-m4_undivert(2)
-};
-m4_divert(3)
-struct f_inst_[[]]INST_NAME() i_[[]]INST_NAME();
-m4_divert(-1)
-]])')
-m4_define(INST, `INST_FLUSH()m4_define([[INST_NAME]], [[$1]])')
-
-m4_define(ARG, `m4_divert(2)const struct f_inst *f$1;
-m4_divert(-1)')
-m4_define(ARG_ANY, `m4_divert(2)const struct f_inst *f$1;
-m4_divert(-1)')
-m4_define(LINE, `m4_divert(2)const struct f_inst *f$1;
-m4_divert(-1)')
-m4_define(LINEP, `m4_divert(2)const struct f_line *fl$1;
-m4_divert(-1)')
-m4_define(SYMBOL, `m4_divert(2)const struct symbol *sym;
-m4_divert(-1)')
-m4_define(VALI, `m4_divert(2)struct f_val vali;
-m4_divert(-1)')
-m4_define(VALP, `m4_divert(2)const struct f_val *valp;
-m4_divert(-1)')
-m4_define(VAR, `VALP()SYMBOL()')
-m4_define(FRET, `m4_divert(2)enum filter_return fret;
-m4_divert(-1)')
-m4_define(ECS, `m4_divert(2)enum ec_subtype ecs;
-m4_divert(-1)')
-m4_define(RTC, `m4_divert(2)const struct rtable_config *rtc;
-m4_divert(-1)')
-m4_define(STATIC_ATTR, `m4_divert(2)struct f_static_attr sa;
-m4_divert(-1)')
-m4_define(DYNAMIC_ATTR, `m4_divert(2)struct f_dynamic_attr da;
-m4_divert(-1)')
-m4_define(COUNT, `m4_divert(2)uint count;
-m4_divert(-1)')
-m4_define(TREE, `m4_divert(2)const struct f_tree *tree;
-m4_divert(-1)')
-m4_define(STRING, `m4_divert(2)const char *s;
-m4_divert(-1)')
-m4_define(STRUCT, `m4_divert(2)$1
-m4_divert(-1)')
-
-m4_m4wrap(`
-INST_FLUSH()
-m4_divert(0)DNL
-m4_undivert(1)
-
-struct f_inst {
- const struct f_inst *next; /* Next instruction */
- enum f_instruction_code fi_code; /* Instruction code */
- int lineno; /* Line number */
- union {
- m4_undivert(3)
- };
-};
-')
-
-m4_changequote([[,]])
diff --git a/filter/tree.c b/filter/tree.c
index 879b0859..46d6e529 100644
--- a/filter/tree.c
+++ b/filter/tree.c
@@ -10,7 +10,7 @@
#include "nest/bird.h"
#include "conf/conf.h"
#include "filter/filter.h"
-#include "filter/f-util.h"
+#include "filter/data.h"
/**
* find_tree
diff --git a/filter/tree_test.c b/filter/tree_test.c
index 9e0de50f..6472d17e 100644
--- a/filter/tree_test.c
+++ b/filter/tree_test.c
@@ -10,7 +10,7 @@
#include "test/bt-utils.h"
#include "filter/filter.h"
-#include "filter/f-util.h"
+#include "filter/data.h"
#include "conf/conf.h"
#define MAX_TREE_HEIGHT 13
diff --git a/filter/trie.c b/filter/trie.c
index dccf9130..3038f5ec 100644
--- a/filter/trie.c
+++ b/filter/trie.c
@@ -73,7 +73,7 @@
#include "lib/string.h"
#include "conf/conf.h"
#include "filter/filter.h"
-#include "filter/f-util.h"
+#include "filter/data.h"
/*
diff --git a/filter/trie_test.c b/filter/trie_test.c
index b6959c4a..38c387b0 100644
--- a/filter/trie_test.c
+++ b/filter/trie_test.c
@@ -10,7 +10,7 @@
#include "test/bt-utils.h"
#include "filter/filter.h"
-#include "filter/f-util.h"
+#include "filter/data.h"
#include "conf/conf.h"
#define TESTS_NUM 10