This allows creation of sets with string and integer types by
providing the datatype width using a comma, e.g.

"type string, 64" or "integer, 32".

This is mainly intended as a fallback for the upcoming "typeof"
keyword -- if we can't make sense of the kernel provided type
(or its missing entirely), we can then fallback to this format.

Signed-off-by: Florian Westphal <[email protected]>
---
 src/parser_bison.y | 18 ++++++++++++++++++
 src/rule.c         | 24 +++++++++++++++++++-----
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/src/parser_bison.y b/src/parser_bison.y
index c531ee1d1dd8..ee169fbac194 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -1826,6 +1826,24 @@ data_type_atom_expr      :       type_identifier
                                                         dtype->size, NULL);
                                xfree($1);
                        }
+                       |       type_identifier COMMA   NUM
+                       {
+                               const struct datatype *dtype = 
datatype_lookup_byname($1);
+                               if (dtype == NULL) {
+                                       erec_queue(error(&@1, "unknown datatype 
%s", $1),
+                                                  state->msgs);
+                                       YYERROR;
+                               }
+
+                               if (dtype->size) {
+                                       erec_queue(error(&@1, "Datatype %s has 
a fixed type", $1),
+                                                  state->msgs);
+                                       YYERROR;
+                               }
+                               $$ = constant_expr_alloc(&@1, dtype, 
dtype->byteorder,
+                                                        $3, NULL);
+                               xfree($1);
+                       }
                        ;
 
 data_type_expr         :       data_type_atom_expr
diff --git a/src/rule.c b/src/rule.c
index aee08ea12c8b..59369c9082a3 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -436,6 +436,16 @@ 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)
+               nft_print(octx, " %s", dtype->name);
+       else
+               nft_print(octx, " %s,%d", dtype->name, expr->len);
+}
+
 static void set_print_declaration(const struct set *set,
                                  struct print_fmt_options *opts,
                                  struct output_ctx *octx)
@@ -465,12 +475,16 @@ 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%stype ",
+                 opts->tab, opts->tab);
+       set_print_key(set->key, octx);
+
+       if (set_is_datamap(set->flags)) {
+               nft_print(octx, " : ");
+               set_print_key(set->data, octx);
+       } else if (set_is_objmap(set->flags)) {
                nft_print(octx, " : %s", obj_type_name(set->objtype));
+       }
 
        nft_print(octx, "%s", opts->stmt_separator);
 
-- 
2.21.0

Reply via email to