From patchwork Fri Nov 19 15:28:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1557213 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4HwgYr3VTNz9sX3 for ; Sat, 20 Nov 2021 02:29:04 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234124AbhKSPcC (ORCPT ); Fri, 19 Nov 2021 10:32:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231563AbhKSPcB (ORCPT ); Fri, 19 Nov 2021 10:32:01 -0500 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1755FC061574 for ; Fri, 19 Nov 2021 07:29:00 -0800 (PST) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1mo5ow-0005QK-Kb; Fri, 19 Nov 2021 16:28:58 +0100 From: Florian Westphal To: Cc: Florian Westphal Subject: [PATCH nft 1/8] tcpopt: remove KIND keyword Date: Fri, 19 Nov 2021 16:28:40 +0100 Message-Id: <20211119152847.18118-2-fw@strlen.de> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119152847.18118-1-fw@strlen.de> References: <20211119152847.18118-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org tcp option kind ... never makes any sense, as "tcp option " already tells the kernel to look for the foo . "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 --- 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 From patchwork Fri Nov 19 15:28:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1557214 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4HwgYv0qGmz9sWJ for ; Sat, 20 Nov 2021 02:29:07 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234286AbhKSPcG (ORCPT ); Fri, 19 Nov 2021 10:32:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44950 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231563AbhKSPcG (ORCPT ); Fri, 19 Nov 2021 10:32:06 -0500 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 76D31C061574 for ; Fri, 19 Nov 2021 07:29:04 -0800 (PST) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1mo5p1-0005Qe-09; Fri, 19 Nov 2021 16:29:03 +0100 From: Florian Westphal To: Cc: Florian Westphal Subject: [PATCH nft 2/8] scanner: add tcp flex scope Date: Fri, 19 Nov 2021 16:28:41 +0100 Message-Id: <20211119152847.18118-3-fw@strlen.de> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119152847.18118-1-fw@strlen.de> References: <20211119152847.18118-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org 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 --- 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 */ $0->reject.expr = $3; datatype_set($0->reject.expr, &icmpx_code_type); } - | WITH TCP RESET + | WITH TCP close_scope_tcp RESET { $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; } } +{ "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; } From patchwork Fri Nov 19 15:28:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1557215 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4HwgYy5nCzz9sWJ for ; Sat, 20 Nov 2021 02:29:10 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234310AbhKSPcK (ORCPT ); Fri, 19 Nov 2021 10:32:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231563AbhKSPcK (ORCPT ); Fri, 19 Nov 2021 10:32:10 -0500 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C4282C061574 for ; Fri, 19 Nov 2021 07:29:08 -0800 (PST) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1mo5p5-0005RC-CC; Fri, 19 Nov 2021 16:29:07 +0100 From: Florian Westphal To: Cc: Florian Westphal Subject: [PATCH nft 3/8] parser: split tcp option rules Date: Fri, 19 Nov 2021 16:28:42 +0100 Message-Id: <20211119152847.18118-4-fw@strlen.de> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119152847.18118-1-fw@strlen.de> References: <20211119152847.18118-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org 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 (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 tcp_hdr_expr %destructor { expr_free($$); } tcp_hdr_expr %type tcp_hdr_field -%type tcp_hdr_option_type tcp_hdr_option_field +%type tcp_hdr_option_type +%type tcp_hdr_option_sack +%type tcpopt_field_maxseg tcpopt_field_sack tcpopt_field_tsopt tcpopt_field_window +%type tcp_hdr_option_kind_and_field %type 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); From patchwork Fri Nov 19 15:28:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1557216 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4HwgZ26c2Vz9sWJ for ; Sat, 20 Nov 2021 02:29:14 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234601AbhKSPcP (ORCPT ); Fri, 19 Nov 2021 10:32:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44986 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231563AbhKSPcO (ORCPT ); Fri, 19 Nov 2021 10:32:14 -0500 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 24CBEC061574 for ; Fri, 19 Nov 2021 07:29:13 -0800 (PST) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1mo5p9-0005RS-ND; Fri, 19 Nov 2021 16:29:11 +0100 From: Florian Westphal To: Cc: Florian Westphal Subject: [PATCH nft 4/8] tcpopt: add md5sig, fastopen and mptcp options Date: Fri, 19 Nov 2021 16:28:43 +0100 Message-Id: <20211119152847.18118-5-fw@strlen.de> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119152847.18118-1-fw@strlen.de> References: <20211119152847.18118-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org 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 --- 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}) { "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, }; /** From patchwork Fri Nov 19 15:28:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1557217 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4HwgZ70fN6z9sWJ for ; Sat, 20 Nov 2021 02:29:19 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234666AbhKSPcT (ORCPT ); Fri, 19 Nov 2021 10:32:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45002 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231563AbhKSPcT (ORCPT ); Fri, 19 Nov 2021 10:32:19 -0500 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 83AB3C061574 for ; Fri, 19 Nov 2021 07:29:17 -0800 (PST) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1mo5pE-0005Rp-27; Fri, 19 Nov 2021 16:29:16 +0100 From: Florian Westphal To: Cc: Florian Westphal Subject: [PATCH nft 5/8] tests: py: add test cases for md5sig, fastopen and mptcp mnemonics Date: Fri, 19 Nov 2021 16:28:44 +0100 Message-Id: <20211119152847.18118-6-fw@strlen.de> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119152847.18118-1-fw@strlen.de> References: <20211119152847.18118-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Signed-off-by: Florian Westphal --- 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 ] From patchwork Fri Nov 19 15:28:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1557218 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4HwgZC2mr5z9sWJ for ; Sat, 20 Nov 2021 02:29:23 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234728AbhKSPcX (ORCPT ); Fri, 19 Nov 2021 10:32:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45020 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231563AbhKSPcX (ORCPT ); Fri, 19 Nov 2021 10:32:23 -0500 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D182DC061574 for ; Fri, 19 Nov 2021 07:29:21 -0800 (PST) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1mo5pI-0005SF-E6; Fri, 19 Nov 2021 16:29:20 +0100 From: Florian Westphal To: Cc: Florian Westphal Subject: [PATCH nft 6/8] mptcp: add subtype matching Date: Fri, 19 Nov 2021 16:28:45 +0100 Message-Id: <20211119152847.18118-7-fw@strlen.de> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119152847.18118-1-fw@strlen.de> References: <20211119152847.18118-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org 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 --- 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 tcp_hdr_field %type tcp_hdr_option_type %type tcp_hdr_option_sack -%type tcpopt_field_maxseg tcpopt_field_sack tcpopt_field_tsopt tcpopt_field_window +%type tcpopt_field_maxseg tcpopt_field_mptcp tcpopt_field_sack tcpopt_field_tsopt tcpopt_field_window %type tcp_hdr_option_kind_and_field %type 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 From patchwork Fri Nov 19 15:28:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1557219 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4HwgZJ4X2kz9sWJ for ; Sat, 20 Nov 2021 02:29:28 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234735AbhKSPc3 (ORCPT ); Fri, 19 Nov 2021 10:32:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45036 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231563AbhKSPc1 (ORCPT ); Fri, 19 Nov 2021 10:32:27 -0500 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 343ECC061574 for ; Fri, 19 Nov 2021 07:29:26 -0800 (PST) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1mo5pM-0005Sc-PV; Fri, 19 Nov 2021 16:29:24 +0100 From: Florian Westphal To: Cc: Florian Westphal Subject: [PATCH nft 7/8] exthdr: fix tcpopt_find_template to use length after mask adjustment Date: Fri, 19 Nov 2021 16:28:46 +0100 Message-Id: <20211119152847.18118-8-fw@strlen.de> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119152847.18118-1-fw@strlen.de> References: <20211119152847.18118-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org 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 --- 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; From patchwork Fri Nov 19 15:28:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1557220 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4HwgZN25MNz9sWJ for ; Sat, 20 Nov 2021 02:29:32 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234745AbhKSPcc (ORCPT ); Fri, 19 Nov 2021 10:32:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45058 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231563AbhKSPcc (ORCPT ); Fri, 19 Nov 2021 10:32:32 -0500 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C3E27C061574 for ; Fri, 19 Nov 2021 07:29:30 -0800 (PST) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1mo5pR-0005Su-59; Fri, 19 Nov 2021 16:29:29 +0100 From: Florian Westphal To: Cc: Florian Westphal Subject: [PATCH nft 8/8] tests: py: add tcp subtype match test cases Date: Fri, 19 Nov 2021 16:28:47 +0100 Message-Id: <20211119152847.18118-9-fw@strlen.de> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119152847.18118-1-fw@strlen.de> References: <20211119152847.18118-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Signed-off-by: Florian Westphal --- 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 ]