summaryrefslogtreecommitdiffstats
path: root/src/libnftables.c
diff options
context:
space:
mode:
authorJindrich Makovicka <makovick@gmail.com>2020-05-02 13:52:06 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2020-09-14 13:47:37 +0200
commit371d32c63b892605b2baa6742234f6974ad59dcc (patch)
treecb443767dea1eb97de08f0065af37fa04c42e91b /src/libnftables.c
parentfc0138b9ec8a2780cd59f31927abab896f6836c3 (diff)
libnftables: avoid repeated command list traversal on errors
Because the command seqnums are monotonic, repeated traversals of the cmds list from the beginning are not necessary as long as the error seqnums are also monotonic. Signed-off-by: Jindrich Makovicka <makovick@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/libnftables.c')
-rw-r--r--src/libnftables.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/libnftables.c b/src/libnftables.c
index fce52ad4..a180a9a3 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -21,7 +21,7 @@ static int nft_netlink(struct nft_ctx *nft,
struct list_head *cmds, struct list_head *msgs,
struct mnl_socket *nf_sock)
{
- uint32_t batch_seqnum, seqnum = 0, num_cmds = 0;
+ uint32_t batch_seqnum, seqnum = 0, last_seqnum = UINT32_MAX, num_cmds = 0;
struct netlink_ctx ctx = {
.nft = nft,
.msgs = msgs,
@@ -65,7 +65,14 @@ static int nft_netlink(struct nft_ctx *nft,
ret = -1;
list_for_each_entry_safe(err, tmp, &err_list, head) {
- list_for_each_entry(cmd, cmds, list) {
+ /* cmd seqnums are monotonic: only reset the starting position
+ * if the error seqnum is lower than the previous one.
+ */
+ if (err->seqnum < last_seqnum)
+ cmd = list_first_entry(cmds, struct cmd, list);
+
+ list_for_each_entry_from(cmd, cmds, list) {
+ last_seqnum = cmd->seqnum;
if (err->seqnum == cmd->seqnum ||
err->seqnum == batch_seqnum) {
nft_cmd_error(&ctx, cmd, err);
@@ -76,6 +83,11 @@ static int nft_netlink(struct nft_ctx *nft,
}
}
}
+
+ if (&cmd->list == cmds) {
+ /* not found, rewind */
+ last_seqnum = UINT32_MAX;
+ }
}
out:
mnl_batch_reset(ctx.batch);