summaryrefslogtreecommitdiffstats
path: root/src/evaluate.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2023-01-02 15:36:33 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2023-01-02 15:36:33 +0100
commitc1f92755437ea4eee10950a196a5c749329ae5f6 (patch)
tree33c6f8fb7f262b274d494a91f3aa43c41dff5c9c /src/evaluate.c
parent75b096c094a5ee1d6ef443f16d6b55fa3dd1f197 (diff)
src: add gre support
GRE has a number of fields that are conditional based on flags, which requires custom dependency code similar to icmp and icmpv6. Matching on optional fields is not supported at this stage. Since this is a layer 3 tunnel protocol, an implicit dependency on NFT_META_L4PROTO for IPPROTO_GRE is generated. To achieve this, this patch adds new infrastructure to remove an outer dependency based on the inner protocol from delinearize path. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r--src/evaluate.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index e98ea424..21de1840 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -881,24 +881,43 @@ static int expr_evaluate_payload(struct eval_ctx *ctx, struct expr **exprp)
static int expr_evaluate_inner(struct eval_ctx *ctx, struct expr **exprp)
{
struct proto_ctx *pctx = eval_proto_ctx(ctx);
- const struct proto_desc *desc;
+ const struct proto_desc *desc = NULL;
struct expr *expr = *exprp;
int ret;
- desc = pctx->protocol[expr->payload.inner_desc->base - 1].desc;
- if (!desc) {
- return expr_error(ctx->msgs, expr,
- "no transport protocol specified");
- }
+ assert(expr->etype == EXPR_PAYLOAD);
- if (proto_find_num(desc, expr->payload.inner_desc) < 0) {
- return expr_error(ctx->msgs, expr,
- "unexpected transport protocol %s",
- desc->name);
+ pctx = eval_proto_ctx(ctx);
+ desc = pctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc;
+
+ if (desc == NULL &&
+ expr->payload.inner_desc->base < PROTO_BASE_INNER_HDR) {
+ struct stmt *nstmt;
+
+ if (payload_gen_inner_dependency(ctx, expr, &nstmt) < 0)
+ return -1;
+
+ rule_stmt_insert_at(ctx->rule, nstmt, ctx->stmt);
+
+ proto_ctx_update(pctx, PROTO_BASE_TRANSPORT_HDR, &expr->location, expr->payload.inner_desc);
}
- proto_ctx_update(pctx, PROTO_BASE_INNER_HDR, &expr->location,
- expr->payload.inner_desc);
+ if (expr->payload.inner_desc->base == PROTO_BASE_INNER_HDR) {
+ desc = pctx->protocol[expr->payload.inner_desc->base - 1].desc;
+ if (!desc) {
+ return expr_error(ctx->msgs, expr,
+ "no transport protocol specified");
+ }
+
+ if (proto_find_num(desc, expr->payload.inner_desc) < 0) {
+ return expr_error(ctx->msgs, expr,
+ "unexpected transport protocol %s",
+ desc->name);
+ }
+
+ proto_ctx_update(pctx, expr->payload.inner_desc->base, &expr->location,
+ expr->payload.inner_desc);
+ }
if (expr->payload.base != PROTO_BASE_INNER_HDR)
ctx->inner_desc = expr->payload.inner_desc;