1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
From 638af0ceb2b22307098bb2730822e148ef0b9424 Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@strlen.de>
Date: Fri, 10 Jun 2022 13:01:46 +0200
Subject: Revert "scanner: flags: move to own scope"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Excess nesting of scanner scopes is very fragile and error prone:
rule `iif != lo ip daddr 127.0.0.1/8 counter limit rate 1/second log flags all prefix "nft_lo4 " drop`
fails with `Error: No symbol type information` hinting at `prefix`
Problem is that we nest via:
counter
limit
log
flags
By the time 'prefix' is scanned, state is still stuck in 'counter' due
to this nesting. Working around "prefix" isn't enough, any other
keyword, e.g. "level" in 'flags all level debug' will be parsed as 'string' too.
So, revert this.
Fixes: a16697097e2b ("scanner: flags: move to own scope")
Reported-by: Christian Göttsche <cgzones@googlemail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/parser.h | 1 -
src/parser_bison.y | 29 ++++++++++++++---------------
src/scanner.l | 18 +++++++-----------
tests/shell/testcases/parsing/log | 10 ++++++++++
4 files changed, 31 insertions(+), 27 deletions(-)
create mode 100755 tests/shell/testcases/parsing/log
diff --git a/include/parser.h b/include/parser.h
index f32154cc..d8d2eb11 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -35,7 +35,6 @@ enum startcond_type {
PARSER_SC_CT,
PARSER_SC_COUNTER,
PARSER_SC_ETH,
- PARSER_SC_FLAGS,
PARSER_SC_ICMP,
PARSER_SC_IGMP,
PARSER_SC_IP,
diff --git a/src/parser_bison.y b/src/parser_bison.y
index ca5c488c..2a0240fb 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -942,7 +942,6 @@ close_scope_esp : { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_ESP); }
close_scope_eth : { scanner_pop_start_cond(nft->scanner, PARSER_SC_ETH); };
close_scope_export : { scanner_pop_start_cond(nft->scanner, PARSER_SC_CMD_EXPORT); };
close_scope_fib : { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_FIB); };
-close_scope_flags : { scanner_pop_start_cond(nft->scanner, PARSER_SC_FLAGS); };
close_scope_frag : { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_FRAG); };
close_scope_fwd : { scanner_pop_start_cond(nft->scanner, PARSER_SC_STMT_FWD); };
close_scope_hash : { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_HASH); };
@@ -1679,7 +1678,7 @@ table_block_alloc : /* empty */
}
;
-table_options : FLAGS STRING close_scope_flags
+table_options : FLAGS STRING
{
if (strcmp($2, "dormant") == 0) {
$<table>0->flags |= TABLE_F_DORMANT;
@@ -1946,7 +1945,7 @@ set_block : /* empty */ { $$ = $<set>-1; }
datatype_set($1->key, $3->dtype);
$$ = $1;
}
- | set_block FLAGS set_flag_list stmt_separator close_scope_flags
+ | set_block FLAGS set_flag_list stmt_separator
{
$1->flags = $3;
$$ = $1;
@@ -2080,7 +2079,7 @@ map_block : /* empty */ { $$ = $<set>-1; }
$1->flags |= NFT_SET_OBJECT;
$$ = $1;
}
- | map_block FLAGS set_flag_list stmt_separator close_scope_flags
+ | map_block FLAGS set_flag_list stmt_separator
{
$1->flags |= $3;
$$ = $1;
@@ -2153,7 +2152,7 @@ flowtable_block : /* empty */ { $$ = $<flowtable>-1; }
{
$$->flags |= NFT_FLOWTABLE_COUNTER;
}
- | flowtable_block FLAGS OFFLOAD stmt_separator close_scope_flags
+ | flowtable_block FLAGS OFFLOAD stmt_separator
{
$$->flags |= FLOWTABLE_F_HW_OFFLOAD;
}
@@ -2520,7 +2519,7 @@ dev_spec : DEVICE string
| /* empty */ { $$ = NULL; }
;
-flags_spec : FLAGS OFFLOAD close_scope_flags
+flags_spec : FLAGS OFFLOAD
{
$<chain>0->flags |= CHAIN_F_HW_OFFLOAD;
}
@@ -3126,7 +3125,7 @@ log_arg : PREFIX string
$<stmt>0->log.level = $2;
$<stmt>0->log.flags |= STMT_LOG_LEVEL;
}
- | FLAGS log_flags close_scope_flags
+ | FLAGS log_flags
{
$<stmt>0->log.logflags |= $2;
}
@@ -3828,13 +3827,13 @@ queue_stmt : queue_stmt_compat close_scope_queue
{
$$ = queue_stmt_alloc(&@$, $3, 0);
}
- | QUEUE FLAGS queue_stmt_flags close_scope_flags TO queue_stmt_expr close_scope_queue
+ | QUEUE FLAGS queue_stmt_flags TO queue_stmt_expr close_scope_queue
{
- $$ = queue_stmt_alloc(&@$, $6, $3);
+ $$ = queue_stmt_alloc(&@$, $5, $3);
}
- | QUEUE FLAGS queue_stmt_flags close_scope_flags QUEUENUM queue_stmt_expr_simple close_scope_queue
+ | QUEUE FLAGS queue_stmt_flags QUEUENUM queue_stmt_expr_simple close_scope_queue
{
- $$ = queue_stmt_alloc(&@$, $6, $3);
+ $$ = queue_stmt_alloc(&@$, $5, $3);
}
;
@@ -5501,7 +5500,7 @@ comp_hdr_expr : COMP comp_hdr_field close_scope_comp
;
comp_hdr_field : NEXTHDR { $$ = COMPHDR_NEXTHDR; }
- | FLAGS close_scope_flags { $$ = COMPHDR_FLAGS; }
+ | FLAGS { $$ = COMPHDR_FLAGS; }
| CPI { $$ = COMPHDR_CPI; }
;
@@ -5562,7 +5561,7 @@ tcp_hdr_field : SPORT { $$ = TCPHDR_SPORT; }
| ACKSEQ { $$ = TCPHDR_ACKSEQ; }
| DOFF { $$ = TCPHDR_DOFF; }
| RESERVED { $$ = TCPHDR_RESERVED; }
- | FLAGS close_scope_flags { $$ = TCPHDR_FLAGS; }
+ | FLAGS { $$ = TCPHDR_FLAGS; }
| WINDOW { $$ = TCPHDR_WINDOW; }
| CHECKSUM { $$ = TCPHDR_CHECKSUM; }
| URGPTR { $$ = TCPHDR_URGPTR; }
@@ -5676,7 +5675,7 @@ sctp_chunk_type : DATA { $$ = SCTP_CHUNK_TYPE_DATA; }
;
sctp_chunk_common_field : TYPE close_scope_type { $$ = SCTP_CHUNK_COMMON_TYPE; }
- | FLAGS close_scope_flags { $$ = SCTP_CHUNK_COMMON_FLAGS; }
+ | FLAGS { $$ = SCTP_CHUNK_COMMON_FLAGS; }
| LENGTH { $$ = SCTP_CHUNK_COMMON_LENGTH; }
;
@@ -5844,7 +5843,7 @@ rt4_hdr_expr : RT4 rt4_hdr_field close_scope_rt
;
rt4_hdr_field : LAST_ENT { $$ = RT4HDR_LASTENT; }
- | FLAGS close_scope_flags { $$ = RT4HDR_FLAGS; }
+ | FLAGS { $$ = RT4HDR_FLAGS; }
| TAG { $$ = RT4HDR_TAG; }
| SID '[' NUM ']'
{
diff --git a/src/scanner.l b/src/scanner.l
index 2154281e..7eb74020 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -201,7 +201,6 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
%s SCANSTATE_CT
%s SCANSTATE_COUNTER
%s SCANSTATE_ETH
-%s SCANSTATE_FLAGS
%s SCANSTATE_ICMP
%s SCANSTATE_IGMP
%s SCANSTATE_IP
@@ -339,7 +338,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"jump" { return JUMP; }
"goto" { return GOTO; }
"return" { return RETURN; }
-<SCANSTATE_EXPR_QUEUE,SCANSTATE_STMT_DUP,SCANSTATE_STMT_FWD,SCANSTATE_STMT_NAT,SCANSTATE_STMT_TPROXY,SCANSTATE_FLAGS,SCANSTATE_IP,SCANSTATE_IP6>"to" { return TO; } /* XXX: SCANSTATE_FLAGS and SCANSTATE_IP here are workarounds */
+<SCANSTATE_EXPR_QUEUE,SCANSTATE_STMT_DUP,SCANSTATE_STMT_FWD,SCANSTATE_STMT_NAT,SCANSTATE_STMT_TPROXY,SCANSTATE_IP,SCANSTATE_IP6>"to" { return TO; } /* XXX: SCANSTATE_IP is a workaround */
"inet" { return INET; }
"netdev" { return NETDEV; }
@@ -363,14 +362,9 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"index" { return INDEX; }
"comment" { return COMMENT; }
-<SCANSTATE_FLAGS>{
- "constant" { return CONSTANT; }
- "dynamic" { return DYNAMIC; }
-
- /* log flags */
- "all" { return ALL; }
-}
+"constant" { return CONSTANT; }
"interval" { return INTERVAL; }
+"dynamic" { return DYNAMIC; }
"auto-merge" { return AUTOMERGE; }
"timeout" { return TIMEOUT; }
"gc-interval" { return GC_INTERVAL; }
@@ -418,7 +412,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
}
"queue" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_QUEUE); return QUEUE;}
-<SCANSTATE_FLAGS,SCANSTATE_EXPR_QUEUE>{
+<SCANSTATE_EXPR_QUEUE>{
"num" { return QUEUENUM;}
"bypass" { return BYPASS;}
"fanout" { return FANOUT;}
@@ -612,7 +606,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
<SCANSTATE_EXPR_COMP>{
"cpi" { return CPI; }
}
-"flags" { scanner_push_start_cond(yyscanner, SCANSTATE_FLAGS); return FLAGS; }
+"flags" { return FLAGS; }
"udp" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_UDP); return UDP; }
"udplite" { scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_UDPLITE); return UDPLITE; }
@@ -781,6 +775,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"notrack" { return NOTRACK; }
+"all" { return ALL; }
+
<SCANSTATE_CMD_EXPORT,SCANSTATE_CMD_IMPORT,SCANSTATE_CMD_MONITOR>{
"xml" { return XML; }
"json" { return JSON; }
diff --git a/tests/shell/testcases/parsing/log b/tests/shell/testcases/parsing/log
new file mode 100755
index 00000000..0b89d589
--- /dev/null
+++ b/tests/shell/testcases/parsing/log
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+$NFT add table t || exit 1
+$NFT add chain t c || exit 1
+$NFT add rule t c 'iif != lo ip daddr 127.0.0.1/8 counter limit rate 1/second log flags all prefix "nft_lo4 " drop' || exit 1
+$NFT add rule t c 'iif != lo ip daddr 127.0.0.1/8 counter limit rate 1/second log flags all level debug drop' || exit 1
+$NFT delete table t || exit 1
+
+exit 0
+
--
cgit v1.2.3
|