summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/nft.xml39
-rw-r--r--include/tcpopt.h32
-rw-r--r--src/exthdr.c2
-rw-r--r--src/parser_bison.y81
-rw-r--r--src/scanner.l19
-rw-r--r--src/tcpopt.c147
-rw-r--r--tests/py/inet/tcpopt.t21
-rw-r--r--tests/py/inet/tcpopt.t.payload.inet20
-rw-r--r--tests/py/ip/tcpopt.t20
-rw-r--r--tests/py/ip/tcpopt.t.payload20
-rw-r--r--tests/py/ip6/tcpopt.t20
-rw-r--r--tests/py/ip6/tcpopt.t.payload20
12 files changed, 243 insertions, 198 deletions
diff --git a/doc/nft.xml b/doc/nft.xml
index 49664c42..990b9368 100644
--- a/doc/nft.xml
+++ b/doc/nft.xml
@@ -2525,11 +2525,14 @@ inet filter meta nfproto ipv6 output rt nexthop fd00::1
<arg>noop</arg>
<arg>maxseg</arg>
<arg>window</arg>
- <arg>sack_permitted</arg>
+ <arg>sack-permitted</arg>
<arg>sack</arg>
+ <arg>sack0</arg>
+ <arg>sack1</arg>
+ <arg>sack2</arg>
+ <arg>sack3</arg>
<arg>timestamp</arg>
</group>
- <arg><replaceable>offset</replaceable></arg>
<arg choice="none"><replaceable>tcp_option_field</replaceable></arg>
</cmdsynopsis>
<para>
@@ -2604,13 +2607,33 @@ inet filter meta nfproto ipv6 output rt nexthop fd00::1
<entry>kind, length, count</entry>
</row>
<row>
- <entry>sack_permitted</entry>
+ <entry>sack-permitted</entry>
<entry>TCP SACK permitted</entry>
<entry>kind, length</entry>
</row>
<row>
<entry>sack</entry>
- <entry>TCP Selective Acknowledgement</entry>
+ <entry>TCP Selective Acknowledgement (alias of block 0)</entry>
+ <entry>kind, length, left, right</entry>
+ </row>
+ <row>
+ <entry>sack0</entry>
+ <entry>TCP Selective Acknowledgement (block 0)</entry>
+ <entry>kind, length, left, right</entry>
+ </row>
+ <row>
+ <entry>sack1</entry>
+ <entry>TCP Selective Acknowledgement (block 1)</entry>
+ <entry>kind, length, left, right</entry>
+ </row>
+ <row>
+ <entry>sack2</entry>
+ <entry>TCP Selective Acknowledgement (block 2)</entry>
+ <entry>kind, length, left, right</entry>
+ </row>
+ <row>
+ <entry>sack3</entry>
+ <entry>TCP Selective Acknowledgement (block 3)</entry>
<entry>kind, length, left, right</entry>
</row>
<row>
@@ -2624,16 +2647,10 @@ inet filter meta nfproto ipv6 output rt nexthop fd00::1
</para>
<para>
- The <replaceable>offset</replaceable> is only used for the SACK TCP option fields <command>left</command> and <command>right</command>.
- For all non-SACK TCP options it is always zero.
- <replaceable>Offsets</replaceable> which equals to zero can be omitted.
- </para>
-
- <para>
<example>
<title>finding TCP options</title>
<programlisting>
-filter input tcp option sack_permitted kind 1 counter
+filter input tcp option sack-permitted kind 1 counter
</programlisting>
</example>
<example>
diff --git a/include/tcpopt.h b/include/tcpopt.h
index 5b990083..f43a7eb7 100644
--- a/include/tcpopt.h
+++ b/include/tcpopt.h
@@ -5,9 +5,7 @@
#include <exthdr.h>
extern struct expr *tcpopt_expr_alloc(const struct location *loc,
- const char *option_str,
- const unsigned int option_num,
- const char *optioni_field);
+ uint8_t type, uint8_t field);
extern void tcpopt_init_raw(struct expr *expr, uint8_t type,
unsigned int offset, unsigned int len);
@@ -15,6 +13,34 @@ extern void tcpopt_init_raw(struct expr *expr, uint8_t type,
extern bool tcpopt_find_template(struct expr *expr, const struct expr *mask,
unsigned int *shift);
+enum tcpopt_hdr_types {
+ TCPOPTHDR_INVALID,
+ TCPOPTHDR_EOL,
+ TCPOPTHDR_NOOP,
+ TCPOPTHDR_MAXSEG,
+ TCPOPTHDR_WINDOW,
+ TCPOPTHDR_SACK_PERMITTED,
+ TCPOPTHDR_SACK0,
+ TCPOPTHDR_SACK1,
+ TCPOPTHDR_SACK2,
+ TCPOPTHDR_SACK3,
+ TCPOPTHDR_TIMESTAMP,
+ TCPOPTHDR_ECHO,
+ TCPOPTHDR_ECHO_REPLY,
+};
+
+enum tcpopt_hdr_fields {
+ TCPOPTHDR_FIELD_INVALID,
+ TCPOPTHDR_FIELD_KIND,
+ TCPOPTHDR_FIELD_LENGTH,
+ TCPOPTHDR_FIELD_SIZE,
+ TCPOPTHDR_FIELD_COUNT,
+ TCPOPTHDR_FIELD_LEFT,
+ TCPOPTHDR_FIELD_RIGHT,
+ TCPOPTHDR_FIELD_TSVAL,
+ TCPOPTHDR_FIELD_TSECR,
+};
+
extern const struct exthdr_desc tcpopt_eol;
extern const struct exthdr_desc tcpopt_nop;
extern const struct exthdr_desc tcpopt_maxseg;
diff --git a/src/exthdr.c b/src/exthdr.c
index cfc6bb60..ddda1b87 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -33,7 +33,7 @@ static void exthdr_expr_print(const struct expr *expr)
char buf[3] = {0};
if (offset)
- snprintf(buf, sizeof buf, " %d", offset);
+ snprintf(buf, sizeof buf, "%d", offset);
printf("tcp option %s%s %s", expr->exthdr.desc->name, buf,
expr->exthdr.tmpl->token);
}
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 36d46050..15931e96 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -309,6 +309,23 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token WINDOW "window"
%token URGPTR "urgptr"
%token OPTION "option"
+%token ECHO "echo"
+%token EOL "eol"
+%token MAXSEG "maxseg"
+%token NOOP "noop"
+%token SACK "sack"
+%token SACK0 "sack0"
+%token SACK1 "sack1"
+%token SACK2 "sack2"
+%token SACK3 "sack3"
+%token SACK_PERMITTED "sack-permitted"
+%token TIMESTAMP "timestamp"
+%token KIND "kind"
+%token COUNT "count"
+%token LEFT "left"
+%token RIGHT "right"
+%token TSVAL "tsval"
+%token TSECR "tsecr"
%token DCCP "dccp"
@@ -430,8 +447,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token NOTRACK "notrack"
-%type <string> identifier type_identifier string comment_spec tcp_option_name tcp_option_field
-%destructor { xfree($$); } identifier type_identifier string comment_spec tcp_option_name tcp_option_field
+%type <string> identifier type_identifier string comment_spec
+%destructor { xfree($$); } identifier type_identifier string comment_spec
%type <val> time_spec quota_used
@@ -602,9 +619,6 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%destructor { expr_free($$); } mh_hdr_expr
%type <val> mh_hdr_field
-%type <expr> tcp_hdr_optexpr
-%destructor { expr_free($$); } tcp_hdr_optexpr
-
%type <expr> meta_expr
%destructor { expr_free($$); } meta_expr
%type <val> meta_key meta_key_qualified meta_key_unqualified numgen_type
@@ -634,6 +648,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%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
%%
@@ -3211,6 +3226,10 @@ 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_hdr_field : SPORT { $$ = TCPHDR_SPORT; }
@@ -3225,6 +3244,30 @@ tcp_hdr_field : SPORT { $$ = TCPHDR_SPORT; }
| URGPTR { $$ = TCPHDR_URGPTR; }
;
+tcp_hdr_option_type : EOL { $$ = TCPOPTHDR_EOL; }
+ | NOOP { $$ = TCPOPTHDR_NOOP; }
+ | MAXSEG { $$ = TCPOPTHDR_MAXSEG; }
+ | WINDOW { $$ = TCPOPTHDR_WINDOW; }
+ | SACK_PERMITTED { $$ = TCPOPTHDR_SACK_PERMITTED; }
+ | SACK { $$ = TCPOPTHDR_SACK0; }
+ | SACK0 { $$ = TCPOPTHDR_SACK0; }
+ | SACK1 { $$ = TCPOPTHDR_SACK1; }
+ | SACK2 { $$ = TCPOPTHDR_SACK2; }
+ | SACK3 { $$ = TCPOPTHDR_SACK3; }
+ | ECHO { $$ = TCPOPTHDR_ECHO; }
+ | TIMESTAMP { $$ = TCPOPTHDR_TIMESTAMP; }
+ ;
+
+tcp_hdr_option_field : KIND { $$ = TCPOPTHDR_FIELD_KIND; }
+ | LENGTH { $$ = TCPOPTHDR_FIELD_LENGTH; }
+ | SIZE { $$ = TCPOPTHDR_FIELD_SIZE; }
+ | COUNT { $$ = TCPOPTHDR_FIELD_COUNT; }
+ | LEFT { $$ = TCPOPTHDR_FIELD_LEFT; }
+ | RIGHT { $$ = TCPOPTHDR_FIELD_RIGHT; }
+ | TSVAL { $$ = TCPOPTHDR_FIELD_TSVAL; }
+ | TSECR { $$ = TCPOPTHDR_FIELD_TSECR; }
+ ;
+
dccp_hdr_expr : DCCP dccp_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_dccp, $2);
@@ -3255,7 +3298,6 @@ exthdr_expr : hbh_hdr_expr
| frag_hdr_expr
| dst_hdr_expr
| mh_hdr_expr
- | tcp_hdr_optexpr
;
hbh_hdr_expr : HBH hbh_hdr_field
@@ -3338,31 +3380,4 @@ mh_hdr_field : NEXTHDR { $$ = MHHDR_NEXTHDR; }
| CHECKSUM { $$ = MHHDR_CHECKSUM; }
;
-tcp_option_name : STRING { $$ = $1; }
- | WINDOW { $$ = xstrdup("window"); }
- ;
-
-tcp_option_field : STRING { $$ = $1; }
- | LENGTH { $$ = xstrdup("length"); }
- | SIZE { $$ = xstrdup("size"); }
- ;
-
-tcp_hdr_optexpr : TCP OPTION tcp_option_name tcp_option_field
- {
- $$ = tcpopt_expr_alloc(&@$, $3, 0, $4);
- }
- | TCP OPTION STRING NUM tcp_option_field
- {
- if (strcmp($3, "sack")) {
- erec_queue(error(&@2, "tcp: number (%d) can only be used with sack option", $4), state->msgs);
- YYERROR;
- }
-
- if ($4 > 3) {
- erec_queue(error(&@2, "tcp: option block (%d) too large (0-3)", $4), state->msgs);
- YYERROR;
- }
- $$ = tcpopt_expr_alloc(&@$, $3, $4, $5);
- }
- ;
%%
diff --git a/src/scanner.l b/src/scanner.l
index e0ddcac1..b70e1a80 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -375,6 +375,25 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"protocol" { return PROTOCOL; }
"checksum" { return CHECKSUM; }
+"echo" { return ECHO; }
+"eol" { return EOL; }
+"maxseg" { return MAXSEG; }
+"noop" { return NOOP; }
+"sack" { return SACK; }
+"sack0" { return SACK0; }
+"sack1" { return SACK1; }
+"sack2" { return SACK2; }
+"sack3" { return SACK3; }
+"sack-permitted" { return SACK_PERMITTED; }
+"timestamp" { return TIMESTAMP; }
+
+"kind" { return KIND; }
+"count" { return COUNT; }
+"left" { return LEFT; }
+"right" { return RIGHT; }
+"tsval" { return TSVAL; }
+"tsecr" { return TSECR; }
+
"icmp" { return ICMP; }
"code" { return CODE; }
"sequence" { return SEQUENCE; }
diff --git a/src/tcpopt.c b/src/tcpopt.c
index e6f92bc6..f8612141 100644
--- a/src/tcpopt.c
+++ b/src/tcpopt.c
@@ -12,48 +12,6 @@
#include <expression.h>
#include <tcpopt.h>
-/* We do not need to export these enums, because the tcpopts are parsed at
- * runtime and not by bison.
- */
-enum tcpopt_eol_hdr_fields {
- TCPOPT_EOLHDR_KIND,
-};
-
-enum tcpopt_nop_hdr_fields {
- TCPOPT_NOPHDR_KIND,
-};
-
-enum tcpopt_maxseg_hdr_fields {
- TCPOPT_MAXSEGHDR_KIND,
- TCPOPT_MAXSEGHDR_LENGTH,
- TCPOPT_MAXSEGHDR_SIZE,
-};
-
-enum tcpopt_window_hdr_fields {
- TCPOPT_WINDOWHDR_KIND,
- TCPOPT_WINDOWHDR_LENGTH,
- TCPOPT_WINDOWHDR_COUNT,
-};
-
-enum tcpopt_sack_permitted_hdr_fields {
- TCPOPT_SACKPERMHDR_KIND,
- TCPOPT_SACKPERMHDR_LENGTH,
-};
-
-enum tcpopt_sack_hdr_fields {
- TCPOPT_SACKHDR_KIND,
- TCPOPT_SACKHDR_LENGTH,
- TCPOPT_SACKHDR_LEFT,
- TCPOPT_SACKHDR_RIGHT,
-};
-
-enum tcpopt_timestamp_hdr_fields {
- TCPOPT_TIMESTAMPSHDR_KIND,
- TCPOPT_TIMESTAMPSHDR_LENGTH,
- TCPOPT_TIMESTAMPSHDR_TSVAL,
- TCPOPT_TIMESTAMPSHDR_TSECR,
-};
-
static const struct proto_hdr_template tcpopt_unknown_template =
PROTO_HDR_TEMPLATE("unknown", &invalid_type, BYTEORDER_INVALID, 0, 0);
@@ -64,7 +22,7 @@ const struct exthdr_desc tcpopt_eol = {
.name = "eol",
.type = TCPOPT_EOL,
.templates = {
- [TCPOPT_EOLHDR_KIND] = PHT("kind", 0, 8),
+ [TCPOPTHDR_FIELD_KIND] = PHT("kind", 0, 8),
},
};
@@ -72,7 +30,7 @@ const struct exthdr_desc tcpopt_nop = {
.name = "noop",
.type = TCPOPT_NOP,
.templates = {
- [TCPOPT_NOPHDR_KIND] = PHT("kind", 0, 8),
+ [TCPOPTHDR_FIELD_KIND] = PHT("kind", 0, 8),
},
};
@@ -80,9 +38,9 @@ const struct exthdr_desc tcptopt_maxseg = {
.name = "maxseg",
.type = TCPOPT_MAXSEG,
.templates = {
- [TCPOPT_MAXSEGHDR_KIND] = PHT("kind", 0, 8),
- [TCPOPT_MAXSEGHDR_LENGTH] = PHT("length", 8, 8),
- [TCPOPT_MAXSEGHDR_SIZE] = PHT("size", 16, 16),
+ [TCPOPTHDR_FIELD_KIND] = PHT("kind", 0, 8),
+ [TCPOPTHDR_FIELD_LENGTH] = PHT("length", 8, 8),
+ [TCPOPTHDR_FIELD_SIZE] = PHT("size", 16, 16),
},
};
@@ -90,18 +48,18 @@ const struct exthdr_desc tcpopt_window = {
.name = "window",
.type = TCPOPT_WINDOW,
.templates = {
- [TCPOPT_WINDOWHDR_KIND] = PHT("kind", 0, 8),
- [TCPOPT_WINDOWHDR_LENGTH] = PHT("length", 8, 8),
- [TCPOPT_WINDOWHDR_COUNT] = PHT("count", 16, 8),
+ [TCPOPTHDR_FIELD_KIND] = PHT("kind", 0, 8),
+ [TCPOPTHDR_FIELD_LENGTH] = PHT("length", 8, 8),
+ [TCPOPTHDR_FIELD_COUNT] = PHT("count", 16, 8),
},
};
const struct exthdr_desc tcpopt_sack_permitted = {
- .name = "sack_permitted",
+ .name = "sack-permitted",
.type = TCPOPT_SACK_PERMITTED,
.templates = {
- [TCPOPT_SACKPERMHDR_KIND] = PHT("kind", 0, 8),
- [TCPOPT_SACKPERMHDR_LENGTH] = PHT("length", 8, 8),
+ [TCPOPTHDR_FIELD_KIND] = PHT("kind", 0, 8),
+ [TCPOPTHDR_FIELD_LENGTH] = PHT("length", 8, 8),
},
};
@@ -109,10 +67,10 @@ const struct exthdr_desc tcpopt_sack = {
.name = "sack",
.type = TCPOPT_SACK,
.templates = {
- [TCPOPT_SACKHDR_KIND] = PHT("kind", 0, 8),
- [TCPOPT_SACKHDR_LENGTH] = PHT("length", 8, 8),
- [TCPOPT_SACKHDR_LEFT] = PHT("left", 16, 32),
- [TCPOPT_SACKHDR_RIGHT] = PHT("right", 48, 32),
+ [TCPOPTHDR_FIELD_KIND] = PHT("kind", 0, 8),
+ [TCPOPTHDR_FIELD_LENGTH] = PHT("length", 8, 8),
+ [TCPOPTHDR_FIELD_LEFT] = PHT("left", 16, 32),
+ [TCPOPTHDR_FIELD_RIGHT] = PHT("right", 48, 32),
},
};
@@ -120,10 +78,10 @@ const struct exthdr_desc tcpopt_timestamp = {
.name = "timestamp",
.type = TCPOPT_TIMESTAMP,
.templates = {
- [TCPOPT_TIMESTAMPSHDR_KIND] = PHT("kind", 0, 8),
- [TCPOPT_TIMESTAMPSHDR_LENGTH] = PHT("length", 8, 8),
- [TCPOPT_TIMESTAMPSHDR_TSVAL] = PHT("tsval", 16, 32),
- [TCPOPT_TIMESTAMPSHDR_TSECR] = PHT("tsecr", 48, 32),
+ [TCPOPTHDR_FIELD_KIND] = PHT("kind", 0, 8),
+ [TCPOPTHDR_FIELD_LENGTH] = PHT("length", 8, 8),
+ [TCPOPTHDR_FIELD_TSVAL] = PHT("tsval", 16, 32),
+ [TCPOPTHDR_FIELD_TSECR] = PHT("tsecr", 48, 32),
},
};
#undef PHT
@@ -178,46 +136,57 @@ static unsigned int calc_offset_reverse(const struct exthdr_desc *desc,
}
}
+static const struct exthdr_desc *tcpopthdr_protocols[] = {
+ [TCPOPTHDR_EOL] = &tcpopt_eol,
+ [TCPOPTHDR_NOOP] = &tcpopt_nop,
+ [TCPOPTHDR_MAXSEG] = &tcptopt_maxseg,
+ [TCPOPTHDR_WINDOW] = &tcpopt_window,
+ [TCPOPTHDR_SACK_PERMITTED] = &tcpopt_sack_permitted,
+ [TCPOPTHDR_SACK0] = &tcpopt_sack,
+ [TCPOPTHDR_SACK1] = &tcpopt_sack,
+ [TCPOPTHDR_SACK2] = &tcpopt_sack,
+ [TCPOPTHDR_SACK3] = &tcpopt_sack,
+ [TCPOPTHDR_ECHO] = TCPOPT_OBSOLETE,
+ [TCPOPTHDR_ECHO_REPLY] = TCPOPT_OBSOLETE,
+ [TCPOPTHDR_TIMESTAMP] = &tcpopt_timestamp,
+};
+
+static uint8_t tcpopt_optnum[] = {
+ [TCPOPTHDR_SACK0] = 0,
+ [TCPOPTHDR_SACK1] = 1,
+ [TCPOPTHDR_SACK2] = 2,
+ [TCPOPTHDR_SACK3] = 3,
+};
-struct expr *tcpopt_expr_alloc(const struct location *loc,
- const char *option_str,
- const unsigned int option_num,
- const char *option_field)
+static uint8_t tcpopt_find_optnum(uint8_t optnum)
{
- const struct proto_hdr_template *tmp, *tmpl = &tcpopt_unknown_template;
- const struct exthdr_desc *desc = NULL;
- struct expr *expr;
- unsigned int i, j;
+ if (optnum > TCPOPTHDR_SACK3)
+ return 0;
- for (i = 0; i < array_size(tcpopt_protocols); ++i) {
- if (tcpopt_protocols[i] == TCPOPT_OBSOLETE)
- continue;
+ return tcpopt_optnum[optnum];
+}
- if (!tcpopt_protocols[i]->name ||
- strcmp(option_str, tcpopt_protocols[i]->name))
- continue;
+struct expr *tcpopt_expr_alloc(const struct location *loc, uint8_t type,
+ uint8_t field)
+{
+ const struct proto_hdr_template *tmpl;
+ const struct exthdr_desc *desc;
+ struct expr *expr;
+ uint8_t optnum;
- for (j = 0; j < array_size(tcpopt_protocols[i]->templates); ++j) {
- tmp = &tcpopt_protocols[i]->templates[j];
- if (!tmp->token || strcmp(option_field, tmp->token))
- continue;
+ desc = tcpopthdr_protocols[type];
+ tmpl = &desc->templates[field];
+ if (!tmpl)
+ return NULL;
- desc = tcpopt_protocols[i];
- tmpl = tmp;
- goto found;
- }
- }
+ optnum = tcpopt_find_optnum(type);
-found:
- /* tmpl still points to tcpopt_unknown_template if nothing was found and
- * desc is null
- */
expr = expr_alloc(loc, &exthdr_expr_ops, tmpl->dtype,
BYTEORDER_BIG_ENDIAN, tmpl->len);
expr->exthdr.desc = desc;
expr->exthdr.tmpl = tmpl;
expr->exthdr.op = NFT_EXTHDR_OP_TCPOPT;
- expr->exthdr.offset = calc_offset(desc, tmpl, option_num);
+ expr->exthdr.offset = calc_offset(desc, tmpl, optnum);
return expr;
}
diff --git a/tests/py/inet/tcpopt.t b/tests/py/inet/tcpopt.t
index 39204fdf..59452b48 100644
--- a/tests/py/inet/tcpopt.t
+++ b/tests/py/inet/tcpopt.t
@@ -10,20 +10,19 @@ 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_permitted kind 1;ok
-tcp option sack_permitted length 1;ok
+tcp option sack-permitted kind 1;ok
+tcp option sack-permitted length 1;ok
tcp option sack kind 1;ok
tcp option sack length 1;ok
tcp option sack left 1;ok
-tcp option sack 0 left 1;ok;tcp option sack left 1
-tcp option sack 1 left 1;ok
-tcp option sack 2 left 1;ok
-tcp option sack 3 left 1;ok
-tcp option sack right 1;ok
-tcp option sack 0 right 1;ok;tcp option sack right 1
-tcp option sack 1 right 1;ok
-tcp option sack 2 right 1;ok
-tcp option sack 3 right 1;ok
+tcp option sack0 left 1;ok;tcp option sack left 1
+tcp option sack1 left 1;ok
+tcp option sack2 left 1;ok
+tcp option sack3 left 1;ok
+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 length 1;ok
tcp option timestamp tsval 1;ok
diff --git a/tests/py/inet/tcpopt.t.payload.inet b/tests/py/inet/tcpopt.t.payload.inet
index 1343ae52..12deab8c 100644
--- a/tests/py/inet/tcpopt.t.payload.inet
+++ b/tests/py/inet/tcpopt.t.payload.inet
@@ -54,14 +54,14 @@ inet test-inet input
[ exthdr load tcpopt 1b @ 3 + 2 => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
-# tcp option sack_permitted kind 1
+# tcp option sack-permitted kind 1
inet test-inet input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 1b @ 4 + 0 => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
-# tcp option sack_permitted length 1
+# tcp option sack-permitted length 1
inet test-inet input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
@@ -89,28 +89,28 @@ inet test-inet input
[ exthdr load tcpopt 4b @ 5 + 2 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 0 left 1
+# tcp option sack0 left 1
inet test-inet input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 2 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 1 left 1
+# tcp option sack1 left 1
inet test-inet input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 10 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 2 left 1
+# tcp option sack2 left 1
inet test-inet input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 18 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 3 left 1
+# tcp option sack3 left 1
inet test-inet input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
@@ -124,28 +124,28 @@ inet test-inet input
[ exthdr load tcpopt 4b @ 5 + 6 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 0 right 1
+# tcp option sack0 right 1
inet test-inet input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 6 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 1 right 1
+# tcp option sack1 right 1
inet test-inet input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 14 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 2 right 1
+# tcp option sack2 right 1
inet test-inet input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 22 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 3 right 1
+# tcp option sack3 right 1
inet test-inet input
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
diff --git a/tests/py/ip/tcpopt.t b/tests/py/ip/tcpopt.t
index fccc6dda..7ee50a89 100644
--- a/tests/py/ip/tcpopt.t
+++ b/tests/py/ip/tcpopt.t
@@ -10,20 +10,20 @@ 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_permitted kind 1;ok
-tcp option sack_permitted length 1;ok
+tcp option sack-permitted kind 1;ok
+tcp option sack-permitted length 1;ok
tcp option sack kind 1;ok
tcp option sack length 1;ok
tcp option sack left 1;ok
-tcp option sack 0 left 1;ok;tcp option sack left 1
-tcp option sack 1 left 1;ok
-tcp option sack 2 left 1;ok
-tcp option sack 3 left 1;ok
+tcp option sack0 left 1;ok;tcp option sack left 1
+tcp option sack1 left 1;ok
+tcp option sack2 left 1;ok
+tcp option sack3 left 1;ok
tcp option sack right 1;ok
-tcp option sack 0 right 1;ok;tcp option sack right 1
-tcp option sack 1 right 1;ok
-tcp option sack 2 right 1;ok
-tcp option sack 3 right 1;ok
+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 length 1;ok
tcp option timestamp tsval 1;ok
diff --git a/tests/py/ip/tcpopt.t.payload b/tests/py/ip/tcpopt.t.payload
index 47e4dee0..3e1d4ad1 100644
--- a/tests/py/ip/tcpopt.t.payload
+++ b/tests/py/ip/tcpopt.t.payload
@@ -54,14 +54,14 @@ ip test-ip input
[ exthdr load tcpopt 1b @ 3 + 2 => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
-# tcp option sack_permitted kind 1
+# tcp option sack-permitted kind 1
ip test-ip input
[ payload load 1b @ network header + 9 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 1b @ 4 + 0 => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
-# tcp option sack_permitted length 1
+# tcp option sack-permitted length 1
ip test-ip input
[ payload load 1b @ network header + 9 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
@@ -89,28 +89,28 @@ ip test-ip input
[ exthdr load tcpopt 4b @ 5 + 2 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 0 left 1
+# tcp option sack0 left 1
ip test-ip input
[ payload load 1b @ network header + 9 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 2 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 1 left 1
+# tcp option sack1 left 1
ip test-ip input
[ payload load 1b @ network header + 9 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 10 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 2 left 1
+# tcp option sack2 left 1
ip test-ip input
[ payload load 1b @ network header + 9 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 18 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 3 left 1
+# tcp option sack3 left 1
ip test-ip input
[ payload load 1b @ network header + 9 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
@@ -124,28 +124,28 @@ ip test-ip input
[ exthdr load tcpopt 4b @ 5 + 6 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 0 right 1
+# tcp option sack0 right 1
ip test-ip input
[ payload load 1b @ network header + 9 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 6 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 1 right 1
+# tcp option sack1 right 1
ip test-ip input
[ payload load 1b @ network header + 9 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 14 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 2 right 1
+# tcp option sack2 right 1
ip test-ip input
[ payload load 1b @ network header + 9 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 22 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 3 right 1
+# tcp option sack3 right 1
ip test-ip input
[ payload load 1b @ network header + 9 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
diff --git a/tests/py/ip6/tcpopt.t b/tests/py/ip6/tcpopt.t
index d6f2dba2..497f69fc 100644
--- a/tests/py/ip6/tcpopt.t
+++ b/tests/py/ip6/tcpopt.t
@@ -9,20 +9,20 @@ 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_permitted kind 1;ok
-tcp option sack_permitted length 1;ok
+tcp option sack-permitted kind 1;ok
+tcp option sack-permitted length 1;ok
tcp option sack kind 1;ok
tcp option sack length 1;ok
tcp option sack left 1;ok
-tcp option sack 0 left 1;ok;tcp option sack left 1
-tcp option sack 1 left 1;ok
-tcp option sack 2 left 1;ok
-tcp option sack 3 left 1;ok
+tcp option sack0 left 1;ok;tcp option sack left 1
+tcp option sack1 left 1;ok
+tcp option sack2 left 1;ok
+tcp option sack3 left 1;ok
tcp option sack right 1;ok
-tcp option sack 0 right 1;ok;tcp option sack right 1
-tcp option sack 1 right 1;ok
-tcp option sack 2 right 1;ok
-tcp option sack 3 right 1;ok
+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 length 1;ok
tcp option timestamp tsval 1;ok
diff --git a/tests/py/ip6/tcpopt.t.payload b/tests/py/ip6/tcpopt.t.payload
index 98389b0a..88e277d1 100644
--- a/tests/py/ip6/tcpopt.t.payload
+++ b/tests/py/ip6/tcpopt.t.payload
@@ -54,14 +54,14 @@ ip6 test-ip input
[ exthdr load tcpopt 1b @ 3 + 2 => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
-# tcp option sack_permitted kind 1
+# tcp option sack-permitted kind 1
ip6 test-ip input
[ payload load 1b @ network header + 6 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 1b @ 4 + 0 => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
-# tcp option sack_permitted length 1
+# tcp option sack-permitted length 1
ip6 test-ip input
[ payload load 1b @ network header + 6 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
@@ -89,28 +89,28 @@ ip6 test-ip input
[ exthdr load tcpopt 4b @ 5 + 2 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 0 left 1
+# tcp option sack0 left 1
ip6 test-ip input
[ payload load 1b @ network header + 6 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 2 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 1 left 1
+# tcp option sack1 left 1
ip6 test-ip input
[ payload load 1b @ network header + 6 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 10 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 2 left 1
+# tcp option sack2 left 1
ip6 test-ip input
[ payload load 1b @ network header + 6 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 18 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 3 left 1
+# tcp option sack3 left 1
ip6 test-ip input
[ payload load 1b @ network header + 6 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
@@ -124,28 +124,28 @@ ip6 test-ip input
[ exthdr load tcpopt 4b @ 5 + 6 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 0 right 1
+# tcp option sack0 right 1
ip6 test-ip input
[ payload load 1b @ network header + 6 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 6 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 1 right 1
+# tcp option sack1 right 1
ip6 test-ip input
[ payload load 1b @ network header + 6 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 14 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 2 right 1
+# tcp option sack2 right 1
ip6 test-ip input
[ payload load 1b @ network header + 6 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ exthdr load tcpopt 4b @ 5 + 22 => reg 1 ]
[ cmp eq reg 1 0x01000000 ]
-# tcp option sack 3 right 1
+# tcp option sack3 right 1
ip6 test-ip input
[ payload load 1b @ network header + 6 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]