186 lines
5.9 KiB
Diff
186 lines
5.9 KiB
Diff
|
From 64b101f4a124f39b494dc5906159a8890568d1f9 Mon Sep 17 00:00:00 2001
|
||
|
From: Phil Sutter <phil@nwl.cc>
|
||
|
Date: Fri, 24 Aug 2018 13:26:57 +0200
|
||
|
Subject: [PATCH] parser_bison: Fix for ECN keyword in LHS of relational
|
||
|
|
||
|
Of all possible TCP flags, 'ecn' is special since it is recognized by
|
||
|
lex as a keyword (there is a a field in IPv4 and IPv6 headers with the
|
||
|
same name). Therefore it is listed in keyword_expr, but that was
|
||
|
sufficient for RHS only. The following statement reproduces the issue:
|
||
|
|
||
|
| tcp flags & (syn | ecn) == (syn | ecn)
|
||
|
|
||
|
The solution is to limit binop expressions to accept an RHS expression
|
||
|
on RHS ("real" LHS expressions don't make much sense there anyway),
|
||
|
which then allows keyword_expr to occur there. In order to maintain the
|
||
|
recursive behaviour if braces are present, allow primary_rhs_expr to
|
||
|
consist of a basic_rhs_expr enclosed in braces. This in turn requires
|
||
|
for braced RHS part in relational_expr to be dropped, otherwise bison
|
||
|
complains about shift/reduce conflict.
|
||
|
|
||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||
|
(cherry picked from commit 14a9968a56f8b35138bab172aa7ce796f5d98e03)
|
||
|
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||
|
---
|
||
|
src/parser_bison.y | 15 ++++++---------
|
||
|
tests/py/inet/tcp.t | 1 +
|
||
|
tests/py/inet/tcp.t.json | 23 +++++++++++++++++++++++
|
||
|
tests/py/inet/tcp.t.json.output | 16 ++++++++++++++++
|
||
|
tests/py/inet/tcp.t.payload | 8 ++++++++
|
||
|
5 files changed, 54 insertions(+), 9 deletions(-)
|
||
|
|
||
|
diff --git a/src/parser_bison.y b/src/parser_bison.y
|
||
|
index d75cd50fa29b9..a6b6fc1745a72 100644
|
||
|
--- a/src/parser_bison.y
|
||
|
+++ b/src/parser_bison.y
|
||
|
@@ -2948,32 +2948,32 @@ fib_tuple : fib_flag DOT fib_tuple
|
||
|
;
|
||
|
|
||
|
shift_expr : primary_expr
|
||
|
- | shift_expr LSHIFT primary_expr
|
||
|
+ | shift_expr LSHIFT primary_rhs_expr
|
||
|
{
|
||
|
$$ = binop_expr_alloc(&@$, OP_LSHIFT, $1, $3);
|
||
|
}
|
||
|
- | shift_expr RSHIFT primary_expr
|
||
|
+ | shift_expr RSHIFT primary_rhs_expr
|
||
|
{
|
||
|
$$ = binop_expr_alloc(&@$, OP_RSHIFT, $1, $3);
|
||
|
}
|
||
|
;
|
||
|
|
||
|
and_expr : shift_expr
|
||
|
- | and_expr AMPERSAND shift_expr
|
||
|
+ | and_expr AMPERSAND shift_rhs_expr
|
||
|
{
|
||
|
$$ = binop_expr_alloc(&@$, OP_AND, $1, $3);
|
||
|
}
|
||
|
;
|
||
|
|
||
|
exclusive_or_expr : and_expr
|
||
|
- | exclusive_or_expr CARET and_expr
|
||
|
+ | exclusive_or_expr CARET and_rhs_expr
|
||
|
{
|
||
|
$$ = binop_expr_alloc(&@$, OP_XOR, $1, $3);
|
||
|
}
|
||
|
;
|
||
|
|
||
|
inclusive_or_expr : exclusive_or_expr
|
||
|
- | inclusive_or_expr '|' exclusive_or_expr
|
||
|
+ | inclusive_or_expr '|' exclusive_or_rhs_expr
|
||
|
{
|
||
|
$$ = binop_expr_alloc(&@$, OP_OR, $1, $3);
|
||
|
}
|
||
|
@@ -3252,10 +3252,6 @@ relational_expr : expr /* implicit */ rhs_expr
|
||
|
{
|
||
|
$$ = relational_expr_alloc(&@2, $2, $1, $3);
|
||
|
}
|
||
|
- | expr relational_op '(' rhs_expr ')'
|
||
|
- {
|
||
|
- $$ = relational_expr_alloc(&@2, $2, $1, $4);
|
||
|
- }
|
||
|
;
|
||
|
|
||
|
list_rhs_expr : basic_rhs_expr COMMA basic_rhs_expr
|
||
|
@@ -3439,6 +3435,7 @@ primary_rhs_expr : symbol_expr { $$ = $1; }
|
||
|
BYTEORDER_HOST_ENDIAN,
|
||
|
sizeof(data) * BITS_PER_BYTE, &data);
|
||
|
}
|
||
|
+ | '(' basic_rhs_expr ')' { $$ = $2; }
|
||
|
;
|
||
|
|
||
|
relational_op : EQ { $$ = OP_EQ; }
|
||
|
diff --git a/tests/py/inet/tcp.t b/tests/py/inet/tcp.t
|
||
|
index d66ba8438a32f..f96e3634f41ed 100644
|
||
|
--- a/tests/py/inet/tcp.t
|
||
|
+++ b/tests/py/inet/tcp.t
|
||
|
@@ -78,6 +78,7 @@ tcp flags cwr;ok
|
||
|
tcp flags != cwr;ok
|
||
|
tcp flags == syn;ok
|
||
|
tcp flags & (syn|fin) == (syn|fin);ok;tcp flags & (fin | syn) == fin | syn
|
||
|
+tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr;ok;tcp flags == 0xff
|
||
|
|
||
|
tcp window 22222;ok
|
||
|
tcp window 22;ok
|
||
|
diff --git a/tests/py/inet/tcp.t.json b/tests/py/inet/tcp.t.json
|
||
|
index f5df72aa252a6..9ae51018e93ee 100644
|
||
|
--- a/tests/py/inet/tcp.t.json
|
||
|
+++ b/tests/py/inet/tcp.t.json
|
||
|
@@ -1068,6 +1068,29 @@
|
||
|
}
|
||
|
]
|
||
|
|
||
|
+# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr
|
||
|
+[
|
||
|
+ {
|
||
|
+ "match": {
|
||
|
+ "left": {
|
||
|
+ "&": [
|
||
|
+ {
|
||
|
+ "payload": {
|
||
|
+ "field": "flags",
|
||
|
+ "protocol": "tcp"
|
||
|
+ }
|
||
|
+ },
|
||
|
+ {
|
||
|
+ "|": [ "fin", { "|": [ "syn", { "|": [ "rst", { "|": [ "psh", { "|": [ "ack", { "|": [ "urg", { "|": [ "ecn", "cwr" ] } ] } ] } ] } ] } ] } ]
|
||
|
+ }
|
||
|
+ ]
|
||
|
+ },
|
||
|
+ "op": "==",
|
||
|
+ "right": { "|": [ "fin", { "|": [ "syn", { "|": [ "rst", { "|": [ "psh", { "|": [ "ack", { "|": [ "urg", { "|": [ "ecn", "cwr" ] } ] } ] } ] } ] } ] } ] }
|
||
|
+ }
|
||
|
+ }
|
||
|
+]
|
||
|
+
|
||
|
# tcp window 22222
|
||
|
[
|
||
|
{
|
||
|
diff --git a/tests/py/inet/tcp.t.json.output b/tests/py/inet/tcp.t.json.output
|
||
|
index d099d6febb122..ff58756cf596d 100644
|
||
|
--- a/tests/py/inet/tcp.t.json.output
|
||
|
+++ b/tests/py/inet/tcp.t.json.output
|
||
|
@@ -132,3 +132,19 @@
|
||
|
}
|
||
|
]
|
||
|
|
||
|
+# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr
|
||
|
+[
|
||
|
+ {
|
||
|
+ "match": {
|
||
|
+ "left": {
|
||
|
+ "payload": {
|
||
|
+ "field": "flags",
|
||
|
+ "protocol": "tcp"
|
||
|
+ }
|
||
|
+ },
|
||
|
+ "op": "==",
|
||
|
+ "right": 255
|
||
|
+ }
|
||
|
+ }
|
||
|
+]
|
||
|
+
|
||
|
diff --git a/tests/py/inet/tcp.t.payload b/tests/py/inet/tcp.t.payload
|
||
|
index 09538aed746c9..2390a24ead15c 100644
|
||
|
--- a/tests/py/inet/tcp.t.payload
|
||
|
+++ b/tests/py/inet/tcp.t.payload
|
||
|
@@ -436,6 +436,14 @@ inet test-inet input
|
||
|
[ bitwise reg 1 = (reg=1 & 0x00000003 ) ^ 0x00000000 ]
|
||
|
[ cmp eq reg 1 0x00000003 ]
|
||
|
|
||
|
+# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr
|
||
|
+inet test-inet input
|
||
|
+ [ meta load l4proto => reg 1 ]
|
||
|
+ [ cmp eq reg 1 0x00000006 ]
|
||
|
+ [ payload load 1b @ transport header + 13 => reg 1 ]
|
||
|
+ [ bitwise reg 1 = (reg=1 & 0x000000ff ) ^ 0x00000000 ]
|
||
|
+ [ cmp eq reg 1 0x000000ff ]
|
||
|
+
|
||
|
# tcp window 22222
|
||
|
inet test-inet input
|
||
|
[ meta load l4proto => reg 1 ]
|
||
|
--
|
||
|
2.19.0
|
||
|
|