summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorJan Maria Matejka <mq@ucw.cz>2018-01-23 15:11:08 +0100
committerMikael Magnusson <mikma@users.sourceforge.net>2019-02-22 23:12:41 +0100
commit0c16ef1b616179ed0a652f162f7e9035104a992d (patch)
tree62b13d3dc05b74aabece6033a587de9be0c3401e /filter
parentff54220ad5240e7a1975f8e8a8adbc754cf84841 (diff)
lua filter saving and reusing
Diffstat (limited to 'filter')
-rw-r--r--filter/config.Y9
-rw-r--r--filter/filter.c33
-rw-r--r--filter/filter.h13
3 files changed, 37 insertions, 18 deletions
diff --git a/filter/config.Y b/filter/config.Y
index 51e7a8cc..3c4d8db6 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -543,6 +543,7 @@ declsn: one_decl { $$ = $1; }
filter_body:
function_body {
struct filter *f = cfg_alloc(sizeof(struct filter));
+ f->type = FILTER_INTERNAL;
f->name = NULL;
f->root = $1;
$$ = f;
@@ -561,6 +562,7 @@ where_filter:
WHERE term {
/* Construct 'IF term THEN ACCEPT; REJECT;' */
struct filter *f = cfg_alloc(sizeof(struct filter));
+ f->type = FILTER_INTERNAL;
struct f_inst *i, *acc, *rej;
acc = f_new_inst(FI_PRINT_AND_DIE); /* ACCEPT */
acc->a1.p = NULL;
@@ -1066,12 +1068,7 @@ cmd:
lua_call:
LUA constant {
- $$ = cfg_alloc(sizeof(struct filter));
- $$->name = NULL;
- $$->root = f_new_inst();
- $$->root->code = P('L','C');
- $$->root->a1.p = $2;
- $$->root->next = NULL;
+ $$ = lua_new_filter($2);
}
get_cf_position:
diff --git a/filter/filter.c b/filter/filter.c
index a13d5cc8..632b4dbf 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -1575,14 +1575,6 @@ interpret(struct f_inst *what)
CALL(bt_assert_hook, res.val.i, what);
break;
- case P('L','C'): /* Lua include */
- ONEARG;
- if (v1.type != T_STRING)
- runtime("Lua code should be a string argument");
-
- res = filter_lua_chunk(v1.val.s, f_rte, f_old_rta, f_tmp_attrs, f_pool);
- break;
-
default:
bug( "Unknown instruction %d (%c)", what->fi_code, what->fi_code & 0xff);
}}
@@ -1781,7 +1773,17 @@ f_run(struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int fla
LOG_BUFFER_INIT(f_buf);
- struct f_val res = interpret(filter->root);
+ struct f_val res;
+ switch (filter->type) {
+ case FILTER_INTERNAL:
+ res = interpret(filter->root);
+ break;
+ case FILTER_LUA:
+ res = lua_interpret(filter->lua_chunk, rte, &f_old_rta, tmp_attrs, tmp_pool, flags);
+ break;
+ default:
+ bug("filter type not set");
+ }
if (f_old_rta) {
/*
@@ -1875,5 +1877,16 @@ filter_same(struct filter *new, struct filter *old)
if (old == FILTER_ACCEPT || old == FILTER_REJECT ||
new == FILTER_ACCEPT || new == FILTER_REJECT)
return 0;
- return i_same(new->root, old->root);
+ if (new->type != old->type)
+ return 0;
+ switch(new->type) {
+ case FILTER_INTERNAL:
+ return i_same(new->root, old->root);
+ break;
+ case FILTER_LUA:
+ return lua_filter_same(new->lua_chunk, old->lua_chunk);
+ break;
+ default:
+ bug("Unknown filter type");
+ }
}
diff --git a/filter/filter.h b/filter/filter.h
index c08f8a48..b49c4c43 100644
--- a/filter/filter.h
+++ b/filter/filter.h
@@ -145,8 +145,15 @@ struct f_static_attr {
};
struct filter {
+ enum filter_type {
+ FILTER_INTERNAL = 1,
+ FILTER_LUA = 2,
+ } type;
char *name;
- struct f_inst *root;
+ union {
+ struct f_inst *root;
+ struct lua_filter_chunk *lua_chunk;
+ };
};
struct f_inst *f_new_inst(enum f_instruction_code fi_code);
@@ -310,6 +317,8 @@ struct f_bt_test_suite {
extern void (*bt_assert_hook)(int result, struct f_inst *assert);
/* Lua */
-struct f_val filter_lua_chunk(const char *chunk, struct rte **e, struct rta *a, struct ea_list **ea, struct linpool *lp);
+struct filter * lua_new_filter(struct f_inst *inst);
+struct f_val lua_interpret(struct lua_filter_chunk *chunk, struct rte **e, struct rta **a, struct ea_list **ea, struct linpool *lp, int flags);
+int lua_filter_same(struct lua_filter_chunk *new, struct lua_filter_chunk *old);
#endif