diff options
-rw-r--r-- | src/evaluate.c | 53 | ||||
-rw-r--r-- | src/rule.c | 112 |
2 files changed, 79 insertions, 86 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index 8b54dbc0..d5817f9b 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -109,37 +109,6 @@ static struct expr *implicit_set_declaration(struct eval_ctx *ctx, return set_ref_expr_alloc(&expr->location, set); } -// FIXME -#include <netlink.h> -static struct set *get_set(struct eval_ctx *ctx, const struct handle *h, - const char *identifier) -{ - struct netlink_ctx nctx = { - .msgs = ctx->msgs, - }; - struct handle handle; - struct set *set; - int err; - - if (ctx->table != NULL) { - set = set_lookup(ctx->table, identifier); - if (set != NULL) - return set; - } - - init_list_head(&nctx.list); - - memset(&handle, 0, sizeof(handle)); - handle_merge(&handle, h); - handle.set = xstrdup(identifier); - err = netlink_get_set(&nctx, &handle, &internal_location); - handle_free(&handle); - - if (err < 0) - return NULL; - return list_first_entry(&nctx.list, struct set, list); -} - static enum ops byteorder_conversion_op(struct expr *expr, enum byteorder byteorder) { @@ -192,6 +161,7 @@ static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr) { struct error_record *erec; struct symbol *sym; + struct table *table; struct set *set; struct expr *new; @@ -213,9 +183,15 @@ static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr) new = expr_clone(sym->expr); break; case SYMBOL_SET: - set = get_set(ctx, &ctx->cmd->handle, (*expr)->identifier); + table = table_lookup(&ctx->cmd->handle); + if (table == NULL) + return cmd_error(ctx, "Could not process rule: Table '%s' does not exist", + ctx->cmd->handle.table); + + set = set_lookup(table, (*expr)->identifier); if (set == NULL) - return -1; + return cmd_error(ctx, "Could not process rule: Set '%s' does not exist", + (*expr)->identifier); new = set_ref_expr_alloc(&(*expr)->location, set); break; } @@ -1737,11 +1713,18 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt) static int setelem_evaluate(struct eval_ctx *ctx, struct expr **expr) { + struct table *table; struct set *set; - set = get_set(ctx, &ctx->cmd->handle, ctx->cmd->handle.set); + table = table_lookup(&ctx->cmd->handle); + if (table == NULL) + return cmd_error(ctx, "Could not process rule: Table '%s' does not exist", + ctx->cmd->handle.table); + + set = set_lookup(table, ctx->cmd->handle.set); if (set == NULL) - return -1; + return cmd_error(ctx, "Could not process rule: Set '%s' does not exist", + ctx->cmd->handle.set); ctx->set = set; expr_set_context(&ctx->ectx, set->keytype, set->keylen); @@ -67,6 +67,22 @@ static int cache_init_tables(struct netlink_ctx *ctx, struct handle *h) return 0; } +static int cache_init_objects(struct netlink_ctx *ctx) +{ + struct table *table; + int ret; + + list_for_each_entry(table, &table_list, list) { + ret = netlink_list_sets(ctx, &table->handle, + &internal_location); + list_splice_tail_init(&ctx->list, &table->sets); + + if (ret < 0) + return -1; + } + return 0; +} + static int cache_init(enum cmd_ops cmd, struct list_head *msgs) { struct handle handle = { @@ -82,6 +98,9 @@ static int cache_init(enum cmd_ops cmd, struct list_head *msgs) ret = cache_init_tables(&ctx, &handle); if (ret < 0) return ret; + ret = cache_init_objects(&ctx); + if (ret < 0) + return ret; return 0; } @@ -596,11 +615,14 @@ struct table *table_alloc(void) void table_free(struct table *table) { struct chain *chain, *next; + struct set *set, *nset; if (--table->refcnt > 0) return; list_for_each_entry_safe(chain, next, &table->chains, list) chain_free(chain); + list_for_each_entry_safe(set, nset, &table->sets, list) + set_free(set); handle_free(&table->handle); scope_release(&table->scope); xfree(table); @@ -889,15 +911,11 @@ static int do_command_delete(struct netlink_ctx *ctx, struct cmd *cmd) static int do_list_sets(struct netlink_ctx *ctx, const struct location *loc, struct table *table) { - struct set *set, *nset; - - if (netlink_list_sets(ctx, &table->handle, loc) < 0) - return -1; + struct set *set; - list_for_each_entry_safe(set, nset, &ctx->list, list) { + list_for_each_entry(set, &table->sets, list) { if (netlink_get_setelems(ctx, &set->handle, loc, set) < 0) return -1; - list_move_tail(&set->list, &table->sets); } return 0; } @@ -966,6 +984,23 @@ err: return -1; } +static int do_list_sets_global(struct netlink_ctx *ctx, struct cmd *cmd) +{ + struct table *table; + struct set *set; + + list_for_each_entry(table, &table_list, list) { + list_for_each_entry(set, &table->sets, list) { + if (netlink_get_setelems(ctx, &set->handle, + &cmd->location, set) < 0) + return -1; + + set_print(set); + } + } + return 0; +} + static int do_list_ruleset(struct netlink_ctx *ctx, struct cmd *cmd) { unsigned int family = cmd->handle.family; @@ -998,10 +1033,25 @@ static int do_list_tables(struct netlink_ctx *ctx, struct cmd *cmd) return 0; } +static int do_list_set(struct netlink_ctx *ctx, struct cmd *cmd, + struct table *table) +{ + struct set *set; + + set = set_lookup(table, cmd->handle.set); + if (set == NULL) + return -1; + + if (netlink_get_setelems(ctx, &cmd->handle, &cmd->location, set) < 0) + return -1; + + set_print(set); + return 0; +} + static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd) { struct table *table = NULL; - struct set *set; if (cmd->handle.table != NULL) table = table_lookup(&cmd->handle); @@ -1014,28 +1064,9 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd) case CMD_OBJ_CHAIN: return do_list_table(ctx, cmd, table); case CMD_OBJ_SETS: - if (netlink_list_sets(ctx, &cmd->handle, &cmd->location) < 0) - return -1; - - list_for_each_entry(set, &ctx->list, list){ - if (netlink_get_setelems(ctx, &set->handle, - &cmd->location, set) < 0) { - return -1; - } - set_print(set); - } - return 0; + return do_list_sets_global(ctx, cmd); case CMD_OBJ_SET: - if (netlink_get_set(ctx, &cmd->handle, &cmd->location) < 0) - goto err; - list_for_each_entry(set, &ctx->list, list) { - if (netlink_get_setelems(ctx, &cmd->handle, - &cmd->location, set) < 0) { - goto err; - } - set_print(set); - } - return 0; + return do_list_set(ctx, cmd, table); case CMD_OBJ_RULESET: return do_list_ruleset(ctx, cmd); default: @@ -1043,9 +1074,6 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd) } return 0; -err: - table_cleanup(table); - return -1; } static int do_command_flush(struct netlink_ctx *ctx, struct cmd *cmd) @@ -1088,10 +1116,7 @@ static int do_command_rename(struct netlink_ctx *ctx, struct cmd *cmd) static int do_command_monitor(struct netlink_ctx *ctx, struct cmd *cmd) { struct table *t; - struct set *s, *ns; - struct netlink_ctx set_ctx; - LIST_HEAD(msgs); - struct handle set_handle; + struct set *s; struct netlink_mon_handler monhandler; /* cache only needed if monitoring: @@ -1106,24 +1131,9 @@ static int do_command_monitor(struct netlink_ctx *ctx, struct cmd *cmd) monhandler.cache_needed = false; if (monhandler.cache_needed) { - memset(&set_ctx, 0, sizeof(set_ctx)); - init_list_head(&msgs); - set_ctx.msgs = &msgs; - list_for_each_entry(t, &table_list, list) { - set_handle.family = t->handle.family; - set_handle.table = t->handle.table; - - init_list_head(&set_ctx.list); - - if (netlink_list_sets(&set_ctx, &set_handle, - &cmd->location) < 0) - return -1; - - list_for_each_entry_safe(s, ns, &set_ctx.list, list) { + list_for_each_entry(s, &t->sets, list) s->init = set_expr_alloc(&cmd->location); - set_add_hash(s, t); - } } } |