summaryrefslogtreecommitdiffstats
path: root/tests/shell
diff options
context:
space:
mode:
Diffstat (limited to 'tests/shell')
-rw-r--r--tests/shell/README29
-rwxr-xr-xtests/shell/run-tests.sh19
-rwxr-xr-xtests/shell/testcases/cache/0010_implicit_chain_019
-rwxr-xr-xtests/shell/testcases/chains/0021prio_01
-rwxr-xr-xtests/shell/testcases/chains/0026prio_netdev_14
-rwxr-xr-xtests/shell/testcases/chains/0040mark_shift_02
-rwxr-xr-xtests/shell/testcases/chains/0041chain_binding_06
-rwxr-xr-xtests/shell/testcases/chains/0043chain_ingress_06
-rw-r--r--tests/shell/testcases/chains/dumps/0021prio_0.nft20
-rwxr-xr-xtests/shell/testcases/comments/comments_044
-rw-r--r--tests/shell/testcases/comments/dumps/comments_0.nft12
-rwxr-xr-xtests/shell/testcases/json/0001set_statements_09
-rwxr-xr-xtests/shell/testcases/json/0002table_map_09
-rwxr-xr-xtests/shell/testcases/json/0003json_schema_version_09
-rwxr-xr-xtests/shell/testcases/json/0004json_schema_version_111
-rwxr-xr-xtests/shell/testcases/json/0005secmark_objref_09
-rwxr-xr-xtests/shell/testcases/json/0006obj_comment_09
-rw-r--r--tests/shell/testcases/json/dumps/0001set_statements_0.nft12
-rw-r--r--tests/shell/testcases/json/dumps/0002table_map_0.nft6
-rw-r--r--tests/shell/testcases/json/dumps/0003json_schema_version_0.nft0
-rw-r--r--tests/shell/testcases/json/dumps/0004json_schema_version_1.nft0
-rw-r--r--tests/shell/testcases/json/dumps/0005secmark_objref_0.nft18
-rw-r--r--tests/shell/testcases/json/dumps/0006obj_comment_0.nft6
-rwxr-xr-xtests/shell/testcases/json/netdev19
-rwxr-xr-xtests/shell/testcases/listing/0020flowtable_051
-rwxr-xr-xtests/shell/testcases/listing/0022terse_069
-rwxr-xr-xtests/shell/testcases/maps/0012map_019
-rwxr-xr-xtests/shell/testcases/maps/0013map_014
-rwxr-xr-xtests/shell/testcases/maps/anon_objmap_concat6
-rw-r--r--tests/shell/testcases/maps/dumps/0010concat_map_0.nft2
-rw-r--r--tests/shell/testcases/maps/dumps/0012map_0.nft13
-rw-r--r--tests/shell/testcases/maps/dumps/0013map_0.nft13
-rw-r--r--tests/shell/testcases/maps/dumps/anon_objmap_concat.nft16
-rw-r--r--tests/shell/testcases/maps/dumps/nat_addr_port.nft8
-rw-r--r--tests/shell/testcases/maps/dumps/typeof_integer_0.nft20
-rw-r--r--tests/shell/testcases/maps/dumps/typeof_maps_0.nft9
-rw-r--r--tests/shell/testcases/maps/dumps/typeof_maps_concat.nft11
-rw-r--r--tests/shell/testcases/maps/dumps/typeof_maps_concat_update_0.nft13
-rw-r--r--tests/shell/testcases/maps/dumps/typeof_raw_0.nft13
-rwxr-xr-xtests/shell/testcases/maps/typeof_integer_027
-rwxr-xr-xtests/shell/testcases/maps/typeof_maps_09
-rwxr-xr-xtests/shell/testcases/maps/typeof_maps_concat6
-rwxr-xr-xtests/shell/testcases/maps/typeof_maps_concat_update_019
-rwxr-xr-xtests/shell/testcases/maps/typeof_raw_018
-rwxr-xr-xtests/shell/testcases/nft-f/0029split_file_025
-rwxr-xr-xtests/shell/testcases/nft-f/0030variable_reuse_019
-rwxr-xr-xtests/shell/testcases/nft-f/0031vmap_string_021
-rw-r--r--tests/shell/testcases/nft-f/dumps/0030variable_reuse_0.nft11
-rw-r--r--tests/shell/testcases/optimizations/dumps/merge_nat.nft20
-rw-r--r--tests/shell/testcases/optimizations/dumps/merge_reject.nft13
-rw-r--r--tests/shell/testcases/optimizations/dumps/merge_stmts.nft5
-rw-r--r--tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft18
-rw-r--r--tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.nft9
-rw-r--r--tests/shell/testcases/optimizations/dumps/merge_stmts_vmap.nft9
-rw-r--r--tests/shell/testcases/optimizations/dumps/merge_vmap_raw.nft31
-rw-r--r--tests/shell/testcases/optimizations/dumps/merge_vmaps.nft20
-rw-r--r--tests/shell/testcases/optimizations/dumps/not_mergeable.nft19
-rw-r--r--tests/shell/testcases/optimizations/dumps/skip_merge.nft23
-rw-r--r--tests/shell/testcases/optimizations/dumps/skip_non_eq.nft6
-rw-r--r--tests/shell/testcases/optimizations/dumps/skip_unsupported.nft7
-rwxr-xr-xtests/shell/testcases/optimizations/merge_nat39
-rwxr-xr-xtests/shell/testcases/optimizations/merge_reject26
-rwxr-xr-xtests/shell/testcases/optimizations/merge_stmts13
-rwxr-xr-xtests/shell/testcases/optimizations/merge_stmts_concat35
-rwxr-xr-xtests/shell/testcases/optimizations/merge_stmts_concat_vmap17
-rwxr-xr-xtests/shell/testcases/optimizations/merge_stmts_vmap17
-rwxr-xr-xtests/shell/testcases/optimizations/merge_vmap_raw32
-rwxr-xr-xtests/shell/testcases/optimizations/merge_vmaps31
-rwxr-xr-xtests/shell/testcases/optimizations/not_mergeable22
-rwxr-xr-xtests/shell/testcases/optimizations/ruleset168
-rwxr-xr-xtests/shell/testcases/optimizations/skip_merge34
-rwxr-xr-xtests/shell/testcases/optimizations/skip_non_eq12
-rwxr-xr-xtests/shell/testcases/optimizations/skip_unsupported14
-rwxr-xr-xtests/shell/testcases/optimizations/variables15
-rwxr-xr-xtests/shell/testcases/owner/0001-flowtable-uaf22
-rwxr-xr-xtests/shell/testcases/parsing/describe7
-rwxr-xr-xtests/shell/testcases/parsing/log10
-rwxr-xr-xtests/shell/testcases/parsing/octal13
-rwxr-xr-xtests/shell/testcases/rule_management/0003insert_04
-rwxr-xr-xtests/shell/testcases/rule_management/0011reset_0168
-rw-r--r--tests/shell/testcases/rule_management/dumps/0003insert_0.nft1
-rw-r--r--tests/shell/testcases/rule_management/dumps/0011reset_0.nft31
-rwxr-xr-xtests/shell/testcases/sets/0024named_objects_015
-rwxr-xr-xtests/shell/testcases/sets/0031set_timeout_size_02
-rwxr-xr-xtests/shell/testcases/sets/0045concat_ipv4_service16
-rwxr-xr-xtests/shell/testcases/sets/0046netmap_06
-rwxr-xr-xtests/shell/testcases/sets/0064map_catchall_05
-rwxr-xr-xtests/shell/testcases/sets/0067nat_concat_interval_011
-rwxr-xr-xtests/shell/testcases/sets/0068interval_stack_overflow_029
-rwxr-xr-xtests/shell/testcases/sets/0069interval_merge_028
-rwxr-xr-xtests/shell/testcases/sets/0070stacked_l2_headers6
-rwxr-xr-xtests/shell/testcases/sets/0071unclosed_prefix_interval_023
-rwxr-xr-xtests/shell/testcases/sets/automerge_0113
-rwxr-xr-xtests/shell/testcases/sets/collapse_elem_019
-rwxr-xr-xtests/shell/testcases/sets/concat_interval_024
-rw-r--r--tests/shell/testcases/sets/dumps/0024named_objects_0.nft18
-rw-r--r--tests/shell/testcases/sets/dumps/0045concat_ipv4_service.nft12
-rw-r--r--tests/shell/testcases/sets/dumps/0046netmap_0.nft6
-rw-r--r--tests/shell/testcases/sets/dumps/0064map_catchall_0.nft6
-rw-r--r--tests/shell/testcases/sets/dumps/0067nat_concat_interval_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0069interval_merge_0.nft9
-rw-r--r--tests/shell/testcases/sets/dumps/0070stacked_l2_headers.nft28
-rw-r--r--tests/shell/testcases/sets/dumps/0071unclosed_prefix_interval_0.nft19
-rw-r--r--tests/shell/testcases/sets/dumps/collapse_elem_0.nft12
-rw-r--r--tests/shell/testcases/sets/dumps/concat_interval_0.nft14
-rw-r--r--tests/shell/testcases/sets/dumps/dynset_missing.nft12
-rw-r--r--tests/shell/testcases/sets/dumps/inner_0.nft18
-rw-r--r--tests/shell/testcases/sets/dumps/set_eval_0.nft11
-rw-r--r--tests/shell/testcases/sets/dumps/sets_with_ifnames.nft62
-rw-r--r--tests/shell/testcases/sets/dumps/typeof_raw_0.nft12
-rw-r--r--tests/shell/testcases/sets/dumps/typeof_sets_0.nft73
-rw-r--r--tests/shell/testcases/sets/dumps/typeof_sets_1.nft15
-rw-r--r--tests/shell/testcases/sets/dumps/typeof_sets_concat.nft12
-rwxr-xr-xtests/shell/testcases/sets/dynset_missing32
-rwxr-xr-xtests/shell/testcases/sets/errors_069
-rwxr-xr-xtests/shell/testcases/sets/exact_overlap_022
-rwxr-xr-xtests/shell/testcases/sets/inner_025
-rwxr-xr-xtests/shell/testcases/sets/set_eval_017
-rwxr-xr-xtests/shell/testcases/sets/sets_with_ifnames150
-rwxr-xr-xtests/shell/testcases/sets/typeof_raw_017
-rwxr-xr-xtests/shell/testcases/sets/typeof_sets_072
-rwxr-xr-xtests/shell/testcases/sets/typeof_sets_122
-rwxr-xr-xtests/shell/testcases/sets/typeof_sets_concat6
123 files changed, 2672 insertions, 25 deletions
diff --git a/tests/shell/README b/tests/shell/README
index e0279bbd..3af17a9e 100644
--- a/tests/shell/README
+++ b/tests/shell/README
@@ -1,16 +1,20 @@
-This test-suite is intended to perform tests of higher level than
-the other regression test-suite.
+This test suite is intended to perform tests on a higher level
+than the other regression test suites.
-It can run arbitrary executables which can perform any test apart of testing
-the nft syntax or netlink code (which is what the regression tests does).
+It can run arbitrary executables which can perform any test, not
+limited to testing the nft syntax or netlink code (which is what
+the regression tests do).
To run the test suite (as root):
$ cd tests/shell
# ./run-tests.sh
-Test files are executables files with the pattern <<name_N>>, where N is the
-expected return code of the executable. Since they are located with `find',
-test-files can be spread in any sub-directories.
+Test files are executable files matching the pattern <<name_N>>,
+where N should be 0 in all new tests. All tests should return 0 on
+success.
+
+Since they are located with `find', test files can be put in any
+subdirectory.
You can turn on a verbose execution by calling:
# ./run-tests.sh -v
@@ -18,11 +22,14 @@ You can turn on a verbose execution by calling:
And generate missing dump files with:
# ./run-tests.sh -g <TESTFILE>
-Before each call to the test-files, `nft flush ruleset' will be called.
-Also, test-files will receive the environment variable $NFT which contains the
-path to the nftables binary being tested.
+Before each test file invocation, `nft flush ruleset' will be called.
+Also, test file process environment will include the variable $NFT
+which contains the nft command being tested.
You can pass an arbitrary $NFT value as well:
# NFT=/usr/local/sbin/nft ./run-tests.sh
-By default the tests are run with the nft binary at '../../src/nft'
+Note that, to support usage such as NFT='valgrind nft', tests must
+invoke $NFT unquoted.
+
+By default, the tests are run with the nft binary at '../../src/nft'
diff --git a/tests/shell/run-tests.sh b/tests/shell/run-tests.sh
index 349ec6cb..931bba96 100755
--- a/tests/shell/run-tests.sh
+++ b/tests/shell/run-tests.sh
@@ -87,6 +87,7 @@ kernel_cleanup() {
nft_fib nft_fib_ipv4 nft_fib_ipv6 nft_fib_inet \
nft_hash nft_ct nft_compat nft_rt nft_objref \
nft_set_hash nft_set_rbtree nft_set_bitmap \
+ nft_synproxy nft_connlimit \
nft_chain_nat \
nft_chain_route_ipv4 nft_chain_route_ipv6 \
nft_dup_netdev nft_fwd_netdev \
@@ -108,8 +109,22 @@ find_tests() {
echo ""
ok=0
failed=0
+taint=0
+
+check_taint()
+{
+ read taint_now < /proc/sys/kernel/tainted
+ if [ $taint -ne $taint_now ] ; then
+ msg_warn "[FAILED] kernel is tainted: $taint -> $taint_now"
+ ((failed++))
+ fi
+}
+
+check_taint
+
for testfile in $(find_tests)
do
+ read taint < /proc/sys/kernel/tainted
kernel_cleanup
msg_info "[EXECUTING] $testfile"
@@ -154,10 +169,12 @@ do
msg_warn "[FAILED] $testfile"
fi
fi
+
+ check_taint
done
echo ""
msg_info "results: [OK] $ok [FAILED] $failed [TOTAL] $((ok+failed))"
kernel_cleanup
-exit $failed
+[ "$failed" -eq 0 ]
diff --git a/tests/shell/testcases/cache/0010_implicit_chain_0 b/tests/shell/testcases/cache/0010_implicit_chain_0
new file mode 100755
index 00000000..0ab0db95
--- /dev/null
+++ b/tests/shell/testcases/cache/0010_implicit_chain_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+set -e
+
+EXPECTED="table ip f {
+ chain c {
+ jump {
+ accept
+ }
+ }
+}"
+
+$NFT 'table ip f { chain c { jump { accept; }; }; }'
+GET="$($NFT list chain ip f c)"
+
+if [ "$EXPECTED" != "$GET" ] ; then
+ $DIFF -u <(echo "$EXPECTED") <(echo "$GET")
+ exit 1
+fi
diff --git a/tests/shell/testcases/chains/0021prio_0 b/tests/shell/testcases/chains/0021prio_0
index e7612974..d450dc0b 100755
--- a/tests/shell/testcases/chains/0021prio_0
+++ b/tests/shell/testcases/chains/0021prio_0
@@ -69,6 +69,7 @@ done
family=netdev
echo "add table $family x"
gen_chains $family ingress filter lo
+gen_chains $family egress filter lo
family=bridge
echo "add table $family x"
diff --git a/tests/shell/testcases/chains/0026prio_netdev_1 b/tests/shell/testcases/chains/0026prio_netdev_1
index aa902e9b..b6fa3db5 100755
--- a/tests/shell/testcases/chains/0026prio_netdev_1
+++ b/tests/shell/testcases/chains/0026prio_netdev_1
@@ -1,7 +1,8 @@
#!/bin/bash
family=netdev
- hook=ingress
+ for hook in ingress egress
+ do
for prioname in raw mangle dstnat security srcnat
do
$NFT add table $family x || exit 1
@@ -12,4 +13,5 @@ family=netdev
exit 1
fi
done
+ done
exit 0
diff --git a/tests/shell/testcases/chains/0040mark_shift_0 b/tests/shell/testcases/chains/0040mark_shift_0
index 55447f0b..ef3dccfa 100755
--- a/tests/shell/testcases/chains/0040mark_shift_0
+++ b/tests/shell/testcases/chains/0040mark_shift_0
@@ -8,4 +8,4 @@ RULESET="
add rule t c oif lo ct mark set (meta mark | 0x10) << 8
"
-$NFT --debug=eval -f - <<< "$RULESET"
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/chains/0041chain_binding_0 b/tests/shell/testcases/chains/0041chain_binding_0
index 59bdbe9f..4b541bb5 100755
--- a/tests/shell/testcases/chains/0041chain_binding_0
+++ b/tests/shell/testcases/chains/0041chain_binding_0
@@ -1,5 +1,11 @@
#!/bin/bash
+# no table x, caused segfault in earlier nft releases
+$NFT insert rule inet x y handle 107 'goto { log prefix "MOO! "; }'
+if [ $? -ne 1 ]; then
+ exit 1
+fi
+
set -e
EXPECTED="table inet x {
diff --git a/tests/shell/testcases/chains/0043chain_ingress_0 b/tests/shell/testcases/chains/0043chain_ingress_0
index 86dc075d..bff46468 100755
--- a/tests/shell/testcases/chains/0043chain_ingress_0
+++ b/tests/shell/testcases/chains/0043chain_ingress_0
@@ -14,5 +14,11 @@ RULESET="table inet filter {
}
}"
+# Test auto-removal of chain hook on netns removal
+unshare -n bash -c "ip link add br0 type bridge; \
+ $NFT add table netdev test; \
+ $NFT add chain netdev test ingress { type filter hook ingress device \"br0\" priority 0\; policy drop\; } ; \
+" || exit 1
+
$NFT -f - <<< "$RULESET" && exit 0
exit 1
diff --git a/tests/shell/testcases/chains/dumps/0021prio_0.nft b/tests/shell/testcases/chains/dumps/0021prio_0.nft
index ca94d441..4297d246 100644
--- a/tests/shell/testcases/chains/dumps/0021prio_0.nft
+++ b/tests/shell/testcases/chains/dumps/0021prio_0.nft
@@ -1382,6 +1382,26 @@ table netdev x {
chain ingressfilterp11 {
type filter hook ingress device "lo" priority 11; policy accept;
}
+
+ chain egressfilterm11 {
+ type filter hook egress device "lo" priority -11; policy accept;
+ }
+
+ chain egressfilterm10 {
+ type filter hook egress device "lo" priority filter - 10; policy accept;
+ }
+
+ chain egressfilter {
+ type filter hook egress device "lo" priority filter; policy accept;
+ }
+
+ chain egressfilterp10 {
+ type filter hook egress device "lo" priority filter + 10; policy accept;
+ }
+
+ chain egressfilterp11 {
+ type filter hook egress device "lo" priority 11; policy accept;
+ }
}
table bridge x {
chain preroutingfilterm11 {
diff --git a/tests/shell/testcases/comments/comments_0 b/tests/shell/testcases/comments/comments_0
new file mode 100755
index 00000000..a50387d6
--- /dev/null
+++ b/tests/shell/testcases/comments/comments_0
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+RULESET="table inet x { # comment
+ # comment 1
+ # comment 2
+ set y { # comment here
+ type ipv4_addr # comment
+ elements = {
+ # 1.1.1.1
+ 2.2.2.2, # comment
+ # more comments
+ 3.3.3.3, # comment
+# comment
+ }
+ # comment
+ }
+
+ # comments are allowed here
+ chain y {
+ # comments are allowed here
+ icmpv6 type {
+ 1, # comments are allowed here
+ 2,
+ } accept
+
+ icmp type {
+# comment
+ 1,
+ # comments also allowed here
+ 2,
+ } accept
+
+ tcp dport {
+ # normal FTP
+ 21,
+ # patched FTP
+ 2121
+ } counter accept
+ }
+}
+"
+
+$NFT -f - <<< "$RULESET"
+
diff --git a/tests/shell/testcases/comments/dumps/comments_0.nft b/tests/shell/testcases/comments/dumps/comments_0.nft
new file mode 100644
index 00000000..82ae510b
--- /dev/null
+++ b/tests/shell/testcases/comments/dumps/comments_0.nft
@@ -0,0 +1,12 @@
+table inet x {
+ set y {
+ type ipv4_addr
+ elements = { 2.2.2.2, 3.3.3.3 }
+ }
+
+ chain y {
+ icmpv6 type { destination-unreachable, packet-too-big } accept
+ icmp type { 1, 2 } accept
+ tcp dport { 21, 2121 } counter packets 0 bytes 0 accept
+ }
+}
diff --git a/tests/shell/testcases/json/0001set_statements_0 b/tests/shell/testcases/json/0001set_statements_0
new file mode 100755
index 00000000..1c72d35b
--- /dev/null
+++ b/tests/shell/testcases/json/0001set_statements_0
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+
+$NFT flush ruleset
+
+RULESET='{"nftables": [{"metainfo": {"version": "1.0.5", "release_name": "Lester Gooch #4", "json_schema_version": 1}}, {"table": {"family": "ip", "name": "testt", "handle": 3}}, {"set": {"family": "ip", "name": "ssh_meter", "table": "testt", "type": "ipv4_addr", "handle": 2, "size": 65535}}, {"chain": {"family": "ip", "table": "testt", "name": "testc", "handle": 1, "type": "filter", "hook": "input", "prio": 0, "policy": "accept"}}, {"rule": {"family": "ip", "table": "testt", "chain": "testc", "handle": 3, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": 22}}, {"match": {"op": "in", "left": {"ct": {"key": "state"}}, "right": "new"}}, {"set": {"op": "add", "elem": {"payload": {"protocol": "ip", "field": "saddr"}}, "stmt": [{"limit": {"rate": 10, "burst": 5, "per": "second"}}], "set": "@ssh_meter"}}, {"accept": null}]}}]}'
+
+$NFT -j -f - <<< $RULESET
diff --git a/tests/shell/testcases/json/0002table_map_0 b/tests/shell/testcases/json/0002table_map_0
new file mode 100755
index 00000000..4b54527b
--- /dev/null
+++ b/tests/shell/testcases/json/0002table_map_0
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+
+$NFT flush ruleset
+
+RULESET='{"nftables": [{"metainfo": {"version": "1.0.5", "release_name": "Lester Gooch #4", "json_schema_version": 1}}, {"table": {"family": "ip", "name": "t", "handle": 4}}, {"map": {"family": "ip", "name": "m", "table": "t", "type": "ipv4_addr", "handle": 1, "map": "mark", "stmt": [{"counter": {"packets": 0, "bytes": 0}}]}}]}'
+
+$NFT -j -f - <<< $RULESET
diff --git a/tests/shell/testcases/json/0003json_schema_version_0 b/tests/shell/testcases/json/0003json_schema_version_0
new file mode 100755
index 00000000..0ccf94c8
--- /dev/null
+++ b/tests/shell/testcases/json/0003json_schema_version_0
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+
+$NFT flush ruleset
+
+RULESET='{"nftables": [{"metainfo": {"json_schema_version": 1}}]}'
+
+$NFT -j -f - <<< $RULESET
diff --git a/tests/shell/testcases/json/0004json_schema_version_1 b/tests/shell/testcases/json/0004json_schema_version_1
new file mode 100755
index 00000000..bc451ae7
--- /dev/null
+++ b/tests/shell/testcases/json/0004json_schema_version_1
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -e
+
+$NFT flush ruleset
+
+RULESET='{"nftables": [{"metainfo": {"json_schema_version": 999}}]}'
+
+$NFT -j -f - <<< $RULESET && exit 1
+
+exit 0
diff --git a/tests/shell/testcases/json/0005secmark_objref_0 b/tests/shell/testcases/json/0005secmark_objref_0
new file mode 100755
index 00000000..ae967435
--- /dev/null
+++ b/tests/shell/testcases/json/0005secmark_objref_0
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+
+$NFT flush ruleset
+
+RULESET='{"nftables": [{"metainfo": {"version": "1.0.5", "release_name": "Lester Gooch #4", "json_schema_version": 1}}, {"table": {"family": "inet", "name": "x", "handle": 4}}, {"secmark": {"family": "inet", "name": "ssh_server", "table": "x", "handle": 1, "context": "system_u:object_r:ssh_server_packet_t:s0"}}, {"chain": {"family": "inet", "table": "x", "name": "y", "handle": 2, "type": "filter", "hook": "input", "prio": -225, "policy": "accept"}}, {"chain": {"family": "inet", "table": "x", "name": "z", "handle": 3, "type": "filter", "hook": "output", "prio": 225, "policy": "accept"}}, {"rule": {"family": "inet", "table": "x", "chain": "y", "handle": 4, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": 2222}}, {"match": {"op": "in", "left": {"ct": {"key": "state"}}, "right": "new"}}, {"secmark": "ssh_server"}]}}, {"rule": {"family": "inet", "table": "x", "chain": "y", "handle": 5, "expr": [{"match": {"op": "in", "left": {"ct": {"key": "state"}}, "right": "new"}}, {"mangle": {"key": {"ct": {"key": "secmark"}}, "value": {"meta": {"key": "secmark"}}}}]}}, {"rule": {"family": "inet", "table": "x", "chain": "y", "handle": 6, "expr": [{"match": {"op": "in", "left": {"ct": {"key": "state"}}, "right": ["established", "related"]}}, {"mangle": {"key": {"meta": {"key": "secmark"}}, "value": {"ct": {"key": "secmark"}}}}]}}, {"rule": {"family": "inet", "table": "x", "chain": "z", "handle": 7, "expr": [{"match": {"op": "in", "left": {"ct": {"key": "state"}}, "right": "new"}}, {"mangle": {"key": {"ct": {"key": "secmark"}}, "value": {"meta": {"key": "secmark"}}}}]}}, {"rule": {"family": "inet", "table": "x", "chain": "z", "handle": 8, "expr": [{"match": {"op": "in", "left": {"ct": {"key": "state"}}, "right": ["established", "related"]}}, {"mangle": {"key": {"meta": {"key": "secmark"}}, "value": {"ct": {"key": "secmark"}}}}]}}]}'
+
+$NFT -j -f - <<< $RULESET
diff --git a/tests/shell/testcases/json/0006obj_comment_0 b/tests/shell/testcases/json/0006obj_comment_0
new file mode 100755
index 00000000..76d8fe16
--- /dev/null
+++ b/tests/shell/testcases/json/0006obj_comment_0
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+
+$NFT flush ruleset
+
+RULESET='{"nftables": [{"metainfo": {"version": "1.0.5", "release_name": "Lester Gooch #4", "json_schema_version": 1}}, {"table": {"family": "inet", "name": "t", "handle": 9}}, {"counter": {"family": "inet", "name": "mycounter", "table": "t", "handle": 1, "comment": "my comment in counter", "packets": 0, "bytes": 0}}]}'
+
+$NFT -j -f - <<< $RULESET
diff --git a/tests/shell/testcases/json/dumps/0001set_statements_0.nft b/tests/shell/testcases/json/dumps/0001set_statements_0.nft
new file mode 100644
index 00000000..ee4a8670
--- /dev/null
+++ b/tests/shell/testcases/json/dumps/0001set_statements_0.nft
@@ -0,0 +1,12 @@
+table ip testt {
+ set ssh_meter {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ }
+
+ chain testc {
+ type filter hook input priority filter; policy accept;
+ tcp dport 22 ct state new add @ssh_meter { ip saddr limit rate 10/second } accept
+ }
+}
diff --git a/tests/shell/testcases/json/dumps/0002table_map_0.nft b/tests/shell/testcases/json/dumps/0002table_map_0.nft
new file mode 100644
index 00000000..357e92cc
--- /dev/null
+++ b/tests/shell/testcases/json/dumps/0002table_map_0.nft
@@ -0,0 +1,6 @@
+table ip t {
+ map m {
+ type ipv4_addr : mark
+ counter
+ }
+}
diff --git a/tests/shell/testcases/json/dumps/0003json_schema_version_0.nft b/tests/shell/testcases/json/dumps/0003json_schema_version_0.nft
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/shell/testcases/json/dumps/0003json_schema_version_0.nft
diff --git a/tests/shell/testcases/json/dumps/0004json_schema_version_1.nft b/tests/shell/testcases/json/dumps/0004json_schema_version_1.nft
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/shell/testcases/json/dumps/0004json_schema_version_1.nft
diff --git a/tests/shell/testcases/json/dumps/0005secmark_objref_0.nft b/tests/shell/testcases/json/dumps/0005secmark_objref_0.nft
new file mode 100644
index 00000000..4c218e93
--- /dev/null
+++ b/tests/shell/testcases/json/dumps/0005secmark_objref_0.nft
@@ -0,0 +1,18 @@
+table inet x {
+ secmark ssh_server {
+ "system_u:object_r:ssh_server_packet_t:s0"
+ }
+
+ chain y {
+ type filter hook input priority -225; policy accept;
+ tcp dport 2222 ct state new meta secmark set "ssh_server"
+ ct state new ct secmark set meta secmark
+ ct state established,related meta secmark set ct secmark
+ }
+
+ chain z {
+ type filter hook output priority 225; policy accept;
+ ct state new ct secmark set meta secmark
+ ct state established,related meta secmark set ct secmark
+ }
+}
diff --git a/tests/shell/testcases/json/dumps/0006obj_comment_0.nft b/tests/shell/testcases/json/dumps/0006obj_comment_0.nft
new file mode 100644
index 00000000..e52b21b4
--- /dev/null
+++ b/tests/shell/testcases/json/dumps/0006obj_comment_0.nft
@@ -0,0 +1,6 @@
+table inet t {
+ counter mycounter {
+ comment "my comment in counter"
+ packets 0 bytes 0
+ }
+}
diff --git a/tests/shell/testcases/json/netdev b/tests/shell/testcases/json/netdev
new file mode 100755
index 00000000..a16a4f5e
--- /dev/null
+++ b/tests/shell/testcases/json/netdev
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+ip link add d0 type dummy || {
+ echo "Skipping, no dummy interface available"
+ exit 0
+}
+trap "ip link del d0" EXIT
+
+set -e
+
+$NFT flush ruleset
+$NFT add table inet test
+$NFT add chain inet test c
+
+$NFT flush ruleset
+
+RULESET='{"nftables":[{"flush":{"ruleset":null}},{"add":{"table":{"family":"netdev","name":"test_table"}}},{"add":{"chain":{"family":"netdev","table":"test_table","name":"test_chain","type":"filter","hook":"ingress","prio":0,"dev":"d0","policy":"accept"}}}]}'
+
+$NFT -j -f - <<< $RULESET
diff --git a/tests/shell/testcases/listing/0020flowtable_0 b/tests/shell/testcases/listing/0020flowtable_0
index 2f0a98d1..47488d8e 100755
--- a/tests/shell/testcases/listing/0020flowtable_0
+++ b/tests/shell/testcases/listing/0020flowtable_0
@@ -2,19 +2,60 @@
# list only the flowtable asked for with table
+FLOWTABLES="flowtable f {
+ hook ingress priority filter
+ devices = { lo }
+}
+flowtable f2 {
+ hook ingress priority filter
+ devices = { d0 }
+}"
+
+RULESET="table inet filter {
+ $FLOWTABLES
+}
+table ip filter {
+ $FLOWTABLES
+}"
+
EXPECTED="table inet filter {
flowtable f {
hook ingress priority filter
devices = { lo }
}
}"
+EXPECTED2="table ip filter {
+ flowtable f2 {
+ hook ingress priority filter
+ devices = { d0 }
+ }
+}"
+EXPECTED3="table ip filter {
+ flowtable f {
+ hook ingress priority filter
+ devices = { lo }
+ }
+ flowtable f2 {
+ hook ingress priority filter
+ devices = { d0 }
+ }
+}"
+
+ip link add d0 type dummy || {
+ echo "Skipping, no dummy interface available"
+ exit 0
+}
+trap "ip link del d0" EXIT
set -e
-$NFT -f - <<< "$EXPECTED"
+$NFT -f - <<< "$RULESET"
GET="$($NFT list flowtable inet filter f)"
-if [ "$EXPECTED" != "$GET" ] ; then
- $DIFF -u <(echo "$EXPECTED") <(echo "$GET")
- exit 1
-fi
+$DIFF -u <(echo "$EXPECTED") <(echo "$GET")
+
+GET="$($NFT list flowtable ip filter f2)"
+$DIFF -u <(echo "$EXPECTED2") <(echo "$GET")
+
+GET="$($NFT list flowtables ip)"
+$DIFF -u <(echo "$EXPECTED3") <(echo "$GET")
diff --git a/tests/shell/testcases/listing/0022terse_0 b/tests/shell/testcases/listing/0022terse_0
new file mode 100755
index 00000000..4841771c
--- /dev/null
+++ b/tests/shell/testcases/listing/0022terse_0
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+RULESET="table inet filter {
+ set example {
+ type ipv4_addr
+ flags interval
+ elements = { 10.10.10.10, 10.10.11.11 }
+ }
+
+ chain input {
+ type filter hook prerouting priority filter; policy accept;
+ ip saddr != { 10.10.10.100, 10.10.10.111 } ip saddr @example drop
+ }
+}"
+
+set -e
+
+$NFT -f - <<< "$RULESET"
+
+GET="$($NFT list ruleset)"
+if [ "$RULESET" != "$GET" ] ; then
+ $DIFF -u <(echo "$RULESET") <(echo "$GET")
+ exit 1
+fi
+
+EXPECTED="table inet filter {
+ set example {
+ type ipv4_addr
+ flags interval
+ }
+
+ chain input {
+ type filter hook prerouting priority filter; policy accept;
+ ip saddr != { 10.10.10.100, 10.10.10.111 } ip saddr @example drop
+ }
+}"
+
+GET="$($NFT -t list ruleset)"
+if [ "$EXPECTED" != "$GET" ] ; then
+ $DIFF -u <(echo "$EXPECTED") <(echo "$GET")
+ exit 1
+fi
+
+EXPECTED="table inet filter {
+ set example {
+ type ipv4_addr
+ flags interval
+ elements = { 10.10.10.10, 10.10.11.11 }
+ }
+}"
+
+GET="$($NFT list set inet filter example)"
+if [ "$EXPECTED" != "$GET" ] ; then
+ $DIFF -u <(echo "$EXPECTED") <(echo "$GET")
+ exit 1
+fi
+
+EXPECTED="table inet filter {
+ set example {
+ type ipv4_addr
+ flags interval
+ }
+}"
+
+GET="$($NFT -t list set inet filter example)"
+if [ "$EXPECTED" != "$GET" ] ; then
+ $DIFF -u <(echo "$EXPECTED") <(echo "$GET")
+ exit 1
+fi
diff --git a/tests/shell/testcases/maps/0012map_0 b/tests/shell/testcases/maps/0012map_0
index dd93c482..49e51b75 100755
--- a/tests/shell/testcases/maps/0012map_0
+++ b/tests/shell/testcases/maps/0012map_0
@@ -15,3 +15,22 @@ table ip x {
}"
$NFT -f - <<< "$EXPECTED"
+
+EXPECTED="table ip x {
+ map w {
+ typeof ip saddr . meta mark : verdict
+ flags interval
+ counter
+ elements = {
+ 127.0.0.1-127.0.0.4 . 0x123434-0xb00122 : accept,
+ }
+ }
+
+ chain k {
+ type filter hook input priority filter + 1; policy accept;
+ meta mark set 0x123434
+ ip saddr . meta mark vmap @w
+ }
+}"
+
+$NFT -f - <<< "$EXPECTED"
diff --git a/tests/shell/testcases/maps/0013map_0 b/tests/shell/testcases/maps/0013map_0
new file mode 100755
index 00000000..70d7fd3b
--- /dev/null
+++ b/tests/shell/testcases/maps/0013map_0
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+RULESET="
+flush ruleset
+
+add table ip filter
+add chain ip filter FORWARD { type filter hook forward priority 0; policy drop; }
+add map ip filter forwport { type ipv4_addr . inet_proto . inet_service: verdict; flags interval; counter; }
+add rule ip filter FORWARD iifname enp0s8 ip daddr . ip protocol . th dport vmap @forwport counter
+add element ip filter forwport { 10.133.89.138 . tcp . 8081: accept }"
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/maps/anon_objmap_concat b/tests/shell/testcases/maps/anon_objmap_concat
new file mode 100755
index 00000000..07820b7c
--- /dev/null
+++ b/tests/shell/testcases/maps/anon_objmap_concat
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+set -e
+dumpfile=$(dirname $0)/dumps/$(basename $0).nft
+
+$NFT -f "$dumpfile"
diff --git a/tests/shell/testcases/maps/dumps/0010concat_map_0.nft b/tests/shell/testcases/maps/dumps/0010concat_map_0.nft
index b6bc338c..2f796b51 100644
--- a/tests/shell/testcases/maps/dumps/0010concat_map_0.nft
+++ b/tests/shell/testcases/maps/dumps/0010concat_map_0.nft
@@ -6,6 +6,6 @@ table inet x {
chain y {
type nat hook prerouting priority dstnat; policy accept;
- meta nfproto ipv4 dnat ip to ip saddr . ip protocol . tcp dport map @z
+ dnat ip to ip saddr . ip protocol . tcp dport map @z
}
}
diff --git a/tests/shell/testcases/maps/dumps/0012map_0.nft b/tests/shell/testcases/maps/dumps/0012map_0.nft
index e734fc1c..895490cf 100644
--- a/tests/shell/testcases/maps/dumps/0012map_0.nft
+++ b/tests/shell/testcases/maps/dumps/0012map_0.nft
@@ -6,7 +6,20 @@ table ip x {
"eth1" : drop }
}
+ map w {
+ typeof ip saddr . meta mark : verdict
+ flags interval
+ counter
+ elements = { 127.0.0.1-127.0.0.4 . 0x00123434-0x00b00122 counter packets 0 bytes 0 : accept }
+ }
+
chain y {
iifname vmap { "lo" : accept, "eth0" : drop, "eth1" : drop }
}
+
+ chain k {
+ type filter hook input priority filter + 1; policy accept;
+ meta mark set 0x00123434
+ ip saddr . meta mark vmap @w
+ }
}
diff --git a/tests/shell/testcases/maps/dumps/0013map_0.nft b/tests/shell/testcases/maps/dumps/0013map_0.nft
new file mode 100644
index 00000000..1455877d
--- /dev/null
+++ b/tests/shell/testcases/maps/dumps/0013map_0.nft
@@ -0,0 +1,13 @@
+table ip filter {
+ map forwport {
+ type ipv4_addr . inet_proto . inet_service : verdict
+ flags interval
+ counter
+ elements = { 10.133.89.138 . tcp . 8081 counter packets 0 bytes 0 : accept }
+ }
+
+ chain FORWARD {
+ type filter hook forward priority filter; policy drop;
+ iifname "enp0s8" ip daddr . ip protocol . th dport vmap @forwport counter packets 0 bytes 0
+ }
+}
diff --git a/tests/shell/testcases/maps/dumps/anon_objmap_concat.nft b/tests/shell/testcases/maps/dumps/anon_objmap_concat.nft
new file mode 100644
index 00000000..23aca0a2
--- /dev/null
+++ b/tests/shell/testcases/maps/dumps/anon_objmap_concat.nft
@@ -0,0 +1,16 @@
+table inet filter {
+ ct helper sip-5060u {
+ type "sip" protocol udp
+ l3proto ip
+ }
+
+ ct helper sip-5060t {
+ type "sip" protocol tcp
+ l3proto ip
+ }
+
+ chain input {
+ type filter hook input priority filter; policy accept;
+ ct helper set ip protocol . th dport map { udp . 10000-20000 : "sip-5060u", tcp . 10000-20000 : "sip-5060t" }
+ }
+}
diff --git a/tests/shell/testcases/maps/dumps/nat_addr_port.nft b/tests/shell/testcases/maps/dumps/nat_addr_port.nft
index cf6b957f..c8493b3a 100644
--- a/tests/shell/testcases/maps/dumps/nat_addr_port.nft
+++ b/tests/shell/testcases/maps/dumps/nat_addr_port.nft
@@ -114,15 +114,15 @@ table inet inetfoo {
dnat ip to ip daddr map @x4
ip saddr 10.1.1.1 dnat ip to 10.2.3.4
ip saddr 10.1.1.2 tcp dport 42 dnat ip to 10.2.3.4:4242
- meta l4proto tcp meta nfproto ipv4 dnat ip to ip saddr map @y4
- meta nfproto ipv4 dnat ip to ip saddr . tcp dport map @z4
+ meta l4proto tcp dnat ip to ip saddr map @y4
+ dnat ip to ip saddr . tcp dport map @z4
dnat ip to numgen inc mod 2 map @t1v4
meta l4proto tcp dnat ip to numgen inc mod 2 map @t2v4
dnat ip6 to ip6 daddr map @x6
ip6 saddr dead::1 dnat ip6 to feed::1
ip6 saddr dead::2 tcp dport 42 dnat ip6 to [c0::1a]:4242
- meta l4proto tcp meta nfproto ipv6 dnat ip6 to ip6 saddr map @y6
- meta nfproto ipv6 dnat ip6 to ip6 saddr . tcp dport map @z6
+ meta l4proto tcp dnat ip6 to ip6 saddr map @y6
+ dnat ip6 to ip6 saddr . tcp dport map @z6
dnat ip6 to numgen inc mod 2 map @t1v6
meta l4proto tcp dnat ip6 to numgen inc mod 2 map @t2v6
}
diff --git a/tests/shell/testcases/maps/dumps/typeof_integer_0.nft b/tests/shell/testcases/maps/dumps/typeof_integer_0.nft
new file mode 100644
index 00000000..33041557
--- /dev/null
+++ b/tests/shell/testcases/maps/dumps/typeof_integer_0.nft
@@ -0,0 +1,20 @@
+table inet t {
+ map m1 {
+ typeof udp length . @ih,32,32 : verdict
+ flags interval
+ elements = { 20-80 . 0x14 : accept,
+ 1-10 . 0xa : drop }
+ }
+
+ map m2 {
+ typeof udp length . @ih,32,32 : verdict
+ elements = { 30 . 0x1e : drop,
+ 20 . 0x24 : accept }
+ }
+
+ chain c {
+ udp length . @ih,32,32 vmap @m1
+ udp length . @ih,32,32 vmap @m2
+ udp length . @th,160,128 vmap { 47-63 . 0xe373135363130333131303735353203 : accept }
+ }
+}
diff --git a/tests/shell/testcases/maps/dumps/typeof_maps_0.nft b/tests/shell/testcases/maps/dumps/typeof_maps_0.nft
index 438b9829..a5c0a609 100644
--- a/tests/shell/testcases/maps/dumps/typeof_maps_0.nft
+++ b/tests/shell/testcases/maps/dumps/typeof_maps_0.nft
@@ -17,11 +17,20 @@ table inet t {
map m4 {
typeof iifname . ip protocol . th dport : verdict
+ elements = { "eth0" . tcp . 22 : accept }
+ }
+
+ map m5 {
+ typeof ipsec in reqid . iifname : verdict
+ elements = { 23 . "eth0" : accept }
}
chain c {
ct mark set osf name map @m1
meta mark set vlan id map @m2
meta mark set ip saddr . ip daddr map @m3
+ iifname . ip protocol . th dport vmap @m4
+ iifname . ip protocol . th dport vmap { "eth0" . tcp . 22 : accept, "eth1" . udp . 67 : drop }
+ ipsec in reqid . iifname vmap @m5
}
}
diff --git a/tests/shell/testcases/maps/dumps/typeof_maps_concat.nft b/tests/shell/testcases/maps/dumps/typeof_maps_concat.nft
new file mode 100644
index 00000000..1ca98d81
--- /dev/null
+++ b/tests/shell/testcases/maps/dumps/typeof_maps_concat.nft
@@ -0,0 +1,11 @@
+table netdev t {
+ map m {
+ typeof ether saddr . vlan id : meta mark
+ size 1234
+ flags dynamic,timeout
+ }
+
+ chain c {
+ ether type != 8021q update @m { ether daddr . 123 timeout 1m : 0x0000002a } counter packets 0 bytes 0 return
+ }
+}
diff --git a/tests/shell/testcases/maps/dumps/typeof_maps_concat_update_0.nft b/tests/shell/testcases/maps/dumps/typeof_maps_concat_update_0.nft
new file mode 100644
index 00000000..f8b574f4
--- /dev/null
+++ b/tests/shell/testcases/maps/dumps/typeof_maps_concat_update_0.nft
@@ -0,0 +1,13 @@
+table ip foo {
+ map pinned {
+ typeof ip saddr . ct original proto-dst : ip daddr . tcp dport
+ size 65535
+ flags dynamic,timeout
+ timeout 6m
+ }
+
+ chain pr {
+ update @pinned { ip saddr . ct original proto-dst timeout 1m30s : ip daddr . tcp dport }
+ update @pinned { ip saddr . ct original proto-dst timeout 1m30s : ip daddr . tcp dport }
+ }
+}
diff --git a/tests/shell/testcases/maps/dumps/typeof_raw_0.nft b/tests/shell/testcases/maps/dumps/typeof_raw_0.nft
new file mode 100644
index 00000000..e876425b
--- /dev/null
+++ b/tests/shell/testcases/maps/dumps/typeof_raw_0.nft
@@ -0,0 +1,13 @@
+table ip x {
+ map y {
+ typeof ip saddr . @ih,32,32 : verdict
+ elements = { 1.1.1.1 . 0x14 : accept,
+ 7.7.7.7 . 0x86 : accept,
+ 7.7.7.8 . 0x97 : drop }
+ }
+
+ chain y {
+ ip saddr . @ih,32,32 vmap @y
+ ip saddr . @ih,32,32 vmap { 4.4.4.4 . 0x34 : accept, 5.5.5.5 . 0x45 : drop }
+ }
+}
diff --git a/tests/shell/testcases/maps/typeof_integer_0 b/tests/shell/testcases/maps/typeof_integer_0
new file mode 100755
index 00000000..d51510af
--- /dev/null
+++ b/tests/shell/testcases/maps/typeof_integer_0
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+EXPECTED="table inet t {
+ map m1 {
+ typeof udp length . @ih,32,32 : verdict
+ flags interval
+ elements = { 20-80 . 0x14 : accept, 1-10 . 0xa : drop }
+ }
+
+ map m2 {
+ typeof udp length . @ih,32,32 : verdict
+ elements = { 20 . 0x24 : accept, 30 . 0x1e : drop }
+ }
+
+ chain c {
+ udp length . @ih,32,32 vmap @m1
+ udp length . @ih,32,32 vmap @m2
+ udp length . @th,160,128 vmap { 47-63 . 0xe373135363130333131303735353203 : accept }
+ }
+}"
+
+$NFT add element inet t m1 { 90-100 . 40 : drop }
+$NFT delete element inet t m2 { 20 . 20 : accept }
+
+set -e
+$NFT -f - <<< $EXPECTED
+
diff --git a/tests/shell/testcases/maps/typeof_maps_0 b/tests/shell/testcases/maps/typeof_maps_0
index f024ebe0..5cf5ddde 100755
--- a/tests/shell/testcases/maps/typeof_maps_0
+++ b/tests/shell/testcases/maps/typeof_maps_0
@@ -24,12 +24,21 @@ EXPECTED="table inet t {
map m4 {
typeof iifname . ip protocol . th dport : verdict
+ elements = { eth0 . tcp . 22 : accept }
+ }
+
+ map m5 {
+ typeof ipsec in reqid . meta iifname : verdict
+ elements = { 23 . eth0 : accept }
}
chain c {
ct mark set osf name map @m1
ether type vlan meta mark set vlan id map @m2
meta mark set ip saddr . ip daddr map @m3
+ iifname . ip protocol . th dport vmap @m4
+ iifname . ip protocol . th dport vmap { \"eth0\" . tcp . 22 : accept, \"eth1\" . udp . 67 : drop }
+ ipsec in reqid . meta iifname vmap @m5
}
}"
diff --git a/tests/shell/testcases/maps/typeof_maps_concat b/tests/shell/testcases/maps/typeof_maps_concat
new file mode 100755
index 00000000..07820b7c
--- /dev/null
+++ b/tests/shell/testcases/maps/typeof_maps_concat
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+set -e
+dumpfile=$(dirname $0)/dumps/$(basename $0).nft
+
+$NFT -f "$dumpfile"
diff --git a/tests/shell/testcases/maps/typeof_maps_concat_update_0 b/tests/shell/testcases/maps/typeof_maps_concat_update_0
new file mode 100755
index 00000000..2a52ea0e
--- /dev/null
+++ b/tests/shell/testcases/maps/typeof_maps_concat_update_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# check update statement does print both concatentations (key and data).
+
+EXPECTED="table ip foo {
+ map pinned {
+ typeof ip saddr . ct original proto-dst : ip daddr . tcp dport
+ size 65535
+ flags dynamic,timeout
+ timeout 6m
+ }
+ chain pr {
+ update @pinned { ip saddr . ct original proto-dst timeout 1m30s : ip daddr . tcp dport }
+ meta l4proto tcp update @pinned { ip saddr . ct original proto-dst timeout 1m30s : ip daddr . tcp dport }
+ }
+}"
+
+set -e
+$NFT -f - <<< $EXPECTED
diff --git a/tests/shell/testcases/maps/typeof_raw_0 b/tests/shell/testcases/maps/typeof_raw_0
new file mode 100755
index 00000000..e3da7825
--- /dev/null
+++ b/tests/shell/testcases/maps/typeof_raw_0
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+EXPECTED="table ip x {
+ map y {
+ typeof ip saddr . @ih,32,32: verdict
+ elements = { 1.1.1.1 . 0x14 : accept, 2.2.2.2 . 0x1e : drop }
+ }
+
+ chain y {
+ ip saddr . @ih,32,32 vmap @y
+ ip saddr . @ih,32,32 vmap { 4.4.4.4 . 0x34 : accept, 5.5.5.5 . 0x45 : drop}
+ }
+}"
+
+set -e
+$NFT -f - <<< $EXPECTED
+$NFT add element ip x y { 7.7.7.7 . 0x86 : accept, 7.7.7.8 . 0x97 : drop }
+$NFT delete element ip x y { 2.2.2.2 . 0x1e : drop }
diff --git a/tests/shell/testcases/nft-f/0029split_file_0 b/tests/shell/testcases/nft-f/0029split_file_0
new file mode 100755
index 00000000..0cc547ab
--- /dev/null
+++ b/tests/shell/testcases/nft-f/0029split_file_0
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table inet filter {
+ set whitelist_v4 {
+ type ipv4_addr;
+ }
+
+ chain prerouting {
+ type filter hook prerouting priority filter;
+ }
+}
+"
+
+$NFT -f - <<< "$RULESET"
+
+RULESET="table inet filter {
+ chain prerouting {
+ ip daddr @whitelist_v4
+ }
+}
+"
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/nft-f/0030variable_reuse_0 b/tests/shell/testcases/nft-f/0030variable_reuse_0
new file mode 100755
index 00000000..8afc54aa
--- /dev/null
+++ b/tests/shell/testcases/nft-f/0030variable_reuse_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+set -e
+
+RULESET="define test = { 1.1.1.1 }
+
+table ip x {
+ set y {
+ type ipv4_addr
+ elements = { 2.2.2.2, \$test }
+ }
+
+ set z {
+ type ipv4_addr
+ elements = { 3.3.3.3, \$test }
+ }
+}"
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/nft-f/0031vmap_string_0 b/tests/shell/testcases/nft-f/0031vmap_string_0
new file mode 100755
index 00000000..2af846a4
--- /dev/null
+++ b/tests/shell/testcases/nft-f/0031vmap_string_0
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# Tests parse of corrupted verdicts
+
+set -e
+
+RULESET="
+table ip foo {
+ map bar {
+ type ipv4_addr : verdict
+ elements = {
+ 192.168.0.1 : ber
+ }
+ }
+
+ chain ber {
+ }
+}"
+
+$NFT -f - <<< "$RULESET" && exit 1
+exit 0
diff --git a/tests/shell/testcases/nft-f/dumps/0030variable_reuse_0.nft b/tests/shell/testcases/nft-f/dumps/0030variable_reuse_0.nft
new file mode 100644
index 00000000..635901f4
--- /dev/null
+++ b/tests/shell/testcases/nft-f/dumps/0030variable_reuse_0.nft
@@ -0,0 +1,11 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ elements = { 1.1.1.1, 2.2.2.2 }
+ }
+
+ set z {
+ type ipv4_addr
+ elements = { 1.1.1.1, 3.3.3.3 }
+ }
+}
diff --git a/tests/shell/testcases/optimizations/dumps/merge_nat.nft b/tests/shell/testcases/optimizations/dumps/merge_nat.nft
new file mode 100644
index 00000000..7a6ecb76
--- /dev/null
+++ b/tests/shell/testcases/optimizations/dumps/merge_nat.nft
@@ -0,0 +1,20 @@
+table ip test1 {
+ chain y {
+ dnat to ip saddr map { 4.4.4.4 : 1.1.1.1, 5.5.5.5 : 2.2.2.2 }
+ }
+}
+table ip test2 {
+ chain y {
+ dnat ip to tcp dport map { 80 : 1.1.1.1 . 8001, 81 : 2.2.2.2 . 9001 }
+ }
+}
+table ip test3 {
+ chain y {
+ snat to ip saddr . tcp sport map { 1.1.1.1 . 1024-65535 : 3.3.3.3, 2.2.2.2 . 1024-65535 : 4.4.4.4 }
+ }
+}
+table ip test4 {
+ chain y {
+ dnat ip to ip daddr . tcp dport map { 1.1.1.1 . 80 : 4.4.4.4 . 8000, 2.2.2.2 . 81 : 3.3.3.3 . 9000 }
+ }
+}
diff --git a/tests/shell/testcases/optimizations/dumps/merge_reject.nft b/tests/shell/testcases/optimizations/dumps/merge_reject.nft
new file mode 100644
index 00000000..c29ad6d5
--- /dev/null
+++ b/tests/shell/testcases/optimizations/dumps/merge_reject.nft
@@ -0,0 +1,13 @@
+table ip x {
+ chain y {
+ ip daddr 172.30.33.70 tcp dport 3306 counter packets 0 bytes 0 drop
+ meta l4proto . ip daddr . tcp dport { tcp . 172.30.238.117 . 8080, tcp . 172.30.33.71 . 3306, tcp . 172.30.254.251 . 3306 } counter packets 0 bytes 0 reject
+ ip daddr 172.30.254.252 tcp dport 3306 counter packets 0 bytes 0 reject with tcp reset
+ }
+}
+table ip6 x {
+ chain y {
+ meta l4proto . ip6 daddr . tcp dport { tcp . aaaa::3 . 8080, tcp . aaaa::2 . 3306, tcp . aaaa::4 . 3306 } counter packets 0 bytes 0 reject
+ ip6 daddr aaaa::5 tcp dport 3306 counter packets 0 bytes 0 reject with tcp reset
+ }
+}
diff --git a/tests/shell/testcases/optimizations/dumps/merge_stmts.nft b/tests/shell/testcases/optimizations/dumps/merge_stmts.nft
new file mode 100644
index 00000000..b56ea3ed
--- /dev/null
+++ b/tests/shell/testcases/optimizations/dumps/merge_stmts.nft
@@ -0,0 +1,5 @@
+table ip x {
+ chain y {
+ ip daddr { 192.168.0.1, 192.168.0.2, 192.168.0.3 } counter packets 0 bytes 0 accept
+ }
+}
diff --git a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft
new file mode 100644
index 00000000..f56cea1c
--- /dev/null
+++ b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat.nft
@@ -0,0 +1,18 @@
+table ip x {
+ chain y {
+ iifname . ip saddr . ip daddr { "eth1" . 1.1.1.1 . 2.2.2.3, "eth1" . 1.1.1.2 . 2.2.2.4, "eth1" . 1.1.1.2 . 2.2.3.0/24, "eth1" . 1.1.1.2 . 2.2.4.0-2.2.4.10, "eth2" . 1.1.1.3 . 2.2.2.5 } accept
+ ip protocol . th dport { tcp . 22, udp . 67 }
+ }
+
+ chain c1 {
+ udp dport . iifname { 51820 . "foo", 514 . "bar", 67 . "bar" } accept
+ }
+
+ chain c2 {
+ udp dport . iifname { 100 . "foo", 51820 . "foo", 514 . "bar", 67 . "bar" } accept
+ }
+
+ chain c3 {
+ udp dport . iifname { 100 . "foo", 51820 . "foo", 514 . "bar", 67 . "bar", 100 . "test", 51820 . "test" } accept
+ }
+}
diff --git a/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.nft b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.nft
new file mode 100644
index 00000000..780aa09a
--- /dev/null
+++ b/tests/shell/testcases/optimizations/dumps/merge_stmts_concat_vmap.nft
@@ -0,0 +1,9 @@
+table ip x {
+ chain x {
+ meta pkttype . udp dport vmap { broadcast . 547 : accept, broadcast . 67 : accept, multicast . 1900 : drop }
+ }
+
+ chain y {
+ ip saddr . ip daddr vmap { 1.1.1.1 . 2.2.2.2 : accept, 2.2.2.2 . 3.3.3.3 : drop, 4.4.4.4 . 5.5.5.5 : accept }
+ }
+}
diff --git a/tests/shell/testcases/optimizations/dumps/merge_stmts_vmap.nft b/tests/shell/testcases/optimizations/dumps/merge_stmts_vmap.nft
new file mode 100644
index 00000000..5a9b3006
--- /dev/null
+++ b/tests/shell/testcases/optimizations/dumps/merge_stmts_vmap.nft
@@ -0,0 +1,9 @@
+table ip x {
+ chain y {
+ ct state vmap { invalid : drop, established : accept, related : accept }
+ }
+
+ chain z {
+ tcp dport vmap { 1 : accept, 2-3 : drop, 4 : accept }
+ }
+}
diff --git a/tests/shell/testcases/optimizations/dumps/merge_vmap_raw.nft b/tests/shell/testcases/optimizations/dumps/merge_vmap_raw.nft
new file mode 100644
index 00000000..18847116
--- /dev/null
+++ b/tests/shell/testcases/optimizations/dumps/merge_vmap_raw.nft
@@ -0,0 +1,31 @@
+table inet x {
+ chain nat_dns_dnstc {
+ meta l4proto udp redirect to :5300
+ drop
+ }
+
+ chain nat_dns_this_5301 {
+ meta l4proto udp redirect to :5301
+ drop
+ }
+
+ chain nat_dns_saturn_5301 {
+ meta nfproto ipv4 meta l4proto udp dnat ip to 240.0.1.2:5301
+ drop
+ }
+
+ chain nat_dns_saturn_5302 {
+ meta nfproto ipv4 meta l4proto udp dnat ip to 240.0.1.2:5302
+ drop
+ }
+
+ chain nat_dns_saturn_5303 {
+ meta nfproto ipv4 meta l4proto udp dnat ip to 240.0.1.2:5303
+ drop
+ }
+
+ chain nat_dns_acme {
+ udp length . @th,160,128 vmap { 47-63 . 0xe373135363130333131303735353203 : goto nat_dns_dnstc, 62-78 . 0xe31393032383939353831343037320e : goto nat_dns_this_5301, 62-78 . 0xe31363436323733373931323934300e : goto nat_dns_saturn_5301, 62-78 . 0xe32393535373539353636383732310e : goto nat_dns_saturn_5302, 62-78 . 0xe38353439353637323038363633390e : goto nat_dns_saturn_5303 }
+ drop
+ }
+}
diff --git a/tests/shell/testcases/optimizations/dumps/merge_vmaps.nft b/tests/shell/testcases/optimizations/dumps/merge_vmaps.nft
new file mode 100644
index 00000000..c981acf0
--- /dev/null
+++ b/tests/shell/testcases/optimizations/dumps/merge_vmaps.nft
@@ -0,0 +1,20 @@
+table ip x {
+ set s {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ }
+
+ chain filter_in_tcp {
+ }
+
+ chain filter_in_udp {
+ }
+
+ chain y {
+ update @s { ip saddr limit rate 12/minute burst 30 packets } accept
+ tcp dport vmap { 80 : accept, 81 : accept, 443 : accept, 8000-8100 : accept, 24000-25000 : accept }
+ meta l4proto vmap { tcp : goto filter_in_tcp, udp : goto filter_in_udp }
+ log
+ }
+}
diff --git a/tests/shell/testcases/optimizations/dumps/not_mergeable.nft b/tests/shell/testcases/optimizations/dumps/not_mergeable.nft
new file mode 100644
index 00000000..02b89207
--- /dev/null
+++ b/tests/shell/testcases/optimizations/dumps/not_mergeable.nft
@@ -0,0 +1,19 @@
+table ip x {
+ chain t1 {
+ }
+
+ chain t2 {
+ }
+
+ chain t3 {
+ }
+
+ chain t4 {
+ }
+
+ chain y {
+ counter packets 0 bytes 0 jump t1
+ counter packets 0 bytes 0 jump t2
+ ip version vmap { 4 : jump t3, 6 : jump t4 }
+ }
+}
diff --git a/tests/shell/testcases/optimizations/dumps/skip_merge.nft b/tests/shell/testcases/optimizations/dumps/skip_merge.nft
new file mode 100644
index 00000000..9c10b74b
--- /dev/null
+++ b/tests/shell/testcases/optimizations/dumps/skip_merge.nft
@@ -0,0 +1,23 @@
+table inet filter {
+ set udp_accepted {
+ type inet_service
+ elements = { 500, 4500 }
+ }
+
+ set tcp_accepted {
+ type inet_service
+ elements = { 80, 443 }
+ }
+
+ chain udp_input {
+ udp dport 1-128 accept
+ udp dport @udp_accepted accept
+ udp dport 53 accept
+ }
+
+ chain tcp_input {
+ tcp dport { 1-128, 8888-9999 } accept
+ tcp dport @tcp_accepted accept
+ tcp dport 1024-65535 accept
+ }
+}
diff --git a/tests/shell/testcases/optimizations/dumps/skip_non_eq.nft b/tests/shell/testcases/optimizations/dumps/skip_non_eq.nft
new file mode 100644
index 00000000..6df38655
--- /dev/null
+++ b/tests/shell/testcases/optimizations/dumps/skip_non_eq.nft
@@ -0,0 +1,6 @@
+table inet x {
+ chain y {
+ iifname "eth0" oifname != "eth0" counter packets 0 bytes 0 accept
+ iifname "eth0" oifname "eth0" counter packets 0 bytes 0 accept
+ }
+}
diff --git a/tests/shell/testcases/optimizations/dumps/skip_unsupported.nft b/tests/shell/testcases/optimizations/dumps/skip_unsupported.nft
new file mode 100644
index 00000000..43b6578d
--- /dev/null
+++ b/tests/shell/testcases/optimizations/dumps/skip_unsupported.nft
@@ -0,0 +1,7 @@
+table inet x {
+ chain y {
+ ip saddr 1.2.3.4 tcp dport 80 meta mark set 0x0000000a accept
+ ip saddr 1.2.3.4 tcp dport 81 meta mark set 0x0000000b accept
+ ip saddr . tcp dport { 1.2.3.5 . 81, 1.2.3.5 . 82 } accept
+ }
+}
diff --git a/tests/shell/testcases/optimizations/merge_nat b/tests/shell/testcases/optimizations/merge_nat
new file mode 100755
index 00000000..290cfcfe
--- /dev/null
+++ b/tests/shell/testcases/optimizations/merge_nat
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip test1 {
+ chain y {
+ ip saddr 4.4.4.4 dnat to 1.1.1.1
+ ip saddr 5.5.5.5 dnat to 2.2.2.2
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
+
+RULESET="table ip test2 {
+ chain y {
+ tcp dport 80 dnat to 1.1.1.1:8001
+ tcp dport 81 dnat to 2.2.2.2:9001
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
+
+RULESET="table ip test3 {
+ chain y {
+ ip saddr 1.1.1.1 tcp sport 1024-65535 snat to 3.3.3.3
+ ip saddr 2.2.2.2 tcp sport 1024-65535 snat to 4.4.4.4
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
+
+RULESET="table ip test4 {
+ chain y {
+ ip daddr 1.1.1.1 tcp dport 80 dnat to 4.4.4.4:8000
+ ip daddr 2.2.2.2 tcp dport 81 dnat to 3.3.3.3:9000
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/merge_reject b/tests/shell/testcases/optimizations/merge_reject
new file mode 100755
index 00000000..c0ef9cac
--- /dev/null
+++ b/tests/shell/testcases/optimizations/merge_reject
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip x {
+ chain y {
+ meta l4proto tcp ip daddr 172.30.33.70 tcp dport 3306 counter packets 0 bytes 0 drop
+ meta l4proto tcp ip daddr 172.30.33.71 tcp dport 3306 counter packets 0 bytes 0 reject
+ meta l4proto tcp ip daddr 172.30.238.117 tcp dport 8080 counter packets 0 bytes 0 reject
+ meta l4proto tcp ip daddr 172.30.254.251 tcp dport 3306 counter packets 0 bytes 0 reject
+ meta l4proto tcp ip daddr 172.30.254.252 tcp dport 3306 counter packets 0 bytes 0 reject with tcp reset
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
+
+RULESET="table ip6 x {
+ chain y {
+ meta l4proto tcp ip6 daddr aaaa::2 tcp dport 3306 counter packets 0 bytes 0 reject
+ meta l4proto tcp ip6 daddr aaaa::3 tcp dport 8080 counter packets 0 bytes 0 reject
+ meta l4proto tcp ip6 daddr aaaa::4 tcp dport 3306 counter packets 0 bytes 0 reject
+ meta l4proto tcp ip6 daddr aaaa::5 tcp dport 3306 counter packets 0 bytes 0 reject with tcp reset
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/merge_stmts b/tests/shell/testcases/optimizations/merge_stmts
new file mode 100755
index 00000000..ec7a9dd6
--- /dev/null
+++ b/tests/shell/testcases/optimizations/merge_stmts
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip x {
+ chain y {
+ ip daddr 192.168.0.1 counter accept comment "test1"
+ ip daddr 192.168.0.2 counter accept comment "test2"
+ ip daddr 192.168.0.3 counter accept comment "test3"
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/merge_stmts_concat b/tests/shell/testcases/optimizations/merge_stmts_concat
new file mode 100755
index 00000000..9679d862
--- /dev/null
+++ b/tests/shell/testcases/optimizations/merge_stmts_concat
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip x {
+ chain y {
+ meta iifname eth1 ip saddr 1.1.1.1 ip daddr 2.2.2.3 accept
+ meta iifname eth1 ip saddr 1.1.1.2 ip daddr 2.2.2.4 accept
+ meta iifname eth1 ip saddr 1.1.1.2 ip daddr 2.2.3.0/24 accept
+ meta iifname eth1 ip saddr 1.1.1.2 ip daddr 2.2.4.0-2.2.4.10 accept
+ meta iifname eth2 ip saddr 1.1.1.3 ip daddr 2.2.2.5 accept
+ ip protocol . th dport { tcp . 22, udp . 67 }
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
+
+RULESET="table ip x {
+ chain c1 {
+ udp dport 51820 iifname "foo" accept
+ udp dport { 67, 514 } iifname "bar" accept
+ }
+
+ chain c2 {
+ udp dport { 51820, 100 } iifname "foo" accept
+ udp dport { 67, 514 } iifname "bar" accept
+ }
+
+ chain c3 {
+ udp dport { 51820, 100 } iifname { "foo", "test" } accept
+ udp dport { 67, 514 } iifname "bar" accept
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/merge_stmts_concat_vmap b/tests/shell/testcases/optimizations/merge_stmts_concat_vmap
new file mode 100755
index 00000000..657d0aea
--- /dev/null
+++ b/tests/shell/testcases/optimizations/merge_stmts_concat_vmap
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip x {
+ chain x {
+ meta pkttype broadcast udp dport { 67, 547 } accept
+ meta pkttype multicast udp dport 1900 drop
+ }
+ chain y {
+ ip saddr 1.1.1.1 ip daddr 2.2.2.2 accept
+ ip saddr 4.4.4.4 ip daddr 5.5.5.5 accept
+ ip saddr 2.2.2.2 ip daddr 3.3.3.3 drop
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/merge_stmts_vmap b/tests/shell/testcases/optimizations/merge_stmts_vmap
new file mode 100755
index 00000000..79350076
--- /dev/null
+++ b/tests/shell/testcases/optimizations/merge_stmts_vmap
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip x {
+ chain y {
+ ct state invalid drop
+ ct state established,related accept
+ }
+ chain z {
+ tcp dport { 1 } accept
+ tcp dport 2-3 drop
+ tcp dport 4 accept
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/merge_vmap_raw b/tests/shell/testcases/optimizations/merge_vmap_raw
new file mode 100755
index 00000000..f3dc0721
--- /dev/null
+++ b/tests/shell/testcases/optimizations/merge_vmap_raw
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table inet x {
+ chain nat_dns_dnstc { meta l4proto udp redirect to :5300 ; drop ; }
+ chain nat_dns_this_5301 { meta l4proto udp redirect to :5301 ; drop ; }
+ chain nat_dns_saturn_5301 { meta nfproto ipv4 meta l4proto udp dnat to 240.0.1.2:5301 ; drop ; }
+ chain nat_dns_saturn_5302 { meta nfproto ipv4 meta l4proto udp dnat to 240.0.1.2:5302 ; drop ; }
+ chain nat_dns_saturn_5303 { meta nfproto ipv4 meta l4proto udp dnat to 240.0.1.2:5303 ; drop ; }
+
+ chain nat_dns_acme {
+ udp length 47-63 @th,160,128 0x0e373135363130333131303735353203 \
+ goto nat_dns_dnstc
+
+ udp length 62-78 @th,160,128 0x0e31393032383939353831343037320e \
+ goto nat_dns_this_5301
+
+ udp length 62-78 @th,160,128 0x0e31363436323733373931323934300e \
+ goto nat_dns_saturn_5301
+
+ udp length 62-78 @th,160,128 0x0e32393535373539353636383732310e \
+ goto nat_dns_saturn_5302
+
+ udp length 62-78 @th,160,128 0x0e38353439353637323038363633390e \
+ goto nat_dns_saturn_5303
+
+ drop
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/merge_vmaps b/tests/shell/testcases/optimizations/merge_vmaps
new file mode 100755
index 00000000..e2e4be15
--- /dev/null
+++ b/tests/shell/testcases/optimizations/merge_vmaps
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip x {
+ set s {
+ type ipv4_addr
+ flags dynamic
+ }
+ chain filter_in_tcp {
+ }
+ chain filter_in_udp {
+ }
+ chain y {
+ update @s { ip saddr limit rate 12/minute burst 30 packets } accept
+ tcp dport vmap {
+ 80 : accept,
+ 81 : accept,
+ 443 : accept,
+ }
+ tcp dport vmap {
+ 8000-8100 : accept,
+ 24000-25000 : accept,
+ }
+ meta l4proto tcp goto filter_in_tcp
+ meta l4proto udp goto filter_in_udp
+ log
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/not_mergeable b/tests/shell/testcases/optimizations/not_mergeable
new file mode 100755
index 00000000..ddb2f0fd
--- /dev/null
+++ b/tests/shell/testcases/optimizations/not_mergeable
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip x {
+ chain t1 {
+ }
+ chain t2 {
+ }
+ chain t3 {
+ }
+ chain t4 {
+ }
+ chain y {
+ counter jump t1
+ counter jump t2
+ ip version 4 jump t3
+ ip version 6 jump t4
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/ruleset b/tests/shell/testcases/optimizations/ruleset
new file mode 100755
index 00000000..ef2652db
--- /dev/null
+++ b/tests/shell/testcases/optimizations/ruleset
@@ -0,0 +1,168 @@
+#!/bin/bash
+
+RULESET="table inet uni {
+ chain gtfo {
+ reject with icmpx type host-unreachable
+ drop
+ }
+
+ chain filter_in_tcp {
+ tcp dport vmap {
+ 80 : accept,
+ 81 : accept,
+ 443 : accept,
+ 931 : accept,
+ 5001 : accept,
+ 5201 : accept,
+ }
+ tcp dport vmap {
+ 6800-6999 : accept,
+ 33434-33499 : accept,
+ }
+
+ drop
+ }
+
+ chain filter_in_udp {
+ udp dport vmap {
+ 53 : accept,
+ 123 : accept,
+ 846 : accept,
+ 849 : accept,
+ 5001 : accept,
+ 5201 : accept,
+ }
+ udp dport vmap {
+ 5300-5399 : accept,
+ 6800-6999 : accept,
+ 33434-33499 : accept,
+ }
+
+ drop
+ }
+
+ chain filter_in {
+ type filter hook input priority 0; policy drop;
+
+ ct state vmap {
+ invalid : drop,
+ established : accept,
+ related : accept,
+ untracked : accept,
+ }
+
+ ct status vmap {
+ dnat : accept,
+ snat : accept,
+ }
+
+ iif lo accept
+
+ meta iifgroup {100-199} accept
+
+ meta l4proto tcp goto filter_in_tcp
+ meta l4proto udp goto filter_in_udp
+
+ icmp type vmap {
+ echo-request : accept,
+ }
+ ip6 nexthdr icmpv6 icmpv6 type vmap {
+ echo-request : accept,
+ }
+ }
+
+ chain filter_fwd_ifgroup {
+ meta iifgroup . oifgroup vmap {
+ 100 . 10 : accept,
+ 100 . 100 : accept,
+ 100 . 101 : accept,
+ 101 . 101 : accept,
+ }
+ goto gtfo
+ }
+
+ chain filter_fwd {
+ type filter hook forward priority 0; policy drop;
+
+ fib daddr type broadcast drop
+
+ ct state vmap {
+ invalid : drop,
+ established : accept,
+ related : accept,
+ untracked : accept,
+ }
+
+ ct status vmap {
+ dnat : accept,
+ snat : accept,
+ }
+
+ meta iifgroup {100-199} goto filter_fwd_ifgroup
+ }
+
+ chain nat_fwd_tun {
+ meta l4proto tcp redirect to :15
+ udp dport 53 redirect to :13
+ goto gtfo
+ }
+
+ chain nat_dns_dnstc { meta l4proto udp redirect to :5300 ; drop ; }
+ chain nat_dns_this_5301 { meta l4proto udp redirect to :5301 ; drop ; }
+ chain nat_dns_moon_5301 { meta nfproto ipv4 meta l4proto udp dnat to 240.0.1.2:5301 ; drop ; }
+ chain nat_dns_moon_5302 { meta nfproto ipv4 meta l4proto udp dnat to 240.0.1.2:5302 ; drop ; }
+ chain nat_dns_moon_5303 { meta nfproto ipv4 meta l4proto udp dnat to 240.0.1.2:5303 ; drop ; }
+
+ chain nat_dns_acme {
+ udp length 47-63 @th,160,128 0x0e373135363130333131303735353203 \
+ goto nat_dns_dnstc
+
+ udp length 62-78 @th,160,128 0x0e31393032383939353831343037320e \
+ goto nat_dns_this_5301
+
+ udp length 62-78 @th,160,128 0x0e31363436323733373931323934300e \
+ goto nat_dns_moon_5301
+
+ udp length 62-78 @th,160,128 0x0e32393535373539353636383732310e \
+ goto nat_dns_moon_5302
+
+ udp length 62-78 @th,160,128 0x0e38353439353637323038363633390e \
+ goto nat_dns_moon_5303
+
+ drop
+ }
+
+ chain nat_prerouting {
+ type nat hook prerouting priority -100; policy accept;
+
+ iifgroup 10 udp dport 53 goto nat_dns_acme
+ iifgroup 10 accept
+
+ ip daddr 198.19.0.0/16 goto nat_fwd_tun
+ ip6 daddr fc00::/8 goto nat_fwd_tun
+
+ tcp dport 53 redirect to :25302
+ udp dport 53 redirect to :25302
+ }
+
+ chain nat_output {
+ type nat hook output priority -100; policy accept;
+
+ ip daddr 198.19.0.0/16 goto nat_fwd_tun
+ ip6 daddr fc00::/8 goto nat_fwd_tun
+ }
+
+ chain nat_postrouting {
+ type nat hook postrouting priority 100; policy accept;
+
+ oif != lo masquerade
+ }
+
+ chain mangle_forward {
+ type filter hook forward priority -150; policy accept;
+
+ tcp flags & (syn | rst) == syn tcp option maxseg size set rt mtu
+ }
+}"
+
+$NFT -o -c -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/skip_merge b/tests/shell/testcases/optimizations/skip_merge
new file mode 100755
index 00000000..8af976ca
--- /dev/null
+++ b/tests/shell/testcases/optimizations/skip_merge
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table inet filter {
+ set udp_accepted {
+ type inet_service;
+ elements = {
+ isakmp, ipsec-nat-t
+ }
+ }
+
+ set tcp_accepted {
+ type inet_service;
+ elements = {
+ http, https
+ }
+ }
+
+ chain udp_input {
+ udp dport 1-128 accept
+ udp dport @udp_accepted accept
+ udp dport domain accept
+ }
+
+ chain tcp_input {
+ tcp dport 1-128 accept
+ tcp dport 8888-9999 accept
+ tcp dport @tcp_accepted accept
+ tcp dport 1024-65535 accept
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/skip_non_eq b/tests/shell/testcases/optimizations/skip_non_eq
new file mode 100755
index 00000000..431ed0ad
--- /dev/null
+++ b/tests/shell/testcases/optimizations/skip_non_eq
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table inet x {
+ chain y {
+ iifname "eth0" oifname != "eth0" counter packets 0 bytes 0 accept
+ iifname "eth0" oifname "eth0" counter packets 0 bytes 0 accept
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/skip_unsupported b/tests/shell/testcases/optimizations/skip_unsupported
new file mode 100755
index 00000000..9313c302
--- /dev/null
+++ b/tests/shell/testcases/optimizations/skip_unsupported
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table inet x {
+ chain y {
+ ip saddr 1.2.3.4 tcp dport 80 meta mark set 10 accept
+ ip saddr 1.2.3.4 tcp dport 81 meta mark set 11 accept
+ ip saddr 1.2.3.5 tcp dport 81 accept comment \"test\"
+ ip saddr 1.2.3.5 tcp dport 82 accept
+ }
+}"
+
+$NFT -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/optimizations/variables b/tests/shell/testcases/optimizations/variables
new file mode 100755
index 00000000..fa986065
--- /dev/null
+++ b/tests/shell/testcases/optimizations/variables
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -e
+
+RULESET="define addrv4_vpnnet = 10.1.0.0/16
+
+table ip nat {
+ chain postrouting {
+ type nat hook postrouting priority 0; policy accept;
+
+ ip saddr \$addrv4_vpnnet counter masquerade fully-random comment \"masquerade ipv4\"
+ }
+}"
+
+$NFT -c -o -f - <<< $RULESET
diff --git a/tests/shell/testcases/owner/0001-flowtable-uaf b/tests/shell/testcases/owner/0001-flowtable-uaf
new file mode 100755
index 00000000..4efbe75c
--- /dev/null
+++ b/tests/shell/testcases/owner/0001-flowtable-uaf
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+set -e
+
+$NFT -f - <<EOF
+table t {
+ flags owner
+ flowtable f {
+ devices = { lo }
+ }
+}
+EOF
+
+# trigger uaf.
+$NFT -f - <<EOF
+table t {
+ flags owner
+ flowtable f {
+ devices = { lo }
+ }
+}
+EOF
diff --git a/tests/shell/testcases/parsing/describe b/tests/shell/testcases/parsing/describe
new file mode 100755
index 00000000..2ee072e8
--- /dev/null
+++ b/tests/shell/testcases/parsing/describe
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+errmsg='Error: unknown ip option type/field'
+
+str=$($NFT describe ip option rr value 2>&1 | head -n 1)
+
+[ "$str" = "$errmsg" ] && exit 0
diff --git a/tests/shell/testcases/parsing/log b/tests/shell/testcases/parsing/log
new file mode 100755
index 00000000..0b89d589
--- /dev/null
+++ b/tests/shell/testcases/parsing/log
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+$NFT add table t || exit 1
+$NFT add chain t c || exit 1
+$NFT add rule t c 'iif != lo ip daddr 127.0.0.1/8 counter limit rate 1/second log flags all prefix "nft_lo4 " drop' || exit 1
+$NFT add rule t c 'iif != lo ip daddr 127.0.0.1/8 counter limit rate 1/second log flags all level debug drop' || exit 1
+$NFT delete table t || exit 1
+
+exit 0
+
diff --git a/tests/shell/testcases/parsing/octal b/tests/shell/testcases/parsing/octal
new file mode 100755
index 00000000..09ac26e7
--- /dev/null
+++ b/tests/shell/testcases/parsing/octal
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+$NFT add table t || exit 1
+$NFT add chain t c || exit 1
+$NFT add rule t c 'ip saddr 01 continue comment "0.0.0.1"' || exit 1
+$NFT add rule t c 'ip saddr 08 continue comment "error"' && {
+ echo "'"ip saddr 08"'" not rejected 1>&2
+ exit 1
+}
+$NFT delete table t || exit 1
+
+exit 0
+
diff --git a/tests/shell/testcases/rule_management/0003insert_0 b/tests/shell/testcases/rule_management/0003insert_0
index 329ccc20..c343d579 100755
--- a/tests/shell/testcases/rule_management/0003insert_0
+++ b/tests/shell/testcases/rule_management/0003insert_0
@@ -9,3 +9,7 @@ $NFT add chain t c
$NFT insert rule t c accept
$NFT insert rule t c drop
$NFT insert rule t c masquerade
+
+# check 'evaluate: un-break rule insert with intervals'
+
+$NFT insert rule t c tcp sport { 3478-3497, 16384-16387 }
diff --git a/tests/shell/testcases/rule_management/0011reset_0 b/tests/shell/testcases/rule_management/0011reset_0
new file mode 100755
index 00000000..1a28b49f
--- /dev/null
+++ b/tests/shell/testcases/rule_management/0011reset_0
@@ -0,0 +1,168 @@
+#!/bin/sh
+
+set -e
+
+echo "loading ruleset"
+$NFT -f - <<EOF
+table ip t {
+ set s {
+ type ipv4_addr
+ counter
+ elements = { 1.1.1.1 counter packets 1 bytes 11 }
+ }
+ chain c {
+ counter packets 1 bytes 11 update @s { ip saddr } accept
+ counter packets 2 bytes 12 drop
+ }
+
+ chain c2 {
+ counter packets 3 bytes 13 accept
+ counter packets 4 bytes 14 drop
+ }
+}
+table inet t {
+ chain c {
+ counter packets 5 bytes 15 accept
+ counter packets 6 bytes 16 drop
+ }
+}
+table ip t2 {
+ chain c2 {
+ counter packets 7 bytes 17 accept
+ counter packets 8 bytes 18 drop
+ }
+}
+EOF
+
+echo "resetting specific rule"
+handle=$($NFT -a list chain t c | sed -n 's/.*accept # handle \([0-9]*\)$/\1/p')
+$NFT reset rule t c handle $handle
+EXPECT='table ip t {
+ set s {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ counter
+ elements = { 1.1.1.1 counter packets 1 bytes 11 }
+ }
+
+ chain c {
+ counter packets 0 bytes 0 update @s { ip saddr } accept
+ counter packets 2 bytes 12 drop
+ }
+
+ chain c2 {
+ counter packets 3 bytes 13 accept
+ counter packets 4 bytes 14 drop
+ }
+}
+table inet t {
+ chain c {
+ counter packets 5 bytes 15 accept
+ counter packets 6 bytes 16 drop
+ }
+}
+table ip t2 {
+ chain c2 {
+ counter packets 7 bytes 17 accept
+ counter packets 8 bytes 18 drop
+ }
+}'
+$DIFF -u <(echo "$EXPECT") <($NFT list ruleset)
+
+echo "resetting specific chain"
+EXPECT='table ip t {
+ set s {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ counter
+ }
+
+ chain c2 {
+ counter packets 3 bytes 13 accept
+ counter packets 4 bytes 14 drop
+ }
+}'
+$DIFF -u <(echo "$EXPECT") <($NFT reset rules chain t c2)
+
+echo "resetting specific table"
+EXPECT='table ip t {
+ set s {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ counter
+ }
+
+ chain c {
+ counter packets 0 bytes 0 update @s { ip saddr } accept
+ counter packets 2 bytes 12 drop
+ }
+
+ chain c2 {
+ counter packets 0 bytes 0 accept
+ counter packets 0 bytes 0 drop
+ }
+}'
+$DIFF -u <(echo "$EXPECT") <($NFT reset rules table t)
+
+echo "resetting specific family"
+EXPECT='table ip t {
+ set s {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ counter
+ }
+
+ chain c {
+ counter packets 0 bytes 0 update @s { ip saddr } accept
+ counter packets 0 bytes 0 drop
+ }
+
+ chain c2 {
+ counter packets 0 bytes 0 accept
+ counter packets 0 bytes 0 drop
+ }
+}
+table ip t2 {
+ chain c2 {
+ counter packets 7 bytes 17 accept
+ counter packets 8 bytes 18 drop
+ }
+}'
+$DIFF -u <(echo "$EXPECT") <($NFT reset rules ip)
+
+echo "resetting whole ruleset"
+EXPECT='table ip t {
+ set s {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ counter
+ }
+
+ chain c {
+ counter packets 0 bytes 0 update @s { ip saddr } accept
+ counter packets 0 bytes 0 drop
+ }
+
+ chain c2 {
+ counter packets 0 bytes 0 accept
+ counter packets 0 bytes 0 drop
+ }
+}
+table inet t {
+ chain c {
+ counter packets 5 bytes 15 accept
+ counter packets 6 bytes 16 drop
+ }
+}
+table ip t2 {
+ chain c2 {
+ counter packets 0 bytes 0 accept
+ counter packets 0 bytes 0 drop
+ }
+}'
+$DIFF -u <(echo "$EXPECT") <($NFT reset rules)
diff --git a/tests/shell/testcases/rule_management/dumps/0003insert_0.nft b/tests/shell/testcases/rule_management/dumps/0003insert_0.nft
index 9421f4ae..b1875aba 100644
--- a/tests/shell/testcases/rule_management/dumps/0003insert_0.nft
+++ b/tests/shell/testcases/rule_management/dumps/0003insert_0.nft
@@ -1,5 +1,6 @@
table ip t {
chain c {
+ tcp sport { 3478-3497, 16384-16387 }
masquerade
drop
accept
diff --git a/tests/shell/testcases/rule_management/dumps/0011reset_0.nft b/tests/shell/testcases/rule_management/dumps/0011reset_0.nft
new file mode 100644
index 00000000..3b4f5a11
--- /dev/null
+++ b/tests/shell/testcases/rule_management/dumps/0011reset_0.nft
@@ -0,0 +1,31 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ counter
+ elements = { 1.1.1.1 counter packets 1 bytes 11 }
+ }
+
+ chain c {
+ counter packets 0 bytes 0 update @s { ip saddr } accept
+ counter packets 0 bytes 0 drop
+ }
+
+ chain c2 {
+ counter packets 0 bytes 0 accept
+ counter packets 0 bytes 0 drop
+ }
+}
+table inet t {
+ chain c {
+ counter packets 0 bytes 0 accept
+ counter packets 0 bytes 0 drop
+ }
+}
+table ip t2 {
+ chain c2 {
+ counter packets 0 bytes 0 accept
+ counter packets 0 bytes 0 drop
+ }
+}
diff --git a/tests/shell/testcases/sets/0024named_objects_0 b/tests/shell/testcases/sets/0024named_objects_0
index 21200c3c..6d21e388 100755
--- a/tests/shell/testcases/sets/0024named_objects_0
+++ b/tests/shell/testcases/sets/0024named_objects_0
@@ -18,6 +18,15 @@ table inet x {
quota user124 {
over 2000 bytes
}
+ synproxy https-synproxy {
+ mss 1460
+ wscale 7
+ timestamp sack-perm
+ }
+ synproxy other-synproxy {
+ mss 1460
+ wscale 5
+ }
set y {
type ipv4_addr
}
@@ -25,9 +34,15 @@ table inet x {
type ipv4_addr : quota
elements = { 192.168.2.2 : "user124", 192.168.2.3 : "user124"}
}
+ map test2 {
+ type ipv4_addr : synproxy
+ flags interval
+ elements = { 192.168.1.0/24 : "https-synproxy", 192.168.2.0/24 : "other-synproxy" }
+ }
chain y {
type filter hook input priority 0; policy accept;
counter name ip saddr map { 192.168.2.2 : "user123", 1.1.1.1 : "user123", 2.2.2.2 : "user123"}
+ synproxy name ip saddr map { 192.168.1.0/24 : "https-synproxy", 192.168.2.0/24 : "other-synproxy" }
quota name ip saddr map @test drop
}
}"
diff --git a/tests/shell/testcases/sets/0031set_timeout_size_0 b/tests/shell/testcases/sets/0031set_timeout_size_0
index 796640d6..9a4a27f6 100755
--- a/tests/shell/testcases/sets/0031set_timeout_size_0
+++ b/tests/shell/testcases/sets/0031set_timeout_size_0
@@ -8,5 +8,5 @@ add rule x test set update ip daddr timeout 100ms @y"
set -e
$NFT -f - <<< "$RULESET"
-$NFT list chain x test | grep -q 'update @y { ip saddr timeout 1d2h3m4s10ms }'
+$NFT list chain x test | grep -q 'update @y { ip saddr timeout 1d2h3m4s\(10\|8\)ms }'
$NFT list chain x test | grep -q 'update @y { ip daddr timeout 100ms }'
diff --git a/tests/shell/testcases/sets/0045concat_ipv4_service b/tests/shell/testcases/sets/0045concat_ipv4_service
new file mode 100755
index 00000000..5b40f973
--- /dev/null
+++ b/tests/shell/testcases/sets/0045concat_ipv4_service
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+$NFT -f - <<EOF
+table inet t {
+ set s {
+ type ipv4_addr . inet_service
+ size 65536
+ flags dynamic,timeout
+ elements = { 192.168.7.1 . 22 }
+ }
+
+ chain c {
+ tcp dport 21 add @s { ip saddr . 22 timeout 60s }
+ }
+}
+EOF
diff --git a/tests/shell/testcases/sets/0046netmap_0 b/tests/shell/testcases/sets/0046netmap_0
index 2804a4a2..60bda401 100755
--- a/tests/shell/testcases/sets/0046netmap_0
+++ b/tests/shell/testcases/sets/0046netmap_0
@@ -8,6 +8,12 @@ EXPECTED="table ip x {
10.141.13.0/24 : 192.168.4.0/24 }
}
}
+ table ip6 x {
+ chain y {
+ type nat hook postrouting priority srcnat; policy accept;
+ snat ip6 prefix to ip6 saddr map { 2001:db8:1111::/64 : 2001:db8:2222::/64 }
+ }
+ }
"
set -e
diff --git a/tests/shell/testcases/sets/0064map_catchall_0 b/tests/shell/testcases/sets/0064map_catchall_0
index 6f2a7c6f..43685160 100755
--- a/tests/shell/testcases/sets/0064map_catchall_0
+++ b/tests/shell/testcases/sets/0064map_catchall_0
@@ -17,3 +17,8 @@ RULESET="table ip x {
$NFT -f - <<< $RULESET
$NFT delete element x y { \* : 192.168.0.3 }
$NFT add element x y { \* : 192.168.0.4 }
+
+$NFT add chain x y
+$NFT add rule x y snat to ip saddr map @z
+$NFT 'add rule x y snat to ip saddr map { 10.141.0.0/24 : 192.168.0.2, * : 192.168.0.3 }'
+$NFT 'add rule x y snat to ip saddr . ip daddr map { 10.141.0.0/24 . 10.0.0.0/8 : 192.168.0.2, 192.168.9.0/24 . 192.168.10.0/24 : 192.168.0.4, * : 192.168.0.3 }'
diff --git a/tests/shell/testcases/sets/0067nat_concat_interval_0 b/tests/shell/testcases/sets/0067nat_concat_interval_0
index 3d1b62d6..530771b0 100755
--- a/tests/shell/testcases/sets/0067nat_concat_interval_0
+++ b/tests/shell/testcases/sets/0067nat_concat_interval_0
@@ -31,3 +31,14 @@ EXPECTED="table ip nat {
}"
$NFT -f - <<< $EXPECTED
+
+EXPECTED="table ip nat {
+ map fwdtoip_th {
+ type ipv4_addr . inet_service : interval ipv4_addr . inet_service
+ flags interval
+ elements = { 1.2.3.4 . 10000-20000 : 192.168.3.4 . 30000-40000 }
+ }
+}"
+
+$NFT -f - <<< $EXPECTED
+$NFT add rule ip nat prerouting meta l4proto { tcp, udp } dnat to ip daddr . th dport map @fwdtoip_th
diff --git a/tests/shell/testcases/sets/0068interval_stack_overflow_0 b/tests/shell/testcases/sets/0068interval_stack_overflow_0
new file mode 100755
index 00000000..2cbc9868
--- /dev/null
+++ b/tests/shell/testcases/sets/0068interval_stack_overflow_0
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+set -e
+
+ruleset_file=$(mktemp)
+
+trap 'rm -f "$ruleset_file"' EXIT
+
+{
+ echo 'define big_set = {'
+ for ((i = 1; i < 255; i++)); do
+ for ((j = 1; j < 255; j++)); do
+ echo "10.0.$i.$j,"
+ done
+ done
+ echo '10.1.0.0/24 }'
+} >"$ruleset_file"
+
+cat >>"$ruleset_file" <<\EOF
+table inet test68_table {
+ set test68_set {
+ type ipv4_addr
+ flags interval
+ elements = { $big_set }
+ }
+}
+EOF
+
+( ulimit -s 400 && $NFT -f "$ruleset_file" )
diff --git a/tests/shell/testcases/sets/0069interval_merge_0 b/tests/shell/testcases/sets/0069interval_merge_0
new file mode 100755
index 00000000..edb6422a
--- /dev/null
+++ b/tests/shell/testcases/sets/0069interval_merge_0
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip x {
+ set y {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ elements = { 1.2.3.0, 1.2.3.255, 1.2.3.0/24, 3.3.3.3, 4.4.4.4, 4.4.4.4-4.4.4.8, 3.3.3.4, 3.3.3.5 }
+ }
+}"
+
+$NFT -f - <<< $RULESET
+
+RULESET="table ip x {
+ set y {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ elements = { 1.2.4.0, 3.3.3.6, 4.4.4.0/24 }
+ }
+}"
+
+$NFT -f - <<< $RULESET
+
+$NFT add element ip x y { 1.2.3.0-1.2.4.255, 3.3.3.5, 4.4.4.1 }
+$NFT add element ip x y { 1.2.3.0-1.2.4.255, 3.3.3.5, 4.4.5.0 }
diff --git a/tests/shell/testcases/sets/0070stacked_l2_headers b/tests/shell/testcases/sets/0070stacked_l2_headers
new file mode 100755
index 00000000..07820b7c
--- /dev/null
+++ b/tests/shell/testcases/sets/0070stacked_l2_headers
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+set -e
+dumpfile=$(dirname $0)/dumps/$(basename $0).nft
+
+$NFT -f "$dumpfile"
diff --git a/tests/shell/testcases/sets/0071unclosed_prefix_interval_0 b/tests/shell/testcases/sets/0071unclosed_prefix_interval_0
new file mode 100755
index 00000000..79e3ca7d
--- /dev/null
+++ b/tests/shell/testcases/sets/0071unclosed_prefix_interval_0
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+set -e
+
+RULESET="
+table inet t {
+ set s1 {
+ type ipv4_addr
+ flags interval
+ elements = { 192.0.0.0/2, 10.0.0.0/8 }
+ }
+ set s2 {
+ type ipv6_addr
+ flags interval
+ elements = { ff00::/8, fe80::/10 }
+ }
+ chain c {
+ ip saddr @s1 accept
+ ip6 daddr @s2 accept
+ }
+}"
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/sets/automerge_0 b/tests/shell/testcases/sets/automerge_0
new file mode 100755
index 00000000..7530b3db
--- /dev/null
+++ b/tests/shell/testcases/sets/automerge_0
@@ -0,0 +1,113 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table inet x {
+ set y {
+ type inet_service
+ flags interval
+ auto-merge
+ }
+}"
+
+$NFT -f - <<< $RULESET
+
+tmpfile=$(mktemp)
+echo -n "add element inet x y { " > $tmpfile
+for ((i=0;i<65535;i+=2))
+do
+ echo -n "$i, " >> $tmpfile
+ if [ $i -eq 65534 ]
+ then
+ echo -n "$i" >> $tmpfile
+ fi
+done
+echo "}" >> $tmpfile
+
+$NFT -f $tmpfile
+
+tmpfile2=$(mktemp)
+for ((i=1;i<65535;i+=2))
+do
+ echo "$i" >> $tmpfile2
+done
+
+tmpfile3=$(mktemp)
+shuf $tmpfile2 > $tmpfile3
+i=0
+cat $tmpfile3 | while read line && [ $i -lt 10 ]
+do
+ $NFT add element inet x y { $line }
+ if [ $? -ne 0 ]
+ then
+ echo "failed to add $line"
+ exit 1
+ fi
+ i=$((i+1))
+done
+
+for ((i=0;i<10;i++))
+do
+ from=$(($RANDOM%65535))
+ to=$(($from+100))
+ $NFT add element inet x y { $from-$to }
+ if [ $? -ne 0 ]
+ then
+ echo "failed to add $from-$to"
+ exit 1
+ fi
+
+ $NFT get element inet x y { $from-$to } 1>/dev/null
+ if [ $? -ne 0 ]
+ then
+ echo "failed to get $from-$to"
+ exit 1
+ fi
+
+ # partial removals in the previous random range
+ from2=$(($from+10))
+ to2=$(($to-10))
+ $NFT delete element inet x y { $from, $to, $from2-$to2 }
+ if [ $? -ne 0 ]
+ then
+ echo "failed to delete $from, $to, $from2-$to2"
+ exit 1
+ fi
+
+ # check deletions are correct
+ from=$(($from+1))
+ $NFT get element inet x y { $from } 1>/dev/null
+ if [ $? -ne 0 ]
+ then
+ echo "failed to get $from"
+ exit 1
+ fi
+
+ to=$(($to-1))
+ $NFT get element inet x y { $to } 1>/dev/null
+ if [ $? -ne 0 ]
+ then
+ echo "failed to get $to"
+ exit 1
+ fi
+
+ from2=$(($from2-1))
+ $NFT get element inet x y { $from2 } 1>/dev/null
+ if [ $? -ne 0 ]
+ then
+ echo "failed to get $from2"
+ exit 1
+ fi
+ to2=$(($to2+1))
+
+ $NFT get element inet x y { $to2 } 1>/dev/null
+ if [ $? -ne 0 ]
+ then
+ echo "failed to get $to2"
+ exit 1
+ fi
+done
+
+rm -f $tmpfile
+rm -f $tmpfile2
+rm -f $tmpfile3
diff --git a/tests/shell/testcases/sets/collapse_elem_0 b/tests/shell/testcases/sets/collapse_elem_0
new file mode 100755
index 00000000..7699e9da
--- /dev/null
+++ b/tests/shell/testcases/sets/collapse_elem_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip a {
+ set x {
+ type inet_service;
+ }
+}
+table ip6 a {
+ set x {
+ type inet_service;
+ }
+}
+add element ip a x { 1 }
+add element ip a x { 2 }
+add element ip6 a x { 2 }"
+
+$NFT -f - <<< $RULESET
diff --git a/tests/shell/testcases/sets/concat_interval_0 b/tests/shell/testcases/sets/concat_interval_0
new file mode 100755
index 00000000..4d90af9a
--- /dev/null
+++ b/tests/shell/testcases/sets/concat_interval_0
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip t {
+ set s {
+ type ipv4_addr . inet_proto . inet_service
+ flags interval
+ counter
+ elements = { 1.0.0.1 . udp . 53 }
+ }
+ set s2 {
+ type ipv4_addr . mark
+ flags interval
+ elements = { 10.10.10.10 . 0x00000100,
+ 20.20.20.20 . 0x00000200 }
+ }
+}"
+
+$NFT -f - <<< $RULESET
+
+$NFT delete element t s { 1.0.0.1 . udp . 53}
+
+exit 0
diff --git a/tests/shell/testcases/sets/dumps/0024named_objects_0.nft b/tests/shell/testcases/sets/dumps/0024named_objects_0.nft
index 2ffa4f2f..52d1bf64 100644
--- a/tests/shell/testcases/sets/dumps/0024named_objects_0.nft
+++ b/tests/shell/testcases/sets/dumps/0024named_objects_0.nft
@@ -15,6 +15,17 @@ table inet x {
over 2000 bytes
}
+ synproxy https-synproxy {
+ mss 1460
+ wscale 7
+ timestamp sack-perm
+ }
+
+ synproxy other-synproxy {
+ mss 1460
+ wscale 5
+ }
+
set y {
type ipv4_addr
}
@@ -24,9 +35,16 @@ table inet x {
elements = { 192.168.2.2 : "user124", 192.168.2.3 : "user124" }
}
+ map test2 {
+ type ipv4_addr : synproxy
+ flags interval
+ elements = { 192.168.1.0/24 : "https-synproxy", 192.168.2.0/24 : "other-synproxy" }
+ }
+
chain y {
type filter hook input priority filter; policy accept;
counter name ip saddr map { 1.1.1.1 : "user123", 2.2.2.2 : "user123", 192.168.2.2 : "user123" }
+ synproxy name ip saddr map { 192.168.1.0/24 : "https-synproxy", 192.168.2.0/24 : "other-synproxy" }
quota name ip saddr map @test drop
}
}
diff --git a/tests/shell/testcases/sets/dumps/0045concat_ipv4_service.nft b/tests/shell/testcases/sets/dumps/0045concat_ipv4_service.nft
new file mode 100644
index 00000000..e548a17a
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0045concat_ipv4_service.nft
@@ -0,0 +1,12 @@
+table inet t {
+ set s {
+ type ipv4_addr . inet_service
+ size 65536
+ flags dynamic,timeout
+ elements = { 192.168.7.1 . 22 }
+ }
+
+ chain c {
+ tcp dport 21 add @s { ip saddr . 22 timeout 1m }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0046netmap_0.nft b/tests/shell/testcases/sets/dumps/0046netmap_0.nft
index e14c3395..5ac6b346 100644
--- a/tests/shell/testcases/sets/dumps/0046netmap_0.nft
+++ b/tests/shell/testcases/sets/dumps/0046netmap_0.nft
@@ -4,3 +4,9 @@ table ip x {
snat ip prefix to ip saddr map { 10.141.11.0/24 : 192.168.2.0/24, 10.141.12.0/24 : 192.168.3.0/24, 10.141.13.0/24 : 192.168.4.0/24 }
}
}
+table ip6 x {
+ chain y {
+ type nat hook postrouting priority srcnat; policy accept;
+ snat ip6 prefix to ip6 saddr map { 2001:db8:1111::/64 : 2001:db8:2222::/64 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0064map_catchall_0.nft b/tests/shell/testcases/sets/dumps/0064map_catchall_0.nft
index 286683a0..890ed2aa 100644
--- a/tests/shell/testcases/sets/dumps/0064map_catchall_0.nft
+++ b/tests/shell/testcases/sets/dumps/0064map_catchall_0.nft
@@ -9,4 +9,10 @@ table ip x {
flags interval
elements = { 10.141.0.0/24 : 192.168.0.2, * : 192.168.0.3 }
}
+
+ chain y {
+ snat to ip saddr map @z
+ snat to ip saddr map { 10.141.0.0/24 : 192.168.0.2, * : 192.168.0.3 }
+ snat to ip saddr . ip daddr map { 10.141.0.0/24 . 10.0.0.0/8 : 192.168.0.2, 192.168.9.0/24 . 192.168.10.0/24 : 192.168.0.4, * : 192.168.0.3 }
+ }
}
diff --git a/tests/shell/testcases/sets/dumps/0067nat_concat_interval_0.nft b/tests/shell/testcases/sets/dumps/0067nat_concat_interval_0.nft
index c565d21f..3226da15 100644
--- a/tests/shell/testcases/sets/dumps/0067nat_concat_interval_0.nft
+++ b/tests/shell/testcases/sets/dumps/0067nat_concat_interval_0.nft
@@ -11,9 +11,16 @@ table ip nat {
elements = { 192.168.1.2 . 192.168.2.2 : 127.0.0.0/8 . 42-43 }
}
+ map fwdtoip_th {
+ type ipv4_addr . inet_service : interval ipv4_addr . inet_service
+ flags interval
+ elements = { 1.2.3.4 . 10000-20000 : 192.168.3.4 . 30000-40000 }
+ }
+
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
ip protocol tcp dnat ip to ip saddr map @ipportmap
ip protocol tcp dnat ip to ip saddr . ip daddr map @ipportmap2
+ meta l4proto { tcp, udp } dnat ip to ip daddr . th dport map @fwdtoip_th
}
}
diff --git a/tests/shell/testcases/sets/dumps/0069interval_merge_0.nft b/tests/shell/testcases/sets/dumps/0069interval_merge_0.nft
new file mode 100644
index 00000000..2d4e1706
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0069interval_merge_0.nft
@@ -0,0 +1,9 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ elements = { 1.2.3.0-1.2.4.255, 3.3.3.3-3.3.3.6,
+ 4.4.4.0-4.4.5.0 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0070stacked_l2_headers.nft b/tests/shell/testcases/sets/dumps/0070stacked_l2_headers.nft
new file mode 100644
index 00000000..0057e9c6
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0070stacked_l2_headers.nft
@@ -0,0 +1,28 @@
+table netdev nt {
+ set vlanidset {
+ typeof vlan id
+ size 1024
+ flags dynamic,timeout
+ }
+
+ set macset {
+ typeof ether saddr . vlan id
+ size 1024
+ flags dynamic,timeout
+ }
+
+ set ipset {
+ typeof vlan id . ip saddr
+ size 1024
+ flags dynamic,timeout
+ }
+
+ chain nc {
+ update @macset { ether saddr . vlan id timeout 5s } counter packets 0 bytes 0
+ ether saddr . vlan id @macset
+ vlan pcp 1
+ ether saddr 0a:0b:0c:0d:0e:0f vlan id 42
+ update @vlanidset { vlan id timeout 5s } counter packets 0 bytes 0
+ update @ipset { vlan id . ip saddr timeout 5s } counter packets 0 bytes 0
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0071unclosed_prefix_interval_0.nft b/tests/shell/testcases/sets/dumps/0071unclosed_prefix_interval_0.nft
new file mode 100644
index 00000000..4eed94c2
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0071unclosed_prefix_interval_0.nft
@@ -0,0 +1,19 @@
+table inet t {
+ set s1 {
+ type ipv4_addr
+ flags interval
+ elements = { 10.0.0.0/8, 192.0.0.0/2 }
+ }
+
+ set s2 {
+ type ipv6_addr
+ flags interval
+ elements = { fe80::/10,
+ ff00::/8 }
+ }
+
+ chain c {
+ ip saddr @s1 accept
+ ip6 daddr @s2 accept
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/collapse_elem_0.nft b/tests/shell/testcases/sets/dumps/collapse_elem_0.nft
new file mode 100644
index 00000000..a3244fc6
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/collapse_elem_0.nft
@@ -0,0 +1,12 @@
+table ip a {
+ set x {
+ type inet_service
+ elements = { 1, 2 }
+ }
+}
+table ip6 a {
+ set x {
+ type inet_service
+ elements = { 2 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/concat_interval_0.nft b/tests/shell/testcases/sets/dumps/concat_interval_0.nft
new file mode 100644
index 00000000..61547c5e
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/concat_interval_0.nft
@@ -0,0 +1,14 @@
+table ip t {
+ set s {
+ type ipv4_addr . inet_proto . inet_service
+ flags interval
+ counter
+ }
+
+ set s2 {
+ type ipv4_addr . mark
+ flags interval
+ elements = { 10.10.10.10 . 0x00000100,
+ 20.20.20.20 . 0x00000200 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/dynset_missing.nft b/tests/shell/testcases/sets/dumps/dynset_missing.nft
new file mode 100644
index 00000000..6c8ed323
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/dynset_missing.nft
@@ -0,0 +1,12 @@
+table ip test {
+ set dlist {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ }
+
+ chain output {
+ type filter hook output priority filter; policy accept;
+ udp dport 1234 update @dlist { ip daddr } counter packets 0 bytes 0
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/inner_0.nft b/tests/shell/testcases/sets/dumps/inner_0.nft
new file mode 100644
index 00000000..925ca777
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/inner_0.nft
@@ -0,0 +1,18 @@
+table netdev x {
+ set x {
+ typeof vxlan ip saddr . vxlan ip daddr
+ elements = { 3.3.3.3 . 4.4.4.4 }
+ }
+
+ set y {
+ typeof vxlan ip saddr
+ size 65535
+ flags dynamic
+ }
+
+ chain y {
+ udp dport 4789 vxlan ip saddr . vxlan ip daddr { 1.1.1.1 . 2.2.2.2 } counter packets 0 bytes 0
+ udp dport 4789 vxlan ip saddr . vxlan ip daddr @x counter packets 0 bytes 0
+ udp dport 4789 update @y { vxlan ip saddr }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/set_eval_0.nft b/tests/shell/testcases/sets/dumps/set_eval_0.nft
new file mode 100644
index 00000000..a45462b8
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/set_eval_0.nft
@@ -0,0 +1,11 @@
+table ip nat {
+ set set_with_interval {
+ type ipv4_addr
+ flags interval
+ }
+
+ chain prerouting {
+ type nat hook prerouting priority dstnat; policy accept;
+ meta l4proto { tcp, udp } th dport 443 dnat to 10.0.0.1
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/sets_with_ifnames.nft b/tests/shell/testcases/sets/dumps/sets_with_ifnames.nft
new file mode 100644
index 00000000..77a8baf5
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/sets_with_ifnames.nft
@@ -0,0 +1,62 @@
+table inet testifsets {
+ set simple {
+ type ifname
+ elements = { "abcdef0",
+ "abcdef1",
+ "othername" }
+ }
+
+ set simple_wild {
+ type ifname
+ flags interval
+ elements = { "abcdef*",
+ "othername",
+ "ppp0" }
+ }
+
+ set concat {
+ type ipv4_addr . ifname
+ elements = { 10.1.2.2 . "abcdef0",
+ 10.1.2.2 . "abcdef1" }
+ }
+
+ set concat_wild {
+ type ipv4_addr . ifname
+ flags interval
+ elements = { 10.1.2.2 . "abcdef*",
+ 10.1.2.1 . "bar",
+ 1.1.2.0/24 . "abcdef0",
+ 12.2.2.0/24 . "abcdef*" }
+ }
+
+ map map_wild {
+ type ifname : verdict
+ flags interval
+ elements = { "abcdef*" : jump do_nothing,
+ "eth0" : jump do_nothing }
+ }
+
+ chain v4icmp {
+ iifname @simple counter packets 0 bytes 0
+ iifname @simple_wild counter packets 0 bytes 0
+ iifname { "eth0", "abcdef0" } counter packets 0 bytes 0
+ iifname { "abcdef*", "eth0" } counter packets 0 bytes 0
+ iifname vmap @map_wild
+ }
+
+ chain v4icmpc {
+ ip saddr . iifname @concat counter packets 0 bytes 0
+ ip saddr . iifname @concat_wild counter packets 0 bytes 0
+ ip saddr . iifname { 10.1.2.2 . "abcdef0" } counter packets 0 bytes 0
+ ip saddr . iifname { 10.1.2.2 . "abcdef*" } counter packets 0 bytes 0
+ }
+
+ chain input {
+ type filter hook input priority filter; policy accept;
+ ip protocol icmp jump v4icmp
+ ip protocol icmp goto v4icmpc
+ }
+
+ chain do_nothing {
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/typeof_raw_0.nft b/tests/shell/testcases/sets/dumps/typeof_raw_0.nft
new file mode 100644
index 00000000..499ff167
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/typeof_raw_0.nft
@@ -0,0 +1,12 @@
+table inet t {
+ set y {
+ typeof ip daddr . @ih,32,32
+ elements = { 1.1.1.1 . 0x14,
+ 2.2.2.2 . 0x20 }
+ }
+
+ chain y {
+ ip saddr . @ih,32,32 { 1.1.1.1 . 0x14, 2.2.2.2 . 0x1e }
+ ip daddr . @ih,32,32 @y
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/typeof_sets_0.nft b/tests/shell/testcases/sets/dumps/typeof_sets_0.nft
index 565369fb..6f5b83af 100644
--- a/tests/shell/testcases/sets/dumps/typeof_sets_0.nft
+++ b/tests/shell/testcases/sets/dumps/typeof_sets_0.nft
@@ -14,6 +14,47 @@ table inet t {
elements = { 2, 3, 103 }
}
+ set s4 {
+ typeof frag frag-off
+ elements = { 1, 1024 }
+ }
+
+ set s5 {
+ typeof ip option ra value
+ elements = { 1, 1024 }
+ }
+
+ set s6 {
+ typeof tcp option maxseg size
+ elements = { 1, 1024 }
+ }
+
+ set s7 {
+ typeof sctp chunk init num-inbound-streams
+ elements = { 1, 4 }
+ }
+
+ set s8 {
+ typeof ip version
+ elements = { 4, 6 }
+ }
+
+ set s9 {
+ typeof ip hdrlength
+ elements = { 0, 1, 2, 3, 4,
+ 15 }
+ }
+
+ set s10 {
+ typeof iifname . ip saddr . ipsec in reqid
+ elements = { "eth0" . 10.1.1.2 . 42 }
+ }
+
+ set s11 {
+ typeof vlan id . ip saddr
+ elements = { 3567 . 1.2.3.4 }
+ }
+
chain c1 {
osf name @s1 accept
}
@@ -21,4 +62,36 @@ table inet t {
chain c2 {
vlan id @s2 accept
}
+
+ chain c4 {
+ frag frag-off @s4 accept
+ }
+
+ chain c5 {
+ ip option ra value @s5 accept
+ }
+
+ chain c6 {
+ tcp option maxseg size @s6 accept
+ }
+
+ chain c7 {
+ sctp chunk init num-inbound-streams @s7 accept
+ }
+
+ chain c8 {
+ ip version @s8 accept
+ }
+
+ chain c9 {
+ ip hdrlength @s9 accept
+ }
+
+ chain c10 {
+ iifname . ip saddr . ipsec in reqid @s10 accept
+ }
+
+ chain c11 {
+ vlan id . ip saddr @s11 accept
+ }
}
diff --git a/tests/shell/testcases/sets/dumps/typeof_sets_1.nft b/tests/shell/testcases/sets/dumps/typeof_sets_1.nft
new file mode 100644
index 00000000..89cbc835
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/typeof_sets_1.nft
@@ -0,0 +1,15 @@
+table bridge t {
+ set nodhcpvlan {
+ typeof vlan id
+ elements = { 1 }
+ }
+
+ chain c1 {
+ vlan id != @nodhcpvlan vlan type arp counter packets 0 bytes 0 jump c2
+ vlan id != @nodhcpvlan vlan type ip counter packets 0 bytes 0 jump c2
+ vlan id != { 1, 2 } vlan type ip6 counter packets 0 bytes 0 jump c2
+ }
+
+ chain c2 {
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/typeof_sets_concat.nft b/tests/shell/testcases/sets/dumps/typeof_sets_concat.nft
new file mode 100644
index 00000000..dbaf7cdc
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/typeof_sets_concat.nft
@@ -0,0 +1,12 @@
+table netdev t {
+ set s {
+ typeof ether saddr . vlan id
+ size 2048
+ flags dynamic,timeout
+ }
+
+ chain c {
+ ether type != 8021q add @s { ether saddr . 0 timeout 5s } counter packets 0 bytes 0 return
+ ether type != 8021q update @s { ether daddr . 123 timeout 1m } counter packets 0 bytes 0 return
+ }
+}
diff --git a/tests/shell/testcases/sets/dynset_missing b/tests/shell/testcases/sets/dynset_missing
new file mode 100755
index 00000000..fdf5f49e
--- /dev/null
+++ b/tests/shell/testcases/sets/dynset_missing
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+set -e
+
+$NFT -f /dev/stdin <<EOF
+table ip test {
+ chain output { type filter hook output priority 0;
+ }
+}
+EOF
+
+# misses 'flags dynamic'
+$NFT 'add set ip test dlist {type ipv4_addr; }'
+
+# picks rhash backend because 'size' was also missing.
+$NFT 'add rule ip test output udp dport 1234 update @dlist { ip daddr } counter'
+
+tmpfile=$(mktemp)
+
+trap "rm -rf $tmpfile" EXIT
+
+# kernel has forced an 64k upper size, i.e. this restore file
+# has 'size 65536' but no 'flags dynamic'.
+$NFT list ruleset > $tmpfile
+
+# this restore works, because set is still the rhash backend.
+$NFT -f $tmpfile # success
+$NFT flush ruleset
+
+# fails without commit 'attempt to set_eval flag if dynamic updates requested',
+# because set in $tmpfile has 'size x' but no 'flags dynamic'.
+$NFT -f $tmpfile
diff --git a/tests/shell/testcases/sets/errors_0 b/tests/shell/testcases/sets/errors_0
new file mode 100755
index 00000000..27f65df3
--- /dev/null
+++ b/tests/shell/testcases/sets/errors_0
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+RULESET="table ip x {
+ set y {
+ type ipv4_addr
+ flags interval
+ }
+}
+
+delete element ip x y { 2.3.4.5 }"
+
+$NFT -f - <<< $RULESET
+if [ $? -eq 0 ]
+then
+ exit 1
+fi
+
+RULESET="table ip x {
+ set y {
+ type ipv4_addr
+ flags interval
+ }
+}
+
+add element x y { 1.1.1.1/24 }
+delete element x y { 1.1.1.1/24 }
+add element x y { 1.1.1.1/24 }
+delete element x y { 2.2.2.2/24 }"
+
+$NFT -f - <<< $RULESET
+if [ $? -eq 0 ]
+then
+ exit 1
+fi
+
+RULESET="flush ruleset
+create table inet filter
+set inet filter foo {}
+add element inet filter foo { foobar }"
+
+$NFT -f - <<< $RULESET
+if [ $? -eq 0 ]
+then
+ exit 1
+fi
+
+RULESET="table ip x {
+ map x {
+ type ifname . ipv4_addr : verdict
+ elements = { if2 . 10.0.0.2 : jump chain2,
+ if2 . 192.168.0.0/24 : jump chain2 }
+ }
+
+ chain chain2 {}
+}"
+
+$NFT -f - <<< $RULESET
+if [ $? -eq 0 ]
+then
+ exit 1
+fi
+
+RULESET="add set inet filter myset { type ipv4_addr; flags interval; auto-merge }
+add element inet filter myset { 192.168.0.0/24 }
+add element inet filter myset { 192.168.0.2 }
+add element inet filter myset { 192.168.1.0/24 }
+add element inet filter myset { 192.168.1.100 }"
+
+$NFT -f - <<< $RULESET || exit 0
diff --git a/tests/shell/testcases/sets/exact_overlap_0 b/tests/shell/testcases/sets/exact_overlap_0
new file mode 100755
index 00000000..1ce9304a
--- /dev/null
+++ b/tests/shell/testcases/sets/exact_overlap_0
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+RULESET="add table t
+add set t s { type ipv4_addr; flags interval; }
+add element t s { 1.0.1.0/24 }
+add element t s { 1.0.2.0/23 }
+add element t s { 1.0.8.0/21 }
+add element t s { 1.0.32.0/19 }
+add element t s { 1.1.0.0/24 }
+add element t s { 1.1.2.0/23 }
+add element t s { 1.1.4.0/22 }
+add element t s { 1.1.8.0/24 }
+add element t s { 1.1.9.0/24 }
+add element t s { 1.1.10.0/23 }
+add element t s { 1.1.12.0/22 }
+add element t s { 1.1.16.0/20 }
+add element t s { 1.1.32.0/19 }
+add element t s { 1.0.1.0/24 }"
+
+$NFT -f - <<< $RULESET || exit 1
+
+$NFT add element t s { 1.0.1.0/24 }
diff --git a/tests/shell/testcases/sets/inner_0 b/tests/shell/testcases/sets/inner_0
new file mode 100755
index 00000000..0eb172a8
--- /dev/null
+++ b/tests/shell/testcases/sets/inner_0
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table netdev x {
+ set x {
+ typeof vxlan ip saddr . vxlan ip daddr
+ elements = {
+ 3.3.3.3 . 4.4.4.4,
+ }
+ }
+
+ set y {
+ typeof vxlan ip saddr
+ flags dynamic
+ }
+
+ chain y {
+ udp dport 4789 vxlan ip saddr . vxlan ip daddr { 1.1.1.1 . 2.2.2.2 } counter
+ udp dport 4789 vxlan ip saddr . vxlan ip daddr @x counter
+ udp dport 4789 update @y { vxlan ip saddr }
+ }
+}"
+
+$NFT -f - <<< $RULESET
diff --git a/tests/shell/testcases/sets/set_eval_0 b/tests/shell/testcases/sets/set_eval_0
new file mode 100755
index 00000000..82b6d3bc
--- /dev/null
+++ b/tests/shell/testcases/sets/set_eval_0
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip nat {
+ set set_with_interval {
+ type ipv4_addr
+ flags interval
+ }
+
+ chain prerouting {
+ type nat hook prerouting priority dstnat; policy accept;
+ meta l4proto { tcp, udp } th dport 443 dnat to 10.0.0.1
+ }
+}"
+
+$NFT -f - <<< $RULESET
diff --git a/tests/shell/testcases/sets/sets_with_ifnames b/tests/shell/testcases/sets/sets_with_ifnames
new file mode 100755
index 00000000..9531c856
--- /dev/null
+++ b/tests/shell/testcases/sets/sets_with_ifnames
@@ -0,0 +1,150 @@
+#!/bin/bash
+
+dumpfile=$(dirname $0)/dumps/$(basename $0).nft
+
+[ -z "$NFT" ] && exit 111
+
+$NFT -f "$dumpfile" || exit 1
+
+rnd=$(mktemp -u XXXXXXXX)
+ns1="nft1ifname-$rnd"
+ns2="nft2ifname-$rnd"
+
+cleanup()
+{
+ ip netns del "$ns1"
+ ip netns del "$ns2"
+}
+
+trap cleanup EXIT
+
+# check a given element is (not) present in the set.
+lookup_elem()
+{
+ local setname=$1
+ local value=$2
+ local fail=$3
+ local expect_result=$4
+ local msg=$5
+
+ result=$(ip netns exec "$ns1" $NFT get element inet testifsets $setname { "$value" } 2>/dev/null | grep "$expect_result" )
+
+ if [ -z "$result" ] && [ $fail -ne 1 ] ; then
+ echo "empty result, expected $expect_result $msg"
+ ip netns exec "$ns1" $NFT get element inet testifsets $setname { "$value" }
+ exit 1
+ fi
+}
+
+check_elem_get()
+{
+ local setname=$1
+ local value=$2
+ local fail=$3
+ local expect_result=$4
+
+ # when query is 'abcde', and set has 'abc*', result is
+ # 'abc*', not 'abcde', so returned element can be different.
+ if [ -z "$expect_result" ]; then
+ expect_result=$ifname
+ fi
+
+ lookup_elem "$setname" "$value" "$fail" "$expect_result" ""
+}
+
+# same, but also delete and re-add the element.
+check_elem()
+{
+ local setname=$1
+ local value=$2
+
+ lookup_elem "$setname" "$value" "0" "$value" "initial check"
+
+ ip netns exec "$ns1" $NFT delete element inet testifsets $setname { "$value" }
+ if [ $? -ne 0 ]; then
+ ip netns exec "$ns1" $NFT list ruleset
+ echo "delete element $setname { $value } failed"
+ exit 1
+ fi
+
+ ip netns exec "$ns1" $NFT add element inet testifsets $setname { "$value" }
+
+ lookup_elem "$setname" "$value" "0" "$value" "check after add/del"
+}
+
+# send pings, check all rules with sets that contain abcdef1 match.
+# there are 4 rules in this chain, 4 should match.
+check_matching_icmp_ppp()
+{
+ pkt=$((RANDOM%10))
+ pkt=$((pkt+1))
+ ip netns exec "$ns1" ping -f -c $pkt 10.1.2.2
+
+ # replies should arrive via 'abcdeg', so, should NOT increment any counters.
+ ip netns exec "$ns1" ping -f -c 100 10.2.2.2
+
+ matches=$(ip netns exec "$ns1" $NFT list chain inet testifsets v4icmp | grep "counter packets $pkt " | wc -l)
+ want=3
+
+ if [ "$matches" -ne $want ] ;then
+ ip netns exec "$ns1" $NFT list ruleset
+ echo "Expected $want matching rules, got $matches, packets $pkt in v4icmp"
+ exit 1
+ fi
+
+ # same, for concat set type.
+
+ matches=$(ip netns exec "$ns1" $NFT list chain inet testifsets v4icmpc | grep "counter packets $pkt " | wc -l)
+
+ if [ "$matches" -ne $want ] ;then
+ ip netns exec "$ns1" $NFT list ruleset
+ echo "Expected $want matching rules, got $matches, packets $pkt in v4icmpc"
+ exit 1
+ fi
+}
+
+ip netns add "$ns1" || exit 111
+ip netns add "$ns2" || exit 111
+ip netns exec "$ns1" $NFT -f "$dumpfile" || exit 3
+
+for n in abcdef0 abcdef1 othername;do
+ check_elem simple $n
+done
+
+check_elem_get simple foo 1
+
+for n in ppp0 othername;do
+ check_elem simple_wild $n
+done
+
+check_elem_get simple_wild enoent 1
+check_elem simple_wild ppp0
+check_elem_get simple_wild abcdefghijk 0 'abcdef\*'
+
+check_elem_get concat '1.2.3.4 . "enoent"' 1
+check_elem_get concat '10.1.2.2 . "abcdef"' 1
+check_elem_get concat '10.1.2.1 . "abcdef1"' 1
+
+check_elem concat '10.1.2.2 . "abcdef0"'
+check_elem concat '10.1.2.2 . "abcdef1"'
+
+set -e
+ip -net "$ns1" link set lo up
+ip -net "$ns2" link set lo up
+ip netns exec "$ns1" ping -f -c 10 127.0.0.1
+
+ip link add abcdef1 netns $ns1 type veth peer name veth0 netns $ns2
+ip link add abcdeg netns $ns1 type veth peer name veth1 netns $ns2
+
+ip -net "$ns1" link set abcdef1 up
+ip -net "$ns2" link set veth0 up
+ip -net "$ns1" link set abcdeg up
+ip -net "$ns2" link set veth1 up
+
+ip -net "$ns1" addr add 10.1.2.1/24 dev abcdef1
+ip -net "$ns1" addr add 10.2.2.1/24 dev abcdeg
+
+ip -net "$ns2" addr add 10.1.2.2/24 dev veth0
+ip -net "$ns2" addr add 10.2.2.2/24 dev veth1
+
+check_matching_icmp_ppp
diff --git a/tests/shell/testcases/sets/typeof_raw_0 b/tests/shell/testcases/sets/typeof_raw_0
new file mode 100755
index 00000000..36396b5c
--- /dev/null
+++ b/tests/shell/testcases/sets/typeof_raw_0
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+EXPECTED="table inet t {
+ set y {
+ typeof ip daddr . @ih,32,32
+ elements = { 1.1.1.1 . 0x14, 2.2.2.2 . 0x20}
+ }
+
+ chain y {
+ ip saddr . @ih,32,32 { 1.1.1.1 . 0x14, 2.2.2.2 . 0x1e }
+ ip daddr . @ih,32,32 @y
+ }
+}"
+
+set -e
+$NFT -f - <<< $EXPECTED
+
diff --git a/tests/shell/testcases/sets/typeof_sets_0 b/tests/shell/testcases/sets/typeof_sets_0
index 9b2712e5..9f777a8c 100755
--- a/tests/shell/testcases/sets/typeof_sets_0
+++ b/tests/shell/testcases/sets/typeof_sets_0
@@ -20,6 +20,46 @@ EXPECTED="table inet t {
elements = { 2, 3, 103 }
}
+ set s4 {
+ typeof frag frag-off
+ elements = { 1, 1024 }
+ }
+
+ set s5 {
+ typeof ip option ra value
+ elements = { 1, 1024 }
+ }
+
+ set s6 {
+ typeof tcp option maxseg size
+ elements = { 1, 1024 }
+ }
+
+ set s7 {
+ typeof sctp chunk init num-inbound-streams
+ elements = { 1, 4 }
+ }
+
+ set s8 {
+ typeof ip version
+ elements = { 4, 6 }
+ }
+
+ set s9 {
+ typeof ip hdrlength
+ elements = { 0, 1, 2, 3, 4, 15 }
+ }
+
+ set s10 {
+ typeof meta iifname . ip saddr . ipsec in reqid
+ elements = { \"eth0\" . 10.1.1.2 . 42 }
+ }
+
+ set s11 {
+ typeof vlan id . ip saddr
+ elements = { 3567 . 1.2.3.4 }
+ }
+
chain c1 {
osf name @s1 accept
}
@@ -27,6 +67,38 @@ EXPECTED="table inet t {
chain c2 {
ether type vlan vlan id @s2 accept
}
+
+ chain c4 {
+ frag frag-off @s4 accept
+ }
+
+ chain c5 {
+ ip option ra value @s5 accept
+ }
+
+ chain c6 {
+ tcp option maxseg size @s6 accept
+ }
+
+ chain c7 {
+ sctp chunk init num-inbound-streams @s7 accept
+ }
+
+ chain c8 {
+ ip version @s8 accept
+ }
+
+ chain c9 {
+ ip hdrlength @s9 accept
+ }
+
+ chain c10 {
+ meta iifname . ip saddr . ipsec in reqid @s10 accept
+ }
+
+ chain c11 {
+ ether type vlan vlan id . ip saddr @s11 accept
+ }
}"
set -e
diff --git a/tests/shell/testcases/sets/typeof_sets_1 b/tests/shell/testcases/sets/typeof_sets_1
new file mode 100755
index 00000000..e520270c
--- /dev/null
+++ b/tests/shell/testcases/sets/typeof_sets_1
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# regression test for corner case in netlink_delinearize
+
+EXPECTED="table bridge t {
+ set nodhcpvlan {
+ typeof vlan id
+ elements = { 1 }
+ }
+
+ chain c1 {
+ vlan id != @nodhcpvlan vlan type arp counter packets 0 bytes 0 jump c2
+ vlan id != @nodhcpvlan vlan type ip counter packets 0 bytes 0 jump c2
+ vlan id != { 1, 2 } vlan type ip6 counter packets 0 bytes 0 jump c2
+ }
+
+ chain c2 {
+ }
+}"
+
+set -e
+$NFT -f - <<< $EXPECTED
diff --git a/tests/shell/testcases/sets/typeof_sets_concat b/tests/shell/testcases/sets/typeof_sets_concat
new file mode 100755
index 00000000..07820b7c
--- /dev/null
+++ b/tests/shell/testcases/sets/typeof_sets_concat
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+set -e
+dumpfile=$(dirname $0)/dumps/$(basename $0).nft
+
+$NFT -f "$dumpfile"