From 371d32c63b892605b2baa6742234f6974ad59dcc Mon Sep 17 00:00:00 2001 From: Jindrich Makovicka Date: Sat, 2 May 2020 13:52:06 +0200 Subject: 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 Signed-off-by: Pablo Neira Ayuso --- src/libnftables.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/libnftables.c') 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); -- cgit v1.2.3