summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2025-10-16 16:59:36 +0200
committerFlorian Westphal <fw@strlen.de>2025-10-17 09:41:56 +0200
commite0fe015343ff77d9176563479934b7c4e9a4683a (patch)
treeee75dc02a63a50f35daf4e904826c4fe8bac0277 /src
parentfb3e048171fe09c347c43398a779180717818466 (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.y38
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; }