From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: kaber@trash.net
Subject: [PATCH nft,v3 1/7] src: consolidate table cache
Date: Thu, 2 Jul 2015 20:25:06 +0200 [thread overview]
Message-ID: <1435861512-23572-2-git-send-email-pablo@netfilter.org> (raw)
In-Reply-To: <1435861512-23572-1-git-send-email-pablo@netfilter.org>
This patch populates the table cache only once through netlink_list_tables()
from the initialization step. As a result, there is a single call to
netlink_list_tables().
Then, new table declarations are also added to this cache, thus follow up calls
to table_lookup() for tables that don't exist yet in the kernel will be found
in the cache.
Note that table_alloc() inserts the object in the cache and table_free()
removes the object from the cache and it releases it.
Table objects may be released from cmd_free() or after all commands in the file
have been processed.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/rule.h | 3 +++
src/main.c | 29 +++++++++++++++++++--
src/netlink.c | 12 +++------
src/rule.c | 78 ++++++++++++++++++++++++++++++++++----------------------
4 files changed, 81 insertions(+), 41 deletions(-)
diff --git a/include/rule.h b/include/rule.h
index 5d44599..ae69a8d 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -89,6 +89,9 @@ struct table {
extern struct table *table_alloc(void);
extern void table_free(struct table *table);
+
+extern int table_init_hash(void);
+extern void table_fini_hash(void);
extern void table_add_hash(struct table *table);
extern struct table *table_lookup(const struct handle *h);
diff --git a/src/main.c b/src/main.c
index bfe589a..a84f2f6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -182,7 +182,6 @@ static int nft_netlink(struct parser_state *state, struct list_head *msgs)
bool batch_supported = netlink_batch_supported();
int ret = 0;
- netlink_genid_get();
mnl_batch_init();
batch_seqnum = mnl_batch_begin();
@@ -224,18 +223,43 @@ out:
return ret;
}
+static int nft_cache_init(void)
+{
+ netlink_genid_get();
+
+ return table_init_hash();
+}
+
+static void nft_cache_fini(void)
+{
+ table_fini_hash();
+}
+
+static int nft_cache_restart(void)
+{
+ nft_cache_fini();
+ return nft_cache_init();
+}
+
int nft_run(void *scanner, struct parser_state *state, struct list_head *msgs)
{
struct cmd *cmd, *next;
int ret;
+ if (nft_cache_init() < 0)
+ return -1;
+
ret = nft_parse(scanner, state);
- if (ret != 0 || state->nerrs > 0)
+ if (ret != 0 || state->nerrs > 0) {
+ nft_cache_fini();
return -1;
+ }
retry:
ret = nft_netlink(state, msgs);
if (ret < 0 && errno == EINTR) {
netlink_restart();
+ if (nft_cache_restart() < 0)
+ return -1;
goto retry;
}
@@ -243,6 +267,7 @@ retry:
list_del(&cmd->list);
cmd_free(cmd);
}
+ nft_cache_fini();
return ret;
}
diff --git a/src/netlink.c b/src/netlink.c
index 429eed4..4b57aab 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -926,10 +926,8 @@ static struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
static int list_table_cb(struct nft_table *nlt, void *arg)
{
struct netlink_ctx *ctx = arg;
- struct table *table;
- table = netlink_delinearize_table(ctx, nlt);
- list_add_tail(&table->list, &ctx->list);
+ netlink_delinearize_table(ctx, nlt);
return 0;
}
@@ -972,7 +970,7 @@ int netlink_get_table(struct netlink_ctx *ctx, const struct handle *h,
ntable = netlink_delinearize_table(ctx, nlt);
table->flags = ntable->flags;
- xfree(ntable);
+ table_free(ntable);
out:
nft_table_free(nlt);
return err;
@@ -1963,13 +1961,10 @@ static void netlink_events_cache_addtable(struct netlink_mon_handler *monh,
const struct nlmsghdr *nlh)
{
struct nft_table *nlt;
- struct table *t;
nlt = netlink_table_alloc(nlh);
- t = netlink_delinearize_table(monh->ctx, nlt);
+ netlink_delinearize_table(monh->ctx, nlt);
nft_table_free(nlt);
-
- table_add_hash(t);
}
static void netlink_events_cache_deltable(struct netlink_mon_handler *monh,
@@ -1987,7 +1982,6 @@ static void netlink_events_cache_deltable(struct netlink_mon_handler *monh,
if (t == NULL)
goto out;
- list_del(&t->list);
table_free(t);
out:
nft_table_free(nlt);
diff --git a/src/rule.c b/src/rule.c
index b2090dd..5df0eda 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -20,6 +20,7 @@
#include <rule.h>
#include <utils.h>
#include <netlink.h>
+#include <erec.h>
#include <libnftnl/common.h>
#include <libnftnl/ruleset.h>
@@ -504,6 +505,8 @@ struct table *table_alloc(void)
init_list_head(&table->chains);
init_list_head(&table->sets);
init_list_head(&table->scope.symbols);
+ table_add_hash(table);
+
return table;
}
@@ -515,11 +518,46 @@ void table_free(struct table *table)
chain_free(chain);
handle_free(&table->handle);
scope_release(&table->scope);
+ list_del(&table->list);
xfree(table);
}
static LIST_HEAD(table_list);
+int table_init_hash(void)
+{
+ struct handle handle = {
+ .family = NFPROTO_UNSPEC,
+ };
+ struct netlink_ctx ctx;
+ LIST_HEAD(msgs);
+ int ret;
+
+ memset(&ctx, 0, sizeof(ctx));
+ init_list_head(&ctx.list);
+ ctx.msgs = &msgs;
+
+ ret = netlink_list_tables(&ctx, &handle, &internal_location);
+ if (ret < 0) {
+ if (errno != EINTR)
+ erec_print_list(stdout, &msgs);
+
+ return ret;
+ }
+
+ list_splice_tail_init(&ctx.list, &table_list);
+
+ return 0;
+}
+
+void table_fini_hash(void)
+{
+ struct table *table, *next;
+
+ list_for_each_entry_safe(table, next, &table_list, list)
+ table_free(table);
+}
+
void table_add_hash(struct table *table)
{
list_add_tail(&table->list, &table_list);
@@ -847,8 +885,6 @@ static int do_list_table(struct netlink_ctx *ctx, struct cmd *cmd,
struct rule *rule, *nrule;
struct chain *chain;
- if (netlink_get_table(ctx, &cmd->handle, &cmd->location, table) < 0)
- goto err;
if (do_list_sets(ctx, &cmd->location, table) < 0)
goto err;
if (netlink_list_chains(ctx, &cmd->handle, &cmd->location) < 0)
@@ -878,25 +914,19 @@ err:
static int do_list_ruleset(struct netlink_ctx *ctx, struct cmd *cmd)
{
- struct table *table, *next;
- LIST_HEAD(tables);
-
- if (netlink_list_tables(ctx, &cmd->handle, &cmd->location) < 0)
- return -1;
-
- list_splice_tail_init(&ctx->list, &tables);
+ unsigned int family = cmd->handle.family;
+ struct table *table;
- list_for_each_entry_safe(table, next, &tables, list) {
- table_add_hash(table);
+ list_for_each_entry(table, &table_list, list) {
+ if (family != NFPROTO_UNSPEC &&
+ table->handle.family != family)
+ continue;
cmd->handle.family = table->handle.family;
cmd->handle.table = xstrdup(table->handle.table);
if (do_list_table(ctx, cmd, table) < 0)
return -1;
-
- list_del(&table->list);
- table_free(table);
}
return 0;
@@ -913,23 +943,17 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd)
if (table == NULL) {
table = table_alloc();
handle_merge(&table->handle, &cmd->handle);
- table_add_hash(table);
}
}
switch (cmd->obj) {
case CMD_OBJ_TABLE:
if (!cmd->handle.table) {
- /* List all existing tables */
struct table *table;
- if (netlink_list_tables(ctx, &cmd->handle,
- &cmd->location) < 0)
- return -1;
-
- list_for_each_entry(table, &ctx->list, list) {
+ list_for_each_entry(table, &table_list, list)
printf("table %s\n", table->handle.table);
- }
+
return 0;
}
return do_list_table(ctx, cmd, table);
@@ -993,7 +1017,6 @@ static int do_command_rename(struct netlink_ctx *ctx, struct cmd *cmd)
table = table_alloc();
handle_merge(&table->handle, &cmd->handle);
- table_add_hash(table);
switch (cmd->obj) {
case CMD_OBJ_CHAIN:
@@ -1013,7 +1036,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, *nt;
+ struct table *t;
struct set *s, *ns;
struct netlink_ctx set_ctx;
LIST_HEAD(msgs);
@@ -1036,10 +1059,7 @@ static int do_command_monitor(struct netlink_ctx *ctx, struct cmd *cmd)
init_list_head(&msgs);
set_ctx.msgs = &msgs;
- if (netlink_list_tables(ctx, &cmd->handle, &cmd->location) < 0)
- return -1;
-
- list_for_each_entry_safe(t, nt, &ctx->list, list) {
+ list_for_each_entry(t, &table_list, list) {
set_handle.family = t->handle.family;
set_handle.table = t->handle.table;
@@ -1053,8 +1073,6 @@ static int do_command_monitor(struct netlink_ctx *ctx, struct cmd *cmd)
s->init = set_expr_alloc(&cmd->location);
set_add_hash(s, t);
}
-
- table_add_hash(t);
}
}
--
1.7.10.4
next prev parent reply other threads:[~2015-07-02 18:19 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-02 18:25 [PATCH nft,v3 0/7] cache consolidation Pablo Neira Ayuso
2015-07-02 18:25 ` Pablo Neira Ayuso [this message]
2015-07-02 18:25 ` [PATCH nft,v3 2/7] src: add table declaration to cache Pablo Neira Ayuso
2015-07-02 18:25 ` [PATCH nft,v3 3/7] src: consolidate set cache Pablo Neira Ayuso
2015-07-02 18:25 ` [PATCH nft,v3 4/7] src: early allocation of the set ID Pablo Neira Ayuso
2015-07-02 18:25 ` [PATCH nft,v3 5/7] segtree: pass element expression as parameter to set_to_intervals() Pablo Neira Ayuso
2015-07-02 18:25 ` [PATCH nft,v3 6/7] rule: use netlink_add_setelems() when creating literal sets Pablo Neira Ayuso
2015-07-02 18:25 ` [PATCH nft,v3 7/7] rule: fix use of intervals in set declarations 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=1435861512-23572-2-git-send-email-pablo@netfilter.org \
--to=pablo@netfilter.org \
--cc=kaber@trash.net \
--cc=netfilter-devel@vger.kernel.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 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).