diff options
| author | Florian Westphal <fw@strlen.de> | 2025-10-16 16:59:36 +0200 |
|---|---|---|
| committer | Florian Westphal <fw@strlen.de> | 2025-10-17 09:41:56 +0200 |
| commit | e0fe015343ff77d9176563479934b7c4e9a4683a (patch) | |
| tree | ee75dc02a63a50f35daf4e904826c4fe8bac0277 /src | |
| parent | fb3e048171fe09c347c43398a779180717818466 (diff) | |
evaluate: reject tunnel section if another one is already present
Included bogon causes a crash because the list head isn't initialised
due to tunnel->type == VXLAN.
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
Diffstat (limited to 'src')
| -rw-r--r-- | src/parser_bison.y | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/src/parser_bison.y b/src/parser_bison.y index 4e028d31..3c21c758 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -144,6 +144,19 @@ static bool already_set(const void *attr, const struct location *loc, return true; } +static bool tunnel_set_type(const struct location *loc, + struct obj *obj, enum tunnel_type type, const char *name, + struct parser_state *state) +{ + if (obj->tunnel.type) { + erec_queue(error(loc, "Cannot create new %s section inside another tunnel", name), state->msgs); + return false; + } + + obj->tunnel.type = type; + return true; +} + static struct expr *ifname_expr_alloc(const struct location *location, struct list_head *queue, const char *name) @@ -4980,11 +4993,15 @@ erspan_block : /* empty */ { $$ = $<obj>-1; } erspan_block_alloc : /* empty */ { $$ = $<obj>-1; + + if (!tunnel_set_type(&$$->location, $$, TUNNEL_ERSPAN, "erspan", state)) + YYERROR; } ; erspan_config : HDRVERSION NUM { + assert($<obj>0->tunnel.type == TUNNEL_ERSPAN); $<obj>0->tunnel.erspan.version = $2; } | INDEX NUM @@ -5017,6 +5034,10 @@ geneve_block : /* empty */ { $$ = $<obj>-1; } geneve_block_alloc : /* empty */ { $$ = $<obj>-1; + if (!tunnel_set_type(&$$->location, $$, TUNNEL_GENEVE, "geneve", state)) + YYERROR; + + init_list_head(&$$->tunnel.geneve_opts); } ; @@ -5024,6 +5045,8 @@ geneve_config : CLASS NUM OPTTYPE NUM DATA string { struct tunnel_geneve *geneve; + assert($<obj>0->tunnel.type == TUNNEL_GENEVE); + geneve = xmalloc(sizeof(struct tunnel_geneve)); geneve->geneve_class = $2; geneve->type = $4; @@ -5034,10 +5057,6 @@ geneve_config : CLASS NUM OPTTYPE NUM DATA string YYERROR; } - if (!$<obj>0->tunnel.type) { - $<obj>0->tunnel.type = TUNNEL_GENEVE; - init_list_head(&$<obj>0->tunnel.geneve_opts); - } list_add_tail(&geneve->list, &$<obj>0->tunnel.geneve_opts); free_const($6); } @@ -5055,11 +5074,15 @@ vxlan_block : /* empty */ { $$ = $<obj>-1; } vxlan_block_alloc : /* empty */ { $$ = $<obj>-1; + + if (!tunnel_set_type(&$$->location, $$, TUNNEL_VXLAN, "vxlan", state)) + YYERROR; } ; vxlan_config : GBP NUM { + assert($<obj>0->tunnel.type == TUNNEL_VXLAN); $<obj>0->tunnel.vxlan.gbp = $2; } ; @@ -5123,13 +5146,16 @@ tunnel_config : ID NUM } | ERSPAN erspan_block_alloc '{' erspan_block '}' { - $<obj>0->tunnel.type = TUNNEL_ERSPAN; + $2->location = @2; } | VXLAN vxlan_block_alloc '{' vxlan_block '}' { - $<obj>0->tunnel.type = TUNNEL_VXLAN; + $2->location = @2; } | GENEVE geneve_block_alloc '{' geneve_block '}' + { + $2->location = @2; + } ; tunnel_block : /* empty */ { $$ = $<obj>-1; } |
