The "ops_cache" will be used for caching the current timestamp (time(NULL)) for the duration of one operation. It will ensure that all decisions regarding the time, are based on the same timestamp. Add the struct for that. The content will be added next. There is already "struct nft_cache", but that seems to have a different purpose. Hence, instead of extending "struct nft_cache", add a new "struct ops_cache". The difficulty is invalidating the cache and find the right places to call nft_ctx_reset_ops_cache(). Signed-off-by: Thomas Haller <thaller@xxxxxxxxxx> --- include/datatype.h | 8 ++++++++ include/nftables.h | 3 +++ src/evaluate.c | 5 +++-- src/libnftables.c | 17 +++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/include/datatype.h b/include/datatype.h index 9ce7359cd340..79d996edd348 100644 --- a/include/datatype.h +++ b/include/datatype.h @@ -120,6 +120,13 @@ enum byteorder { struct expr; +struct ops_cache { +}; + +#define CTX_CACHE_INIT() \ + { \ + } + /** * enum datatype_flags * @@ -182,6 +189,7 @@ struct datatype *dtype_clone(const struct datatype *orig_dtype); struct parse_ctx { struct symbol_tables *tbl; const struct input_ctx *input; + struct ops_cache *ops_cache; }; extern struct error_record *symbol_parse(struct parse_ctx *ctx, diff --git a/include/nftables.h b/include/nftables.h index 219a10100206..b0a7f2f874ca 100644 --- a/include/nftables.h +++ b/include/nftables.h @@ -6,6 +6,7 @@ #include <utils.h> #include <cache.h> #include <nftables/libnftables.h> +#include <datatype.h> struct cookie { FILE *fp; @@ -47,6 +48,7 @@ struct output_ctx { struct cookie error_cookie; }; struct symbol_tables tbl; + struct ops_cache *ops_cache; }; static inline bool nft_output_reversedns(const struct output_ctx *octx) @@ -136,6 +138,7 @@ struct nft_ctx { struct output_ctx output; bool check; struct nft_cache cache; + struct ops_cache ops_cache; uint32_t flags; uint32_t optimize_flags; struct parser_state *state; diff --git a/src/evaluate.c b/src/evaluate.c index fdd2433b4780..ea910786f3e4 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -43,8 +43,9 @@ static struct parse_ctx *parse_ctx_init(struct parse_ctx *parse_ctx, const struct eval_ctx *ctx) { struct parse_ctx tmp = { - .tbl = &ctx->nft->output.tbl, - .input = &ctx->nft->input, + .tbl = &ctx->nft->output.tbl, + .input = &ctx->nft->input, + .ops_cache = &ctx->nft->ops_cache, }; /* "tmp" only exists, so we can search for "/struct parse_ctx .*=/" and find the location diff --git a/src/libnftables.c b/src/libnftables.c index 9c802ec95f27..e520bac76dfa 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -19,6 +19,15 @@ #include <stdlib.h> #include <string.h> +static void nft_ctx_reset_ops_cache(struct nft_ctx *ctx) +{ + ctx->ops_cache = (struct ops_cache) CTX_CACHE_INIT(); + + /* The cache is also referenced by the output context. Set + * up the pointer. */ + ctx->output.ops_cache = &ctx->ops_cache; +} + static int nft_netlink(struct nft_ctx *nft, struct list_head *cmds, struct list_head *msgs) { @@ -37,6 +46,8 @@ static int nft_netlink(struct nft_ctx *nft, if (list_empty(cmds)) goto out; + nft_ctx_reset_ops_cache(nft); + batch_seqnum = mnl_batch_begin(ctx.batch, mnl_seqnum_alloc(&seqnum)); list_for_each_entry(cmd, cmds, list) { ctx.seqnum = cmd->seqnum = mnl_seqnum_alloc(&seqnum); @@ -522,6 +533,8 @@ static int nft_evaluate(struct nft_ctx *nft, struct list_head *msgs, unsigned int flags; int err = 0; + nft_ctx_reset_ops_cache(nft); + filter = nft_cache_filter_init(); if (nft_cache_evaluate(nft, cmds, msgs, filter, &flags) < 0) { nft_cache_filter_fini(filter); @@ -630,6 +643,8 @@ err: if (rc || nft->check) nft_cache_release(&nft->cache); + nft_ctx_reset_ops_cache(nft); + return rc; } @@ -740,6 +755,8 @@ err: scope_release(nft->state->scopes[0]); + nft_ctx_reset_ops_cache(nft); + return rc; } -- 2.41.0