summaryrefslogtreecommitdiffstats
path: root/tests/shell/testcases/packetpath
diff options
context:
space:
mode:
Diffstat (limited to 'tests/shell/testcases/packetpath')
-rw-r--r--tests/shell/testcases/packetpath/dumps/flowtables.nodump0
-rw-r--r--tests/shell/testcases/packetpath/dumps/payload.nodump0
-rw-r--r--tests/shell/testcases/packetpath/dumps/policy.json-nft121
-rw-r--r--tests/shell/testcases/packetpath/dumps/policy.nft11
-rw-r--r--tests/shell/testcases/packetpath/dumps/set_lookups.json-nft674
-rw-r--r--tests/shell/testcases/packetpath/dumps/set_lookups.nft51
-rw-r--r--tests/shell/testcases/packetpath/dumps/tcp_options.nodump0
-rw-r--r--tests/shell/testcases/packetpath/dumps/tcp_reset.json-nft168
-rw-r--r--tests/shell/testcases/packetpath/dumps/tcp_reset.nft13
-rw-r--r--tests/shell/testcases/packetpath/dumps/vlan_8021ad_tag.nodump0
-rw-r--r--tests/shell/testcases/packetpath/dumps/vlan_mangling.nodump0
-rw-r--r--tests/shell/testcases/packetpath/dumps/vlan_qinq.nodump0
-rwxr-xr-xtests/shell/testcases/packetpath/flowtables98
-rwxr-xr-xtests/shell/testcases/packetpath/match_l4proto149
-rwxr-xr-xtests/shell/testcases/packetpath/payload251
-rwxr-xr-xtests/shell/testcases/packetpath/policy42
-rwxr-xr-xtests/shell/testcases/packetpath/set_lookups66
-rwxr-xr-xtests/shell/testcases/packetpath/tcp_options57
-rwxr-xr-xtests/shell/testcases/packetpath/tcp_reset31
-rwxr-xr-xtests/shell/testcases/packetpath/vlan_8021ad_tag50
-rwxr-xr-xtests/shell/testcases/packetpath/vlan_mangling77
-rwxr-xr-xtests/shell/testcases/packetpath/vlan_qinq73
22 files changed, 1932 insertions, 0 deletions
diff --git a/tests/shell/testcases/packetpath/dumps/flowtables.nodump b/tests/shell/testcases/packetpath/dumps/flowtables.nodump
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/flowtables.nodump
diff --git a/tests/shell/testcases/packetpath/dumps/payload.nodump b/tests/shell/testcases/packetpath/dumps/payload.nodump
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/payload.nodump
diff --git a/tests/shell/testcases/packetpath/dumps/policy.json-nft b/tests/shell/testcases/packetpath/dumps/policy.json-nft
new file mode 100644
index 00000000..26e8a052
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/policy.json-nft
@@ -0,0 +1,121 @@
+{
+ "nftables": [
+ {
+ "metainfo": {
+ "version": "VERSION",
+ "release_name": "RELEASE_NAME",
+ "json_schema_version": 1
+ }
+ },
+ {
+ "table": {
+ "family": "inet",
+ "name": "filter",
+ "handle": 0
+ }
+ },
+ {
+ "chain": {
+ "family": "inet",
+ "table": "filter",
+ "name": "underflow",
+ "handle": 0
+ }
+ },
+ {
+ "chain": {
+ "family": "inet",
+ "table": "filter",
+ "name": "input",
+ "handle": 0,
+ "type": "filter",
+ "hook": "input",
+ "prio": 0,
+ "policy": "drop"
+ }
+ },
+ {
+ "rule": {
+ "family": "inet",
+ "table": "filter",
+ "chain": "input",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "icmp",
+ "field": "type"
+ }
+ },
+ "right": "echo-reply"
+ }
+ },
+ {
+ "accept": null
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "inet",
+ "table": "filter",
+ "chain": "input",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ },
+ "right": "127.0.0.1"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "ip",
+ "field": "daddr"
+ }
+ },
+ "right": "127.0.0.2"
+ }
+ },
+ {
+ "counter": {
+ "packets": 3,
+ "bytes": 252
+ }
+ },
+ {
+ "accept": null
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "inet",
+ "table": "filter",
+ "chain": "input",
+ "handle": 0,
+ "expr": [
+ {
+ "goto": {
+ "target": "underflow"
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/tests/shell/testcases/packetpath/dumps/policy.nft b/tests/shell/testcases/packetpath/dumps/policy.nft
new file mode 100644
index 00000000..e625ea6c
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/policy.nft
@@ -0,0 +1,11 @@
+table inet filter {
+ chain underflow {
+ }
+
+ chain input {
+ type filter hook input priority filter; policy drop;
+ icmp type echo-reply accept
+ ip saddr 127.0.0.1 ip daddr 127.0.0.2 counter packets 3 bytes 252 accept
+ goto underflow
+ }
+}
diff --git a/tests/shell/testcases/packetpath/dumps/set_lookups.json-nft b/tests/shell/testcases/packetpath/dumps/set_lookups.json-nft
new file mode 100644
index 00000000..24363f90
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/set_lookups.json-nft
@@ -0,0 +1,674 @@
+{
+ "nftables": [
+ {
+ "metainfo": {
+ "version": "VERSION",
+ "release_name": "RELEASE_NAME",
+ "json_schema_version": 1
+ }
+ },
+ {
+ "table": {
+ "family": "ip",
+ "name": "t",
+ "handle": 0
+ }
+ },
+ {
+ "chain": {
+ "family": "ip",
+ "table": "t",
+ "name": "c",
+ "handle": 0,
+ "type": "filter",
+ "hook": "input",
+ "prio": 0,
+ "policy": "accept"
+ }
+ },
+ {
+ "set": {
+ "family": "ip",
+ "name": "s",
+ "table": "t",
+ "type": [
+ "ipv4_addr",
+ "iface_index"
+ ],
+ "handle": 0,
+ "flags": [
+ "interval"
+ ],
+ "elem": [
+ {
+ "concat": [
+ "127.0.0.1",
+ "lo"
+ ]
+ },
+ {
+ "concat": [
+ "127.0.0.2",
+ "lo"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "set": {
+ "family": "ip",
+ "name": "s2",
+ "table": "t",
+ "type": [
+ "ipv4_addr",
+ "iface_index"
+ ],
+ "handle": 0,
+ "elem": [
+ {
+ "concat": [
+ "127.0.0.1",
+ "lo"
+ ]
+ },
+ {
+ "concat": [
+ "127.0.0.2",
+ "lo"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "set": {
+ "family": "ip",
+ "name": "s3",
+ "table": "t",
+ "type": "iface_index",
+ "handle": 0,
+ "elem": [
+ "lo"
+ ]
+ }
+ },
+ {
+ "set": {
+ "family": "ip",
+ "name": "s4",
+ "table": "t",
+ "type": "iface_index",
+ "handle": 0,
+ "flags": [
+ "interval"
+ ],
+ "elem": [
+ "lo"
+ ]
+ }
+ },
+ {
+ "set": {
+ "family": "ip",
+ "name": "nomatch",
+ "table": "t",
+ "type": [
+ "ipv4_addr",
+ "iface_index"
+ ],
+ "handle": 0,
+ "elem": [
+ {
+ "concat": [
+ "127.0.0.3",
+ "lo"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "set": {
+ "family": "ip",
+ "name": "nomatch2",
+ "table": "t",
+ "type": [
+ "ipv4_addr",
+ "iface_index"
+ ],
+ "handle": 0,
+ "elem": [
+ {
+ "concat": [
+ "127.0.0.2",
+ "90000"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "t",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "icmp",
+ "field": "type"
+ }
+ },
+ "right": "echo-request"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ },
+ {
+ "meta": {
+ "key": "iif"
+ }
+ }
+ ]
+ },
+ "right": "@s"
+ }
+ },
+ {
+ "counter": {
+ "packets": 1,
+ "bytes": 84
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "t",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "icmp",
+ "field": "type"
+ }
+ },
+ "right": "echo-request"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ },
+ "lo"
+ ]
+ },
+ "right": "@s"
+ }
+ },
+ {
+ "counter": {
+ "packets": 1,
+ "bytes": 84
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "t",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "icmp",
+ "field": "type"
+ }
+ },
+ "right": "echo-request"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ },
+ "lo"
+ ]
+ },
+ "right": "@s"
+ }
+ },
+ {
+ "counter": {
+ "packets": 1,
+ "bytes": 84
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "t",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "icmp",
+ "field": "type"
+ }
+ },
+ "right": "echo-request"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ },
+ {
+ "meta": {
+ "key": "iif"
+ }
+ }
+ ]
+ },
+ "right": "@s2"
+ }
+ },
+ {
+ "counter": {
+ "packets": 1,
+ "bytes": 84
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "t",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "icmp",
+ "field": "type"
+ }
+ },
+ "right": "echo-request"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ },
+ "lo"
+ ]
+ },
+ "right": "@s2"
+ }
+ },
+ {
+ "counter": {
+ "packets": 1,
+ "bytes": 84
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "t",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "icmp",
+ "field": "type"
+ }
+ },
+ "right": "echo-request"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "saddr"
+ }
+ },
+ "lo"
+ ]
+ },
+ "right": "@s2"
+ }
+ },
+ {
+ "counter": {
+ "packets": 1,
+ "bytes": 84
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "t",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "icmp",
+ "field": "type"
+ }
+ },
+ "right": "echo-request"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "daddr"
+ }
+ },
+ "lo"
+ ]
+ },
+ "right": "@s"
+ }
+ },
+ {
+ "counter": {
+ "packets": 1,
+ "bytes": 84
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "t",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "icmp",
+ "field": "type"
+ }
+ },
+ "right": "echo-request"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "daddr"
+ }
+ },
+ "lo"
+ ]
+ },
+ "right": "@s2"
+ }
+ },
+ {
+ "counter": {
+ "packets": 1,
+ "bytes": 84
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "t",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "icmp",
+ "field": "type"
+ }
+ },
+ "right": "echo-request"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "meta": {
+ "key": "iif"
+ }
+ },
+ "right": "@s3"
+ }
+ },
+ {
+ "counter": {
+ "packets": 1,
+ "bytes": 84
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "t",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "icmp",
+ "field": "type"
+ }
+ },
+ "right": "echo-request"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "meta": {
+ "key": "iif"
+ }
+ },
+ "right": "@s4"
+ }
+ },
+ {
+ "counter": {
+ "packets": 1,
+ "bytes": 84
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "t",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "daddr"
+ }
+ },
+ "lo"
+ ]
+ },
+ "right": "@nomatch"
+ }
+ },
+ {
+ "counter": {
+ "packets": 0,
+ "bytes": 0
+ }
+ },
+ {
+ "drop": null
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "ip",
+ "table": "t",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "concat": [
+ {
+ "payload": {
+ "protocol": "ip",
+ "field": "daddr"
+ }
+ },
+ {
+ "meta": {
+ "key": "iif"
+ }
+ }
+ ]
+ },
+ "right": "@nomatch2"
+ }
+ },
+ {
+ "counter": {
+ "packets": 0,
+ "bytes": 0
+ }
+ },
+ {
+ "drop": null
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/tests/shell/testcases/packetpath/dumps/set_lookups.nft b/tests/shell/testcases/packetpath/dumps/set_lookups.nft
new file mode 100644
index 00000000..7566f557
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/set_lookups.nft
@@ -0,0 +1,51 @@
+table ip t {
+ set s {
+ type ipv4_addr . iface_index
+ flags interval
+ elements = { 127.0.0.1 . "lo",
+ 127.0.0.2 . "lo" }
+ }
+
+ set s2 {
+ typeof ip saddr . iif
+ elements = { 127.0.0.1 . "lo",
+ 127.0.0.2 . "lo" }
+ }
+
+ set s3 {
+ type iface_index
+ elements = { "lo" }
+ }
+
+ set s4 {
+ type iface_index
+ flags interval
+ elements = { "lo" }
+ }
+
+ set nomatch {
+ typeof ip saddr . iif
+ elements = { 127.0.0.3 . "lo" }
+ }
+
+ set nomatch2 {
+ type ipv4_addr . iface_index
+ elements = { 127.0.0.2 . 90000 }
+ }
+
+ chain c {
+ type filter hook input priority filter; policy accept;
+ icmp type echo-request ip saddr . iif @s counter packets 1 bytes 84
+ icmp type echo-request ip saddr . "lo" @s counter packets 1 bytes 84
+ icmp type echo-request ip saddr . "lo" @s counter packets 1 bytes 84
+ icmp type echo-request ip saddr . iif @s2 counter packets 1 bytes 84
+ icmp type echo-request ip saddr . "lo" @s2 counter packets 1 bytes 84
+ icmp type echo-request ip saddr . "lo" @s2 counter packets 1 bytes 84
+ icmp type echo-request ip daddr . "lo" @s counter packets 1 bytes 84
+ icmp type echo-request ip daddr . "lo" @s2 counter packets 1 bytes 84
+ icmp type echo-request iif @s3 counter packets 1 bytes 84
+ icmp type echo-request iif @s4 counter packets 1 bytes 84
+ ip daddr . "lo" @nomatch counter packets 0 bytes 0 drop
+ ip daddr . iif @nomatch2 counter packets 0 bytes 0 drop
+ }
+}
diff --git a/tests/shell/testcases/packetpath/dumps/tcp_options.nodump b/tests/shell/testcases/packetpath/dumps/tcp_options.nodump
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/tcp_options.nodump
diff --git a/tests/shell/testcases/packetpath/dumps/tcp_reset.json-nft b/tests/shell/testcases/packetpath/dumps/tcp_reset.json-nft
new file mode 100644
index 00000000..e1367cc1
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/tcp_reset.json-nft
@@ -0,0 +1,168 @@
+{
+ "nftables": [
+ {
+ "metainfo": {
+ "version": "VERSION",
+ "release_name": "RELEASE_NAME",
+ "json_schema_version": 1
+ }
+ },
+ {
+ "table": {
+ "family": "inet",
+ "name": "filter",
+ "handle": 0
+ }
+ },
+ {
+ "chain": {
+ "family": "inet",
+ "table": "filter",
+ "name": "input",
+ "handle": 0,
+ "type": "filter",
+ "hook": "input",
+ "prio": 0,
+ "policy": "accept"
+ }
+ },
+ {
+ "chain": {
+ "family": "inet",
+ "table": "filter",
+ "name": "output",
+ "handle": 0,
+ "type": "filter",
+ "hook": "output",
+ "prio": 0,
+ "policy": "accept"
+ }
+ },
+ {
+ "rule": {
+ "family": "inet",
+ "table": "filter",
+ "chain": "input",
+ "handle": 0,
+ "expr": [
+ {
+ "mangle": {
+ "key": {
+ "meta": {
+ "key": "nftrace"
+ }
+ },
+ "value": 1
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "inet",
+ "table": "filter",
+ "chain": "input",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "ip",
+ "field": "daddr"
+ }
+ },
+ "right": "127.0.0.1"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "tcp",
+ "field": "dport"
+ }
+ },
+ "right": 5555
+ }
+ },
+ {
+ "reject": {
+ "type": "tcp reset"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "inet",
+ "table": "filter",
+ "chain": "input",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "ip6",
+ "field": "daddr"
+ }
+ },
+ "right": "::1"
+ }
+ },
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "tcp",
+ "field": "dport"
+ }
+ },
+ "right": 5555
+ }
+ },
+ {
+ "reject": {
+ "type": "tcp reset"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "rule": {
+ "family": "inet",
+ "table": "filter",
+ "chain": "input",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "payload": {
+ "protocol": "tcp",
+ "field": "dport"
+ }
+ },
+ "right": 5555
+ }
+ },
+ {
+ "counter": {
+ "packets": 0,
+ "bytes": 0
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/tests/shell/testcases/packetpath/dumps/tcp_reset.nft b/tests/shell/testcases/packetpath/dumps/tcp_reset.nft
new file mode 100644
index 00000000..fb3df1af
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/tcp_reset.nft
@@ -0,0 +1,13 @@
+table inet filter {
+ chain input {
+ type filter hook input priority filter; policy accept;
+ meta nftrace set 1
+ ip daddr 127.0.0.1 tcp dport 5555 reject with tcp reset
+ ip6 daddr ::1 tcp dport 5555 reject with tcp reset
+ tcp dport 5555 counter packets 0 bytes 0
+ }
+
+ chain output {
+ type filter hook output priority filter; policy accept;
+ }
+}
diff --git a/tests/shell/testcases/packetpath/dumps/vlan_8021ad_tag.nodump b/tests/shell/testcases/packetpath/dumps/vlan_8021ad_tag.nodump
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/vlan_8021ad_tag.nodump
diff --git a/tests/shell/testcases/packetpath/dumps/vlan_mangling.nodump b/tests/shell/testcases/packetpath/dumps/vlan_mangling.nodump
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/vlan_mangling.nodump
diff --git a/tests/shell/testcases/packetpath/dumps/vlan_qinq.nodump b/tests/shell/testcases/packetpath/dumps/vlan_qinq.nodump
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/shell/testcases/packetpath/dumps/vlan_qinq.nodump
diff --git a/tests/shell/testcases/packetpath/flowtables b/tests/shell/testcases/packetpath/flowtables
new file mode 100755
index 00000000..2c4a7e1f
--- /dev/null
+++ b/tests/shell/testcases/packetpath/flowtables
@@ -0,0 +1,98 @@
+#!/bin/bash
+
+# NFT_TEST_SKIP(NFT_TEST_SKIP_slow)
+
+set -x
+
+rnd=$(mktemp -u XXXXXXXX)
+R="flowtable-router-$rnd"
+C="flowtable-client-$rnd"
+S="flowtbale-server-$rnd"
+
+cleanup()
+{
+ for i in $R $C $S;do
+ kill $(ip netns pid $i) 2>/dev/null
+ ip netns del $i
+ done
+}
+
+trap cleanup EXIT
+
+ip netns add $R
+ip netns add $S
+ip netns add $C
+
+ip link add s_r netns $S type veth peer name r_s netns $R
+ip netns exec $S ip link set s_r up
+ip netns exec $R ip link set r_s up
+ip link add c_r netns $C type veth peer name r_c netns $R
+ip netns exec $R ip link set r_c up
+ip netns exec $C ip link set c_r up
+
+ip netns exec $S ip -6 addr add 2001:db8:ffff:22::1/64 dev s_r
+ip netns exec $C ip -6 addr add 2001:db8:ffff:21::2/64 dev c_r
+ip netns exec $R ip -6 addr add 2001:db8:ffff:22::fffe/64 dev r_s
+ip netns exec $R ip -6 addr add 2001:db8:ffff:21::fffe/64 dev r_c
+ip netns exec $R sysctl -w net.ipv6.conf.all.forwarding=1
+ip netns exec $C ip route add 2001:db8:ffff:22::/64 via 2001:db8:ffff:21::fffe dev c_r
+ip netns exec $S ip route add 2001:db8:ffff:21::/64 via 2001:db8:ffff:22::fffe dev s_r
+ip netns exec $S ethtool -K s_r tso off
+ip netns exec $C ethtool -K c_r tso off
+
+sleep 3
+ip netns exec $C ping -6 2001:db8:ffff:22::1 -c1 || exit 1
+
+ip netns exec $R nft -f - <<EOF
+table ip6 filter {
+ flowtable f1 {
+ hook ingress priority -100
+ devices = { r_c, r_s }
+ }
+
+ chain forward {
+ type filter hook forward priority filter; policy accept;
+ ip6 nexthdr tcp ct state established,related counter packets 0 bytes 0 flow add @f1 counter packets 0 bytes 0
+ ip6 nexthdr tcp ct state invalid counter packets 0 bytes 0 drop
+ tcp flags fin,rst counter packets 0 bytes 0 accept
+ meta l4proto tcp meta length < 100 counter packets 0 bytes 0 accept
+ ip6 nexthdr tcp counter packets 0 bytes 0 log drop
+ }
+}
+EOF
+
+if [ ! -r /proc/net/nf_conntrack ]
+then
+ echo "E: nf_conntrack unreadable, skipping" >&2
+ exit 77
+fi
+
+ip netns exec $R nft list ruleset
+ip netns exec $R sysctl -w net.netfilter.nf_flowtable_tcp_timeout=5 || {
+ echo "E: set net.netfilter.nf_flowtable_tcp_timeout fail, skipping" >&2
+ exit 77
+}
+ip netns exec $R sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=86400 || {
+ echo "E: set net.netfilter.nf_conntrack_tcp_timeout_established fail, skipping" >&2
+ exit 77
+
+}
+
+# A trick to control the timing to send a packet
+ip netns exec $S socat TCP6-LISTEN:10001 GOPEN:/tmp/pipefile-$rnd,ignoreeof &
+sleep 1
+ip netns exec $C socat -b 2048 PIPE:/tmp/pipefile-$rnd 'TCP:[2001:db8:ffff:22::1]:10001' &
+sleep 1
+ip netns exec $R grep 'OFFLOAD' /proc/net/nf_conntrack || { echo "check [OFFLOAD] tag (failed)"; exit 1; }
+ip netns exec $R cat /proc/net/nf_conntrack
+sleep 6
+ip netns exec $R grep 'OFFLOAD' /proc/net/nf_conntrack && { echo "CT OFFLOAD timeout, fail back to classical path (failed)"; exit 1; }
+ip netns exec $R grep '8639[0-9]' /proc/net/nf_conntrack || { echo "check nf_conntrack_tcp_timeout_established (failed)"; exit 1; }
+ip netns exec $C echo "send sth" >> /tmp/pipefile-$rnd
+ip netns exec $R grep 'OFFLOAD' /proc/net/nf_conntrack || { echo "traffic seen, back to OFFLOAD path (failed)"; exit 1; }
+ip netns exec $C sleep 3
+ip netns exec $C echo "send sth" >> /tmp/pipefile-$rnd
+ip netns exec $C sleep 3
+ip netns exec $R grep 'OFFLOAD' /proc/net/nf_conntrack || { echo "Traffic seen in 5s (nf_flowtable_tcp_timeout), so stay in OFFLOAD (failed)"; exit 1; }
+
+exit 0
diff --git a/tests/shell/testcases/packetpath/match_l4proto b/tests/shell/testcases/packetpath/match_l4proto
new file mode 100755
index 00000000..31fbe6c2
--- /dev/null
+++ b/tests/shell/testcases/packetpath/match_l4proto
@@ -0,0 +1,149 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_netdev_egress)
+
+rnd=$(mktemp -u XXXXXXXX)
+ns1="nft1payload-$rnd"
+ns2="nft2payload-$rnd"
+
+cleanup()
+{
+ ip netns del "$ns1"
+ ip netns del "$ns2"
+}
+
+trap cleanup EXIT
+
+run_test()
+{
+ ns1_addr=$2
+ ns2_addr=$3
+ cidr=$4
+
+ # socat needs square brackets, ie. [abcd::2]
+ if [ $1 -eq 6 ]; then
+ nsx1_addr="["$ns1_addr"]"
+ nsx2_addr="["$ns2_addr"]"
+ else
+ nsx1_addr="$ns1_addr"
+ nsx2_addr="$ns2_addr"
+ fi
+
+ ip netns add "$ns1" || exit 111
+ ip netns add "$ns2" || exit 111
+
+ ip -net "$ns1" link set lo up
+ ip -net "$ns2" link set lo up
+
+ ip link add veth0 netns $ns1 type veth peer name veth0 netns $ns2
+
+ ip -net "$ns1" link set veth0 up
+ ip -net "$ns2" link set veth0 up
+ ip -net "$ns1" addr add $ns1_addr/$cidr dev veth0
+ ip -net "$ns2" addr add $ns2_addr/$cidr dev veth0
+
+ sleep 5
+
+RULESET="table netdev payload_netdev {
+ counter ingress {}
+ counter ingress_2 {}
+ counter egress {}
+ counter egress_2 {}
+
+ chain ingress {
+ type filter hook ingress device veth0 priority 0;
+ udp dport 7777 counter name ingress
+ meta l4proto udp counter name ingress_2
+ }
+
+ chain egress {
+ type filter hook egress device veth0 priority 0;
+ udp dport 7777 counter name egress
+ meta l4proto udp counter name egress_2
+ }
+}"
+
+ ip netns exec "$ns1" $NFT -f - <<< "$RULESET" || exit 1
+
+ ip netns exec "$ns1" bash -c "echo 'A' | socat -u STDIN UDP:$nsx2_addr:7777 > /dev/null"
+ ip netns exec "$ns1" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx2_addr:7777 > /dev/null"
+ ip netns exec "$ns1" bash -c "echo 'AAA' | socat -u STDIN UDP:$nsx2_addr:7777 > /dev/null"
+ ip netns exec "$ns1" bash -c "echo 'AAAA' | socat -u STDIN UDP:$nsx2_addr:7777 > /dev/null"
+ ip netns exec "$ns1" bash -c "echo 'AAAAA' | socat -u STDIN UDP:$nsx2_addr:7777 > /dev/null"
+
+ ip netns exec "$ns2" bash -c "echo 'A' | socat -u STDIN UDP:$nsx1_addr:7777 > /dev/null"
+ ip netns exec "$ns2" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx1_addr:7777 > /dev/null"
+ ip netns exec "$ns2" bash -c "echo 'AAA' | socat -u STDIN UDP:$nsx1_addr:7777 > /dev/null"
+ ip netns exec "$ns2" bash -c "echo 'AAAA' | socat -u STDIN UDP:$nsx1_addr:7777 > /dev/null"
+ ip netns exec "$ns2" bash -c "echo 'AAAAA' | socat -u STDIN UDP:$nsx1_addr:7777 > /dev/null"
+
+ ip netns exec "$ns1" $NFT list ruleset
+
+ ip netns exec "$ns1" $NFT list counter netdev payload_netdev ingress | grep "packets 5" > /dev/null || exit 1
+ ip netns exec "$ns1" $NFT list counter netdev payload_netdev ingress_2 | grep "packets 5" > /dev/null || exit 1
+ ip netns exec "$ns1" $NFT list counter netdev payload_netdev egress | grep "packets 5" > /dev/null || exit 1
+ ip netns exec "$ns1" $NFT list counter netdev payload_netdev egress_2| grep "packets 5" > /dev/null || exit 1
+
+ #
+ # ... next stage
+ #
+ ip netns exec "$ns1" $NFT flush ruleset
+
+ #
+ # bridge
+ #
+
+ ip -net "$ns1" addr del $ns1_addr/$cidr dev veth0
+
+ ip -net "$ns1" link add name br0 type bridge
+ ip -net "$ns1" link set veth0 master br0
+ ip -net "$ns1" addr add $ns1_addr/$cidr dev br0
+ ip -net "$ns1" link set up dev br0
+
+ sleep 5
+
+RULESET="table bridge payload_bridge {
+ counter input {}
+ counter output {}
+ counter input_2 {}
+ counter output_2 {}
+
+ chain in {
+ type filter hook input priority 0;
+ udp dport 7777 counter name input
+ meta l4proto udp counter name input_2
+ }
+
+ chain out {
+ type filter hook output priority 0;
+ udp dport 7777 counter name output
+ meta l4proto udp counter name output_2
+ }
+}"
+
+ ip netns exec "$ns1" $NFT -f - <<< "$RULESET" || exit 1
+
+ ip netns exec "$ns1" bash -c "echo 'A' | socat -u STDIN UDP:$nsx2_addr:7777 > /dev/null"
+ ip netns exec "$ns1" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx2_addr:7777 > /dev/null"
+ ip netns exec "$ns1" bash -c "echo 'AAA' | socat -u STDIN UDP:$nsx2_addr:7777 > /dev/null"
+ ip netns exec "$ns1" bash -c "echo 'AAAA' | socat -u STDIN UDP:$nsx2_addr:7777 > /dev/null"
+ ip netns exec "$ns1" bash -c "echo 'AAAAA' | socat -u STDIN UDP:$nsx2_addr:7777 > /dev/null"
+
+ ip netns exec "$ns2" bash -c "echo 'A' | socat -u STDIN UDP:$nsx1_addr:7777 > /dev/null"
+ ip netns exec "$ns2" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx1_addr:7777 > /dev/null"
+ ip netns exec "$ns2" bash -c "echo 'AAA' | socat -u STDIN UDP:$nsx1_addr:7777 > /dev/null"
+ ip netns exec "$ns2" bash -c "echo 'AAAA' | socat -u STDIN UDP:$nsx1_addr:7777 > /dev/null"
+ ip netns exec "$ns2" bash -c "echo 'AAAAA' | socat -u STDIN UDP:$nsx1_addr:7777 > /dev/null"
+
+ ip netns exec "$ns1" $NFT list ruleset
+
+ ip netns exec "$ns1" $NFT list counter bridge payload_bridge input | grep "packets 5" > /dev/null || exit 1
+ ip netns exec "$ns1" $NFT list counter bridge payload_bridge input_2 | grep "packets 5" > /dev/null || exit 1
+ ip netns exec "$ns1" $NFT list counter bridge payload_bridge output | grep "packets 5" > /dev/null || exit 1
+ ip netns exec "$ns1" $NFT list counter bridge payload_bridge output_2 | grep "packets 5" > /dev/null || exit 1
+}
+
+run_test "4" "10.141.10.2" "10.141.10.3" "24"
+cleanup
+run_test "6" "abcd::2" "abcd::3" "64"
+# trap calls cleanup
diff --git a/tests/shell/testcases/packetpath/payload b/tests/shell/testcases/packetpath/payload
new file mode 100755
index 00000000..83e0b7fc
--- /dev/null
+++ b/tests/shell/testcases/packetpath/payload
@@ -0,0 +1,251 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_netdev_egress)
+
+rnd=$(mktemp -u XXXXXXXX)
+ns1="nft1payload-$rnd"
+ns2="nft2payload-$rnd"
+
+cleanup()
+{
+ ip netns del "$ns1"
+ ip netns del "$ns2"
+}
+
+trap cleanup EXIT
+
+run_test()
+{
+ ns1_addr=$2
+ ns2_addr=$3
+ cidr=$4
+ mode=$5
+
+ case $mode in
+ "udp")
+ l4proto="udp"
+ udp_checksum="udp checksum != 0"
+ udp_zero_checksum=""
+ ;;
+ "udp-zero-checksum")
+ l4proto="udp"
+ udp_checksum="udp checksum 0"
+ udp_zero_checksum="udp checksum set 0"
+ ;;
+ "tcp")
+ l4proto="tcp"
+ udp_checksum=""
+ udp_zero_checksum=""
+ ;;
+ *)
+ echo "unexpected, incorrect mode"
+ exit 0
+ esac
+
+ # socat needs square brackets, ie. [abcd::2]
+ if [ $1 -eq 6 ]; then
+ nsx1_addr="["$ns1_addr"]"
+ nsx2_addr="["$ns2_addr"]"
+ else
+ nsx1_addr="$ns1_addr"
+ nsx2_addr="$ns2_addr"
+ fi
+
+ ip netns add "$ns1" || exit 111
+ ip netns add "$ns2" || exit 111
+
+ ip -net "$ns1" link set lo up
+ ip -net "$ns2" link set lo up
+
+ ip link add veth0 netns $ns1 type veth peer name veth0 netns $ns2
+
+ ip -net "$ns1" link set veth0 up
+ ip -net "$ns2" link set veth0 up
+ ip -net "$ns1" addr add $ns1_addr/$cidr dev veth0
+ ip -net "$ns2" addr add $ns2_addr/$cidr dev veth0
+
+ sleep 3
+
+RULESET="table netdev payload_netdev {
+ counter ingress {}
+ counter egress {}
+ counter mangle_ingress {}
+ counter mangle_egress {}
+ counter mangle_ingress_match {}
+ counter mangle_egress_match {}
+
+ chain ingress {
+ type filter hook ingress device veth0 priority 0;
+ $udp_zero_checksum
+ $l4proto dport 7777 counter name ingress
+ $l4proto dport 7778 $l4proto dport set 7779 $udp_checksum counter name mangle_ingress
+ $l4proto dport 7779 counter name mangle_ingress_match
+ }
+
+ chain egress {
+ type filter hook egress device veth0 priority 0;
+ $udp_zero_checksum
+ $l4proto dport 8887 counter name egress
+ $l4proto dport 8888 $l4proto dport set 8889 $udp_checksum counter name mangle_egress
+ $l4proto dport 8889 counter name mangle_egress_match
+ }
+}
+
+table inet payload_inet {
+ counter input {}
+ counter output {}
+ counter mangle_input {}
+ counter mangle_output {}
+ counter mangle_input_match {}
+ counter mangle_output_match {}
+
+ chain in {
+ type filter hook input priority 0;
+ $udp_zero_checksum
+ $l4proto dport 7770 counter name input
+ $l4proto dport 7771 $l4proto dport set 7772 $udp_checksum counter name mangle_input
+ $l4proto dport 7772 counter name mangle_input_match
+ }
+
+ chain out {
+ type filter hook output priority 0;
+ $udp_zero_checksum
+ $l4proto dport 8880 counter name output
+ $l4proto dport 8881 $l4proto dport set 8882 $udp_checksum counter name mangle_output
+ $l4proto dport 8882 counter name mangle_output_match
+ }
+}"
+
+ ip netns exec "$ns1" $NFT -f - <<< "$RULESET" || exit 1
+
+ case $l4proto in
+ "tcp")
+ ip netns exec "$ns1" socat -u STDIN TCP:$nsx2_addr:8887,connect-timeout=4 < /dev/null > /dev/null
+ ip netns exec "$ns1" socat -u STDIN TCP:$nsx2_addr:8888,connect-timeout=4 < /dev/null > /dev/null
+
+ ip netns exec "$ns1" socat -u STDIN TCP:$nsx2_addr:8880,connect-timeout=4 < /dev/null > /dev/null
+ ip netns exec "$ns1" socat -u STDIN TCP:$nsx2_addr:8881,connect-timeout=4 < /dev/null > /dev/null
+
+ ip netns exec "$ns2" socat -u STDIN TCP:$nsx1_addr:7777,connect-timeout=4 < /dev/null > /dev/null
+ ip netns exec "$ns2" socat -u STDIN TCP:$nsx1_addr:7778,connect-timeout=4 < /dev/null > /dev/null
+
+ ip netns exec "$ns2" socat -u STDIN TCP:$nsx1_addr:7770,connect-timeout=4 < /dev/null > /dev/null
+ ip netns exec "$ns2" socat -u STDIN TCP:$nsx1_addr:7771,connect-timeout=4 < /dev/null > /dev/null
+ ;;
+ "udp")
+ ip netns exec "$ns1" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx2_addr:8887 > /dev/null"
+ ip netns exec "$ns1" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx2_addr:8888 > /dev/null"
+
+ ip netns exec "$ns1" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx2_addr:8880 > /dev/null"
+ ip netns exec "$ns1" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx2_addr:8881 > /dev/null"
+
+ ip netns exec "$ns2" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx1_addr:7777 > /dev/null"
+ ip netns exec "$ns2" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx1_addr:7778 > /dev/null"
+
+ ip netns exec "$ns2" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx1_addr:7770 > /dev/null"
+ ip netns exec "$ns2" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx1_addr:7771 > /dev/null"
+ ;;
+ esac
+
+ ip netns exec "$ns1" $NFT list ruleset
+
+ ip netns exec "$ns1" $NFT list counter netdev payload_netdev ingress | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter netdev payload_netdev mangle_ingress | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter netdev payload_netdev mangle_ingress_match | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter netdev payload_netdev egress | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter netdev payload_netdev mangle_egress | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter netdev payload_netdev mangle_egress_match | grep -q "packets 0" && exit 1
+
+ ip netns exec "$ns1" $NFT list counter inet payload_inet input | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter inet payload_inet mangle_input | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter inet payload_inet mangle_input_match | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter inet payload_inet output | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter inet payload_inet mangle_output | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter inet payload_inet mangle_output_match | grep -q "packets 0" && exit 1
+
+ #
+ # ... next stage
+ #
+
+ ip netns exec "$ns1" $NFT flush ruleset
+
+ #
+ # bridge
+ #
+
+ ip -net "$ns1" addr del $ns1_addr/$cidr dev veth0
+
+ ip -net "$ns1" link add name br0 type bridge
+ ip -net "$ns1" link set veth0 master br0
+ ip -net "$ns1" addr add $ns1_addr/$cidr dev br0
+ ip -net "$ns1" link set up dev br0
+
+ sleep 3
+
+RULESET="table bridge payload_bridge {
+ counter input {}
+ counter output {}
+ counter mangle_input {}
+ counter mangle_output {}
+ counter mangle_input_match {}
+ counter mangle_output_match {}
+
+ chain in {
+ type filter hook input priority 0;
+ $udp_zero_checksum
+ $l4proto dport 7770 counter name input
+ $l4proto dport 7771 $l4proto dport set 7772 $udp_checksum counter name mangle_input
+ $l4proto dport 7772 counter name mangle_input_match
+ }
+
+ chain out {
+ type filter hook output priority 0;
+ $udp_zero_checksum
+ $l4proto dport 8880 counter name output
+ $l4proto dport 8881 $l4proto dport set 8882 $udp_checksum counter name mangle_output
+ $l4proto dport 8882 counter name mangle_output_match
+ }
+}"
+
+ ip netns exec "$ns1" $NFT -f - <<< "$RULESET" || exit 1
+
+ case $l4proto in
+ "tcp")
+ ip netns exec "$ns1" socat -u STDIN TCP:$nsx2_addr:8880,connect-timeout=4 < /dev/null > /dev/null
+ ip netns exec "$ns1" socat -u STDIN TCP:$nsx2_addr:8881,connect-timeout=4 < /dev/null > /dev/null
+
+ ip netns exec "$ns2" socat -u STDIN TCP:$nsx1_addr:7770,connect-timeout=4 < /dev/null > /dev/null
+ ip netns exec "$ns2" socat -u STDIN TCP:$nsx1_addr:7771,connect-timeout=4 < /dev/null > /dev/null
+ ;;
+ "udp")
+ ip netns exec "$ns1" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx2_addr:8880 > /dev/null"
+ ip netns exec "$ns1" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx2_addr:8881 > /dev/null"
+
+ ip netns exec "$ns2" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx1_addr:7770 > /dev/null"
+ ip netns exec "$ns2" bash -c "echo 'AA' | socat -u STDIN UDP:$nsx1_addr:7771 > /dev/null"
+ ;;
+ esac
+
+ ip netns exec "$ns1" $NFT list ruleset
+
+ ip netns exec "$ns1" $NFT list counter bridge payload_bridge input | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter bridge payload_bridge mangle_input | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter bridge payload_bridge mangle_input_match | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter bridge payload_bridge output | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter bridge payload_bridge mangle_output | grep -q "packets 0" && exit 1
+ ip netns exec "$ns1" $NFT list counter bridge payload_bridge mangle_output_match | grep -q "packets 0" && exit 1
+}
+
+run_test "4" "10.141.10.2" "10.141.10.3" "24" "tcp"
+cleanup
+run_test 6 "abcd::2" "abcd::3" "64" "tcp"
+cleanup
+run_test "4" "10.141.10.2" "10.141.10.3" "24" "udp"
+cleanup
+run_test 6 "abcd::2" "abcd::3" "64" "udp"
+cleanup
+run_test "4" "10.141.10.2" "10.141.10.3" "24" "udp-zero-checksum"
+cleanup
+run_test 6 "abcd::2" "abcd::3" "64" "udp-zero-checksum"
+# trap calls cleanup
+exit 0
diff --git a/tests/shell/testcases/packetpath/policy b/tests/shell/testcases/packetpath/policy
new file mode 100755
index 00000000..0bb42a54
--- /dev/null
+++ b/tests/shell/testcases/packetpath/policy
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+ip link set lo up
+
+$NFT -f - <<EOF
+table inet filter {
+ chain underflow { }
+
+ chain input {
+ type filter hook input priority filter; policy accept;
+ icmp type echo-reply accept
+ ip saddr 127.0.0.1 ip daddr 127.0.0.2 counter accept
+ goto underflow
+ }
+}
+EOF
+[ $? -ne 0 ] && exit 1
+
+ping -q -c 1 127.0.0.2 >/dev/null || exit 2
+
+# should work, polict is accept.
+ping -q -c 1 127.0.0.1 >/dev/null || exit 1
+
+$NFT -f - <<EOF
+table inet filter {
+ chain input {
+ type filter hook input priority filter; policy drop;
+ }
+}
+EOF
+[ $? -ne 0 ] && exit 1
+
+$NFT list ruleset
+
+ping -W 1 -q -c 1 127.0.0.2
+
+ping -q -c 1 127.0.0.2 >/dev/null || exit 2
+
+# should fail, policy is set to drop
+ping -W 1 -q -c 1 127.0.0.1 >/dev/null 2>&1 && exit 1
+
+exit 0
diff --git a/tests/shell/testcases/packetpath/set_lookups b/tests/shell/testcases/packetpath/set_lookups
new file mode 100755
index 00000000..85159858
--- /dev/null
+++ b/tests/shell/testcases/packetpath/set_lookups
@@ -0,0 +1,66 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_pipapo)
+
+set -e
+
+$NFT -f /dev/stdin <<"EOF"
+table ip t {
+ set s {
+ type ipv4_addr . iface_index
+ flags interval
+ elements = { 127.0.0.1 . 1 }
+ }
+
+ set s2 {
+ typeof ip saddr . meta iif
+ elements = { 127.0.0.1 . 1 }
+ }
+
+ set s3 {
+ type iface_index
+ elements = { "lo" }
+ }
+
+ set s4 {
+ type iface_index
+ flags interval
+ elements = { "lo" }
+ }
+
+ set nomatch {
+ typeof ip saddr . meta iif
+ elements = { 127.0.0.3 . 1 }
+ }
+
+ set nomatch2 {
+ type ipv4_addr . iface_index
+ elements = { 127.0.0.2 . 90000 }
+ }
+
+ chain c {
+ type filter hook input priority filter;
+ icmp type echo-request ip saddr . meta iif @s counter
+ icmp type echo-request ip saddr . 1 @s counter
+ icmp type echo-request ip saddr . "lo" @s counter
+ icmp type echo-request ip saddr . meta iif @s2 counter
+ icmp type echo-request ip saddr . 1 @s2 counter
+ icmp type echo-request ip saddr . "lo" @s2 counter
+
+ icmp type echo-request ip daddr . "lo" @s counter
+ icmp type echo-request ip daddr . "lo" @s2 counter
+
+ icmp type echo-request meta iif @s3 counter
+ icmp type echo-request meta iif @s4 counter
+
+ ip daddr . 1 @nomatch counter drop
+ ip daddr . meta iif @nomatch2 counter drop
+ }
+}
+EOF
+
+$NFT add element t s { 127.0.0.2 . 1 }
+$NFT add element t s2 { 127.0.0.2 . "lo" }
+
+ip link set lo up
+ping -q -c 1 127.0.0.2 > /dev/null
diff --git a/tests/shell/testcases/packetpath/tcp_options b/tests/shell/testcases/packetpath/tcp_options
new file mode 100755
index 00000000..57e228c5
--- /dev/null
+++ b/tests/shell/testcases/packetpath/tcp_options
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_reset_tcp_options)
+
+have_socat="no"
+socat -h > /dev/null && have_socat="yes"
+
+ip link set lo up
+
+$NFT -f /dev/stdin <<EOF
+table inet t {
+ counter nomatchc {}
+ counter sackpermc {}
+ counter maxsegc {}
+ counter nopc {}
+
+ chain c {
+ type filter hook output priority 0;
+ tcp dport != 22345 accept
+ tcp flags & (fin | syn | rst | ack ) == syn tcp option 254 length ge 4 counter name nomatchc drop
+ tcp flags & (fin | syn | rst | ack ) == syn tcp option fastopen length ge 2 reset tcp option fastopen counter name nomatchc
+ tcp flags & (fin | syn | rst | ack ) == syn tcp option sack-perm missing counter name nomatchc
+ tcp flags & (fin | syn | rst | ack) == syn tcp option sack-perm exists counter name sackpermc
+ tcp flags & (fin | syn | rst | ack) == syn tcp option maxseg size gt 1400 counter name maxsegc
+ tcp flags & (fin | syn | rst | ack) == syn tcp option nop missing counter name nomatchc
+ tcp flags & (fin | syn | rst | ack) == syn tcp option nop exists counter name nopc
+ tcp flags & (fin | syn | rst | ack) == syn drop
+ }
+}
+EOF
+
+if [ $? -ne 0 ]; then
+ exit 1
+fi
+
+if [ $have_socat != "yes" ]; then
+ echo "Ran partial test, socat not available (skipped)"
+ exit 77
+fi
+
+# This will fail (drop in output -> connect fails with eperm)
+socat -u STDIN TCP:127.0.0.1:22345,connect-timeout=1 < /dev/null > /dev/null
+
+# can't validate via dump file, syn rexmit can cause counters to be > 1 in rare cases.
+
+$NFT list counter inet t nomatchc
+
+# nomatchc must be 0.
+$NFT list counter inet t nomatchc | grep -q "packets 0" || exit 1
+
+# these counters must not be 0.
+for nz in sackpermc maxsegc nopc; do
+ $NFT list counter inet t $nz
+ $NFT list counter inet t $nz | grep -q "packets 0" && exit 1
+done
+
+exit 0
diff --git a/tests/shell/testcases/packetpath/tcp_reset b/tests/shell/testcases/packetpath/tcp_reset
new file mode 100755
index 00000000..3dfcdde4
--- /dev/null
+++ b/tests/shell/testcases/packetpath/tcp_reset
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# regression check for kernel commit
+# netfilter: nf_reject: init skb->dev for reset packet
+
+socat -h > /dev/null || exit 77
+
+ip link set lo up
+
+$NFT -f - <<EOF
+table inet filter {
+ chain input {
+ type filter hook input priority filter; policy accept;
+ meta nftrace set 1
+ ip daddr 127.0.0.1 tcp dport 5555 reject with tcp reset
+ ip6 daddr ::1 tcp dport 5555 reject with tcp reset
+ tcp dport 5555 counter
+ }
+ chain output {
+ type filter hook output priority filter; policy accept;
+ # empty chain, so nf_hook_slow is called from ip_local_out.
+ }
+}
+EOF
+[ $? -ne 0 ] && exit 1
+
+socat -u STDIN TCP:127.0.0.1:5555,connect-timeout=2 < /dev/null > /dev/null
+socat -u STDIN TCP:[::1]:5555,connect-timeout=2 < /dev/null > /dev/null
+
+$NFT list ruleset |grep -q 'counter packets 0 bytes 0' || exit 1
+exit 0
diff --git a/tests/shell/testcases/packetpath/vlan_8021ad_tag b/tests/shell/testcases/packetpath/vlan_8021ad_tag
new file mode 100755
index 00000000..379a5710
--- /dev/null
+++ b/tests/shell/testcases/packetpath/vlan_8021ad_tag
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+rnd=$(mktemp -u XXXXXXXX)
+ns1="nft1ifname-$rnd"
+ns2="nft2ifname-$rnd"
+
+cleanup()
+{
+ ip netns del "$ns1"
+ ip netns del "$ns2"
+}
+
+trap cleanup EXIT
+
+set -e
+
+ip netns add "$ns1"
+ip netns add "$ns2"
+ip -net "$ns1" link set lo up
+ip -net "$ns2" link set lo up
+
+ip link add veth0 netns $ns1 type veth peer name veth0 netns $ns2
+
+ip -net "$ns1" link set veth0 addr da:d3:00:01:02:03
+
+ip -net "$ns1" link add vlan123 link veth0 type vlan id 123 proto 802.1ad
+ip -net "$ns2" link add vlan123 link veth0 type vlan id 123 proto 802.1ad
+
+
+for dev in veth0 vlan123; do
+ ip -net "$ns1" link set $dev up
+ ip -net "$ns2" link set $dev up
+done
+
+ip -net "$ns1" addr add 10.1.1.1/24 dev vlan123
+ip -net "$ns2" addr add 10.1.1.2/24 dev vlan123
+
+ip netns exec "$ns2" $NFT -f /dev/stdin <<"EOF"
+table netdev t {
+ chain c {
+ type filter hook ingress device veth0 priority filter;
+ ether saddr da:d3:00:01:02:03 ether type 8021ad vlan id 123 ip daddr 10.1.1.2 icmp type echo-request counter
+ }
+}
+EOF
+
+ip netns exec "$ns1" ping -c 1 10.1.1.2
+
+ip netns exec "$ns2" $NFT list ruleset
+ip netns exec "$ns2" $NFT list chain netdev t c | grep 'counter packets 1 bytes 84'
diff --git a/tests/shell/testcases/packetpath/vlan_mangling b/tests/shell/testcases/packetpath/vlan_mangling
new file mode 100755
index 00000000..e3fd443e
--- /dev/null
+++ b/tests/shell/testcases/packetpath/vlan_mangling
@@ -0,0 +1,77 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_netdev_egress)
+
+rnd=$(mktemp -u XXXXXXXX)
+ns1="nft1ifname-$rnd"
+ns2="nft2ifname-$rnd"
+
+cleanup()
+{
+ ip netns del "$ns1"
+ ip netns del "$ns2"
+}
+
+trap cleanup EXIT
+
+set -e
+
+ip netns add "$ns1"
+ip netns add "$ns2"
+ip -net "$ns1" link set lo up
+ip -net "$ns2" link set lo up
+
+ip link add veth0 netns $ns1 type veth peer name veth0 netns $ns2
+
+ip -net "$ns1" link set veth0 addr da:d3:00:01:02:03
+
+ip -net "$ns1" link add vlan123 link veth0 type vlan id 123
+ip -net "$ns2" link add vlan321 link veth0 type vlan id 321
+
+
+for dev in veth0 ; do
+ ip -net "$ns1" link set $dev up
+ ip -net "$ns2" link set $dev up
+done
+ip -net "$ns1" link set vlan123 up
+ip -net "$ns2" link set vlan321 up
+
+ip -net "$ns1" addr add 10.1.1.1/24 dev vlan123
+ip -net "$ns2" addr add 10.1.1.2/24 dev vlan321
+
+ip netns exec "$ns2" $NFT -f /dev/stdin <<"EOF"
+table netdev t {
+ chain in_update_vlan {
+ vlan type arp vlan id set 321 counter
+ ip saddr 10.1.1.1 icmp type echo-request vlan id set 321 counter
+ }
+
+ chain in {
+ type filter hook ingress device veth0 priority filter;
+ ether saddr da:d3:00:01:02:03 vlan id 123 jump in_update_vlan
+ }
+
+ chain out_update_vlan {
+ vlan type arp vlan id set 123 counter
+ ip daddr 10.1.1.1 icmp type echo-reply vlan id set 123 counter
+ }
+
+ chain out {
+ type filter hook egress device veth0 priority filter;
+ ether daddr da:d3:00:01:02:03 vlan id 321 jump out_update_vlan
+ }
+}
+EOF
+
+ip netns exec "$ns1" ping -c 1 10.1.1.2
+
+set +e
+
+ip netns exec "$ns2" $NFT list ruleset
+ip netns exec "$ns2" $NFT list table netdev t | grep 'counter packets' | grep 'counter packets 0 bytes 0'
+if [ $? -eq 1 ]
+then
+ exit 0
+fi
+
+exit 1
diff --git a/tests/shell/testcases/packetpath/vlan_qinq b/tests/shell/testcases/packetpath/vlan_qinq
new file mode 100755
index 00000000..28655766
--- /dev/null
+++ b/tests/shell/testcases/packetpath/vlan_qinq
@@ -0,0 +1,73 @@
+#!/bin/bash
+
+rnd=$(mktemp -u XXXXXXXX)
+ns1="nft1ifname-$rnd"
+ns2="nft2ifname-$rnd"
+
+cleanup()
+{
+ ip netns del "$ns1"
+ ip netns del "$ns2"
+}
+
+trap cleanup EXIT
+
+set -e
+
+ip netns add "$ns1"
+ip netns add "$ns2"
+ip -net "$ns1" link set lo up
+ip -net "$ns2" link set lo up
+
+ip link add veth0 netns $ns1 type veth peer name veth0 netns $ns2
+
+ip -net "$ns1" link set veth0 addr da:d3:00:01:02:03
+
+ip -net "$ns1" link add link veth0 name vlan10 type vlan proto 802.1ad id 10
+ip -net "$ns1" link add link vlan10 name vlan10.100 type vlan proto 802.1q id 100
+
+ip -net "$ns2" link add link veth0 name vlan10 type vlan proto 802.1ad id 10
+ip -net "$ns2" link add link vlan10 name vlan10.100 type vlan proto 802.1q id 100
+
+for dev in veth0 vlan10 vlan10.100; do
+ ip -net "$ns1" link set $dev up
+ ip -net "$ns2" link set $dev up
+done
+
+ip -net "$ns1" addr add 10.1.1.1/24 dev vlan10.100
+ip -net "$ns2" addr add 10.1.1.2/24 dev vlan10.100
+
+ip netns exec "$ns2" $NFT -f /dev/stdin <<"EOF"
+table netdev t {
+ chain c1 {
+ type filter hook ingress device veth0 priority filter;
+ ether type 8021ad vlan id 10 vlan type 8021q vlan id 100 vlan type ip counter
+ }
+
+ chain c2 {
+ type filter hook ingress device vlan10 priority filter;
+ vlan id 100 ip daddr 10.1.1.2 counter
+ }
+
+ chain c3 {
+ type filter hook ingress device vlan10.100 priority filter;
+ ip daddr 10.1.1.2 counter
+ }
+}
+EOF
+
+ip netns exec "$ns1" ping -c 1 10.1.1.2
+ip netns exec "$ns2" $NFT list ruleset
+
+set +e
+
+ip netns exec "$ns2" $NFT list chain netdev t c1 | grep 'counter packets 0 bytes 0'
+[[ $? -eq 0 ]] && exit 1
+
+ip netns exec "$ns2" $NFT list chain netdev t c2 | grep 'counter packets 0 bytes 0'
+[[ $? -eq 0 ]] && exit 1
+
+ip netns exec "$ns2" $NFT list chain netdev t c3 | grep 'counter packets 0 bytes 0'
+[[ $? -eq 0 ]] && exit 1
+
+exit 0