@@ -38,9 +38,18 @@ enum cache_level_flags {
NFT_CACHE_FLUSHED = (1 << 31),
};
+#define NFT_CACHE_MAX_FILTER 12
+
struct nft_cache_filter {
- const char *table;
- const char *set;
+ const char *table;
+ const char *set;
+
+ struct {
+ const char *table;
+ const char *set;
+ } obj[NFT_CACHE_MAX_FILTER];
+
+ unsigned int num_objs;
};
struct nft_cache;
@@ -96,13 +96,43 @@ static unsigned int evaluate_cache_get(struct cmd *cmd, unsigned int flags)
return flags;
}
-static unsigned int evaluate_cache_flush(struct cmd *cmd, unsigned int flags)
+static void cache_filter_add(struct nft_cache_filter *filter,
+ const struct cmd *cmd)
+{
+ int i;
+
+ if (filter->num_objs >= NFT_CACHE_MAX_FILTER)
+ return;
+
+ i = filter->num_objs;
+ filter->obj[i].table = cmd->handle.table.name;
+ filter->obj[i].set = cmd->handle.set.name;
+ filter->num_objs++;
+}
+
+static bool cache_filter_find(const struct nft_cache_filter *filter,
+ const struct handle *handle)
+{
+ unsigned int i;
+
+ for (i = 0; i < filter->num_objs; i++) {
+ if (!strcmp(filter->obj[i].table, handle->table.name) &&
+ !strcmp(filter->obj[i].set, handle->set.name))
+ return true;
+ }
+
+ return false;
+}
+
+static unsigned int evaluate_cache_flush(struct cmd *cmd, unsigned int flags,
+ struct nft_cache_filter *filter)
{
switch (cmd->obj) {
case CMD_OBJ_SET:
case CMD_OBJ_MAP:
case CMD_OBJ_METER:
flags |= NFT_CACHE_SET;
+ cache_filter_add(filter, cmd);
break;
case CMD_OBJ_RULESET:
flags |= NFT_CACHE_FLUSHED;
@@ -219,7 +249,7 @@ unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds,
flags |= NFT_CACHE_FULL;
break;
case CMD_FLUSH:
- flags = evaluate_cache_flush(cmd, flags);
+ flags = evaluate_cache_flush(cmd, flags, filter);
break;
case CMD_RENAME:
flags = evaluate_cache_rename(cmd, flags);
@@ -685,6 +715,9 @@ static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags,
}
if (flags & NFT_CACHE_SETELEM_BIT) {
list_for_each_entry(set, &table->set_cache.list, cache.list) {
+ if (cache_filter_find(filter, &set->handle))
+ continue;
+
ret = netlink_list_setelems(ctx, &set->handle,
set);
if (ret < 0) {
@@ -694,6 +727,9 @@ static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags,
}
} else if (flags & NFT_CACHE_SETELEM_MAYBE) {
list_for_each_entry(set, &table->set_cache.list, cache.list) {
+ if (cache_filter_find(filter, &set->handle))
+ continue;
+
if (!set_is_non_concat_range(set))
continue;
Skip set element netlink dump if set is flushed, this speeds up set flush + add element operation in a batch file for an existing set. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- include/cache.h | 13 +++++++++++-- src/cache.c | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 4 deletions(-)