summaryrefslogtreecommitdiffstats
path: root/src/rule.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2019-08-04 22:24:22 +0200
committerFlorian Westphal <fw@strlen.de>2019-12-17 23:10:32 +0100
commit6e48df5329eab9b8316eb0d40f77b5a9457741a8 (patch)
treeb597311a61de695691fb5bbf46ff233fe5cf667a /src/rule.c
parent14357cff40eda63f75efc878324aaaafbf3ed748 (diff)
src: add "typeof" build/parse/print support
This patch adds two new expression operations to build and to parse the userdata area that describe the set key and data typeof definitions. For maps, the grammar enforces either "type data_type : data_type" or or "typeof expression : expression". Check both key and data for valid user typeof info first. If they check out, flag set->key_typeof_valid as true and use it for printing the key info. This patch comes with initial support for using payload expressions with the 'typeof' keyword, followup patches will add support for other expressions as well. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'src/rule.c')
-rw-r--r--src/rule.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/src/rule.c b/src/rule.c
index f8cd4a73..57f1fc83 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -438,6 +438,38 @@ const char *set_policy2str(uint32_t policy)
}
}
+static void set_print_key(const struct expr *expr, struct output_ctx *octx)
+{
+ const struct datatype *dtype = expr->dtype;
+
+ if (dtype->size || dtype->type == TYPE_VERDICT)
+ nft_print(octx, "%s", dtype->name);
+ else
+ expr_print(expr, octx);
+}
+
+static void set_print_key_and_data(const struct set *set, struct output_ctx *octx)
+{
+ bool use_typeof = set->key_typeof_valid;
+
+ nft_print(octx, "%s ", use_typeof ? "typeof" : "type");
+
+ if (use_typeof)
+ expr_print(set->key, octx);
+ else
+ set_print_key(set->key, octx);
+
+ if (set_is_datamap(set->flags)) {
+ nft_print(octx, " : ");
+ if (use_typeof)
+ expr_print(set->data, octx);
+ else
+ set_print_key(set->data, octx);
+ } else if (set_is_objmap(set->flags)) {
+ nft_print(octx, " : %s", obj_type_name(set->objtype));
+ }
+}
+
static void set_print_declaration(const struct set *set,
struct print_fmt_options *opts,
struct output_ctx *octx)
@@ -465,13 +497,9 @@ static void set_print_declaration(const struct set *set,
if (nft_output_handle(octx))
nft_print(octx, " # handle %" PRIu64, set->handle.handle.id);
- nft_print(octx, "%s", opts->nl);
- nft_print(octx, "%s%stype %s",
- opts->tab, opts->tab, set->key->dtype->name);
- if (set_is_datamap(set->flags))
- nft_print(octx, " : %s", set->data->dtype->name);
- else if (set_is_objmap(set->flags))
- nft_print(octx, " : %s", obj_type_name(set->objtype));
+ nft_print(octx, "%s%s%s", opts->nl, opts->tab, opts->tab);
+
+ set_print_key_and_data(set, octx);
nft_print(octx, "%s", opts->stmt_separator);