All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH nft 0/8] mptcp subtype option match support
@ 2021-11-19 15:28 Florian Westphal
  2021-11-19 15:28 ` [PATCH nft 1/8] tcpopt: remove KIND keyword Florian Westphal
                   ` (8 more replies)
  0 siblings, 9 replies; 14+ messages in thread
From: Florian Westphal @ 2021-11-19 15:28 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

This series adds 'tcp option mptcp subtype' matching to nft.

Because the subtype is only 4 bits in size the exthdr
delinearization needs a fixup to remove the binop added by the
evaluation step.

One remaining usablility problem is the lack of mnemonics for the
subtype, i.e. something like:

static const struct symbol_table mptcp_subtype_tbl = {
       .base           = BASE_DECIMAL,
       .symbols        = {
               SYMBOL("mp-capable",    0),
               SYMBOL("mp-join",       1),
               SYMBOL("dss",           2),
               SYMBOL("add-addr",      3),
               SYMBOL("remove-addr",   4),
               SYMBOL("mp-prio",       5),
               SYMBOL("mp-fail",       6),
               SYMBOL("mp-fastclose",  7),
               SYMBOL("mp-tcprst",     8),
               SYMBOL_LIST_END
       },

... but this would need addition of yet another data type.

Use of implicit/context-dependent symbol table would
be preferrable, I will look into this next.

Florian Westphal (8):
  tcpopt: remove KIND keyword
  scanner: add tcp flex scope
  parser: split tcp option rules
  tcpopt: add md5sig, fastopen and mptcp options
  tests: py: add test cases for md5sig, fastopen and mptcp mnemonics
  mptcp: add subtype matching
  exthdr: fix tcpopt_find_template to use length after mask adjustment
  tests: py: add tcp subtype match test cases

 doc/payload-expression.txt    |  29 ++++---
 include/parser.h              |   1 +
 include/tcpopt.h              |  13 ++-
 src/exthdr.c                  |  46 +++++-----
 src/parser_bison.y            | 108 +++++++++++++++++------
 src/scanner.l                 |  22 +++--
 src/tcpopt.c                  |  38 +++++++-
 tests/py/any/tcpopt.t         |  21 +++--
 tests/py/any/tcpopt.t.json    | 159 +++++++++++++++++++++++++---------
 tests/py/any/tcpopt.t.payload |  64 ++++++++++----
 10 files changed, 360 insertions(+), 141 deletions(-)

-- 
2.32.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH nft 1/8] tcpopt: remove KIND keyword
  2021-11-19 15:28 [PATCH nft 0/8] mptcp subtype option match support Florian Westphal
@ 2021-11-19 15:28 ` Florian Westphal
  2021-11-19 15:28 ` [PATCH nft 2/8] scanner: add tcp flex scope Florian Westphal
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Florian Westphal @ 2021-11-19 15:28 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

tcp option <foo> kind ... never makes any sense, as "tcp option <foo>"
already tells the kernel to look for the foo <kind>.

"tcp option sack kind 5" matches if the sack option is present; its a
more complicated form of the simpler "tcp option sack exists".

"tcp option sack kind 1" (or any other value than 5) will never match.

So remove this.

Test cases are converted to "exists".

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 doc/payload-expression.txt    | 29 +++++++++-------
 src/parser_bison.y            |  4 +--
 src/scanner.l                 |  1 -
 tests/py/any/tcpopt.t         | 13 ++++----
 tests/py/any/tcpopt.t.json    | 63 +++++++++++------------------------
 tests/py/any/tcpopt.t.payload | 29 +++++++---------
 6 files changed, 56 insertions(+), 83 deletions(-)

diff --git a/doc/payload-expression.txt b/doc/payload-expression.txt
index 930a18074a6c..106ff74ce57e 100644
--- a/doc/payload-expression.txt
+++ b/doc/payload-expression.txt
@@ -614,37 +614,37 @@ Segment Routing Header
 |Keyword| Description | TCP option fields
 |eol|
 End if option list|
-kind
+-
 |nop|
 1 Byte TCP Nop padding option |
-kind
+-
 |maxseg|
 TCP Maximum Segment Size|
-kind, length, size
+length, size
 |window|
 TCP Window Scaling |
-kind, length, count
+length, count
 |sack-perm |
 TCP SACK permitted |
-kind, length
+length
 |sack|
 TCP Selective Acknowledgement (alias of block 0) |
-kind, length, left, right
+length, left, right
 |sack0|
 TCP Selective Acknowledgement (block 0) |
-kind, length, left, right
+length, left, right
 |sack1|
 TCP Selective Acknowledgement (block 1) |
-kind, length, left, right
+length, left, right
 |sack2|
 TCP Selective Acknowledgement (block 2) |
-kind, length, left, right
+length, left, right
 |sack3|
 TCP Selective Acknowledgement (block 3) |
-kind, length, left, right
+length, left, right
 |timestamp|
 TCP Timestamps |
-kind, length, tsval, tsecr
+length, tsval, tsecr
 |============================
 
 TCP option matching also supports raw expression syntax to access arbitrary options:
@@ -673,7 +673,12 @@ type, length, ptr, addr
 
 .finding TCP options
 --------------------
-filter input tcp option sack-perm kind 1 counter
+filter input tcp option sack-perm exists counter
+--------------------
+
+.matching TCP options
+--------------------
+filter input tcp option maxseg size lt 536
 --------------------
 
 .matching IPv6 exthdr
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 81d75ecb2fe8..bc5ec2e667b8 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -412,7 +412,6 @@ int nft_lex(void *, void *, void *);
 %token SACK3			"sack3"
 %token SACK_PERM		"sack-permitted"
 %token TIMESTAMP		"timestamp"
-%token KIND			"kind"
 %token COUNT			"count"
 %token LEFT			"left"
 %token RIGHT			"right"
@@ -5526,8 +5525,7 @@ tcp_hdr_option_type	:	EOL		{ $$ = TCPOPT_KIND_EOL; }
 			}
 			;
 
-tcp_hdr_option_field	:	KIND		{ $$ = TCPOPT_COMMON_KIND; }
-			|	LENGTH		{ $$ = TCPOPT_COMMON_LENGTH; }
+tcp_hdr_option_field	:	LENGTH		{ $$ = TCPOPT_COMMON_LENGTH; }
 			|	SIZE		{ $$ = TCPOPT_MAXSEG_SIZE; }
 			|	COUNT		{ $$ = TCPOPT_WINDOW_COUNT; }
 			|	LEFT		{ $$ = TCPOPT_SACK_LEFT; }
diff --git a/src/scanner.l b/src/scanner.l
index 6cc7778dd85e..455ef99fea8f 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -481,7 +481,6 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "timestamp"		{ return TIMESTAMP; }
 "time"			{ return TIME; }
 
-"kind"			{ return KIND; }
 "count"			{ return COUNT; }
 "left"			{ return LEFT; }
 "right"			{ return RIGHT; }
diff --git a/tests/py/any/tcpopt.t b/tests/py/any/tcpopt.t
index bcc64eac2e21..d3586eae8399 100644
--- a/tests/py/any/tcpopt.t
+++ b/tests/py/any/tcpopt.t
@@ -4,17 +4,16 @@
 *ip6;test-ip6;input
 *inet;test-inet;input
 
-tcp option eol kind 1;ok
-tcp option nop kind 1;ok
-tcp option maxseg kind 1;ok
+tcp option eol exists;ok
+tcp option nop exists;ok
+tcp option maxseg exists;ok
 tcp option maxseg length 1;ok
 tcp option maxseg size 1;ok
-tcp option window kind 1;ok
 tcp option window length 1;ok
 tcp option window count 1;ok
-tcp option sack-perm kind 1;ok
+tcp option sack-perm exists;ok
 tcp option sack-perm length 1;ok
-tcp option sack kind 1;ok
+tcp option sack exists;ok
 tcp option sack length 1;ok
 tcp option sack left 1;ok
 tcp option sack0 left 1;ok;tcp option sack left 1
