diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2018-03-19 13:29:39 +0100 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2018-03-19 13:29:39 +0100 |
commit | 89ac4dd3c433cae865d5339efe5e682d4506044d (patch) | |
tree | 60200bcacf7e1bb95d51f8339b361a7b59329828 | |
parent | bcb4af81fc8ea0acf7c2fa5a6854cd3c23d92d9f (diff) | |
parent | 8a871e890a7198f7cbaff5c75033160ae3ad68f3 (diff) |
Merge remote-tracking branch 'birdlab-tmp/int-new' into int-new
-rw-r--r-- | filter/config.Y | 23 | ||||
-rw-r--r-- | filter/filter.c | 39 | ||||
-rw-r--r-- | filter/filter.h | 2 | ||||
-rw-r--r-- | nest/a-path.c | 3 |
4 files changed, 53 insertions, 14 deletions
diff --git a/filter/config.Y b/filter/config.Y index 6b7bedaf..f8170a83 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -315,6 +315,27 @@ f_generate_lc(struct f_inst *t1, struct f_inst *t2, struct f_inst *t3) return rv; } +static inline struct f_inst * +f_generate_path_mask(struct f_path_mask *t) +{ + for (struct f_path_mask *tt = t; tt; tt = tt->next) { + if (tt->kind == PM_ASN_EXPR) { + struct f_inst *mrv = f_new_inst(FI_PATHMASK_CONSTRUCT); + mrv->a1.p = t; + return mrv; + } + } + + NEW_F_VAL; + val->type = T_PATH_MASK; + val->val.path_mask = t; + + struct f_inst *rv = f_new_inst(FI_CONSTANT_INDIRECT); + rv->a1.p = val; + + return rv; +} + /* * Remove all new lines and doubled whitespaces * and convert all tabulators to spaces @@ -775,13 +796,13 @@ constant: | '[' set_items ']' { DBG( "We've got a set here..." ); $$ = f_new_inst(FI_CONSTANT); $$->aux = T_SET; $$->a2.p = build_tree($2); DBG( "ook\n" ); } | '[' fprefix_set ']' { $$ = f_new_inst(FI_CONSTANT); $$->aux = T_PREFIX_SET; $$->a2.p = $2; } | ENUM { $$ = f_new_inst(FI_CONSTANT); $$->aux = $1 >> 16; $$->a2.i = $1 & 0xffff; } - | bgp_path { NEW_F_VAL; $$ = f_new_inst(FI_CONSTANT_INDIRECT); val->type = T_PATH_MASK; val->val.path_mask = $1; $$->a1.p = val; } ; constructor: '(' term ',' term ')' { $$ = f_generate_dpair($2, $4); } | '(' ec_kind ',' term ',' term ')' { $$ = f_generate_ec($2, $4, $6); } | '(' term ',' term ',' term ')' { $$ = f_generate_lc($2, $4, $6); } + | bgp_path { $$ = f_generate_path_mask($1); } ; diff --git a/filter/filter.c b/filter/filter.c index 28603f27..bb3146e7 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -97,8 +97,7 @@ pm_format(struct f_path_mask *p, buffer *buf) break; case PM_ASN_EXPR: - buffer_print(buf, "%u ", f_eval_asn((struct f_inst *) p->val)); - break; + ASSERT(0); } p = p->next; @@ -766,6 +765,32 @@ interpret(struct f_inst *what) break; } + case FI_PATHMASK_CONSTRUCT: + { + struct f_path_mask *tt = what->a1.p, *vbegin, **vv = &vbegin; + + while (tt) { + *vv = lp_alloc(f_pool, sizeof(struct f_path_mask)); + if (tt->kind == PM_ASN_EXPR) { + struct f_val res = interpret((struct f_inst *) tt->val); + (*vv)->kind = PM_ASN; + if (res.type != T_INT) { + runtime( "Error resolving path mask template: value not an integer" ); + return (struct f_val) { .type = T_VOID }; + } + + (*vv)->val = res.val.i; + } else { + **vv = *tt; + } + tt = tt->next; + vv = &((*vv)->next); + } + + res = (struct f_val) { .type = T_PATH_MASK, .val.path_mask = vbegin }; + break; + } + /* Relational operators */ #define COMPARE(x) \ @@ -1616,6 +1641,8 @@ i_same(struct f_inst *f1, struct f_inst *f2) case FI_LT: case FI_LTE: TWOARGS; break; + case FI_PATHMASK_CONSTRUCT: if (!pm_same(f1->a1.p, f2->a1.p)) return 0; break; + case FI_NOT: ONEARG; break; case FI_NOT_MATCH: case FI_MATCH: TWOARGS; break; @@ -1839,14 +1866,6 @@ f_eval_int(struct f_inst *expr) return res.val.i; } -u32 -f_eval_asn(struct f_inst *expr) -{ - /* Called as a part of another interpret call, therefore no log_reset() */ - struct f_val res = interpret(expr); - return (res.type == T_INT) ? res.val.i : 0; -} - /** * filter_same - compare two filters * @new: first filter to be compared diff --git a/filter/filter.h b/filter/filter.h index 47014785..d347924a 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -27,6 +27,7 @@ F(FI_PAIR_CONSTRUCT, 'm', 'p') \ F(FI_EC_CONSTRUCT, 'm', 'c') \ F(FI_LC_CONSTRUCT, 'm', 'l') \ + F(FI_PATHMASK_CONSTRUCT, 'm', 'P') \ F(FI_NEQ, '!', '=') \ F(FI_EQ, '=', '=') \ F(FI_LT, 0, '<') \ @@ -181,7 +182,6 @@ int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, s struct f_val f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool); struct f_val f_eval(struct f_inst *expr, struct linpool *tmp_pool); uint f_eval_int(struct f_inst *expr); -u32 f_eval_asn(struct f_inst *expr); char *filter_name(struct filter *filter); int filter_same(struct filter *new, struct filter *old); diff --git a/nest/a-path.c b/nest/a-path.c index c0d16c30..6bad9747 100644 --- a/nest/a-path.c +++ b/nest/a-path.c @@ -805,8 +805,7 @@ as_path_match(const struct adata *path, struct f_path_mask *mask) val2 = val = mask->val; goto step; case PM_ASN_EXPR: - val2 = val = f_eval_asn((struct f_inst *) mask->val); - goto step; + ASSERT(0); case PM_ASN_RANGE: val = mask->val; val2 = mask->val2; |