]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
tcp: add raw tcp option match support
authorFlorian Westphal <fw@strlen.de>
Mon, 2 Nov 2020 19:10:25 +0000 (20:10 +0100)
committerFlorian Westphal <fw@strlen.de>
Mon, 9 Nov 2020 11:19:31 +0000 (12:19 +0100)
tcp option @42,16,4 (@kind,offset,length).

Signed-off-by: Florian Westphal <fw@strlen.de>
doc/payload-expression.txt
src/exthdr.c
src/parser_bison.y
src/tcpopt.c
tests/py/any/tcpopt.t
tests/py/any/tcpopt.t.payload

index 3cfa7791edac4003f7f1613b404541e5eed46abc..ffd1b671637a93175c878e1af16085a8d26c7f37 100644 (file)
@@ -591,6 +591,12 @@ TCP Timestamps |
 kind, length, tsval, tsecr
 |============================
 
+TCP option matching also supports raw expression syntax to access arbitrary options:
+[verse]
+*tcp option*
+[verse]
+*tcp option* *@*'number'*,*'offset'*,*'length'
+
 .IP Options
 [options="header"]
 |==================
index 8995ad1775a0c9417c3cc3c8aca27999eb662741..5eb66529b5d7736e6c07574b89cdde8fae9e3e8c 100644 (file)
@@ -52,10 +52,15 @@ static void exthdr_expr_print(const struct expr *expr, struct output_ctx *octx)
                 */
                unsigned int offset = expr->exthdr.offset / 64;
 
-               if (expr->exthdr.desc == NULL &&
-                   expr->exthdr.offset == 0 &&
-                   expr->exthdr.flags & NFT_EXTHDR_F_PRESENT) {
-                       nft_print(octx, "tcp option %d", expr->exthdr.raw_type);
+               if (expr->exthdr.desc == NULL) {
+                       if (expr->exthdr.offset == 0 &&
+                           expr->exthdr.flags & NFT_EXTHDR_F_PRESENT) {
+                               nft_print(octx, "tcp option %d", expr->exthdr.raw_type);
+                               return;
+                       }
+
+                       nft_print(octx, "tcp option @%u,%u,%u", expr->exthdr.raw_type,
+                                                               expr->exthdr.offset, expr->len);
                        return;
                }
 
index 9a2b1b6f0301e56a5d221ad06ccf50ecb21d9c49..a88844661af5837d08f5144ca1ff89c6cdae3da4 100644 (file)
@@ -5198,6 +5198,11 @@ tcp_hdr_expr             :       TCP     tcp_hdr_field
                                $$ = tcpopt_expr_alloc(&@$, $3, TCPOPT_COMMON_KIND);
                                $$->exthdr.flags = NFT_EXTHDR_F_PRESENT;
                        }
+                       |       TCP     OPTION  AT tcp_hdr_option_type  COMMA   NUM     COMMA   NUM
+                       {
+                               $$ = tcpopt_expr_alloc(&@$, $4, 0);
+                               tcpopt_init_raw($$, $4, $6, $8, 0);
+                       }
                        ;
 
 tcp_hdr_field          :       SPORT           { $$ = TCPHDR_SPORT; }
index 1cf97a563bc27030b051a2087083cf44b9238d6f..05b5ee6e3a0be6fa5ba755f230ab9cec52aaa153 100644 (file)
@@ -197,6 +197,8 @@ void tcpopt_init_raw(struct expr *expr, uint8_t type, unsigned int off,
 
        if (flags & NFT_EXTHDR_F_PRESENT)
                datatype_set(expr, &boolean_type);
+       else
+               datatype_set(expr, &integer_type);
 
        if (type >= array_size(tcpopt_protocols))
                return;
index 7b17014b300315e3fb03ab8937163d677d13d556..e759ac6132d912b3ad9e24d176ad0bc500782022 100644 (file)
@@ -31,6 +31,7 @@ tcp option timestamp length 1;ok
 tcp option timestamp tsval 1;ok
 tcp option timestamp tsecr 1;ok
 tcp option 255 missing;ok
+tcp option @255,8,8 255;ok
 
 tcp option foobar;fail
 tcp option foo bar;fail
@@ -40,6 +41,7 @@ tcp option eol left 1;fail
 tcp option sack window;fail
 tcp option sack window 1;fail
 tcp option 256 exists;fail
+tcp option @255,8,8 256;fail
 
 tcp option window exists;ok
 tcp option window missing;ok
index 34f8e26c440937b2470922afd6080b89f6b49072..cddba613a088e377ae48afaa8fac536943d396b6 100644 (file)
@@ -523,6 +523,13 @@ inet
   [ exthdr load tcpopt 1b @ 255 + 0 present => reg 1 ]
   [ cmp eq reg 1 0x00000000 ]
 
+# tcp option @255,8,8 255
+inet
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x00000006 ]
+  [ exthdr load tcpopt 1b @ 255 + 1 => reg 1 ]
+  [ cmp eq reg 1 0x000000ff ]
+
 # tcp option window exists
 inet 
   [ meta load l4proto => reg 1 ]