From 2e1f821d713aa44717b38901ee80cac8e2aa0335 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 2 Nov 2020 15:22:40 +0100 Subject: tcpopt: split tcpopt_hdr_fields into per-option enum Currently we're limited to ten template fields in exthdr_desc struct. Using a single enum for all tpc option fields thus won't work indefinitely (TCPOPTHDR_FIELD_TSECR is 9) when new option templates get added. Fortunately we can just use one enum per tcp option to avoid this. As a side effect this also allows to simplify the sack offset calculations. Rather than computing that on-the-fly, just add extra fields to the SACK template. expr->exthdr.offset now holds the 'raw' value, filled in from the option template. This would ease implementation of 'raw option matching' using offset and length to load from the option. Signed-off-by: Florian Westphal --- src/evaluate.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'src/evaluate.c') diff --git a/src/evaluate.c b/src/evaluate.c index af52ab18..76b25b40 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -477,7 +477,7 @@ static void expr_evaluate_bits(struct eval_ctx *ctx, struct expr **exprp) &extra_len); break; case EXPR_EXTHDR: - shift = expr_offset_shift(expr, expr->exthdr.tmpl->offset, + shift = expr_offset_shift(expr, expr->exthdr.offset, &extra_len); break; default: @@ -530,18 +530,16 @@ static int __expr_evaluate_exthdr(struct eval_ctx *ctx, struct expr **exprp) if (expr_evaluate_primary(ctx, exprp) < 0) return -1; - if (expr->exthdr.tmpl->offset % BITS_PER_BYTE != 0 || + if (expr->exthdr.offset % BITS_PER_BYTE != 0 || expr->len % BITS_PER_BYTE != 0) expr_evaluate_bits(ctx, exprp); switch (expr->exthdr.op) { case NFT_EXTHDR_OP_TCPOPT: { static const unsigned int max_tcpoptlen = (15 * 4 - 20) * BITS_PER_BYTE; - unsigned int totlen = 0; + unsigned int totlen; - totlen += expr->exthdr.tmpl->offset; - totlen += expr->exthdr.tmpl->len; - totlen += expr->exthdr.offset; + totlen = expr->exthdr.tmpl->len + expr->exthdr.offset; if (totlen > max_tcpoptlen) return expr_error(ctx->msgs, expr, @@ -551,11 +549,9 @@ static int __expr_evaluate_exthdr(struct eval_ctx *ctx, struct expr **exprp) } case NFT_EXTHDR_OP_IPV4: { static const unsigned int max_ipoptlen = 40 * BITS_PER_BYTE; - unsigned int totlen = 0; + unsigned int totlen; - totlen += expr->exthdr.tmpl->offset; - totlen += expr->exthdr.tmpl->len; - totlen += expr->exthdr.offset; + totlen = expr->exthdr.offset + expr->exthdr.tmpl->len; if (totlen > max_ipoptlen) return expr_error(ctx->msgs, expr, -- cgit v1.2.3