.flags = flags,
};
- LOG_BUFFER_INIT(filter_state.buf);
+ f_stack_init(filter_state);
/* Run the interpreter itself */
- enum filter_return fret = interpret(&filter_state, filter->root, argc, argv, NULL);
+ enum filter_return fret = interpret(&filter_state, filter->root, argc, argv, 0, NULL);
- if (filter_state.old_rta) {
- /*
- * Cached rta was modified and filter_state->rte contains now an uncached one,
- * sharing some part with the cached one. The cached rta should
- * be freed (if rte was originally COW, filter_state->old_rta is a clone
- * obtained during rte_cow()).
- *
- * This also implements the exception mentioned in f_run()
- * description. The reason for this is that rta reuses parts of
- * filter_state->old_rta, and these may be freed during rta_free(filter_state->old_rta).
- * This is not the problem if rte was COW, because original rte
- * also holds the same rta.
- */
- if (!rte_cow) {
- /* Cache the new attrs */
- (*filter_state.rte)->attrs = rta_lookup((*filter_state.rte)->attrs);
-
- /* Drop cached ea_list pointer */
- filter_state.eattrs = NULL;
- }
-
- /* Uncache the old attrs and drop the pointer as it is invalid now. */
- rta_free(filter_state.old_rta);
- filter_state.old_rta = NULL;
- }
-
/* Process the filter output, log it and return */
if (fret < F_ACCEPT) {
if (!(filter_state.flags & FF_SILENT))
*/
enum filter_return
- f_eval_rte(const struct f_line *expr, struct rte *rte, uint argc, const struct f_val *argv, struct f_val *pres)
-f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, uint resc, struct f_val *resv)
++f_eval_rte(const struct f_line *expr, struct rte *rte, uint argc, const struct f_val *argv, uint resc, struct f_val *resv)
{
filter_state = (struct filter_state) {
- .stack = &filter_stack,
.rte = rte,
- .pool = tmp_pool,
};
- LOG_BUFFER_INIT(filter_state.buf);
+ f_stack_init(filter_state);
- return interpret(&filter_state, expr, argc, argv, pres);
+ return interpret(&filter_state, expr, argc, argv, resc, resv);
}
/*
* f_eval - get a value of a term
* @expr: filter line containing the term
* @tmp_pool: long data may get allocated from this pool
- * @pres: here the output will be stored
+ * @pres: here the output will be stored if requested
*/
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) {
- .stack = &filter_stack,
- .pool = tmp_pool,
- };
+ filter_state = (struct filter_state) {};
- LOG_BUFFER_INIT(filter_state.buf);
+ f_stack_init(filter_state);
- enum filter_return fret = interpret(&filter_state, expr, 0, NULL, pres);
+ enum filter_return fret = interpret(&filter_state, expr, 0, NULL, !!pres, pres);
return fret;
}
struct rte;
-enum filter_return f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags);
-enum filter_return f_run_args(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, int flags);
-enum filter_return f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool, uint argc, const struct f_val *argv, uint resc, struct f_val *resv);
-enum filter_return f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf);
+enum filter_return f_run(const struct filter *filter, struct rte *rte, int flags);
+enum filter_return f_run_args(const struct filter *filter, struct rte *rte, uint argc, const struct f_val *argv, int flags);
- enum filter_return f_eval_rte(const struct f_line *expr, struct rte *rte, uint argc, const struct f_val *argv, struct f_val *pres);
++enum filter_return f_eval_rte(const struct f_line *expr, struct rte *rte, uint argc, const struct f_val *argv, uint resc, struct f_val *resv);
+enum filter_return f_eval_buf(const struct f_line *expr, buffer *buf);
-struct f_val cf_eval(const struct f_inst *inst, int type);
-static inline uint cf_eval_int(const struct f_inst *inst) { return cf_eval(inst, T_INT).val.i; };
+struct f_val cf_eval_tmp(const struct f_inst *inst, int type);
+static inline struct f_val *cf_eval(const struct f_inst *inst, int type)
+{
+ struct f_val val = cf_eval_tmp(inst, type);
+ return lp_val_copy(cfg_mem, &val);
+}
+
+static inline uint cf_eval_int(const struct f_inst *inst) { return cf_eval_tmp(inst, T_INT).val.i; };
const char *filter_name(const struct filter *filter);
int filter_same(const struct filter *new, const struct filter *old);
return;
/* We skip rta_lookup() here */
- rte *e = rte_get_temp(a, src);
+ src = static_get_source(p, r->index);
+ rte e0 = { .attrs = ea, .src = src, .net = r->net, }, *e = &e0;
+ /* Evaluate the filter */
if (r->cmds)
- f_eval_rte(r->cmds, e, 0, NULL, NULL);
- {
- /* Create a temporary table node */
- e->net = alloca(sizeof(net) + r->net->length);
- memset(e->net, 0, sizeof(net) + r->net->length);
- net_copy(e->net->n.addr, r->net);
++ f_eval_rte(r->cmds, e, 0, NULL, 0, NULL);
- /* Evaluate the filter */
- f_eval_rte(r->cmds, &e, static_lp, 0, NULL, 0, NULL);
-
- /* Remove the temporary node */
- e->net = NULL;
- }
+ rte_update(p->p.main_channel, r->net, e, src);
+ static_free_source(src, r->index);
- rte_update2(p->p.main_channel, r->net, e, src);
r->state = SRS_CLEAN;
-
- if (r->cmds)
- lp_flush(static_lp);
-
return;
withdraw: