From: Phil Sutter <phil@nwl.cc>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Subject: [nft PATCH 3/5] cache: Filter chain list on kernel side
Date: Wed, 1 Dec 2021 16:02:56 +0100 [thread overview]
Message-ID: <20211201150258.18436-4-phil@nwl.cc> (raw)
In-Reply-To: <20211201150258.18436-1-phil@nwl.cc>
When operating on a specific chain, add payload to NFT_MSG_GETCHAIN so
kernel returns only relevant data. Since in non-dump mode kernel returns
error if the requested item was not found, ignore errors then - chain
not found is handled anyway and kernel returns just EINVAL so no point
in checking what exactly was returned.
While being at it, improve code in chain_cache_cb() a bit:
- Check chain's family first, it is a less expensive check than
comparing table names.
- Do not extract chain name of uninteresting chains.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
include/mnl.h | 3 ++-
src/cache.c | 38 +++++++++++++++++++-------------------
src/mnl.c | 21 ++++++++++++++++++---
3 files changed, 39 insertions(+), 23 deletions(-)
diff --git a/include/mnl.h b/include/mnl.h
index 19faa651fdb91..9d54aac876dc1 100644
--- a/include/mnl.h
+++ b/include/mnl.h
@@ -43,7 +43,8 @@ int mnl_nft_chain_rename(struct netlink_ctx *ctx, const struct cmd *cmd,
const struct chain *chain);
struct nftnl_chain_list *mnl_nft_chain_dump(struct netlink_ctx *ctx,
- int family);
+ int family, const char *table,
+ const char *chain);
int mnl_nft_table_add(struct netlink_ctx *ctx, struct cmd *cmd,
unsigned int flags);
diff --git a/src/cache.c b/src/cache.c
index 484efdb93862b..3ecea38b550d4 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -342,31 +342,23 @@ struct table *table_cache_find(const struct cache *cache,
struct chain_cache_dump_ctx {
struct netlink_ctx *nlctx;
struct table *table;
- const struct nft_cache_filter *filter;
};
static int chain_cache_cb(struct nftnl_chain *nlc, void *arg)
{
struct chain_cache_dump_ctx *ctx = arg;
- const struct nft_cache_filter *filter = ctx->filter;
const char *chain_name, *table_name;
uint32_t hash, family;
struct chain *chain;
table_name = nftnl_chain_get_str(nlc, NFTNL_CHAIN_TABLE);
- chain_name = nftnl_chain_get_str(nlc, NFTNL_CHAIN_NAME);
family = nftnl_chain_get_u32(nlc, NFTNL_CHAIN_FAMILY);
- if (strcmp(table_name, ctx->table->handle.table.name) ||
- family != ctx->table->handle.family)
- return 0;
-
- if (filter && filter->list.table && filter->list.chain &&
- (filter->list.family != family ||
- strcmp(filter->list.table, table_name) ||
- strcmp(filter->list.chain, chain_name)))
+ if (family != ctx->table->handle.family ||
+ strcmp(table_name, ctx->table->handle.table.name))
return 0;
+ chain_name = nftnl_chain_get_str(nlc, NFTNL_CHAIN_NAME);
hash = djb_hash(chain_name) % NFT_CACHE_HSIZE;
chain = netlink_delinearize_chain(ctx->nlctx, nlc);
@@ -383,25 +375,33 @@ static int chain_cache_cb(struct nftnl_chain *nlc, void *arg)
}
static int chain_cache_init(struct netlink_ctx *ctx, struct table *table,
- struct nftnl_chain_list *chain_list,
- const struct nft_cache_filter *filter)
+ struct nftnl_chain_list *chain_list)
{
struct chain_cache_dump_ctx dump_ctx = {
.nlctx = ctx,
.table = table,
- .filter = filter,
};
nftnl_chain_list_foreach(chain_list, chain_cache_cb, &dump_ctx);
return 0;
}
-static struct nftnl_chain_list *chain_cache_dump(struct netlink_ctx *ctx,
- int *err)
+static struct nftnl_chain_list *
+chain_cache_dump(struct netlink_ctx *ctx,
+ const struct nft_cache_filter *filter, int *err)
{
struct nftnl_chain_list *chain_list;
+ const char *table = NULL;
+ const char *chain = NULL;
+ int family = AF_UNSPEC;
+
+ if (filter && filter->list.table && filter->list.chain) {
+ family = filter->list.family;
+ table = filter->list.table;
+ chain = filter->list.chain;
+ }
- chain_list = mnl_nft_chain_dump(ctx, AF_UNSPEC);
+ chain_list = mnl_nft_chain_dump(ctx, family, table, chain);
if (chain_list == NULL) {
if (errno == EINTR) {
*err = -1;
@@ -781,7 +781,7 @@ static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags,
int ret = 0;
if (flags & NFT_CACHE_CHAIN_BIT) {
- chain_list = chain_cache_dump(ctx, &ret);
+ chain_list = chain_cache_dump(ctx, filter, &ret);
if (!chain_list)
return -1;
}
@@ -834,7 +834,7 @@ static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags,
}
}
if (flags & NFT_CACHE_CHAIN_BIT) {
- ret = chain_cache_init(ctx, table, chain_list, filter);
+ ret = chain_cache_init(ctx, table, chain_list);
if (ret < 0) {
ret = -1;
goto cache_fails;
diff --git a/src/mnl.c b/src/mnl.c
index 35fff92a180c7..03484c03d9ff8 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -906,10 +906,12 @@ err_free:
}
struct nftnl_chain_list *mnl_nft_chain_dump(struct netlink_ctx *ctx,
- int family)
+ int family, const char *table,
+ const char *chain)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nftnl_chain_list *nlc_list;
+ struct nftnl_chain *nlc = NULL;
struct nlmsghdr *nlh;
int ret;
@@ -917,11 +919,24 @@ struct nftnl_chain_list *mnl_nft_chain_dump(struct netlink_ctx *ctx,
if (nlc_list == NULL)
memory_allocation_error();
+ if (table && chain) {
+ nlc = nftnl_chain_alloc();
+ if (!nlc)
+ memory_allocation_error();
+
+ nftnl_chain_set_str(nlc, NFTNL_CHAIN_TABLE, table);
+ nftnl_chain_set_str(nlc, NFTNL_CHAIN_NAME, chain);
+ }
+
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, family,
- NLM_F_DUMP, ctx->seqnum);
+ nlc ? NLM_F_ACK : NLM_F_DUMP, ctx->seqnum);
+ if (nlc) {
+ nftnl_chain_nlmsg_build_payload(nlh, nlc);
+ nftnl_chain_free(nlc);
+ }
ret = nft_mnl_talk(ctx, nlh, nlh->nlmsg_len, chain_cb, nlc_list);
- if (ret < 0)
+ if (ret < 0 && !nlc)
goto err;
return nlc_list;
--
2.33.0
next prev parent reply other threads:[~2021-12-01 15:03 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-01 15:02 [nft PATCH 0/5] Reduce cache overhead a bit Phil Sutter
2021-12-01 15:02 ` [nft PATCH 1/5] cache: Filter tables on kernel side Phil Sutter
2021-12-01 15:02 ` [nft PATCH 2/5] cache: Filter rule list " Phil Sutter
2021-12-01 15:02 ` Phil Sutter [this message]
2021-12-01 15:02 ` [nft PATCH 4/5] cache: Filter set list on server side Phil Sutter
2021-12-01 15:02 ` [nft PATCH 5/5] cache: Support filtering for a specific flowtable Phil Sutter
2021-12-01 16:48 ` [nft PATCH 0/5] Reduce cache overhead a bit Pablo Neira Ayuso
2021-12-01 17:18 ` Phil Sutter
2021-12-01 18:02 ` Phil Sutter
2021-12-01 18:20 ` Pablo Neira Ayuso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211201150258.18436-4-phil@nwl.cc \
--to=phil@nwl.cc \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.