diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2013-07-25 13:15:32 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2013-07-25 13:15:32 +0200 |
commit | 508d936078aecc8fbbb9ca1218104599c4a3cb4a (patch) | |
tree | d84c6b098342fc2f366d960bd90d6a158610ea48 /filter | |
parent | a0b176e3b2b50d3a30574afa927e0ee8ef65be68 (diff) |
Implements eval command and minor CLI cleanups.
Implemented eval command can be used to evaluate expressions.
The patch also documents echo command and allows to use log classes
instead of integer as a mask for echo.
Diffstat (limited to 'filter')
-rw-r--r-- | filter/filter.c | 32 | ||||
-rw-r--r-- | filter/filter.h | 3 |
2 files changed, 25 insertions, 10 deletions
diff --git a/filter/filter.c b/filter/filter.c index 432fa122..d784c253 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -440,8 +440,6 @@ val_in_range(struct f_val v1, struct f_val v2) return CMP_ERROR; } -static void val_print(struct f_val v); - static void tree_node_print(struct f_tree *t, char **sep) { @@ -474,7 +472,7 @@ tree_print(struct f_tree *t) /* * val_print - format filter value */ -static void +void val_print(struct f_val v) { char buf2[1024]; @@ -558,6 +556,8 @@ static struct rate_limit rl_runtime_err; #define TWOARGS_C TWOARGS \ if (v1.type != v2.type) \ runtime( "Can't operate with values of incompatible types" ); +#define ACCESS_RTE \ + do { if (!f_rte) runtime("No route to access"); } while (0) /** * interpret @@ -821,6 +821,7 @@ interpret(struct f_inst *what) break; case 'a': /* rta access */ { + ACCESS_RTE; struct rta *rta = (*f_rte)->attrs; res.type = what->aux; switch(res.type) { @@ -845,6 +846,7 @@ interpret(struct f_inst *what) } break; case P('a','S'): + ACCESS_RTE; ONEARG; if (what->aux != v1.type) runtime( "Attempt to set static attribute to incompatible type" ); @@ -877,6 +879,7 @@ interpret(struct f_inst *what) } break; case P('e','a'): /* Access to extended attributes */ + ACCESS_RTE; { eattr *e = NULL; if (!(f_flags & FF_FORCE_TMPATTR)) @@ -944,6 +947,7 @@ interpret(struct f_inst *what) } break; case P('e','S'): + ACCESS_RTE; ONEARG; { struct ea_list *l = lp_alloc(f_pool, sizeof(struct ea_list) + sizeof(eattr)); @@ -1021,10 +1025,12 @@ interpret(struct f_inst *what) } break; case 'P': + ACCESS_RTE; res.type = T_INT; res.val.i = (*f_rte)->pref; break; case P('P','S'): + ACCESS_RTE; ONEARG; if (v1.type != T_INT) runtime( "Can't set preference to non-integer" ); @@ -1246,6 +1252,7 @@ interpret(struct f_inst *what) } else { + ACCESS_RTE; v1.val.px.ip = (*f_rte)->net->n.prefix; v1.val.px.len = (*f_rte)->net->n.pxlen; @@ -1478,22 +1485,27 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc return res.val.i; } -int -f_eval_int(struct f_inst *expr) +struct f_val +f_eval(struct f_inst *expr, struct linpool *tmp_pool) { - /* Called independently in parse-time to eval expressions */ - struct f_val res; - f_flags = 0; f_tmp_attrs = NULL; f_rte = NULL; - f_pool = cfg_mem; + f_pool = tmp_pool; log_reset(); - res = interpret(expr); + return interpret(expr); +} + +int +f_eval_int(struct f_inst *expr) +{ + /* Called independently in parse-time to eval expressions */ + struct f_val res = f_eval(expr, cfg_mem); if (res.type != T_INT) cf_error("Integer expression expected"); + return res.val.i; } diff --git a/filter/filter.h b/filter/filter.h index 2386fc95..1d5150e7 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -106,6 +106,7 @@ struct ea_list; struct rte; int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags); +struct f_val f_eval(struct f_inst *expr, struct linpool *tmp_pool); int f_eval_int(struct f_inst *expr); u32 f_eval_asn(struct f_inst *expr); @@ -117,6 +118,8 @@ int i_same(struct f_inst *f1, struct f_inst *f2); int val_compare(struct f_val v1, struct f_val v2); int tree_compare(const void *p1, const void *p2); +void val_print(struct f_val v); + #define F_NOP 0 #define F_NONL 1 #define F_ACCEPT 2 /* Need to preserve ordering: accepts < rejects! */ |