@@ -26,7 +25,7 @@ tcp option sack0 right 1;ok;tcp option sack right 1
 tcp option sack1 right 1;ok
 tcp option sack2 right 1;ok
 tcp option sack3 right 1;ok
-tcp option timestamp kind 1;ok
+tcp option timestamp exists;ok
 tcp option timestamp length 1;ok
 tcp option timestamp tsval 1;ok
 tcp option timestamp tsecr 1;ok
diff --git a/tests/py/any/tcpopt.t.json b/tests/py/any/tcpopt.t.json
index a45b4c8b5c58..5468accb16b4 100644
--- a/tests/py/any/tcpopt.t.json
+++ b/tests/py/any/tcpopt.t.json
@@ -1,47 +1,44 @@
-# tcp option eol kind 1
+# tcp option eol exists
 [
     {
         "match": {
             "left": {
                 "tcp option": {
-                    "field": "kind",
                     "name": "eol"
                 }
             },
             "op": "==",
-            "right": 1
+            "right": true
         }
     }
 ]
 
-# tcp option nop kind 1
+# tcp option nop exists
 [
     {
         "match": {
             "left": {
                 "tcp option": {
-                    "field": "kind",
                     "name": "nop"
                 }
             },
             "op": "==",
-            "right": 1
+            "right": true
         }
     }
 ]
 
-# tcp option maxseg kind 1
+# tcp option maxseg exists
 [
     {
         "match": {
             "left": {
                 "tcp option": {
-                    "field": "kind",
                     "name": "maxseg"
                 }
             },
             "op": "==",
-            "right": 1
+            "right": true
         }
     }
 ]
@@ -78,22 +75,6 @@
     }
 ]
 
-# tcp option window kind 1
-[
-    {
-        "match": {
-            "left": {
-                "tcp option": {
-                    "field": "kind",
-                    "name": "window"
-                }
-            },
-            "op": "==",
-            "right": 1
-        }
-    }
-]
-
 # tcp option window length 1
 [
     {
@@ -126,18 +107,17 @@
     }
 ]
 
-# tcp option sack-perm kind 1
+# tcp option sack-perm exists
 [
     {
         "match": {
             "left": {
                 "tcp option": {
-                    "field": "kind",
                     "name": "sack-perm"
                 }
             },
             "op": "==",
-            "right": 1
+            "right": true
         }
     }
 ]
@@ -158,18 +138,17 @@
     }
 ]
 
-# tcp option sack kind 1
+# tcp option sack exists
 [
     {
         "match": {
             "left": {
                 "tcp option": {
-                    "field": "kind",
                     "name": "sack"
                 }
             },
             "op": "==",
-            "right": 1
+            "right": true
         }
     }
 ]
@@ -213,7 +192,7 @@
             "left": {
                 "tcp option": {
                     "field": "left",
-                    "name": "sack0"
+                    "name": "sack"
                 }
             },
             "op": "==",
@@ -293,7 +272,7 @@
             "left": {
                 "tcp option": {
                     "field": "right",
-                    "name": "sack0"
+                    "name": "sack"
                 }
             },
             "op": "==",
@@ -350,18 +329,17 @@
     }
 ]
 
-# tcp option timestamp kind 1
+# tcp option timestamp exists
 [
     {
         "match": {
             "left": {
                 "tcp option": {
-                    "field": "kind",
                     "name": "timestamp"
                 }
             },
             "op": "==",
-            "right": 1
+            "right": true
         }
     }
 ]
@@ -414,36 +392,36 @@
     }
 ]
 
-# tcp option 6 exists
+# tcp option 255 missing
 [
     {
         "match": {
             "left": {
                 "tcp option": {
-                    "base": 6,
+                    "base": 255,
                     "len": 8,
                     "offset": 0
                 }
             },
             "op": "==",
-            "right": true
+            "right": false
         }
     }
 ]
 
-# tcp option 255 missing
+# tcp option 6 exists
 [
     {
         "match": {
             "left": {
                 "tcp option": {
-                    "base": 255,
+                    "base": 6,
                     "len": 8,
                     "offset": 0
                 }
             },
             "op": "==",
-            "right": false
+            "right": true
         }
     }
 ]
@@ -509,4 +487,3 @@
         }
     }
 ]
-
diff --git a/tests/py/any/tcpopt.t.payload b/tests/py/any/tcpopt.t.payload
index 51f3a7527668..d88bcd433a10 100644
--- a/tests/py/any/tcpopt.t.payload
+++ b/tests/py/any/tcpopt.t.payload
@@ -1,16 +1,16 @@
-# tcp option eol kind 1
+# tcp option eol exists
 inet 
