summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2019-10-23 22:56:23 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2019-11-05 15:28:47 +0100
commitc00c20a79941b2bbed9e957134259763dcbb29f0 (patch)
tree17fdf80d6f7cc2f6e140f93467975ea96357efa7
parent26194bd684b2926740a74ebdfe73e6afc3c145b6 (diff)
Filter: Better constant promotion
We use constant promotion from IPv4 to Router-ID values, as they have same literals. Instead of ad-hoc code in filter instructions, add constant promotion code to parse-time typecheck code.
-rw-r--r--filter/decl.m421
1 files changed, 20 insertions, 1 deletions
diff --git a/filter/decl.m4 b/filter/decl.m4
index e7d8c1d8..5618dafa 100644
--- a/filter/decl.m4
+++ b/filter/decl.m4
@@ -163,7 +163,7 @@ FID_HIC(,[[
m4_define(ARG, `ARG_ANY($1) ARG_TYPE($1,$2)')
m4_define(ARG_TYPE, `
FID_NEW_BODY()m4_dnl
-if (f$1->type && (f$1->type != ($2)))
+if (f$1->type && (f$1->type != ($2)) && !f_const_promotion(f$1, ($2)))
cf_error("Argument $1 of instruction %s must be of type $2, got 0x%02x", f_instruction_name(what->fi_code), f$1->type);
FID_INTERPRET_EXEC()m4_dnl
if (v$1.type != ($2))
@@ -446,6 +446,25 @@ fi_constant(struct f_inst *what, struct f_val val)
return what;
}
+static int
+f_const_promotion(struct f_inst *arg, enum f_type want)
+{
+ if (arg->fi_code != FI_CONSTANT)
+ return 0;
+
+ struct f_val *c = &arg->i_FI_CONSTANT.val;
+
+ if ((c->type == T_IP) && ipa_is_ip4(c->val.ip) && (want == T_QUAD)) {
+ *c = (struct f_val) {
+ .type = T_QUAD,
+ .val.i = ipa_to_u32(c->val.ip),
+ };
+ return 1;
+ }
+
+ return 0;
+}
+
#define v1 whati->f1->i_FI_CONSTANT.val
#define v2 whati->f2->i_FI_CONSTANT.val
#define v3 whati->f3->i_FI_CONSTANT.val