diff options
author | Florian Westphal <fw@strlen.de> | 2020-11-02 15:22:40 +0100 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2020-11-09 12:19:31 +0100 |
commit | 2e1f821d713aa44717b38901ee80cac8e2aa0335 (patch) | |
tree | 4f9fbf0959b49a58ec5499005f68d3a74e15ddff /src/parser_json.c | |
parent | 8f591eba561aceeef605283c693b659a708d1cd3 (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/parser_json.c')
-rw-r--r-- | src/parser_json.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/src/parser_json.c b/src/parser_json.c index c68b64d9..6e133365 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -468,8 +468,10 @@ static int json_parse_tcp_option_type(const char *name, int *val) } /* special case for sack0 - sack3 */ if (sscanf(name, "sack%u", &i) == 1 && i < 4) { - if (val) - *val = TCPOPT_KIND_SACK + i; + if (val && i == 0) + *val = TCPOPT_KIND_SACK; + else if (val && i > 0) + *val = TCPOPT_KIND_SACK1 + i - 1; return 0; } return 1; @@ -477,12 +479,38 @@ static int json_parse_tcp_option_type(const char *name, int *val) static int json_parse_tcp_option_field(int type, const char *name, int *val) { + const struct exthdr_desc *desc; + unsigned int block = 0; unsigned int i; - const struct exthdr_desc *desc = tcpopt_protocols[type]; + + switch (type) { + case TCPOPT_KIND_SACK1: + type = TCPOPT_KIND_SACK; + block = 1; + break; + case TCPOPT_KIND_SACK2: + type = TCPOPT_KIND_SACK; + block = 2; + break; + case TCPOPT_KIND_SACK3: + type = TCPOPT_KIND_SACK; + block = 3; + break; + } + + if (type < 0 || type >= (int)array_size(tcpopt_protocols)) + return 1; + + desc = tcpopt_protocols[type]; for (i = 0; i < array_size(desc->templates); i++) { if (desc->templates[i].token && !strcmp(desc->templates[i].token, name)) { + if (block) { + block--; + continue; + } + if (val) *val = i; return 0; @@ -587,7 +615,7 @@ static struct expr *json_parse_tcp_option_expr(struct json_ctx *ctx, if (json_unpack(root, "{s:s}", "field", &field)) { expr = tcpopt_expr_alloc(int_loc, descval, - TCPOPTHDR_FIELD_KIND); + TCPOPT_COMMON_KIND); expr->exthdr.flags = NFT_EXTHDR_F_PRESENT; return expr; |