-  [ exthdr load tcpopt 1b @ 0 + 0 => reg 1 ]
+  [ exthdr load tcpopt 1b @ 0 + 0 present => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
-# tcp option nop kind 1
+# tcp option nop exists
 inet 
-  [ exthdr load tcpopt 1b @ 1 + 0 => reg 1 ]
+  [ exthdr load tcpopt 1b @ 1 + 0 present => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
-# tcp option maxseg kind 1
+# tcp option maxseg exists
 inet 
-  [ exthdr load tcpopt 1b @ 2 + 0 => reg 1 ]
+  [ exthdr load tcpopt 1b @ 2 + 0 present => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
 # tcp option maxseg length 1
@@ -23,11 +23,6 @@ inet
   [ exthdr load tcpopt 2b @ 2 + 2 => reg 1 ]
   [ cmp eq reg 1 0x00000100 ]
 
-# tcp option window kind 1
-inet 
-  [ exthdr load tcpopt 1b @ 3 + 0 => reg 1 ]
-  [ cmp eq reg 1 0x00000001 ]
-
 # tcp option window length 1
 inet 
   [ exthdr load tcpopt 1b @ 3 + 1 => reg 1 ]
@@ -38,9 +33,9 @@ inet
   [ exthdr load tcpopt 1b @ 3 + 2 => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
-# tcp option sack-perm kind 1
+# tcp option sack-perm exists
 inet 
-  [ exthdr load tcpopt 1b @ 4 + 0 => reg 1 ]
+  [ exthdr load tcpopt 1b @ 4 + 0 present => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
 # tcp option sack-perm length 1
@@ -48,9 +43,9 @@ inet
   [ exthdr load tcpopt 1b @ 4 + 1 => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
-# tcp option sack kind 1
+# tcp option sack exists
 inet 
-  [ exthdr load tcpopt 1b @ 5 + 0 => reg 1 ]
+  [ exthdr load tcpopt 1b @ 5 + 0 present => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
 # tcp option sack length 1
@@ -108,9 +103,9 @@ inet
   [ exthdr load tcpopt 4b @ 5 + 30 => reg 1 ]
   [ cmp eq reg 1 0x01000000 ]
 
-# tcp option timestamp kind 1
+# tcp option timestamp exists
 inet 
-  [ exthdr load tcpopt 1b @ 8 + 0 => reg 1 ]
+  [ exthdr load tcpopt 1b @ 8 + 0 present => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
 # tcp option timestamp length 1
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH nft 2/8] scanner: add tcp flex scope
  2021-11-19 15:28 [PATCH nft 0/8] mptcp subtype option match support Florian Westphal
  2021-11-19 15:28 ` [PATCH nft 1/8] tcpopt: remove KIND keyword Florian Westphal
@ 2021-11-19 15:28 ` Florian Westphal
  2021-11-19 15:28 ` [PATCH nft 3/8] parser: split tcp option rules Florian Westphal
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Florian Westphal @ 2021-11-19 15:28 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

This moves tcp options not used anywhere else (e.g. in synproxy) to a
distinct scope.  This will also allow to avoid exposing new option
keywords in the ruleset context.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/parser.h   |  1 +
 src/parser_bison.y | 11 ++++++-----
 src/scanner.l      | 17 +++++++++++------
 3 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/include/parser.h b/include/parser.h
index e8635b4c0feb..cb7d12a36edb 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -40,6 +40,7 @@ enum startcond_type {
 	PARSER_SC_QUOTA,
 	PARSER_SC_SCTP,
 	PARSER_SC_SECMARK,
+	PARSER_SC_TCP,
 	PARSER_SC_VLAN,
 	PARSER_SC_CMD_LIST,
 	PARSER_SC_EXPR_FIB,
diff --git a/src/parser_bison.y b/src/parser_bison.y
index bc5ec2e667b8..2606098534e6 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -929,6 +929,7 @@ close_scope_list	: { scanner_pop_start_cond(nft->scanner, PARSER_SC_CMD_LIST); }
 close_scope_limit	: { scanner_pop_start_cond(nft->scanner, PARSER_SC_LIMIT); };
 close_scope_numgen	: { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_NUMGEN); };
 close_scope_quota	: { scanner_pop_start_cond(nft->scanner, PARSER_SC_QUOTA); };
+close_scope_tcp		: { scanner_pop_start_cond(nft->scanner, PARSER_SC_TCP); }
 close_scope_queue	: { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_QUEUE); };
 close_scope_rt		: { scanner_pop_start_cond(nft->scanner, PARSER_SC_EXPR_RT); };
 close_scope_sctp	: { scanner_pop_start_cond(nft->scanner, PARSER_SC_SCTP); };
@@ -3109,7 +3110,7 @@ level_type		:	string
 			}
 			;
 
-log_flags		:	TCP	log_flags_tcp
+log_flags		:	TCP	log_flags_tcp	close_scope_tcp
 			{
 				$$ = $2;
 			}
@@ -3360,7 +3361,7 @@ reject_opts		:       /* empty */
 				$<stmt>0->reject.expr = $3;
 				datatype_set($<stmt>0->reject.expr, &icmpx_code_type);
 			}
-			|	WITH	TCP	RESET
+			|	WITH	TCP	close_scope_tcp RESET
 			{
 				$<stmt>0->reject.type = NFT_REJECT_TCP_RST;
 			}
@@ -4460,7 +4461,7 @@ ct_cmd_type		:	HELPERS		{ $$ = CMD_OBJ_CT_HELPERS; }
 			|	EXPECTATION	{ $$ = CMD_OBJ_CT_EXPECT; }
 			;
 
-ct_l4protoname		:	TCP	{ $$ = IPPROTO_TCP; }
+ct_l4protoname		:	TCP	close_scope_tcp	{ $$ = IPPROTO_TCP; }
 			|	UDP	{ $$ = IPPROTO_UDP; }
 			;
 
@@ -4734,7 +4735,7 @@ primary_rhs_expr	:	symbol_expr		{ $$ = $1; }
 			|	integer_expr		{ $$ = $1; }
 			|	boolean_expr		{ $$ = $1; }
 			|	keyword_expr		{ $$ = $1; }
-			|	TCP
+			|	TCP	close_scope_tcp
 			{
 				uint8_t data = IPPROTO_TCP;
 				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
@@ -5241,7 +5242,7 @@ payload_expr		:	payload_raw_expr
 			|	comp_hdr_expr
 			|	udp_hdr_expr
 			|	udplite_hdr_expr
-			|	tcp_hdr_expr
+			|	tcp_hdr_expr	close_scope_tcp
 			|	dccp_hdr_expr
 			|	sctp_hdr_expr
 			|	th_hdr_expr
diff --git a/src/scanner.l b/src/scanner.l
index 455ef99fea8f..09fcbd094aa6 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -206,6 +206,7 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 %s SCANSTATE_QUOTA
 %s SCANSTATE_SCTP
 %s SCANSTATE_SECMARK
+%s SCANSTATE_TCP
 %s SCANSTATE_VLAN
 %s SCANSTATE_CMD_LIST
 %s SCANSTATE_EXPR_FIB
@@ -465,10 +466,9 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 	"value"			{ return VALUE; }
 }
 
+<SCANSTATE_TCP>{
 "echo"			{ return ECHO; }
 "eol"			{ return EOL; }
-"maxseg"		{ return MSS; }
-"mss"			{ return MSS; }
 "nop"			{ return NOP; }
 "noop"			{ return NOP; }
 "sack"			{ return SACK; }
@@ -476,9 +476,6 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "sack1"			{ return SACK1; }
 "sack2"			{ return SACK2; }
 "sack3"			{ return SACK3; }
-"sack-permitted"	{ return SACK_PERM; }
-"sack-perm"		{ return SACK_PERM; }
-"timestamp"		{ return TIMESTAMP; }
 "time"			{ return TIME; }
 
 "count"			{ return COUNT; }
@@ -486,6 +483,12 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "right"			{ return RIGHT; }
 "tsval"			{ return TSVAL; }
 "tsecr"			{ return TSECR; }
+}
+"maxseg"		{ return MSS; }
+"mss"			{ return MSS; }
+"sack-permitted"	{ return SACK_PERM; }
+"sack-perm"		{ return SACK_PERM; }
+"timestamp"		{ return TIMESTAMP; }
 
 "icmp"			{ return ICMP; }
 "code"			{ return CODE; }
@@ -524,7 +527,7 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "dport"			{ return DPORT; }
 "port"			{ return PORT; }
 
-"tcp"			{ return TCP; }
+"tcp"			{ scanner_push_start_cond(yyscanner, SCANSTATE_TCP); return TCP; }
 "ackseq"		{ return ACKSEQ; }
 "doff"			{ return DOFF; }
 "window"		{ return WINDOW; }
@@ -560,6 +563,7 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 	"asconf"		{ return ASCONF; }
 
 	"tsn"			{ return TSN; }
+	"sack"			{ return SACK; }
 	"stream"		{ return STREAM; }
 	"ssn"			{ return SSN; }
 	"ppid"			{ return PPID; }
@@ -641,6 +645,7 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 	"label"			{ return LABEL; }
 	"state"			{ return STATE; }
 	"status"		{ return STATUS; }
+	"count"			{ return COUNT; }
 }
 
 "numgen"		{ scanner_push_start_cond(yyscanner, SCANSTATE_EXPR_NUMGEN); return NUMGEN; }
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH nft 3/8] parser: split tcp option rules
  2021-11-19 15:28 [PATCH nft 0/8] mptcp subtype option match support Florian Westphal
  2021-11-19 15:28 ` [PATCH nft 1/8] tcpopt: remove KIND keyword Florian Westphal
  2021-11-19 15:28 ` [PATCH nft 2/8] scanner: add tcp flex scope Florian Westphal
@ 2021-11-19 15:28 ` Florian Westphal
  2021-11-19 15:28 ` [PATCH nft 4/8] tcpopt: add md5sig, fastopen and mptcp options Florian Westphal
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Florian Westphal @ 2021-11-19 15:28 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

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)
---
 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 2606098534e6..fca791326094 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -187,6 +187,10 @@ int nft_lex(void *, void *, void *);
 	struct position_spec	position_spec;
 	struct prio_spec	prio_spec;
 	struct limit_rate	limit_rate;
+	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,49 @@ 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_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,15 +5563,20 @@ tcp_hdr_option_type	:	EOL		{ $$ = TCPOPT_KIND_EOL; }
 			}
 			;
 
-tcp_hdr_option_field	:	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);
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH nft 4/8] tcpopt: add md5sig, fastopen and mptcp options
  2021-11-19 15:28 [PATCH nft 0/8] mptcp subtype option match support Florian Westphal
                   ` (2 preceding siblings ...)
  2021-11-19 15:28 ` [PATCH nft 3/8] parser: split tcp option rules Florian Westphal
@ 2021-11-19 15:28 ` Florian Westphal
  2021-11-19 15:28 ` [PATCH nft 5/8] tests: py: add test cases for md5sig, fastopen and mptcp mnemonics Florian Westphal
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Florian Westphal @ 2021-11-19 15:28 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

Allow to use "fastopen", "md5sig" and "mptcp" mnemonics rather than the
raw option numbers.

These new keywords are only recognized while scanner is in tcp state.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/tcpopt.h   |  8 ++++++++
 src/parser_bison.y | 10 ++++++++--
 src/scanner.l      |  3 +++
 src/tcpopt.c       | 30 ++++++++++++++++++++++++++++++
 4 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/include/tcpopt.h b/include/tcpopt.h
index 667c8a7725d8..22df69dc5b93 100644
--- a/include/tcpopt.h
+++ b/include/tcpopt.h
@@ -25,6 +25,9 @@ enum tcpopt_kind {
 	TCPOPT_KIND_SACK = 5,
 	TCPOPT_KIND_TIMESTAMP = 8,
 	TCPOPT_KIND_ECHO = 8,
+	TCPOPT_KIND_MD5SIG = 19,
+	TCPOPT_KIND_MPTCP = 30,
+	TCPOPT_KIND_FASTOPEN = 34,
 	__TCPOPT_KIND_MAX,
 
 	/* extra oob info, internal to nft */
@@ -71,6 +74,11 @@ enum tcpopt_hdr_field_sack {
 	TCPOPT_SACK_RIGHT3,
 };
 
+enum tcpopt_hdr_mptcp_common {
+	TCPOPT_MPTCP_KIND,
+	TCPOPT_MPTCP_LENGTH,
+};
+
 extern const struct exthdr_desc *tcpopt_protocols[__TCPOPT_KIND_MAX];
 
 #endif /* NFTABLES_TCPOPT_H */
diff --git a/src/parser_bison.y b/src/parser_bison.y
index fca791326094..a6a591b7e00d 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -408,6 +408,7 @@ int nft_lex(void *, void *, void *);
 %token OPTION			"option"
 %token ECHO			"echo"
 %token EOL			"eol"
+%token MPTCP			"mptcp"
 %token NOP			"nop"
 %token SACK			"sack"
 %token SACK0			"sack0"
@@ -415,6 +416,8 @@ int nft_lex(void *, void *, void *);
 %token SACK2			"sack2"
 %token SACK3			"sack3"
 %token SACK_PERM		"sack-permitted"
+%token FASTOPEN			"fastopen"
+%token MD5SIG			"md5sig"
 %token TIMESTAMP		"timestamp"
 %token COUNT			"count"
 %token LEFT			"left"
@@ -5548,11 +5551,14 @@ tcp_hdr_option_sack	:	SACK		{ $$ = TCPOPT_KIND_SACK; }
 
 tcp_hdr_option_type	:	ECHO			{ $$ = TCPOPT_KIND_ECHO; }
 			|	EOL			{ $$ = TCPOPT_KIND_EOL; }
+			|	FASTOPEN		{ $$ = TCPOPT_KIND_FASTOPEN; }
+			|	MD5SIG			{ $$ = TCPOPT_KIND_MD5SIG; }
+			|	MPTCP			{ $$ = TCPOPT_KIND_MPTCP; }
 			|	MSS			{ $$ = TCPOPT_KIND_MAXSEG; }
 			|	NOP			{ $$ = TCPOPT_KIND_NOP; }
 			|	SACK_PERM		{ $$ = TCPOPT_KIND_SACK_PERMITTED; }
-			|	TIMESTAMP		{ $$ = TCPOPT_KIND_TIMESTAMP; }
-			|	WINDOW			{ $$ = TCPOPT_KIND_WINDOW; }
+			|       TIMESTAMP               { $$ = TCPOPT_KIND_TIMESTAMP; }
+			|       WINDOW                  { $$ = TCPOPT_KIND_WINDOW; }
 			|	tcp_hdr_option_sack	{ $$ = $1; }
 			|	NUM			{
 				if ($1 > 255) {
diff --git a/src/scanner.l b/src/scanner.l
index 09fcbd094aa6..c65d57846c59 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -469,6 +469,9 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 <SCANSTATE_TCP>{
 "echo"			{ return ECHO; }
 "eol"			{ return EOL; }
+"fastopen"		{ return FASTOPEN; }
+"mptcp"			{ return MPTCP; }
+"md5sig"		{ return MD5SIG; }
 "nop"			{ return NOP; }
 "noop"			{ return NOP; }
 "sack"			{ return SACK; }
diff --git a/src/tcpopt.c b/src/tcpopt.c
index 53fe9bc860a8..5913cd065d03 100644
--- a/src/tcpopt.c
+++ b/src/tcpopt.c
@@ -91,6 +91,33 @@ static const struct exthdr_desc tcpopt_timestamp = {
 	},
 };
 
+static const struct exthdr_desc tcpopt_fastopen = {
+	.name		= "fastopen",
+	.type		= TCPOPT_KIND_FASTOPEN,
+	.templates	= {
+		[TCPOPT_COMMON_KIND]	= PHT("kind",   0, 8),
+		[TCPOPT_COMMON_LENGTH]	= PHT("length", 8, 8),
+	},
+};
+
+static const struct exthdr_desc tcpopt_md5sig = {
+	.name		= "md5sig",
+	.type		= TCPOPT_KIND_MD5SIG,
+	.templates	= {
+		[TCPOPT_COMMON_KIND]	= PHT("kind",   0, 8),
+		[TCPOPT_COMMON_LENGTH]	= PHT("length", 8, 8),
+	},
+};
+
+
+static const struct exthdr_desc tcpopt_mptcp = {
+	.name		= "mptcp",
+	.type		= TCPOPT_KIND_MPTCP,
+	.templates	= {
+		[TCPOPT_MPTCP_KIND]	= PHT("kind",   0,   8),
+		[TCPOPT_MPTCP_LENGTH]	= PHT("length", 8,  8),
+	},
+};
 #undef PHT
 
 const struct exthdr_desc *tcpopt_protocols[] = {
@@ -101,6 +128,9 @@ const struct exthdr_desc *tcpopt_protocols[] = {
 	[TCPOPT_KIND_SACK_PERMITTED]	= &tcpopt_sack_permitted,
 	[TCPOPT_KIND_SACK]		= &tcpopt_sack,
 	[TCPOPT_KIND_TIMESTAMP]		= &tcpopt_timestamp,
+	[TCPOPT_KIND_MD5SIG]		= &tcpopt_md5sig,
+	[TCPOPT_KIND_MPTCP]		= &tcpopt_mptcp,
+	[TCPOPT_KIND_FASTOPEN]		= &tcpopt_fastopen,
 };
 
 /**
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH nft 5/8] tests: py: add test cases for md5sig, fastopen and mptcp mnemonics
  2021-11-19 15:28 [PATCH nft 0/8] mptcp subtype option match support Florian Westphal
                   ` (3 preceding siblings ...)
  2021-11-19 15:28 ` [PATCH nft 4/8] tcpopt: add md5sig, fastopen and mptcp options Florian Westphal
@ 2021-11-19 15:28 ` Florian Westphal
  2021-11-19 15:28 ` [PATCH nft 6/8] mptcp: add subtype matching Florian Westphal
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Florian Westphal @ 2021-11-19 15:28 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 tests/py/any/tcpopt.t         |  4 ++++
 tests/py/any/tcpopt.t.json    | 45 +++++++++++++++++++++++++++++++++++
 tests/py/any/tcpopt.t.payload | 14 +++++++++++
 3 files changed, 63 insertions(+)

diff --git a/tests/py/any/tcpopt.t b/tests/py/any/tcpopt.t
index d3586eae8399..343c76e49a6e 100644
--- a/tests/py/any/tcpopt.t
+++ b/tests/py/any/tcpopt.t
@@ -46,3 +46,7 @@ tcp option window exists;ok
 tcp option window missing;ok
 
 tcp option maxseg size set 1360;ok
+
+tcp option md5sig exists;ok
+tcp option fastopen exists;ok
+tcp option mptcp exists;ok
diff --git a/tests/py/any/tcpopt.t.json b/tests/py/any/tcpopt.t.json
index 5468accb16b4..5c63fd6b2a56 100644
--- a/tests/py/any/tcpopt.t.json
+++ b/tests/py/any/tcpopt.t.json
@@ -487,3 +487,48 @@
         }
     }
 ]
+
+# tcp option md5sig exists
+[
+    {
+        "match": {
+            "left": {
+                "tcp option": {
+                    "name": "md5sig"
+                }
+            },
+            "op": "==",
+            "right": true
+        }
+    }
+]
+
+# tcp option fastopen exists
+[
+    {
+        "match": {
+            "left": {
+                "tcp option": {
+                    "name": "fastopen"
+                }
+            },
+            "op": "==",
+            "right": true
+        }
+    }
+]
+
+# tcp option mptcp exists
+[
+    {
+        "match": {
+            "left": {
+                "tcp option": {
+                    "name": "mptcp"
+                }
+            },
+            "op": "==",
+            "right": true
+        }
+    }
+]
diff --git a/tests/py/any/tcpopt.t.payload b/tests/py/any/tcpopt.t.payload
index d88bcd433a10..7ad19183d4e7 100644
--- a/tests/py/any/tcpopt.t.payload
+++ b/tests/py/any/tcpopt.t.payload
@@ -153,3 +153,17 @@ inet
   [ immediate reg 1 0x00005005 ]
   [ exthdr write tcpopt reg 1 => 2b @ 2 + 2 ]
 
+# tcp option md5sig exists
+inet
+  [ exthdr load tcpopt 1b @ 19 + 0 present => reg 1 ]
+  [ cmp eq reg 1 0x00000001 ]
+
+# tcp option fastopen exists
+inet
+  [ exthdr load tcpopt 1b @ 34 + 0 present => reg 1 ]
+  [ cmp eq reg 1 0x00000001 ]
+
+# tcp option mptcp exists
+inet
+  [ exthdr load tcpopt 1b @ 30 + 0 present => reg 1 ]
+  [ cmp eq reg 1 0x00000001 ]
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH nft 6/8] mptcp: add subtype matching
  2021-11-19 15:28 [PATCH nft 0/8] mptcp subtype option match support Florian Westphal
                   ` (4 preceding siblings ...)
  2021-11-19 15:28 ` [PATCH nft 5/8] tests: py: add test cases for md5sig, fastopen and mptcp mnemonics Florian Westphal
@ 2021-11-19 15:28 ` Florian Westphal
  2021-11-19 15:28 ` [PATCH nft 7/8] exthdr: fix tcpopt_find_template to use length after mask adjustment Florian Westphal
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Florian Westphal @ 2021-11-19 15:28 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

MPTCP multiplexes the various mptcp signalling data using the
first 4 bits of the mptcp option.

This allows to match on the mptcp subtype via:

   tcp option mptcp subtype 1

This misses delinearization support. mptcp subtype is the first tcp
option field that has a length of less than one byte.

Serialization processing will add a binop for this, but netlink
delinearization can't remove them, yet.

Also misses a new datatype/symbol table to allow to use mnemonics like
'mp_join' instead of raw numbers.

For this reason, no tests are added yet.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/tcpopt.h   |  1 +
 src/parser_bison.y | 11 ++++++++++-
 src/scanner.l      |  1 +
 src/tcpopt.c       |  1 +
 4 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/include/tcpopt.h b/include/tcpopt.h
index 22df69dc5b93..bb5c1329018e 100644
--- a/include/tcpopt.h
+++ b/include/tcpopt.h
@@ -77,6 +77,7 @@ enum tcpopt_hdr_field_sack {
 enum tcpopt_hdr_mptcp_common {
 	TCPOPT_MPTCP_KIND,
 	TCPOPT_MPTCP_LENGTH,
+	TCPOPT_MPTCP_SUBTYPE,
 };
 
 extern const struct exthdr_desc *tcpopt_protocols[__TCPOPT_KIND_MAX];
diff --git a/src/parser_bison.y b/src/parser_bison.y
index a6a591b7e00d..355758e1befb 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -424,6 +424,7 @@ int nft_lex(void *, void *, void *);
 %token RIGHT			"right"
 %token TSVAL			"tsval"
 %token TSECR			"tsecr"
+%token SUBTYPE			"subtype"
 
 %token DCCP			"dccp"
 
@@ -882,7 +883,7 @@ int nft_lex(void *, void *, void *);
 %type <val>			tcp_hdr_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 <val>			tcpopt_field_maxseg	tcpopt_field_mptcp	tcpopt_field_sack	 tcpopt_field_tsopt	tcpopt_field_window
 %type <tcp_kind_field>		tcp_hdr_option_kind_and_field
 
 %type <expr>			boolean_expr
@@ -5540,6 +5541,11 @@ tcp_hdr_option_kind_and_field	:	MSS	tcpopt_field_maxseg
 					struct tcp_kind_field kind_field = { .kind = $1, .field = TCPOPT_COMMON_LENGTH };
 					$$ = kind_field;
 				}
+				|	MPTCP	tcpopt_field_mptcp
+				{
+					struct tcp_kind_field kind_field = { .kind = TCPOPT_KIND_MPTCP, .field = $2 };
+					$$ = kind_field;
+				}
 				;
 
 tcp_hdr_option_sack	:	SACK		{ $$ = TCPOPT_KIND_SACK; }
@@ -5583,6 +5589,9 @@ tcpopt_field_tsopt	:	TSVAL           { $$ = TCPOPT_TS_TSVAL; }
 tcpopt_field_maxseg	:	SIZE		{ $$ = TCPOPT_MAXSEG_SIZE; }
 			;
 
+tcpopt_field_mptcp	:	SUBTYPE		{ $$ = TCPOPT_MPTCP_SUBTYPE; }
+			;
+
 dccp_hdr_expr		:	DCCP	dccp_hdr_field
 			{
 				$$ = payload_expr_alloc(&@$, &proto_dccp, $2);
diff --git a/src/scanner.l b/src/scanner.l
index c65d57846c59..f28bf3153f0b 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -472,6 +472,7 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "fastopen"		{ return FASTOPEN; }
 "mptcp"			{ return MPTCP; }
 "md5sig"		{ return MD5SIG; }
+"subtype"		{ return SUBTYPE; }
 "nop"			{ return NOP; }
 "noop"			{ return NOP; }
 "sack"			{ return SACK; }
diff --git a/src/tcpopt.c b/src/tcpopt.c
index 5913cd065d03..641daa7359a3 100644
--- a/src/tcpopt.c
+++ b/src/tcpopt.c
@@ -116,6 +116,7 @@ static const struct exthdr_desc tcpopt_mptcp = {
 	.templates	= {
 		[TCPOPT_MPTCP_KIND]	= PHT("kind",   0,   8),
 		[TCPOPT_MPTCP_LENGTH]	= PHT("length", 8,  8),
+		[TCPOPT_MPTCP_SUBTYPE]  = PHT("subtype", 16, 4),
 	},
 };
 #undef PHT
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH nft 7/8] exthdr: fix tcpopt_find_template to use length after mask adjustment
  2021-11-19 15:28 [PATCH nft 0/8] mptcp subtype option match support Florian Westphal
                   ` (5 preceding siblings ...)
  2021-11-19 15:28 ` [PATCH nft 6/8] mptcp: add subtype matching Florian Westphal
@ 2021-11-19 15:28 ` Florian Westphal
  2021-11-19 15:28 ` [PATCH nft 8/8] tests: py: add tcp subtype match test cases Florian Westphal
  2021-11-23 13:16 ` [PATCH nft 0/8] mptcp subtype option match support Pablo Neira Ayuso
  8 siblings, 0 replies; 14+ messages in thread
From: Florian Westphal @ 2021-11-19 15:28 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

Unify bitop handling for ipv6 extension header, ip option and tcp option
processing.

Pass the real offset and length expected, not the one used in the
kernel.

mptcp subtype would pass 8 bits as length rather than 4 bits.

This makes nft show 'tcp option mptcp subtype 1' instead of
'tcp option mptcp unknown & 240 == 16'.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/tcpopt.h |  4 ++--
 src/exthdr.c     | 46 ++++++++++++++++++++++------------------------
 src/tcpopt.c     |  7 +++----
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/include/tcpopt.h b/include/tcpopt.h
index bb5c1329018e..3a0b8424a990 100644
--- a/include/tcpopt.h
+++ b/include/tcpopt.h
@@ -12,8 +12,8 @@ extern void tcpopt_init_raw(struct expr *expr, uint8_t type,
 			    unsigned int offset, unsigned int len,
 			    uint32_t flags);
 
-extern bool tcpopt_find_template(struct expr *expr, const struct expr *mask,
-				 unsigned int *shift);
+extern bool tcpopt_find_template(struct expr *expr, unsigned int offset,
+				 unsigned int len);
 
 /* TCP option numbers used on wire */
 enum tcpopt_kind {
diff --git a/src/exthdr.c b/src/exthdr.c
index 22a08b0c9c2b..d2ae0f948f5e 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -348,16 +348,7 @@ static unsigned int mask_length(const struct expr *mask)
 bool exthdr_find_template(struct expr *expr, const struct expr *mask, unsigned int *shift)
 {
 	unsigned int off, mask_offset, mask_len;
-
-	if (expr->exthdr.op != NFT_EXTHDR_OP_IPV4 &&
-	    expr->exthdr.tmpl != &exthdr_unknown_template)
-		return false;
-
-	/* In case we are handling tcp options instead of the default ipv6
-	 * extension headers.
-	 */
-	if (expr->exthdr.op == NFT_EXTHDR_OP_TCPOPT)
-		return tcpopt_find_template(expr, mask, shift);
+	bool found;
 
 	mask_offset = mpz_scan1(mask->value, 0);
 	mask_len = mask_length(mask);
@@ -366,24 +357,31 @@ bool exthdr_find_template(struct expr *expr, const struct expr *mask, unsigned i
 	off += round_up(mask->len, BITS_PER_BYTE) - mask_len;
 
 	/* Handle ip options after the offset and mask have been calculated. */
-	if (expr->exthdr.op == NFT_EXTHDR_OP_IPV4) {
-		if (ipopt_find_template(expr, off, mask_len - mask_offset)) {
-			*shift = mask_offset;
-			return true;
-		} else {
+	switch (expr->exthdr.op) {
+	case NFT_EXTHDR_OP_IPV4:
+		found = ipopt_find_template(expr, off, mask_len - mask_offset);
+		break;
+	case NFT_EXTHDR_OP_TCPOPT:
+		found = tcpopt_find_template(expr, off, mask_len - mask_offset);
+		break;
+	case NFT_EXTHDR_OP_IPV6:
+		exthdr_init_raw(expr, expr->exthdr.desc->type,
+				off, mask_len - mask_offset, expr->exthdr.op, 0);
+
+		/* still failed to find a template... Bug. */
+		if (expr->exthdr.tmpl == &exthdr_unknown_template)
 			return false;
-		}
+		found = true;
+		break;
+	default:
+		found = false;
+		break;
 	}
 
-	exthdr_init_raw(expr, expr->exthdr.desc->type,
-			off, mask_len - mask_offset, expr->exthdr.op, 0);
-
-	/* still failed to find a template... Bug. */
-	if (expr->exthdr.tmpl == &exthdr_unknown_template)
-		return false;
+	if (found)
+		*shift = mask_offset;
 
-	*shift = mask_offset;
-	return true;
+	return found;
 }
 
 #define HDR_TEMPLATE(__name, __dtype, __type, __member)			\
diff --git a/src/tcpopt.c b/src/tcpopt.c
index 641daa7359a3..c3e07d7889ab 100644
--- a/src/tcpopt.c
+++ b/src/tcpopt.c
@@ -225,6 +225,7 @@ void tcpopt_init_raw(struct expr *expr, uint8_t type, unsigned int off,
 	expr->exthdr.flags = flags;
 	expr->exthdr.offset = off;
 	expr->exthdr.op = NFT_EXTHDR_OP_TCPOPT;
+	expr->exthdr.tmpl = &tcpopt_unknown_template;
 
 	if (flags & NFT_EXTHDR_F_PRESENT)
 		datatype_set(expr, &boolean_type);
@@ -252,14 +253,12 @@ void tcpopt_init_raw(struct expr *expr, uint8_t type, unsigned int off,
 	}
 }
 
-bool tcpopt_find_template(struct expr *expr, const struct expr *mask,
-			  unsigned int *shift)
+bool tcpopt_find_template(struct expr *expr, unsigned int offset, unsigned int len)
 {
 	if (expr->exthdr.tmpl != &tcpopt_unknown_template)
 		return false;
 
-	tcpopt_init_raw(expr, expr->exthdr.desc->type, expr->exthdr.offset,
-			expr->len, 0);
+	tcpopt_init_raw(expr, expr->exthdr.desc->type, offset, len, 0);
 
 	if (expr->exthdr.tmpl == &tcpopt_unknown_template)
 		return false;
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH nft 8/8] tests: py: add tcp subtype match test cases
  2021-11-19 15:28 [PATCH nft 0/8] mptcp subtype option match support Florian Westphal
                   ` (6 preceding siblings ...)
  2021-11-19 15:28 ` [PATCH nft 7/8] exthdr: fix tcpopt_find_template to use length after mask adjustment Florian Westphal
@ 2021-11-19 15:28 ` Florian Westphal
  2021-11-23 13:16 ` [PATCH nft 0/8] mptcp subtype option match support Pablo Neira Ayuso
  8 siblings, 0 replies; 14+ messages in thread
From: Florian Westphal @ 2021-11-19 15:28 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 tests/py/any/tcpopt.t         |  4 +++
 tests/py/any/tcpopt.t.json    | 53 +++++++++++++++++++++++++++++++++++
 tests/py/any/tcpopt.t.payload | 21 ++++++++++++++
 3 files changed, 78 insertions(+)

diff --git a/tests/py/any/tcpopt.t b/tests/py/any/tcpopt.t
index 343c76e49a6e..3d4be2a274df 100644
--- a/tests/py/any/tcpopt.t
+++ b/tests/py/any/tcpopt.t
@@ -50,3 +50,7 @@ tcp option maxseg size set 1360;ok
 tcp option md5sig exists;ok
 tcp option fastopen exists;ok
 tcp option mptcp exists;ok
+
+tcp option mptcp subtype 0;ok
+tcp option mptcp subtype 1;ok
+tcp option mptcp subtype { 0, 2};ok
diff --git a/tests/py/any/tcpopt.t.json b/tests/py/any/tcpopt.t.json
index 5c63fd6b2a56..5cc6f8f42446 100644
--- a/tests/py/any/tcpopt.t.json
+++ b/tests/py/any/tcpopt.t.json
@@ -532,3 +532,56 @@
         }
     }
 ]
+
+# tcp option mptcp subtype 0
+[
+    {
+        "match": {
+            "left": {
+                "tcp option": {
+                    "field": "subtype",
+                    "name": "mptcp"
+                }
+            },
+            "op": "==",
+            "right": 0
+        }
+    }
+]
+
+# tcp option mptcp subtype 1
+[
+    {
+        "match": {
+            "left": {
+                "tcp option": {
+                    "field": "subtype",
+                    "name": "mptcp"
+                }
+            },
+            "op": "==",
+            "right": 1
+        }
+    }
+]
+
+# tcp option mptcp subtype { 0, 2}
+[
+    {
+        "match": {
+            "left": {
+                "tcp option": {
+                    "field": "subtype",
+                    "name": "mptcp"
+                }
+            },
+            "op": "==",
+            "right": {
+                "set": [
+                    0,
+                    2
+                ]
+            }
+        }
+   }
+]
diff --git a/tests/py/any/tcpopt.t.payload b/tests/py/any/tcpopt.t.payload
index 7ad19183d4e7..121cc97fac09 100644
--- a/tests/py/any/tcpopt.t.payload
+++ b/tests/py/any/tcpopt.t.payload
@@ -167,3 +167,24 @@ inet
 inet
   [ exthdr load tcpopt 1b @ 30 + 0 present => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
+
+# tcp option mptcp subtype 0
+inet
+  [ exthdr load tcpopt 1b @ 30 + 2 => reg 1 ]
+  [ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000000 ]
+  [ cmp eq reg 1 0x00000000 ]
+
+# tcp option mptcp subtype 1
+inet
+  [ exthdr load tcpopt 1b @ 30 + 2 => reg 1 ]
+  [ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000000 ]
+  [ cmp eq reg 1 0x00000010 ]
+
+# tcp option mptcp subtype { 0, 2}
+__set%d test-inet 3 size 2
+__set%d test-inet 0
+	element 00000000  : 0 [end]	element 00000020  : 0 [end]
+inet
+  [ exthdr load tcpopt 1b @ 30 + 2 => reg 1 ]
+  [ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000000 ]
+  [ lookup reg 1 set __set%d ]
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH nft 0/8] mptcp subtype option match support
  2021-11-19 15:28 [PATCH nft 0/8] mptcp subtype option match support Florian Westphal
                   ` (7 preceding siblings ...)
  2021-11-19 15:28 ` [PATCH nft 8/8] tests: py: add tcp subtype match test cases Florian Westphal
@ 2021-11-23 13:16 ` Pablo Neira Ayuso
  2021-11-23 13:37   ` Florian Westphal
  8 siblings, 1 reply; 14+ messages in thread
From: Pablo Neira Ayuso @ 2021-11-23 13:16 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Fri, Nov 19, 2021 at 04:28:39PM +0100, Florian Westphal wrote:
> This series adds 'tcp option mptcp subtype' matching to nft.

LGTM.

> Because the subtype is only 4 bits in size the exthdr
> delinearization needs a fixup to remove the binop added by the
> evaluation step.

By the bitwise operation to take the 4 bits you can infer this refers to
mptcp, but it might be good to store in the rule userdata area that this
expression refers to mptcp as a suggestion to userspace when
delinearizing the rule. I wanted to look into this for a different
usecase.

> One remaining usablility problem is the lack of mnemonics for the
> subtype, i.e. something like:
> 
> static const struct symbol_table mptcp_subtype_tbl = {
>        .base           = BASE_DECIMAL,
>        .symbols        = {
>                SYMBOL("mp-capable",    0),
>                SYMBOL("mp-join",       1),
>                SYMBOL("dss",           2),
>                SYMBOL("add-addr",      3),
>                SYMBOL("remove-addr",   4),
>                SYMBOL("mp-prio",       5),
>                SYMBOL("mp-fail",       6),
>                SYMBOL("mp-fastclose",  7),
>                SYMBOL("mp-tcprst",     8),
>                SYMBOL_LIST_END
>        },
> 
> ... but this would need addition of yet another data type.
>
> Use of implicit/context-dependent symbol table would
> be preferrable, I will look into this next.

Could you develop your idea?

Thanks.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH nft 0/8] mptcp subtype option match support
  2021-11-23 13:16 ` [PATCH nft 0/8] mptcp subtype option match support Pablo Neira Ayuso
@ 2021-11-23 13:37   ` Florian Westphal
  2021-11-30 21:45     ` Pablo Neira Ayuso
  0 siblings, 1 reply; 14+ messages in thread
From: Florian Westphal @ 2021-11-23 13:37 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Florian Westphal, netfilter-devel

Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Fri, Nov 19, 2021 at 04:28:39PM +0100, Florian Westphal wrote:
> > Because the subtype is only 4 bits in size the exthdr
> > delinearization needs a fixup to remove the binop added by the
> > evaluation step.
> 
> By the bitwise operation to take the 4 bits you can infer this refers to
> mptcp, but it might be good to store in the rule userdata area that this
> expression refers to mptcp as a suggestion to userspace when
> delinearizing the rule.

Why?  Userspace has all info: its a tcp option, we have the tcp option
number (mptcp) and a 4 bit field which matches the template field.

There is no guesswork here.

Without this patch, we're asked to find a matching 1-byte field
(which does not exist).

Whats different vs. payload expressions here to require annotations?

> > One remaining usablility problem is the lack of mnemonics for the
> > subtype, i.e. something like:
> > 
> > static const struct symbol_table mptcp_subtype_tbl = {
> >        .base           = BASE_DECIMAL,
> >        .symbols        = {
> >                SYMBOL("mp-capable",    0),
> >                SYMBOL("mp-join",       1),
> >                SYMBOL("dss",           2),
> >                SYMBOL("add-addr",      3),
> >                SYMBOL("remove-addr",   4),
> >                SYMBOL("mp-prio",       5),
> >                SYMBOL("mp-fail",       6),
> >                SYMBOL("mp-fastclose",  7),
> >                SYMBOL("mp-tcprst",     8),
> >                SYMBOL_LIST_END
> >        },
> > 
> > ... but this would need addition of yet another data type.
> >
> > Use of implicit/context-dependent symbol table would
> > be preferrable, I will look into this next.
> 
> Could you develop your idea?

No idea, I have not thought about it at all.  I do not want
to add a new data type for this.

One way is to just extend the scanner with even more keywords.
I tought I could annotate the eval context with 'saw mptcp'
and then use that when trying to resolve the symbol expressions.

No idea if that works and no idea how much hassle that is.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH nft 0/8] mptcp subtype option match support
  2021-11-23 13:37   ` Florian Westphal
@ 2021-11-30 21:45     ` Pablo Neira Ayuso
  2021-12-01 11:30       ` Florian Westphal
  0 siblings, 1 reply; 14+ messages in thread
From: Pablo Neira Ayuso @ 2021-11-30 21:45 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Tue, Nov 23, 2021 at 02:37:42PM +0100, Florian Westphal wrote:
> Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> > On Fri, Nov 19, 2021 at 04:28:39PM +0100, Florian Westphal wrote:
> > > Because the subtype is only 4 bits in size the exthdr
> > > delinearization needs a fixup to remove the binop added by the
> > > evaluation step.
> > 
> > By the bitwise operation to take the 4 bits you can infer this refers to
> > mptcp, but it might be good to store in the rule userdata area that this
> > expression refers to mptcp as a suggestion to userspace when
> > delinearizing the rule.
> 
> Why?  Userspace has all info: its a tcp option, we have the tcp option
> number (mptcp) and a 4 bit field which matches the template field.
> 
> There is no guesswork here.

OK, thanks for explaining.

> Without this patch, we're asked to find a matching 1-byte field
> (which does not exist).
> 
> Whats different vs. payload expressions here to require annotations?
> 
> > > One remaining usablility problem is the lack of mnemonics for the
> > > subtype, i.e. something like:
> > > 
> > > static const struct symbol_table mptcp_subtype_tbl = {
> > >        .base           = BASE_DECIMAL,
> > >        .symbols        = {
> > >                SYMBOL("mp-capable",    0),
> > >                SYMBOL("mp-join",       1),
> > >                SYMBOL("dss",           2),
> > >                SYMBOL("add-addr",      3),
> > >                SYMBOL("remove-addr",   4),
> > >                SYMBOL("mp-prio",       5),
> > >                SYMBOL("mp-fail",       6),
> > >                SYMBOL("mp-fastclose",  7),
> > >                SYMBOL("mp-tcprst",     8),
> > >                SYMBOL_LIST_END
> > >        },
> > > 
> > > ... but this would need addition of yet another data type.
> > >
> > > Use of implicit/context-dependent symbol table would
> > > be preferrable, I will look into this next.
> > 
> > Could you develop your idea?
> 
> No idea, I have not thought about it at all.  I do not want
> to add a new data type for this.
> 
> One way is to just extend the scanner with even more keywords.
> I tought I could annotate the eval context with 'saw mptcp'
> and then use that when trying to resolve the symbol expressions.
> 
> No idea if that works and no idea how much hassle that is.

You can probably use a string in the parser for these types, then
invoke the symbol_table lookup from the parser to fetch the value?

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH nft 0/8] mptcp subtype option match support
  2021-11-30 21:45     ` Pablo Neira Ayuso
@ 2021-12-01 11:30       ` Florian Westphal
  2021-12-02 21:42         ` Pablo Neira Ayuso
  0 siblings, 1 reply; 14+ messages in thread
From: Florian Westphal @ 2021-12-01 11:30 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Florian Westphal, netfilter-devel

Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Tue, Nov 23, 2021 at 02:37:42PM +0100, Florian Westphal wrote:
> > Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> > > On Fri, Nov 19, 2021 at 04:28:39PM +0100, Florian Westphal wrote:
> > > > Because the subtype is only 4 bits in size the exthdr
> > > > delinearization needs a fixup to remove the binop added by the
> > > > evaluation step.
> > > 
> > > By the bitwise operation to take the 4 bits you can infer this refers to
> > > mptcp, but it might be good to store in the rule userdata area that this
> > > expression refers to mptcp as a suggestion to userspace when
> > > delinearizing the rule.
> > 
> > Why?  Userspace has all info: its a tcp option, we have the tcp option
> > number (mptcp) and a 4 bit field which matches the template field.
> > 
> > There is no guesswork here.
> 
> OK, thanks for explaining.

I can add a commet before pushing this out.

All mptcp suboptions have this 4bit identifier at the same location,
so

'tcp option == mptcp' always allows to take those 4 bit to identify
the next subheader.

The only caveat is that some suboptions have different sizes depending
on the option length field, this will get more complicated once matching
on those is added (we will need to take moer dependencies into account).

> > > > One remaining usablility problem is the lack of mnemonics for the
> > > > subtype, i.e. something like:
> > > > 
> > > > static const struct symbol_table mptcp_subtype_tbl = {
> > > >        .base           = BASE_DECIMAL,
> > > >        .symbols        = {
> > > >                SYMBOL("mp-capable",    0),
> > > >                SYMBOL("mp-join",       1),
> > > >                SYMBOL("dss",           2),
> > > >                SYMBOL("add-addr",      3),
> > > >                SYMBOL("remove-addr",   4),
> > > >                SYMBOL("mp-prio",       5),
> > > >                SYMBOL("mp-fail",       6),
> > > >                SYMBOL("mp-fastclose",  7),
> > > >                SYMBOL("mp-tcprst",     8),
> > > >                SYMBOL_LIST_END
> > > >        },
> > > > 
> > > > ... but this would need addition of yet another data type.
> > > >
> > > > Use of implicit/context-dependent symbol table would
> > > > be preferrable, I will look into this next.
> > > 
> > > Could you develop your idea?
> > 
> > No idea, I have not thought about it at all.  I do not want
> > to add a new data type for this.
> > 
> > One way is to just extend the scanner with even more keywords.
> > I tought I could annotate the eval context with 'saw mptcp'
> > and then use that when trying to resolve the symbol expressions.
> > 
> > No idea if that works and no idea how much hassle that is.
> 
> You can probably use a string in the parser for these types, then
> invoke the symbol_table lookup from the parser to fetch the value?

Current solution I'm working on adds a phony integer type, similar
to the 'hex output' one.

Delinearization needs to do some extra steps to override the integer
again though.

I will share some draft patches soon.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH nft 0/8] mptcp subtype option match support
  2021-12-01 11:30       ` Florian Westphal
@ 2021-12-02 21:42         ` Pablo Neira Ayuso
  0 siblings, 0 replies; 14+ messages in thread
From: Pablo Neira Ayuso @ 2021-12-02 21:42 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Wed, Dec 01, 2021 at 12:30:10PM +0100, Florian Westphal wrote:
> Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> > On Tue, Nov 23, 2021 at 02:37:42PM +0100, Florian Westphal wrote:
> > > Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> > > > On Fri, Nov 19, 2021 at 04:28:39PM +0100, Florian Westphal wrote:
> > > > > Because the subtype is only 4 bits in size the exthdr
> > > > > delinearization needs a fixup to remove the binop added by the
> > > > > evaluation step.
> > > > 
> > > > By the bitwise operation to take the 4 bits you can infer this refers to
> > > > mptcp, but it might be good to store in the rule userdata area that this
> > > > expression refers to mptcp as a suggestion to userspace when
> > > > delinearizing the rule.
> > > 
> > > Why?  Userspace has all info: its a tcp option, we have the tcp option
> > > number (mptcp) and a 4 bit field which matches the template field.
> > > 
> > > There is no guesswork here.
> > 
> > OK, thanks for explaining.
> 
> I can add a commet before pushing this out.

Please add a comment and push out this.

> 'tcp option == mptcp' always allows to take those 4 bit to identify
> the next subheader.
> 
> The only caveat is that some suboptions have different sizes depending
> on the option length field, this will get more complicated once matching
> on those is added (we will need to take moer dependencies into account).

This might require to extend the dependency infrastructure.

> > > > > One remaining usablility problem is the lack of mnemonics for the
> > > > > subtype, i.e. something like:
> > > > > 
> > > > > static const struct symbol_table mptcp_subtype_tbl = {
> > > > >        .base           = BASE_DECIMAL,
> > > > >        .symbols        = {
> > > > >                SYMBOL("mp-capable",    0),
> > > > >                SYMBOL("mp-join",       1),
> > > > >                SYMBOL("dss",           2),
> > > > >                SYMBOL("add-addr",      3),
> > > > >                SYMBOL("remove-addr",   4),
> > > > >                SYMBOL("mp-prio",       5),
> > > > >                SYMBOL("mp-fail",       6),
> > > > >                SYMBOL("mp-fastclose",  7),
> > > > >                SYMBOL("mp-tcprst",     8),
> > > > >                SYMBOL_LIST_END
> > > > >        },
> > > > > 
> > > > > ... but this would need addition of yet another data type.
> > > > >
> > > > > Use of implicit/context-dependent symbol table would
> > > > > be preferrable, I will look into this next.
> > > > 
> > > > Could you develop your idea?
> > > 
> > > No idea, I have not thought about it at all.  I do not want
> > > to add a new data type for this.
> > > 
> > > One way is to just extend the scanner with even more keywords.
> > > I tought I could annotate the eval context with 'saw mptcp'
> > > and then use that when trying to resolve the symbol expressions.
> > > 
> > > No idea if that works and no idea how much hassle that is.
> > 
> > You can probably use a string in the parser for these types, then
> > invoke the symbol_table lookup from the parser to fetch the value?
> 
> Current solution I'm working on adds a phony integer type, similar
> to the 'hex output' one.
> 
> Delinearization needs to do some extra steps to override the integer
> again though.
> 
> I will share some draft patches soon.

Sounds good, please consider the typeof path for set/map too.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2021-12-02 21:42 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-19 15:28 [PATCH nft 0/8] mptcp subtype option match support Florian Westphal
2021-11-19 15:28 ` [PATCH nft 1/8] tcpopt: remove KIND keyword Florian Westphal
2021-11-19 15:28 ` [PATCH nft 2/8] scanner: add tcp flex scope Florian Westphal
2021-11-19 15:28 ` [PATCH nft 3/8] parser: split tcp option rules Florian Westphal
2021-11-19 15:28 ` [PATCH nft 4/8] tcpopt: add md5sig, fastopen and mptcp options Florian Westphal
2021-11-19 15:28 ` [PATCH nft 5/8] tests: py: add test cases for md5sig, fastopen and mptcp mnemonics Florian Westphal
2021-11-19 15:28 ` [PATCH nft 6/8] mptcp: add subtype matching Florian Westphal
2021-11-19 15:28 ` [PATCH nft 7/8] exthdr: fix tcpopt_find_template to use length after mask adjustment Florian Westphal
2021-11-19 15:28 ` [PATCH nft 8/8] tests: py: add tcp subtype match test cases Florian Westphal
2021-11-23 13:16 ` [PATCH nft 0/8] mptcp subtype option match support Pablo Neira Ayuso
2021-11-23 13:37   ` Florian Westphal
2021-11-30 21:45     ` Pablo Neira Ayuso
2021-12-01 11:30       ` Florian Westphal
2021-12-02 21:42         ` Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.