summaryrefslogtreecommitdiffstats
path: root/src/evaluate.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2020-11-02 15:22:40 +0100
committerFlorian Westphal <fw@strlen.de>2020-11-09 12:19:31 +0100
commit2e1f821d713aa44717b38901ee80cac8e2aa0335 (patch)
tree4f9fbf0959b49a58ec5499005f68d3a74e15ddff /src/evaluate.c
parent8f591eba561aceeef605283c693b659a708d1cd3 (diff)
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 <fw@strlen.de>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r--src/evaluate.c16
1 files changed, 6 insertions, 10 deletions
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,