summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/expression.h2
-rw-r--r--include/netlink.h2
-rw-r--r--include/rule.h4
-rw-r--r--src/evaluate.c13
-rw-r--r--src/netlink.c4
-rw-r--r--src/rule.c44
-rw-r--r--src/segtree.c17
7 files changed, 40 insertions, 46 deletions
diff --git a/include/expression.h b/include/expression.h
index 0210a3cb..130912a8 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -479,7 +479,7 @@ extern void interval_map_decompose(struct expr *set);
extern struct expr *get_set_intervals(const struct set *set,
const struct expr *init);
struct table;
-extern int get_set_decompose(struct table *table, struct set *set);
+extern int get_set_decompose(struct set *cache_set, struct set *set);
extern struct expr *mapping_expr_alloc(const struct location *loc,
struct expr *from, struct expr *to);
diff --git a/include/netlink.h b/include/netlink.h
index 14fcec16..1077096e 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -149,7 +149,7 @@ extern struct stmt *netlink_parse_set_expr(const struct set *set,
extern int netlink_list_setelems(struct netlink_ctx *ctx,
const struct handle *h, struct set *set);
extern int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h,
- const struct location *loc, struct table *table,
+ const struct location *loc, struct set *cache_set,
struct set *set, struct expr *init);
extern int netlink_delinearize_setelem(struct nftnl_set_elem *nlse,
struct set *set,
diff --git a/include/rule.h b/include/rule.h
index 4de7a0d9..60eadfa3 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -683,6 +683,10 @@ struct cmd {
void *data;
struct expr *expr;
struct set *set;
+ struct {
+ struct expr *expr; /* same offset as cmd->expr */
+ struct set *set;
+ } elem;
struct rule *rule;
struct chain *chain;
struct table *table;
diff --git a/src/evaluate.c b/src/evaluate.c
index bb504962..26d73959 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -3560,7 +3560,7 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt)
}
}
-static int setelem_evaluate(struct eval_ctx *ctx, struct expr **expr)
+static int setelem_evaluate(struct eval_ctx *ctx, struct cmd *cmd)
{
struct table *table;
struct set *set;
@@ -3576,9 +3576,12 @@ static int setelem_evaluate(struct eval_ctx *ctx, struct expr **expr)
ctx->set = set;
expr_set_context(&ctx->ectx, set->key->dtype, set->key->len);
- if (expr_evaluate(ctx, expr) < 0)
+ if (expr_evaluate(ctx, &cmd->expr) < 0)
return -1;
ctx->set = NULL;
+
+ cmd->elem.set = set_get(set);
+
return 0;
}
@@ -4141,7 +4144,7 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd)
{
switch (cmd->obj) {
case CMD_OBJ_ELEMENTS:
- return setelem_evaluate(ctx, &cmd->expr);
+ return setelem_evaluate(ctx, cmd);
case CMD_OBJ_SET:
handle_merge(&cmd->set->handle, &cmd->handle);
return set_evaluate(ctx, cmd->set);
@@ -4173,7 +4176,7 @@ static int cmd_evaluate_delete(struct eval_ctx *ctx, struct cmd *cmd)
{
switch (cmd->obj) {
case CMD_OBJ_ELEMENTS:
- return setelem_evaluate(ctx, &cmd->expr);
+ return setelem_evaluate(ctx, cmd);
case CMD_OBJ_SET:
case CMD_OBJ_RULE:
case CMD_OBJ_CHAIN:
@@ -4197,7 +4200,7 @@ static int cmd_evaluate_get(struct eval_ctx *ctx, struct cmd *cmd)
{
switch (cmd->obj) {
case CMD_OBJ_ELEMENTS:
- return setelem_evaluate(ctx, &cmd->expr);
+ return setelem_evaluate(ctx, cmd);
default:
BUG("invalid command object type %u\n", cmd->obj);
}
diff --git a/src/netlink.c b/src/netlink.c
index b57e1c55..2f1dbe17 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -1228,7 +1228,7 @@ int netlink_list_setelems(struct netlink_ctx *ctx, const struct handle *h,
}
int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h,
- const struct location *loc, struct table *table,
+ const struct location *loc, struct set *cache_set,
struct set *set, struct expr *init)
{
struct nftnl_set *nls, *nls_out = NULL;
@@ -1261,7 +1261,7 @@ int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h,
if (set->flags & NFT_SET_INTERVAL && set->desc.field_count > 1)
concat_range_aggregate(set->init);
else if (set->flags & NFT_SET_INTERVAL)
- err = get_set_decompose(table, set);
+ err = get_set_decompose(cache_set, set);
else
list_expr_sort(&ctx->set->init->expressions);
diff --git a/src/rule.c b/src/rule.c
index 65973ccb..fed9e123 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1577,6 +1577,8 @@ void cmd_free(struct cmd *cmd)
switch (cmd->obj) {
case CMD_OBJ_ELEMENTS:
expr_free(cmd->expr);
+ if (cmd->elem.set)
+ set_free(cmd->elem.set);
break;
case CMD_OBJ_SET:
case CMD_OBJ_SETELEMS:
@@ -1647,13 +1649,8 @@ static int __do_add_setelems(struct netlink_ctx *ctx, struct set *set,
static int do_add_setelems(struct netlink_ctx *ctx, struct cmd *cmd,
uint32_t flags)
{
- struct handle *h = &cmd->handle;
struct expr *init = cmd->expr;
- struct table *table;
- struct set *set;
-
- table = table_lookup(h, &ctx->nft->cache);
- set = set_lookup(table, h->set.name);
+ struct set *set = cmd->elem.set;
if (set_is_non_concat_range(set) &&
set_to_intervals(ctx->msgs, set, init, true,
@@ -1750,13 +1747,8 @@ static int do_command_insert(struct netlink_ctx *ctx, struct cmd *cmd)
static int do_delete_setelems(struct netlink_ctx *ctx, struct cmd *cmd)
{
- struct handle *h = &cmd->handle;
- struct expr *expr = cmd->expr;
- struct table *table;
- struct set *set;
-
- table = table_lookup(h, &ctx->nft->cache);
- set = set_lookup(table, h->set.name);
+ struct expr *expr = cmd->elem.expr;
+ struct set *set = cmd->elem.set;
if (set_is_non_concat_range(set) &&
set_to_intervals(ctx->msgs, set, expr, false,
@@ -2521,9 +2513,15 @@ static int do_list_chains(struct netlink_ctx *ctx, struct cmd *cmd)
}
static void __do_list_set(struct netlink_ctx *ctx, struct cmd *cmd,
- struct table *table, struct set *set)
+ struct set *set)
{
+ struct table *table = table_alloc();
+
+ table->handle.table.name = xstrdup(cmd->handle.table.name);
+ table->handle.family = cmd->handle.family;
table_print_declaration(table, &ctx->nft->output);
+ table_free(table);
+
set_print(set, &ctx->nft->output);
nft_print(&ctx->nft->output, "}\n");
}
@@ -2537,7 +2535,7 @@ static int do_list_set(struct netlink_ctx *ctx, struct cmd *cmd,
if (set == NULL)
return -1;
- __do_list_set(ctx, cmd, table, set);
+ __do_list_set(ctx, cmd, set);
return 0;
}
@@ -2608,14 +2606,13 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd)
return 0;
}
-static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd,
- struct table *table)
+static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd)
{
struct set *set, *new_set;
struct expr *init;
int err;
- set = set_lookup(table, cmd->handle.set.name);
+ set = cmd->elem.set;
/* Create a list of elements based of what we got from command line. */
if (set_is_non_concat_range(set))
@@ -2627,9 +2624,9 @@ static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd,
/* Fetch from kernel the elements that have been requested .*/
err = netlink_get_setelem(ctx, &cmd->handle, &cmd->location,
- table, new_set, init);
+ cmd->elem.set, new_set, init);
if (err >= 0)
- __do_list_set(ctx, cmd, table, new_set);
+ __do_list_set(ctx, cmd, new_set);
if (set_is_non_concat_range(set))
expr_free(init);
@@ -2641,14 +2638,9 @@ static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd,
static int do_command_get(struct netlink_ctx *ctx, struct cmd *cmd)
{
- struct table *table = NULL;
-
- if (cmd->handle.table.name != NULL)
- table = table_lookup(&cmd->handle, &ctx->nft->cache);
-
switch (cmd->obj) {
case CMD_OBJ_ELEMENTS:
- return do_get_setelems(ctx, cmd, table);
+ return do_get_setelems(ctx, cmd);
default:
BUG("invalid command object type %u\n", cmd->obj);
}
diff --git a/src/segtree.c b/src/segtree.c
index 49169e73..a9b4b1bd 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -687,17 +687,15 @@ struct expr *get_set_intervals(const struct set *set, const struct expr *init)
return new_init;
}
-static struct expr *get_set_interval_find(const struct table *table,
- const char *set_name,
+static struct expr *get_set_interval_find(const struct set *cache_set,
struct expr *left,
struct expr *right)
{
+ const struct set *set = cache_set;
struct expr *range = NULL;
- struct set *set;
struct expr *i;
mpz_t val;
- set = set_lookup(table, set_name);
mpz_init2(val, set->key->len);
list_for_each_entry(i, &set->init->expressions, list) {
@@ -724,7 +722,7 @@ out:
return range;
}
-int get_set_decompose(struct table *table, struct set *set)
+int get_set_decompose(struct set *cache_set, struct set *set)
{
struct expr *i, *next, *range;
struct expr *left = NULL;
@@ -737,8 +735,7 @@ int get_set_decompose(struct table *table, struct set *set)
list_del(&left->list);
list_del(&i->list);
mpz_sub_ui(i->key->value, i->key->value, 1);
- range = get_set_interval_find(table, set->handle.set.name,
- left, i);
+ range = get_set_interval_find(cache_set, left, i);
if (!range) {
expr_free(new_init);
errno = ENOENT;
@@ -751,8 +748,7 @@ int get_set_decompose(struct table *table, struct set *set)
left = NULL;
} else {
if (left) {
- range = get_set_interval_find(table,
- set->handle.set.name,
+ range = get_set_interval_find(cache_set,
left, NULL);
if (range)
compound_expr_add(new_init, range);
@@ -764,8 +760,7 @@ int get_set_decompose(struct table *table, struct set *set)
}
}
if (left) {
- range = get_set_interval_find(table, set->handle.set.name,
- left, NULL);
+ range = get_set_interval_find(cache_set, left, NULL);
if (range)
compound_expr_add(new_init, range);
else