diff options
Diffstat (limited to 'filter')
-rw-r--r-- | filter/config.Y | 2 | ||||
-rw-r--r-- | filter/data.c | 72 | ||||
-rw-r--r-- | filter/data.h | 4 | ||||
-rw-r--r-- | filter/f-inst.c | 6 | ||||
-rw-r--r-- | filter/filter.c | 29 | ||||
-rw-r--r-- | filter/filter.h | 6 | ||||
-rw-r--r-- | filter/filter_test.c | 2 |
7 files changed, 93 insertions, 28 deletions
diff --git a/filter/config.Y b/filter/config.Y index 22981945..92656f7c 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -529,7 +529,7 @@ set_atom: | VPN_RD { $$.type = T_RD; $$.val.ec = $1; } | ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); } | '(' term ')' { - if (f_eval(f_linearize($2), cfg_mem, &($$)) > F_RETURN) cf_error("Runtime error"); + if (f_eval(f_linearize($2), &($$)) > F_RETURN) cf_error("Runtime error"); if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type"); } | CF_SYM_KNOWN { diff --git a/filter/data.c b/filter/data.c index 381448fa..425dfdd3 100644 --- a/filter/data.c +++ b/filter/data.c @@ -602,3 +602,75 @@ val_dump(const struct f_val *v) { return val_dump_buffer; } + +struct f_val * +lp_val_copy(struct linpool *lp, const struct f_val *v) +{ + switch (v->type) + { + case T_VOID: + case T_BOOL: + case T_INT: + case T_IP: + case T_PAIR: + case T_QUAD: + case T_EC: + case T_LC: + case T_RD: + case T_ENUM: + case T_PATH_MASK_ITEM: + /* These aren't embedded but there is no need to copy them */ + case T_SET: + case T_PREFIX_SET: + case T_PATH_MASK: + case T_IFACE: + { + struct f_val *out = lp_alloc(lp, sizeof(*out)); + *out = *v; + return out; + } + + case T_NET: + { + struct { + struct f_val val; + net_addr net[0]; + } *out = lp_alloc(lp, sizeof(*out) + v->val.net->length); + out->val = *v; + out->val.val.net = out->net; + net_copy(out->net, v->val.net); + return &out->val; + } + + case T_STRING: + { + uint len = strlen(v->val.s); + struct { + struct f_val val; + char buf[0]; + } *out = lp_alloc(lp, sizeof(*out) + len + 1); + out->val = *v; + out->val.val.s = out->buf; + memcpy(out->buf, v->val.s, len+1); + return &out->val; + } + + case T_PATH: + case T_CLIST: + case T_ECLIST: + case T_LCLIST: + { + struct { + struct f_val val; + struct adata ad; + } *out = lp_alloc(lp, sizeof(*out) + v->val.ad->length); + out->val = *v; + out->val.val.ad = &out->ad; + memcpy(&out->ad, v->val.ad, v->val.ad->length); + return &out->val; + } + + default: + bug("Unknown type in value copy: %d", v->type); + } +} diff --git a/filter/data.h b/filter/data.h index 9ffa1b61..cba47d6a 100644 --- a/filter/data.h +++ b/filter/data.h @@ -213,6 +213,8 @@ 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); +struct f_val *lp_val_copy(struct linpool *lp, const struct f_val *v); + static inline int val_is_ip4(const struct f_val *v) { return (v->type == T_IP) && ipa_is_ip4(v->val.ip); } int val_in_range(const struct f_val *v1, const struct f_val *v2); @@ -249,6 +251,6 @@ static inline const struct f_val *f_get_empty(btype t) } } -enum filter_return f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres); +enum filter_return f_eval(const struct f_line *expr, struct f_val *pres); #endif diff --git a/filter/f-inst.c b/filter/f-inst.c index 7b3db1c7..3a2554fd 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -696,7 +696,7 @@ DYNAMIC_ATTR; ARG_TYPE(1, da.type); { - struct ea_list *l = lp_alloc(fs->pool, sizeof(struct ea_list) + sizeof(eattr)); + struct ea_list *l = tmp_alloc(sizeof(struct ea_list) + sizeof(eattr)); l->next = NULL; l->flags = EALF_SORTED; @@ -718,7 +718,7 @@ break; case T_IP: - l->attrs[0].u.ptr = lp_store_adata(fs->pool, &v1.val.ip, sizeof(ip_addr)); + l->attrs[0].u.ptr = tmp_store_adata(&v1.val.ip, sizeof(ip_addr)); break; default: @@ -739,7 +739,7 @@ ACCESS_EATTRS; f_rta_cow(fs); - ea_unset_attr(fs->eattrs, fs->pool, 1, da.ea_code); + ea_unset_attr(fs->eattrs, tmp_linpool, 1, da.ea_code); } INST(FI_LENGTH, 1, 1) { /* Get length of */ diff --git a/filter/filter.c b/filter/filter.c index 8f946f5b..9bedb938 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -82,9 +82,6 @@ struct filter_state { /* Cached pointer to ea_list */ struct ea_list **eattrs; - /* Linpool for adata allocation */ - struct linpool *pool; - /* Buffer for log output */ struct buffer buf; @@ -134,7 +131,7 @@ f_rta_cow(struct filter_state *fs) * at the end of f_run()), also the lock of hostentry is inherited (we * suppose hostentry is not changed by filters). */ - (*fs->rte)->attrs = rta_do_cow((*fs->rte)->attrs, fs->pool); + (*fs->rte)->attrs = rta_do_cow((*fs->rte)->attrs, tmp_linpool); /* Re-cache the ea_list */ f_cache_eattrs(fs); @@ -202,8 +199,8 @@ 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 falloc(size) tmp_alloc(size) +#define fpool tmp_linpool #define ACCESS_EATTRS do { if (!fs->eattrs) f_cache_eattrs(fs); } while (0) @@ -268,7 +265,7 @@ interpret(struct filter_state *fs, const struct f_line *line, struct f_val *val) * modified in place, old cached rta is possibly freed. */ enum filter_return -f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags) +f_run(const struct filter *filter, struct rte **rte, int flags) { if (filter == FILTER_ACCEPT) return F_ACCEPT; @@ -282,7 +279,6 @@ f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, i /* Initialize the filter state */ filter_state = (struct filter_state) { .rte = rte, - .pool = tmp_pool, .flags = flags, }; @@ -343,11 +339,10 @@ f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, i */ enum filter_return -f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool) +f_eval_rte(const struct f_line *expr, struct rte **rte) { filter_state = (struct filter_state) { .rte = rte, - .pool = tmp_pool, }; f_stack_init(filter_state); @@ -367,11 +362,9 @@ f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool * @pres: here the output will be stored */ enum filter_return -f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres) +f_eval(const struct f_line *expr, struct f_val *pres) { - filter_state = (struct filter_state) { - .pool = tmp_pool, - }; + filter_state = (struct filter_state) {}; f_stack_init(filter_state); @@ -390,9 +383,7 @@ uint f_eval_int(const struct f_line *expr) { /* Called independently in parse-time to eval expressions */ - filter_state = (struct filter_state) { - .pool = cfg_mem, - }; + filter_state = (struct filter_state) {}; f_stack_init(filter_state); @@ -413,10 +404,10 @@ f_eval_int(const struct f_line *expr) * f_eval_buf - get a value of a term and print it to the supplied buffer */ enum filter_return -f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf) +f_eval_buf(const struct f_line *expr, buffer *buf) { struct f_val val; - enum filter_return fret = f_eval(expr, tmp_pool, &val); + enum filter_return fret = f_eval(expr, &val); if (fret <= F_RETURN) val_format(&val, buf); return fret; diff --git a/filter/filter.h b/filter/filter.h index 385f1179..43c04443 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -51,10 +51,10 @@ struct filter { struct rte; -enum filter_return f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags); -enum filter_return f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool); +enum filter_return f_run(const struct filter *filter, struct rte **rte, int flags); +enum filter_return f_eval_rte(const struct f_line *expr, struct rte **rte); uint f_eval_int(const struct f_line *expr); -enum filter_return f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf); +enum filter_return f_eval_buf(const struct f_line *expr, buffer *buf); const char *filter_name(const struct filter *filter); int filter_same(const struct filter *new, const struct filter *old); diff --git a/filter/filter_test.c b/filter/filter_test.c index e8e8b747..63764964 100644 --- a/filter/filter_test.c +++ b/filter/filter_test.c @@ -46,7 +46,7 @@ run_function(const void *arg) if (t->cmp) return t->result == f_same(t->fn, t->cmp); - enum filter_return fret = f_eval(t->fn, tmp_linpool, NULL); + enum filter_return fret = f_eval(t->fn, NULL); return (fret < F_REJECT); } |