diff options
author | Phil Sutter <phil@nwl.cc> | 2022-03-01 19:46:21 +0100 |
---|---|---|
committer | Phil Sutter <phil@nwl.cc> | 2022-03-10 17:38:31 +0100 |
commit | 07ee529f5a62838d68be59683be99bf6a7cda0f2 (patch) | |
tree | 60454796d86f28ecdc76ce10656de049af73c2b7 /iptables/nft-shared.c | |
parent | b5f2faea325a315bfb932ebc634f3298d4824cae (diff) |
nft: Speed up immediate parsing
Parsing of rules which jump to a chain pointlessly causes a call to
xtables_find_target() despite the code already knowing the outcome.
Avoid the significant delay for rulesets with many chain jumps by
performing the (standard) target lookup only for accept/drop/return
verdicts.
From a biased test-case on my VM:
| # iptables-nft-save | grep -c -- '-j'
| 133943
| # time ./old/iptables-nft-save >/dev/null
| real 0m45.566s
| user 0m1.308s
| sys 0m8.430s
| # time ./new/iptables-nft-save >/dev/null
| real 0m3.547s
| user 0m0.762s
| sys 0m2.476s
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'iptables/nft-shared.c')
-rw-r--r-- | iptables/nft-shared.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c index daa251ae..861aa064 100644 --- a/iptables/nft-shared.c +++ b/iptables/nft-shared.c @@ -907,6 +907,8 @@ static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e) { const char *chain = nftnl_expr_get_str(e, NFTNL_EXPR_IMM_CHAIN); struct iptables_command_state *cs = ctx->cs; + struct xt_entry_target *t; + uint32_t size; int verdict; if (nftnl_expr_is_set(e, NFTNL_EXPR_IMM_DATA)) { @@ -943,8 +945,21 @@ static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e) /* fall through */ case NFT_JUMP: cs->jumpto = chain; - break; + /* fall through */ + default: + return; } + + cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD); + if (!cs->target) + return; + + size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size; + t = xtables_calloc(1, size); + t->u.target_size = size; + t->u.user.revision = cs->target->revision; + strcpy(t->u.user.name, cs->jumpto); + cs->target->t = t; } static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e) @@ -1143,25 +1158,8 @@ void nft_rule_to_iptables_command_state(struct nft_handle *h, } } - if (cs->target != NULL) { - cs->jumpto = cs->target->name; - } else if (cs->jumpto != NULL) { - struct xt_entry_target *t; - uint32_t size; - - cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD); - if (!cs->target) - return; - - size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size; - t = xtables_calloc(1, size); - t->u.target_size = size; - t->u.user.revision = cs->target->revision; - strcpy(t->u.user.name, cs->jumpto); - cs->target->t = t; - } else { + if (!cs->jumpto) cs->jumpto = ""; - } } void nft_clear_iptables_command_state(struct iptables_command_state *cs) @@ -1326,6 +1324,7 @@ void nft_ipv46_parse_target(struct xtables_target *t, void *data) struct iptables_command_state *cs = data; cs->target = t; + cs->jumpto = t->name; } void nft_check_xt_legacy(int family, bool is_ipt_save) |