165 lines
5.3 KiB
Diff
165 lines
5.3 KiB
Diff
From c009df1fded60c64075493c875873f05606f17ef Mon Sep 17 00:00:00 2001
|
|
From: Florian Westphal <fw@strlen.de>
|
|
Date: Sun, 21 Nov 2021 23:33:09 +0100
|
|
Subject: parser: split tcp option rules
|
|
|
|
At this time the parser will accept nonsensical input like
|
|
|
|
tcp option mss left 2
|
|
|
|
which will be treated as 'tcp option maxseg size 2'.
|
|
This is because the enum space overlaps.
|
|
|
|
Split the rules so that 'tcp option mss' will only
|
|
accept field names specific to the mss/maxseg option kind.
|
|
|
|
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
(cherry picked from commit 46168852c03d73c29b557c93029dc512ca6e233a)
|
|
|
|
Conflict:change context and add KIND type in parser_bison.y
|
|
Reference:https://git.netfilter.org/nftables/commit/?id=c009df1fded60c64075493c875873f05606f17ef
|
|
|
|
---
|
|
src/parser_bison.y | 80 +++++++++++++++++++++++++++++++++++++++++-------------
|
|
1 file changed, 61 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/src/parser_bison.y b/src/parser_bison.y
|
|
index 26060985..fca79132 100644
|
|
--- a/src/parser_bison.y
|
|
+++ b/src/parser_bison.y
|
|
@@ -187,6 +187,10 @@ int nft_lex(void *, void *, void *);
|
|
struct handle_spec handle_spec;
|
|
struct position_spec position_spec;
|
|
struct prio_spec prio_spec;
|
|
+ struct tcp_kind_field {
|
|
+ uint16_t kind; /* must allow > 255 for SACK1, 2.. hack */
|
|
+ uint8_t field;
|
|
+ } tcp_kind_field;
|
|
}
|
|
|
|
%token TOKEN_EOF 0 "end of file"
|
|
@@ -873,7 +877,10 @@ int nft_lex(void *, void *, void *);
|
|
%type <expr> tcp_hdr_expr
|
|
%destructor { expr_free($$); } tcp_hdr_expr
|
|
%type <val> tcp_hdr_field
|
|
-%type <val> tcp_hdr_option_type tcp_hdr_option_field
|
|
+%type <val> tcp_hdr_option_type
|
|
+%type <val> tcp_hdr_option_sack
|
|
+%type <val> tcpopt_field_maxseg tcpopt_field_sack tcpopt_field_tsopt tcpopt_field_window
|
|
+%type <tcp_kind_field> tcp_hdr_option_kind_and_field
|
|
|
|
%type <expr> boolean_expr
|
|
%destructor { expr_free($$); } boolean_expr
|
|
@@ -5477,15 +5484,15 @@ tcp_hdr_expr : TCP tcp_hdr_field
|
|
{
|
|
$$ = payload_expr_alloc(&@$, &proto_tcp, $2);
|
|
}
|
|
- | TCP OPTION tcp_hdr_option_type tcp_hdr_option_field
|
|
- {
|
|
- $$ = tcpopt_expr_alloc(&@$, $3, $4);
|
|
- }
|
|
| TCP OPTION tcp_hdr_option_type
|
|
{
|
|
$$ = tcpopt_expr_alloc(&@$, $3, TCPOPT_COMMON_KIND);
|
|
$$->exthdr.flags = NFT_EXTHDR_F_PRESENT;
|
|
}
|
|
+ | TCP OPTION tcp_hdr_option_kind_and_field
|
|
+ {
|
|
+ $$ = tcpopt_expr_alloc(&@$, $3.kind, $3.field);
|
|
+ }
|
|
| TCP OPTION AT tcp_hdr_option_type COMMA NUM COMMA NUM
|
|
{
|
|
$$ = tcpopt_expr_alloc(&@$, $4, 0);
|
|
@@ -5505,19 +5512,53 @@ tcp_hdr_field : SPORT { $$ = TCPHDR_SPORT; }
|
|
| URGPTR { $$ = TCPHDR_URGPTR; }
|
|
;
|
|
|
|
-tcp_hdr_option_type : EOL { $$ = TCPOPT_KIND_EOL; }
|
|
- | NOP { $$ = TCPOPT_KIND_NOP; }
|
|
- | MSS { $$ = TCPOPT_KIND_MAXSEG; }
|
|
- | WINDOW { $$ = TCPOPT_KIND_WINDOW; }
|
|
- | SACK_PERM { $$ = TCPOPT_KIND_SACK_PERMITTED; }
|
|
- | SACK { $$ = TCPOPT_KIND_SACK; }
|
|
+tcp_hdr_option_kind_and_field : MSS tcpopt_field_maxseg
|
|
+ {
|
|
+ struct tcp_kind_field kind_field = { .kind = TCPOPT_KIND_MAXSEG, .field = $2 };
|
|
+ $$ = kind_field;
|
|
+ }
|
|
+ | tcp_hdr_option_sack tcpopt_field_sack
|
|
+ {
|
|
+ struct tcp_kind_field kind_field = { .kind = $1, .field = $2 };
|
|
+ $$ = kind_field;
|
|
+ }
|
|
+ | WINDOW tcpopt_field_window
|
|
+ {
|
|
+ struct tcp_kind_field kind_field = { .kind = TCPOPT_KIND_WINDOW, .field = $2 };
|
|
+ $$ = kind_field;
|
|
+ }
|
|
+ | TIMESTAMP tcpopt_field_tsopt
|
|
+ {
|
|
+ struct tcp_kind_field kind_field = { .kind = TCPOPT_KIND_TIMESTAMP, .field = $2 };
|
|
+ $$ = kind_field;
|
|
+ }
|
|
+ | tcp_hdr_option_type LENGTH
|
|
+ {
|
|
+ struct tcp_kind_field kind_field = { .kind = $1, .field = TCPOPT_COMMON_LENGTH };
|
|
+ $$ = kind_field;
|
|
+ }
|
|
+ | tcp_hdr_option_type KIND
|
|
+ { struct tcp_kind_field kind_field = { .kind = $1, .field = TCPOPT_COMMON_KIND };
|
|
+ $$ = kind_field;
|
|
+ }
|
|
+ ;
|
|
+
|
|
+tcp_hdr_option_sack : SACK { $$ = TCPOPT_KIND_SACK; }
|
|
| SACK0 { $$ = TCPOPT_KIND_SACK; }
|
|
| SACK1 { $$ = TCPOPT_KIND_SACK1; }
|
|
| SACK2 { $$ = TCPOPT_KIND_SACK2; }
|
|
| SACK3 { $$ = TCPOPT_KIND_SACK3; }
|
|
- | ECHO { $$ = TCPOPT_KIND_ECHO; }
|
|
- | TIMESTAMP { $$ = TCPOPT_KIND_TIMESTAMP; }
|
|
- | NUM {
|
|
+ ;
|
|
+
|
|
+tcp_hdr_option_type : ECHO { $$ = TCPOPT_KIND_ECHO; }
|
|
+ | EOL { $$ = TCPOPT_KIND_EOL; }
|
|
+ | MSS { $$ = TCPOPT_KIND_MAXSEG; }
|
|
+ | NOP { $$ = TCPOPT_KIND_NOP; }
|
|
+ | SACK_PERM { $$ = TCPOPT_KIND_SACK_PERMITTED; }
|
|
+ | TIMESTAMP { $$ = TCPOPT_KIND_TIMESTAMP; }
|
|
+ | WINDOW { $$ = TCPOPT_KIND_WINDOW; }
|
|
+ | tcp_hdr_option_sack { $$ = $1; }
|
|
+ | NUM {
|
|
if ($1 > 255) {
|
|
erec_queue(error(&@1, "value too large"), state->msgs);
|
|
YYERROR;
|
|
@@ -5526,16 +5563,20 @@ tcp_hdr_option_type : EOL { $$ = TCPOPT_KIND_EOL; }
|
|
}
|
|
;
|
|
|
|
-tcp_hdr_option_field : KIND { $$ = TCPOPT_COMMON_KIND; }
|
|
- | LENGTH { $$ = TCPOPT_COMMON_LENGTH; }
|
|
- | SIZE { $$ = TCPOPT_MAXSEG_SIZE; }
|
|
- | COUNT { $$ = TCPOPT_WINDOW_COUNT; }
|
|
- | LEFT { $$ = TCPOPT_SACK_LEFT; }
|
|
+tcpopt_field_sack : LEFT { $$ = TCPOPT_SACK_LEFT; }
|
|
| RIGHT { $$ = TCPOPT_SACK_RIGHT; }
|
|
- | TSVAL { $$ = TCPOPT_TS_TSVAL; }
|
|
+ ;
|
|
+
|
|
+tcpopt_field_window : COUNT { $$ = TCPOPT_WINDOW_COUNT; }
|
|
+ ;
|
|
+
|
|
+tcpopt_field_tsopt : TSVAL { $$ = TCPOPT_TS_TSVAL; }
|
|
| TSECR { $$ = TCPOPT_TS_TSECR; }
|
|
;
|
|
|
|
+tcpopt_field_maxseg : SIZE { $$ = TCPOPT_MAXSEG_SIZE; }
|
|
+ ;
|
|
+
|
|
dccp_hdr_expr : DCCP dccp_hdr_field
|
|
{
|
|
$$ = payload_expr_alloc(&@$, &proto_dccp, $2);
|
|
--
|
|
cgit v1.2.3
|