diff options
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; |