]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
scanner: introduce start condition stack
authorFlorian Westphal <fw@strlen.de>
Mon, 8 Mar 2021 17:18:33 +0000 (18:18 +0100)
committerFlorian Westphal <fw@strlen.de>
Thu, 11 Mar 2021 12:43:30 +0000 (13:43 +0100)
Add a small initial chunk of flex start conditionals.

This starts with two low-hanging fruits, numgen and j/symhash.

NUMGEN and HASH start conditions are entered from flex when
the corresponding expression token is encountered.

Flex returns to the INIT condition when the bison parser
has seen a complete numgen/hash statement.

This intentionally uses a stack rather than BEGIN()
to eventually support nested states.

The scanner_pop_start_cond() function argument is not used yet, but
will need to be used later to deal with nesting.

Signed-off-by: Florian Westphal <fw@strlen.de>
include/parser.h
src/parser_bison.y
src/scanner.l

index 9baa3a4db789f6a4060594eed770f416eda511c1..b2ebd7aa226c56c02b6feec225f0c0aee0b4935e 100644 (file)
@@ -26,6 +26,12 @@ struct parser_state {
        struct list_head                *cmds;
 };
 
+enum startcond_type {
+       PARSER_SC_BEGIN,
+       PARSER_SC_EXPR_HASH,
+       PARSER_SC_EXPR_NUMGEN,
+};
+
 struct mnl_socket;
 
 extern void parser_init(struct nft_ctx *nft, struct parser_state *state,
@@ -45,4 +51,6 @@ extern void scanner_push_buffer(void *scanner,
                                const struct input_descriptor *indesc,
                                const char *buffer);
 
+extern void scanner_pop_start_cond(void *scanner, enum startcond_type sc);
+
 #endif /* NFTABLES_PARSER_H */
index abfcccc4a021fd367a9e55f49fc0ecb609bbca6c..1ac4dbe43c84926d406335af643ab9cd17db02d3 100644 (file)
@@ -861,6 +861,9 @@ opt_newline         :       NEWLINE
                        |       /* empty */
                        ;
 
+close_scope_hash       : { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_HASH); };
+close_scope_numgen     : { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_NUMGEN); };
+
 common_block           :       INCLUDE         QUOTED_STRING   stmt_separator
                        {
                                if (scanner_include_file(nft, scanner, $2, &@$) < 0) {
@@ -4811,7 +4814,7 @@ numgen_type               :       INC             { $$ = NFT_NG_INCREMENTAL; }
                        |       RANDOM          { $$ = NFT_NG_RANDOM; }
                        ;
 
-numgen_expr            :       NUMGEN  numgen_type     MOD     NUM     offset_opt
+numgen_expr            :       NUMGEN  numgen_type     MOD     NUM     offset_opt      close_scope_numgen
                        {
                                $$ = numgen_expr_alloc(&@$, $2, $4, $5);
                        }
@@ -4868,17 +4871,17 @@ xfrm_expr               :       IPSEC   xfrm_dir        xfrm_spnum      xfrm_state_key
                        }
                        ;
 
-hash_expr              :       JHASH           expr    MOD     NUM     SEED    NUM     offset_opt
+hash_expr              :       JHASH           expr    MOD     NUM     SEED    NUM     offset_opt      close_scope_hash
                        {
                                $$ = hash_expr_alloc(&@$, $4, true, $6, $7, NFT_HASH_JENKINS);
                                $$->hash.expr = $2;
                        }
-                       |       JHASH           expr    MOD     NUM     offset_opt
+                       |       JHASH           expr    MOD     NUM     offset_opt      close_scope_hash
                        {
                                $$ = hash_expr_alloc(&@$, $4, false, 0, $5, NFT_HASH_JENKINS);
                                $$->hash.expr = $2;
                        }
-                       |       SYMHASH         MOD     NUM     offset_opt
+                       |       SYMHASH         MOD     NUM     offset_opt      close_scope_hash
                        {
                                $$ = hash_expr_alloc(&@$, $3, false, 0, $4, NFT_HASH_SYM);
                        }
index 1da3b5e0628cb8343f5537ebbdd478d900b38204..94225c296a3b8adefe36ec77ea8aa2db37d70039 100644 (file)
@@ -98,6 +98,8 @@ static void reset_pos(struct parser_state *state, struct location *loc)
        state->indesc->column           = 1;
 }
 
+static void scanner_push_start_cond(void *scanner, enum startcond_type type);
+
 #define YY_USER_ACTION {                                       \
        update_pos(yyget_extra(yyscanner), yylloc, yyleng);     \
        update_offset(yyget_extra(yyscanner), yylloc, yyleng);  \
@@ -193,6 +195,9 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 %option yylineno
 %option nodefault
 %option warn
+%option stack
+%s SCANSTATE_EXPR_HASH
+%s SCANSTATE_EXPR_NUMGEN
 
 %%
 
@@ -548,15 +553,21 @@ addrstring        ({macaddr}|{ip4addr}|{ip6addr})
 "state"                        { return STATE; }
 "status"               { return STATUS; }
 
-"numgen"               { return NUMGEN; }
-"inc"                  { return INC; }
-"mod"                  { return MOD; }
-"offset"               { return OFFSET; }
+"numgen"               { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_NUMGEN); return NUMGEN; }
+<SCANSTATE_EXPR_NUMGEN>{
+       "inc"           { return INC; }
+}
 
-"jhash"                        { return JHASH; }
-"symhash"              { return SYMHASH; }
-"seed"                 { return SEED; }
+"jhash"                        { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_HASH); return JHASH; }
+"symhash"              { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_HASH); return SYMHASH; }
 
+<SCANSTATE_EXPR_HASH>{
+       "seed"          { return SEED; }
+}
+<SCANSTATE_EXPR_HASH,SCANSTATE_EXPR_NUMGEN>{
+       "mod"           { return MOD; }
+       "offset"        { return OFFSET; }
+}
 "dup"                  { return DUP; }
 "fwd"                  { return FWD; }
 
@@ -967,3 +978,14 @@ void scanner_destroy(struct nft_ctx *nft)
        input_descriptor_list_destroy(state);
        yylex_destroy(nft->scanner);
 }
+
+static void scanner_push_start_cond(void *scanner, enum startcond_type type)
+{
+       yy_push_state((int)type, scanner);
+}
+
+void scanner_pop_start_cond(void *scanner, enum startcond_type t)
+{
+       yy_pop_state(scanner);
+       (void)yy_top_state(scanner); /* suppress gcc warning wrt. unused function */
+}