* [PATCH nft 1/2] cache: finer grain cache population for list commands
@ 2021-09-29 11:33 Pablo Neira Ayuso
2021-09-29 11:33 ` [PATCH nft 2/2] cache: filter out tables that are not requested Pablo Neira Ayuso
0 siblings, 1 reply; 2+ messages in thread
From: Pablo Neira Ayuso @ 2021-09-29 11:33 UTC (permalink / raw)
To: netfilter-devel
Skip full cache population for list commands to speed up listing.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
src/cache.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/src/cache.c b/src/cache.c
index 544f64a20396..a0898a976e88 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -127,6 +127,27 @@ static unsigned int evaluate_cache_rename(struct cmd *cmd, unsigned int flags)
return flags;
}
+static unsigned int evaluate_cache_list(struct cmd *cmd, unsigned int flags)
+{
+ switch (cmd->obj) {
+ case CMD_OBJ_CHAINS:
+ flags |= NFT_CACHE_TABLE | NFT_CACHE_CHAIN;
+ break;
+ case CMD_OBJ_SETS:
+ case CMD_OBJ_MAPS:
+ flags |= NFT_CACHE_TABLE | NFT_CACHE_SET;
+ break;
+ case CMD_OBJ_FLOWTABLES:
+ flags |= NFT_CACHE_TABLE | NFT_CACHE_FLOWTABLE;
+ break;
+ default:
+ flags |= NFT_CACHE_FULL | NFT_CACHE_REFRESH;
+ break;
+ }
+
+ return flags;
+}
+
unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
{
unsigned int flags = NFT_CACHE_EMPTY;
@@ -160,8 +181,7 @@ unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
flags |= NFT_CACHE_TABLE;
break;
case CMD_LIST:
- case CMD_EXPORT:
- flags |= NFT_CACHE_FULL | NFT_CACHE_REFRESH;
+ flags |= evaluate_cache_list(cmd, flags);
break;
case CMD_MONITOR:
flags |= NFT_CACHE_FULL;
@@ -174,6 +194,7 @@ unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
break;
case CMD_DESCRIBE:
case CMD_IMPORT:
+ case CMD_EXPORT:
break;
default:
break;
--
2.30.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH nft 2/2] cache: filter out tables that are not requested
2021-09-29 11:33 [PATCH nft 1/2] cache: finer grain cache population for list commands Pablo Neira Ayuso
@ 2021-09-29 11:33 ` Pablo Neira Ayuso
0 siblings, 0 replies; 2+ messages in thread
From: Pablo Neira Ayuso @ 2021-09-29 11:33 UTC (permalink / raw)
To: netfilter-devel
Do not fetch table content for list commands that specify a
table name, e.g.
# nft list table filter
This speeds up listing of a given table by not populating the
cache with tables that are not needed.
- Full ruleset (huge with ~100k lines).
# sudo nft list ruleset &> /dev/null
real 0m3,049s
user 0m2,080s
sys 0m0,968s
- Listing per table is now faster:
# nft list table nat &> /dev/null
real 0m1,969s
user 0m1,412s
sys 0m0,556s
# nft list table filter &> /dev/null
real 0m0,697s
user 0m0,478s
sys 0m0,220s
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1326
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/cache.h | 11 +++++++++--
src/cache.c | 42 ++++++++++++++++++++++++++++++++----------
src/cmd.c | 2 +-
src/libnftables.c | 5 +++--
4 files changed, 45 insertions(+), 15 deletions(-)
diff --git a/include/cache.h b/include/cache.h
index 70aaf735f7d9..b238c1cfe326 100644
--- a/include/cache.h
+++ b/include/cache.h
@@ -38,12 +38,19 @@ enum cache_level_flags {
NFT_CACHE_FLUSHED = (1 << 31),
};
+struct nft_cache_filter {
+ bool enabled;
+ const char *table;
+};
+
struct nft_cache;
enum cmd_ops;
-unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds);
+unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds,
+ struct nft_cache_filter *filter);
int nft_cache_update(struct nft_ctx *ctx, enum cmd_ops cmd,
- struct list_head *msgs);
+ struct list_head *msgs,
+ const struct nft_cache_filter *filter);
bool nft_cache_needs_update(struct nft_cache *cache);
void nft_cache_release(struct nft_cache *cache);
diff --git a/src/cache.c b/src/cache.c
index a0898a976e88..563860e82fb8 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -127,9 +127,17 @@ static unsigned int evaluate_cache_rename(struct cmd *cmd, unsigned int flags)
return flags;
}
-static unsigned int evaluate_cache_list(struct cmd *cmd, unsigned int flags)
+static unsigned int evaluate_cache_list(struct cmd *cmd, unsigned int flags,
+ struct nft_cache_filter *filter)
{
switch (cmd->obj) {
+ case CMD_OBJ_TABLE:
+ if (filter && cmd->handle.table.name) {
+ filter->table = cmd->handle.table.name;
+ filter->enabled = true;
+ }
+ flags |= NFT_CACHE_FULL | NFT_CACHE_REFRESH;
+ break;
case CMD_OBJ_CHAINS:
flags |= NFT_CACHE_TABLE | NFT_CACHE_CHAIN;
break;
@@ -148,12 +156,16 @@ static unsigned int evaluate_cache_list(struct cmd *cmd, unsigned int flags)
return flags;
}
-unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
+unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds,
+ struct nft_cache_filter *filter)
{
unsigned int flags = NFT_CACHE_EMPTY;
struct cmd *cmd;
list_for_each_entry(cmd, cmds, list) {
+ if (filter->enabled && cmd->op != CMD_LIST)
+ filter->enabled = false;
+
switch (cmd->op) {
case CMD_ADD:
case CMD_INSERT:
@@ -181,7 +193,7 @@ unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
flags |= NFT_CACHE_TABLE;
break;
case CMD_LIST:
- flags |= evaluate_cache_list(cmd, flags);
+ flags |= evaluate_cache_list(cmd, flags, filter);
break;
case CMD_MONITOR:
flags |= NFT_CACHE_FULL;
@@ -582,7 +594,8 @@ struct flowtable *ft_cache_find(const struct table *table, const char *name)
}
static int cache_init_tables(struct netlink_ctx *ctx, struct handle *h,
- struct nft_cache *cache)
+ struct nft_cache *cache,
+ const struct nft_cache_filter *filter)
{
struct table *table, *next;
int ret;
@@ -593,13 +606,20 @@ static int cache_init_tables(struct netlink_ctx *ctx, struct handle *h,
list_for_each_entry_safe(table, next, &ctx->list, list) {
list_del(&table->list);
+
+ if (filter && filter->enabled &&
+ (strcmp(filter->table, table->handle.table.name))) {
+ table_free(table);
+ continue;
+ }
table_cache_add(table, cache);
}
return 0;
}
-static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags)
+static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags,
+ const struct nft_cache_filter *filter)
{
struct nftnl_flowtable_list *ft_list = NULL;
struct nftnl_chain_list *chain_list = NULL;
@@ -721,7 +741,8 @@ cache_fails:
return ret;
}
-static int nft_cache_init(struct netlink_ctx *ctx, unsigned int flags)
+static int nft_cache_init(struct netlink_ctx *ctx, unsigned int flags,
+ const struct nft_cache_filter *filter)
{
struct handle handle = {
.family = NFPROTO_UNSPEC,
@@ -732,10 +753,10 @@ static int nft_cache_init(struct netlink_ctx *ctx, unsigned int flags)
return 0;
/* assume NFT_CACHE_TABLE is always set. */
- ret = cache_init_tables(ctx, &handle, &ctx->nft->cache);
+ ret = cache_init_tables(ctx, &handle, &ctx->nft->cache, filter);
if (ret < 0)
return ret;
- ret = cache_init_objects(ctx, flags);
+ ret = cache_init_objects(ctx, flags, filter);
if (ret < 0)
return ret;
@@ -763,7 +784,8 @@ bool nft_cache_needs_update(struct nft_cache *cache)
}
int nft_cache_update(struct nft_ctx *nft, unsigned int flags,
- struct list_head *msgs)
+ struct list_head *msgs,
+ const struct nft_cache_filter *filter)
{
struct netlink_ctx ctx = {
.list = LIST_HEAD_INIT(ctx.list),
@@ -792,7 +814,7 @@ replay:
goto skip;
}
- ret = nft_cache_init(&ctx, flags);
+ ret = nft_cache_init(&ctx, flags, filter);
if (ret < 0) {
if (errno == EINTR) {
nft_cache_release(cache);
diff --git a/src/cmd.c b/src/cmd.c
index d956919b6b5e..f6a8aa114768 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -81,7 +81,7 @@ static int nft_cmd_enoent_rule(struct netlink_ctx *ctx, const struct cmd *cmd,
const struct table *table = NULL;
struct chain *chain;
- if (nft_cache_update(ctx->nft, flags, ctx->msgs) < 0)
+ if (nft_cache_update(ctx->nft, flags, ctx->msgs, NULL) < 0)
return 0;
chain = chain_lookup_fuzzy(&cmd->handle, &ctx->nft->cache, &table);
diff --git a/src/libnftables.c b/src/libnftables.c
index fc52fbc35d21..2b2ed1a44329 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -459,11 +459,12 @@ static int nft_parse_bison_filename(struct nft_ctx *nft, const char *filename,
static int nft_evaluate(struct nft_ctx *nft, struct list_head *msgs,
struct list_head *cmds)
{
+ struct nft_cache_filter filter = {};
unsigned int flags;
struct cmd *cmd;
- flags = nft_cache_evaluate(nft, cmds);
- if (nft_cache_update(nft, flags, msgs) < 0)
+ flags = nft_cache_evaluate(nft, cmds, &filter);
+ if (nft_cache_update(nft, flags, msgs, &filter) < 0)
return -1;
list_for_each_entry(cmd, cmds, list) {
--
2.30.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-09-29 11:33 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-09-29 11:33 [PATCH nft 1/2] cache: finer grain cache population for list commands Pablo Neira Ayuso
2021-09-29 11:33 ` [PATCH nft 2/2] cache: filter out tables that are not requested Pablo Neira Ayuso
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).