summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2025-11-21 16:53:35 +0100
committerPhil Sutter <phil@nwl.cc>2026-01-20 16:02:37 +0100
commit7cab33a24a7293dc2ec4f132933ce1227d226b5b (patch)
tree017043d4b786ce08918c497a37094042fa5b6d92
parent9e80bfd0344cc0c05004c8cd1dd13e6cfa3df446 (diff)
parser_bison: Introduce tokens for chain types
Use the already existing SCANSTATE_TYPE for keyword scoping. This is a bit of back-n-forth from string to token and back to string but it eliminates the helper function and also takes care of error handling. Note that JSON parser does not validate the type string at all but relies upon the kernel to reject wrong ones. Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Florian Westphal <fw@strlen.de>
-rw-r--r--include/rule.h1
-rw-r--r--src/parser_bison.y28
-rw-r--r--src/rule.c19
-rw-r--r--src/scanner.l6
4 files changed, 20 insertions, 34 deletions
diff --git a/include/rule.h b/include/rule.h
index e67a0152..7c704be8 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -260,7 +260,6 @@ struct chain {
#define STD_PRIO_BUFSIZE 100
extern int std_prio_lookup(const char *std_prio_name, int family, int hook);
-extern const char *chain_type_name_lookup(const char *name);
extern const char *chain_hookname_lookup(const char *name);
extern struct chain *chain_alloc(void);
extern struct chain *chain_get(struct chain *chain);
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 96d0e151..405fe8f2 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -715,6 +715,10 @@ int nft_lex(void *, void *, void *);
%token XT "xt"
+%token FILTER "filter"
+%token NAT "nat"
+%token ROUTE "route"
+
%type <limit_rate> limit_rate_pkts
%type <limit_rate> limit_rate_bytes
@@ -1034,6 +1038,9 @@ int nft_lex(void *, void *, void *);
%type <expr> set_elem_key_expr
%destructor { expr_free($$); } set_elem_key_expr
+%type <string> chain_type
+%destructor { free_const($$); } chain_type
+
%%
input : /* empty */
@@ -2736,22 +2743,10 @@ type_identifier : STRING { $$ = $1; }
| CLASSID { $$ = xstrdup("classid"); }
;
-hook_spec : TYPE close_scope_type STRING HOOK STRING dev_spec prio_spec
+hook_spec : TYPE chain_type close_scope_type HOOK STRING dev_spec prio_spec
{
- const char *chain_type = chain_type_name_lookup($3);
-
- if (chain_type == NULL) {
- erec_queue(error(&@3, "unknown chain type"),
- state->msgs);
- free_const($3);
- free_const($5);
- expr_free($6);
- expr_free($7.expr);
- YYERROR;
- }
$<chain>0->type.loc = @3;
- $<chain>0->type.str = xstrdup(chain_type);
- free_const($3);
+ $<chain>0->type.str = $2;
$<chain>0->loc = @$;
$<chain>0->hook.loc = @5;
@@ -2772,6 +2767,11 @@ hook_spec : TYPE close_scope_type STRING HOOK STRING dev_spec prio_spec
}
;
+chain_type : FILTER { $$ = xstrdup("filter"); }
+ | NAT { $$ = xstrdup("nat"); }
+ | ROUTE { $$ = xstrdup("route"); }
+ ;
+
prio_spec : PRIORITY extended_prio_spec
{
$$ = $2;
diff --git a/src/rule.c b/src/rule.c
index dabc1620..c32e0831 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -676,25 +676,6 @@ struct symbol *symbol_lookup_fuzzy(const struct scope *scope,
return st.obj;
}
-static const char * const chain_type_str_array[] = {
- "filter",
- "nat",
- "route",
- NULL,
-};
-
-const char *chain_type_name_lookup(const char *name)
-{
- int i;
-
- for (i = 0; chain_type_str_array[i]; i++) {
- if (!strcmp(name, chain_type_str_array[i]))
- return chain_type_str_array[i];
- }
-
- return NULL;
-}
-
static const char * const chain_hookname_str_array[] = {
"prerouting",
"input",
diff --git a/src/scanner.l b/src/scanner.l
index 99ace057..b397a147 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -858,6 +858,12 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"out" { return OUT; }
}
+<SCANSTATE_TYPE>{
+ "filter" { return FILTER; }
+ "nat" { return NAT; }
+ "route" { return ROUTE; }
+}
+
"secmark" { scanner_push_start_cond(yyscanner, SCANSTATE_SECMARK); return SECMARK; }
"xt" { scanner_push_start_cond(yyscanner, SCANSTATE_XT); return XT; }