From 37f494198fe9dd9f98a487043af37d5bd72dde7e Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 3 Nov 2020 14:32:12 +0100 Subject: json: add missing nat_type flag and netmap nat flag JSON in/output doesn't know about nat_type and thus cannot save/restore nat mappings involving prefixes or concatenations because the snat statement lacks the prefix/concat/interval type flags. Furthermore, bison parser was extended to support netmap. This is done with an internal 'netmap' flag that is passed to the kernel. We need to dump/restore that as well. Also make sure ip/snat.t passes in json mode. Fixes: 35a6b10c1bc4 ("src: add netmap support") Fixes: 9599d9d25a6b ("src: NAT support for intervals in maps") Signed-off-by: Florian Westphal --- src/parser_json.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) (limited to 'src/parser_json.c') diff --git a/src/parser_json.c b/src/parser_json.c index ac89166e..13623912 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1358,8 +1358,8 @@ static struct expr *json_parse_expr(struct json_ctx *ctx, json_t *root) { "set", json_parse_set_expr, CTX_F_RHS | CTX_F_STMT }, /* allow this as stmt expr because that allows set references */ { "map", json_parse_map_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS }, /* below three are multiton_rhs_expr */ - { "prefix", json_parse_prefix_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_CONCAT }, - { "range", json_parse_range_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_CONCAT }, + { "prefix", json_parse_prefix_expr, CTX_F_RHS | CTX_F_SET_RHS | CTX_F_STMT | CTX_F_CONCAT }, + { "range", json_parse_range_expr, CTX_F_RHS | CTX_F_SET_RHS | CTX_F_STMT | CTX_F_CONCAT }, { "payload", json_parse_payload_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, { "exthdr", json_parse_exthdr_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, { "tcp option", json_parse_tcp_option_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_CONCAT }, @@ -1861,6 +1861,7 @@ static int json_parse_nat_flag(struct json_ctx *ctx, { "random", NF_NAT_RANGE_PROTO_RANDOM }, { "fully-random", NF_NAT_RANGE_PROTO_RANDOM_FULLY }, { "persistent", NF_NAT_RANGE_PERSISTENT }, + { "netmap", NF_NAT_RANGE_NETMAP }, }; const char *flag; unsigned int i; @@ -1905,6 +1906,60 @@ static int json_parse_nat_flags(struct json_ctx *ctx, json_t *root) return flags; } +static int json_parse_nat_type_flag(struct json_ctx *ctx, + json_t *root, int *flags) +{ + const struct { + const char *flag; + int val; + } flag_tbl[] = { + { "interval", STMT_NAT_F_INTERVAL }, + { "prefix", STMT_NAT_F_PREFIX }, + { "concat", STMT_NAT_F_CONCAT }, + }; + const char *flag; + unsigned int i; + + assert(flags); + + if (!json_is_string(root)) { + json_error(ctx, "Invalid nat type flag type %s, expected string.", + json_typename(root)); + return 1; + } + flag = json_string_value(root); + for (i = 0; i < array_size(flag_tbl); i++) { + if (!strcmp(flag, flag_tbl[i].flag)) { + *flags |= flag_tbl[i].val; + return 0; + } + } + json_error(ctx, "Unknown nat type flag '%s'.", flag); + return 1; +} + +static int json_parse_nat_type_flags(struct json_ctx *ctx, json_t *root) +{ + int flags = 0; + json_t *value; + size_t index; + + if (json_is_string(root)) { + json_parse_nat_type_flag(ctx, root, &flags); + return flags; + } else if (!json_is_array(root)) { + json_error(ctx, "Invalid nat flags type %s.", + json_typename(root)); + return -1; + } + json_array_foreach(root, index, value) { + if (json_parse_nat_type_flag(ctx, value, &flags)) + json_error(ctx, "Parsing nat type flag at index %zu failed.", + index); + } + return flags; +} + static int nat_type_parse(const char *type) { const char * const nat_etypes[] = { @@ -1967,6 +2022,17 @@ static struct stmt *json_parse_nat_stmt(struct json_ctx *ctx, } stmt->nat.flags = flags; } + + if (!json_unpack(value, "{s:o}", "type_flags", &tmp)) { + int flags = json_parse_nat_type_flags(ctx, tmp); + + if (flags < 0) { + stmt_free(stmt); + return NULL; + } + stmt->nat.type_flags = flags; + } + return stmt; } -- cgit v1.2.3