diff options
author | Jeremy Sowden <jeremy@azazel.net> | 2022-01-15 18:27:07 +0000 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2022-01-15 20:17:41 +0100 |
commit | a2086fea4a243ef449a0ccc3bf9486d7b12ee0f3 (patch) | |
tree | e582f5af5c8e555f1c4bc7d742b6b0b8bfc072f3 /src/payload.c | |
parent | 8f85d9f4469e50ade883b652ab3c112c90d477c3 (diff) |
src: store more than one payload dependency
Change the payload-dependency context to store a dependency for every
protocol layer. This allows us to eliminate more redundant protocol
expressions.
Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'src/payload.c')
-rw-r--r-- | src/payload.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/src/payload.c b/src/payload.c index accbe0ab..f433c384 100644 --- a/src/payload.c +++ b/src/payload.c @@ -610,8 +610,7 @@ void payload_dependency_store(struct payload_dep_ctx *ctx, if (ignore_dep) return; - ctx->pdep = stmt; - ctx->pbase = base + 1; + ctx->pdeps[base + 1] = stmt; } /** @@ -626,9 +625,11 @@ void payload_dependency_store(struct payload_dep_ctx *ctx, bool payload_dependency_exists(const struct payload_dep_ctx *ctx, enum proto_bases base) { - return ctx->pbase != PROTO_BASE_INVALID && - ctx->pdep != NULL && - (ctx->pbase == base || (base == PROTO_BASE_TRANSPORT_HDR && ctx->pbase == base + 1)); + if (ctx->pdeps[base]) + return true; + + return base == PROTO_BASE_TRANSPORT_HDR && + ctx->pdeps[PROTO_BASE_INNER_HDR]; } /** @@ -642,25 +643,35 @@ bool payload_dependency_exists(const struct payload_dep_ctx *ctx, struct expr *payload_dependency_get(struct payload_dep_ctx *ctx, enum proto_bases base) { - if (ctx->pbase == base) - return ctx->pdep->expr; + if (ctx->pdeps[base]) + return ctx->pdeps[base]->expr; if (base == PROTO_BASE_TRANSPORT_HDR && - ctx->pbase == PROTO_BASE_INNER_HDR) - return ctx->pdep->expr; + ctx->pdeps[PROTO_BASE_INNER_HDR]) + return ctx->pdeps[PROTO_BASE_INNER_HDR]->expr; return NULL; } -void payload_dependency_release(struct payload_dep_ctx *ctx) +static void __payload_dependency_release(struct payload_dep_ctx *ctx, + enum proto_bases base) { - list_del(&ctx->pdep->list); - stmt_free(ctx->pdep); + list_del(&ctx->pdeps[base]->list); + stmt_free(ctx->pdeps[base]); - ctx->pbase = PROTO_BASE_INVALID; - if (ctx->pdep == ctx->prev) + if (ctx->pdeps[base] == ctx->prev) ctx->prev = NULL; - ctx->pdep = NULL; + ctx->pdeps[base] = NULL; +} + +void payload_dependency_release(struct payload_dep_ctx *ctx, + enum proto_bases base) +{ + if (ctx->pdeps[base]) + __payload_dependency_release(ctx, base); + else if (base == PROTO_BASE_TRANSPORT_HDR && + ctx->pdeps[PROTO_BASE_INNER_HDR]) + __payload_dependency_release(ctx, PROTO_BASE_INNER_HDR); } static uint8_t icmp_dep_to_type(enum icmp_hdr_field_type t) @@ -786,7 +797,7 @@ void payload_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr, { if (payload_dependency_exists(ctx, expr->payload.base) && payload_may_dependency_kill(ctx, family, expr)) - payload_dependency_release(ctx); + payload_dependency_release(ctx, expr->payload.base); } void exthdr_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr, @@ -795,15 +806,15 @@ void exthdr_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr, switch (expr->exthdr.op) { case NFT_EXTHDR_OP_TCPOPT: if (payload_dependency_exists(ctx, PROTO_BASE_TRANSPORT_HDR)) - payload_dependency_release(ctx); + payload_dependency_release(ctx, PROTO_BASE_TRANSPORT_HDR); break; case NFT_EXTHDR_OP_IPV6: if (payload_dependency_exists(ctx, PROTO_BASE_NETWORK_HDR)) - payload_dependency_release(ctx); + payload_dependency_release(ctx, PROTO_BASE_NETWORK_HDR); break; case NFT_EXTHDR_OP_IPV4: if (payload_dependency_exists(ctx, PROTO_BASE_NETWORK_HDR)) - payload_dependency_release(ctx); + payload_dependency_release(ctx, PROTO_BASE_NETWORK_HDR); break; default: break; |