summaryrefslogtreecommitdiffstats
path: root/tests/shell/testcases/sets
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-09 13:08:37 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-09 13:08:37 +0000
commit971e619d8602fa52b1bfcb3ea65b7ab96be85318 (patch)
tree26feb2498c72b796e07b86349d17f544046de279 /tests/shell/testcases/sets
parentInitial commit. (diff)
downloadnftables-upstream.tar.xz
nftables-upstream.zip
Adding upstream version 1.0.9.upstream/1.0.9upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/shell/testcases/sets')
-rwxr-xr-xtests/shell/testcases/sets/0001named_interval_039
-rwxr-xr-xtests/shell/testcases/sets/0002named_interval_automerging_012
-rwxr-xr-xtests/shell/testcases/sets/0003named_interval_missing_flag_012
-rwxr-xr-xtests/shell/testcases/sets/0004named_interval_shadow_013
-rwxr-xr-xtests/shell/testcases/sets/0005named_interval_shadow_013
-rwxr-xr-xtests/shell/testcases/sets/0006create_set_014
-rwxr-xr-xtests/shell/testcases/sets/0007create_element_015
-rwxr-xr-xtests/shell/testcases/sets/0008comments_interval_012
-rwxr-xr-xtests/shell/testcases/sets/0008create_verdict_map_017
-rwxr-xr-xtests/shell/testcases/sets/0009comments_timeout_012
-rwxr-xr-xtests/shell/testcases/sets/0010comments_011
-rwxr-xr-xtests/shell/testcases/sets/0011add_many_elements_047
-rwxr-xr-xtests/shell/testcases/sets/0012add_delete_many_elements_047
-rwxr-xr-xtests/shell/testcases/sets/0013add_delete_many_elements_048
-rwxr-xr-xtests/shell/testcases/sets/0014malformed_set_is_not_defined_025
-rwxr-xr-xtests/shell/testcases/sets/0015rulesetflush_018
-rwxr-xr-xtests/shell/testcases/sets/0016element_leak_011
-rwxr-xr-xtests/shell/testcases/sets/0017add_after_flush_012
-rwxr-xr-xtests/shell/testcases/sets/0018set_check_size_111
-rwxr-xr-xtests/shell/testcases/sets/0019set_check_size_020
-rwxr-xr-xtests/shell/testcases/sets/0020comments_012
-rwxr-xr-xtests/shell/testcases/sets/0021nesting_024
-rwxr-xr-xtests/shell/testcases/sets/0022type_selective_flush_032
-rwxr-xr-xtests/shell/testcases/sets/0023incomplete_add_set_command_016
-rwxr-xr-xtests/shell/testcases/sets/0024named_objects_063
-rwxr-xr-xtests/shell/testcases/sets/0025anonymous_set_017
-rwxr-xr-xtests/shell/testcases/sets/0026named_limit_019
-rwxr-xr-xtests/shell/testcases/sets/0027ipv6_maps_ipv4_017
-rwxr-xr-xtests/shell/testcases/sets/0028autoselect_017
-rwxr-xr-xtests/shell/testcases/sets/0028delete_handle_034
-rwxr-xr-xtests/shell/testcases/sets/0029named_ifname_dtype_065
-rwxr-xr-xtests/shell/testcases/sets/0030add_many_elements_interval_044
-rwxr-xr-xtests/shell/testcases/sets/0031set_timeout_size_012
-rwxr-xr-xtests/shell/testcases/sets/0032restore_set_simple_06
-rwxr-xr-xtests/shell/testcases/sets/0033add_set_simple_flat_09
-rwxr-xr-xtests/shell/testcases/sets/0034get_element_070
-rwxr-xr-xtests/shell/testcases/sets/0035add_set_elements_flat_010
-rwxr-xr-xtests/shell/testcases/sets/0036add_set_element_expiration_024
-rwxr-xr-xtests/shell/testcases/sets/0037_set_with_inet_service_06
-rwxr-xr-xtests/shell/testcases/sets/0038meter_list_029
-rwxr-xr-xtests/shell/testcases/sets/0039delete_interval_017
-rwxr-xr-xtests/shell/testcases/sets/0040get_host_endian_elements_043
-rwxr-xr-xtests/shell/testcases/sets/0041interval_025
-rwxr-xr-xtests/shell/testcases/sets/0042update_set_021
-rwxr-xr-xtests/shell/testcases/sets/0043concatenated_ranges_0194
-rwxr-xr-xtests/shell/testcases/sets/0043concatenated_ranges_123
-rwxr-xr-xtests/shell/testcases/sets/0044interval_overlap_0166
-rwxr-xr-xtests/shell/testcases/sets/0044interval_overlap_138
-rwxr-xr-xtests/shell/testcases/sets/0045concat_ipv4_service16
-rwxr-xr-xtests/shell/testcases/sets/0046netmap_020
-rwxr-xr-xtests/shell/testcases/sets/0047nat_040
-rwxr-xr-xtests/shell/testcases/sets/0048set_counters_018
-rwxr-xr-xtests/shell/testcases/sets/0049set_define_016
-rwxr-xr-xtests/shell/testcases/sets/0050set_define_117
-rwxr-xr-xtests/shell/testcases/sets/0051set_interval_counter_019
-rwxr-xr-xtests/shell/testcases/sets/0052overlap_016
-rwxr-xr-xtests/shell/testcases/sets/0053echo_016
-rwxr-xr-xtests/shell/testcases/sets/0054comments_set_09
-rwxr-xr-xtests/shell/testcases/sets/0055tcpflags_027
-rwxr-xr-xtests/shell/testcases/sets/0056dynamic_limit_019
-rwxr-xr-xtests/shell/testcases/sets/0057set_create_fails_018
-rwxr-xr-xtests/shell/testcases/sets/0058_setupdate_timeout_017
-rwxr-xr-xtests/shell/testcases/sets/0059set_update_multistmt_019
-rwxr-xr-xtests/shell/testcases/sets/0060set_multistmt_052
-rwxr-xr-xtests/shell/testcases/sets/0060set_multistmt_140
-rwxr-xr-xtests/shell/testcases/sets/0061anonymous_automerge_011
-rwxr-xr-xtests/shell/testcases/sets/0062set_connlimit_026
-rwxr-xr-xtests/shell/testcases/sets/0063set_catchall_023
-rwxr-xr-xtests/shell/testcases/sets/0064map_catchall_026
-rwxr-xr-xtests/shell/testcases/sets/0065_icmp_postprocessing13
-rwxr-xr-xtests/shell/testcases/sets/0067nat_concat_interval_071
-rwxr-xr-xtests/shell/testcases/sets/0068interval_stack_overflow_045
-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/0072destroy_012
-rwxr-xr-xtests/shell/testcases/sets/0073flat_interval_set11
-rwxr-xr-xtests/shell/testcases/sets/0074nested_interval_set6
-rwxr-xr-xtests/shell/testcases/sets/automerge_0131
-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/0001named_interval_0.nft34
-rw-r--r--tests/shell/testcases/sets/dumps/0002named_interval_automerging_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0003named_interval_missing_flag_0.nft5
-rw-r--r--tests/shell/testcases/sets/dumps/0004named_interval_shadow_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0005named_interval_shadow_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0006create_set_0.nft5
-rw-r--r--tests/shell/testcases/sets/dumps/0007create_element_0.nft6
-rw-r--r--tests/shell/testcases/sets/dumps/0008comments_interval_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0008create_verdict_map_0.nft13
-rw-r--r--tests/shell/testcases/sets/dumps/0009comments_timeout_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0010comments_0.nft6
-rw-r--r--tests/shell/testcases/sets/dumps/0011add_many_elements_0.nodump0
-rw-r--r--tests/shell/testcases/sets/dumps/0012add_delete_many_elements_0.nft5
-rw-r--r--tests/shell/testcases/sets/dumps/0013add_delete_many_elements_0.nft5
-rw-r--r--tests/shell/testcases/sets/dumps/0014malformed_set_is_not_defined_0.nft0
-rw-r--r--tests/shell/testcases/sets/dumps/0015rulesetflush_0.nft11
-rw-r--r--tests/shell/testcases/sets/dumps/0016element_leak_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0017add_after_flush_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0018set_check_size_1.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0019set_check_size_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0020comments_0.nft6
-rw-r--r--tests/shell/testcases/sets/dumps/0021nesting_0.nft5
-rw-r--r--tests/shell/testcases/sets/dumps/0022type_selective_flush_0.nft13
-rw-r--r--tests/shell/testcases/sets/dumps/0023incomplete_add_set_command_0.nft2
-rw-r--r--tests/shell/testcases/sets/dumps/0024named_objects_0.nft50
-rw-r--r--tests/shell/testcases/sets/dumps/0025anonymous_set_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0026named_limit_0.nft10
-rw-r--r--tests/shell/testcases/sets/dumps/0027ipv6_maps_ipv4_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0028autoselect_0.nft26
-rw-r--r--tests/shell/testcases/sets/dumps/0028delete_handle_0.nft15
-rw-r--r--tests/shell/testcases/sets/dumps/0029named_ifname_dtype_0.nft57
-rw-r--r--tests/shell/testcases/sets/dumps/0030add_many_elements_interval_0.nodump0
-rw-r--r--tests/shell/testcases/sets/dumps/0031set_timeout_size_0.nodump0
-rw-r--r--tests/shell/testcases/sets/dumps/0032restore_set_simple_0.nft11
-rw-r--r--tests/shell/testcases/sets/dumps/0033add_set_simple_flat_0.nft11
-rw-r--r--tests/shell/testcases/sets/dumps/0034get_element_0.nft23
-rw-r--r--tests/shell/testcases/sets/dumps/0035add_set_elements_flat_0.nft6
-rw-r--r--tests/shell/testcases/sets/dumps/0036add_set_element_expiration_0.nodump0
-rw-r--r--tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft16
-rw-r--r--tests/shell/testcases/sets/dumps/0038meter_list_0.nft11
-rw-r--r--tests/shell/testcases/sets/dumps/0039delete_interval_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0040get_host_endian_elements_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0041interval_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0042update_set_0.nft15
-rw-r--r--tests/shell/testcases/sets/dumps/0043concatenated_ranges_0.nft11
-rw-r--r--tests/shell/testcases/sets/dumps/0043concatenated_ranges_1.nft116
-rw-r--r--tests/shell/testcases/sets/dumps/0044interval_overlap_0.nodump0
-rw-r--r--tests/shell/testcases/sets/dumps/0044interval_overlap_1.nft106
-rw-r--r--tests/shell/testcases/sets/dumps/0045concat_ipv4_service.nft12
-rw-r--r--tests/shell/testcases/sets/dumps/0046netmap_0.nft12
-rw-r--r--tests/shell/testcases/sets/dumps/0047nat_0.nft30
-rw-r--r--tests/shell/testcases/sets/dumps/0048set_counters_0.nft13
-rw-r--r--tests/shell/testcases/sets/dumps/0049set_define_0.nft6
-rw-r--r--tests/shell/testcases/sets/dumps/0050set_define_1.nft0
-rw-r--r--tests/shell/testcases/sets/dumps/0051set_interval_counter_0.nft13
-rw-r--r--tests/shell/testcases/sets/dumps/0052overlap_0.nft8
-rw-r--r--tests/shell/testcases/sets/dumps/0053echo_0.nft6
-rw-r--r--tests/shell/testcases/sets/dumps/0054comments_set_0.nft13
-rw-r--r--tests/shell/testcases/sets/dumps/0055tcpflags_0.nft10
-rw-r--r--tests/shell/testcases/sets/dumps/0056dynamic_limit_0.nft0
-rw-r--r--tests/shell/testcases/sets/dumps/0057set_create_fails_0.nft7
-rw-r--r--tests/shell/testcases/sets/dumps/0058_setupdate_timeout_0.nft12
-rw-r--r--tests/shell/testcases/sets/dumps/0059set_update_multistmt_0.nft13
-rw-r--r--tests/shell/testcases/sets/dumps/0060set_multistmt_0.nft13
-rw-r--r--tests/shell/testcases/sets/dumps/0060set_multistmt_1.nft15
-rw-r--r--tests/shell/testcases/sets/dumps/0061anonymous_automerge_0.nft5
-rw-r--r--tests/shell/testcases/sets/dumps/0062set_connlimit_0.nft16
-rw-r--r--tests/shell/testcases/sets/dumps/0063set_catchall_0.nft14
-rw-r--r--tests/shell/testcases/sets/dumps/0064map_catchall_0.nft18
-rw-r--r--tests/shell/testcases/sets/dumps/0065_icmp_postprocessing.nft6
-rw-r--r--tests/shell/testcases/sets/dumps/0067nat_concat_interval_0.nft42
-rw-r--r--tests/shell/testcases/sets/dumps/0068interval_stack_overflow_0.nodump0
-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/0072destroy_0.nft2
-rw-r--r--tests/shell/testcases/sets/dumps/0073flat_interval_set.nft11
-rw-r--r--tests/shell/testcases/sets/dumps/0074nested_interval_set.nft11
-rw-r--r--tests/shell/testcases/sets/dumps/automerge_0.nodump0
-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/errors_0.nft0
-rw-r--r--tests/shell/testcases/sets/dumps/exact_overlap_0.nft13
-rw-r--r--tests/shell/testcases/sets/dumps/inner_0.nft18
-rw-r--r--tests/shell/testcases/sets/dumps/reset_command_0.nodump0
-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/type_set_symbol.nft16
-rw-r--r--tests/shell/testcases/sets/dumps/typeof_raw_0.nft12
-rw-r--r--tests/shell/testcases/sets/dumps/typeof_sets_0.nft97
-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_027
-rwxr-xr-xtests/shell/testcases/sets/reset_command_093
-rwxr-xr-xtests/shell/testcases/sets/set_eval_017
-rwxr-xr-xtests/shell/testcases/sets/sets_with_ifnames150
-rwxr-xr-xtests/shell/testcases/sets/type_set_symbol6
-rwxr-xr-xtests/shell/testcases/sets/typeof_raw_017
-rwxr-xr-xtests/shell/testcases/sets/typeof_sets_0226
-rwxr-xr-xtests/shell/testcases/sets/typeof_sets_122
-rwxr-xr-xtests/shell/testcases/sets/typeof_sets_concat6
186 files changed, 4359 insertions, 0 deletions
diff --git a/tests/shell/testcases/sets/0001named_interval_0 b/tests/shell/testcases/sets/0001named_interval_0
new file mode 100755
index 0000000..612eee0
--- /dev/null
+++ b/tests/shell/testcases/sets/0001named_interval_0
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# This is the most basic testscase:
+# * creating a valid interval set
+# * referencing it from a valid rule
+
+RULESET="
+table inet t {
+ set s1 {
+ type ipv4_addr
+ flags interval
+ elements = { 10.0.0.0-11.0.0.0, 172.16.0.0/16 }
+ }
+ set s2 {
+ type ipv6_addr
+ flags interval
+ elements = { fe00::/64, fe11::-fe22::}
+ }
+ set s3 {
+ type inet_proto
+ flags interval
+ elements = { 10-20, 50-60}
+ }
+ set s4 {
+ type inet_service
+ flags interval
+ elements = {8080-8082, 0-1024, 10000-40000}
+ }
+ chain c {
+ ip saddr @s1 accept
+ ip6 daddr @s2 accept
+ ip protocol @s3 accept
+ ip6 nexthdr @s3 accept
+ tcp dport @s4 accept
+ }
+}"
+
+set -e
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/sets/0002named_interval_automerging_0 b/tests/shell/testcases/sets/0002named_interval_automerging_0
new file mode 100755
index 0000000..6889863
--- /dev/null
+++ b/tests/shell/testcases/sets/0002named_interval_automerging_0
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# This testscase checks the automerging of adjacent intervals
+
+set -e
+
+$NFT add table t
+$NFT add set t s { type ipv4_addr \; flags interval \; }
+$NFT add element t s { 192.168.0.0/24, 192.168.1.0/24 }
+$NFT list ruleset | grep "192.168.0.0/23" >/dev/null || exit 0
+echo "E: automerging of adjacent intervals happened unexpectedly." >&2
+exit 1
diff --git a/tests/shell/testcases/sets/0003named_interval_missing_flag_0 b/tests/shell/testcases/sets/0003named_interval_missing_flag_0
new file mode 100755
index 0000000..e0b7f74
--- /dev/null
+++ b/tests/shell/testcases/sets/0003named_interval_missing_flag_0
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# This testscase checks the nft checking of flags in named intervals
+
+set -e
+$NFT add table t
+$NFT add set t s { type ipv4_addr \; }
+if $NFT add element t s { 192.168.0.0/24, 192.168.1.0/24 } 2>/dev/null ; then
+ echo "E: accepted interval in named set without proper flags" >&2
+ exit 1
+fi
+exit 0
diff --git a/tests/shell/testcases/sets/0004named_interval_shadow_0 b/tests/shell/testcases/sets/0004named_interval_shadow_0
new file mode 100755
index 0000000..827423d
--- /dev/null
+++ b/tests/shell/testcases/sets/0004named_interval_shadow_0
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# This testscase checks the nft checking of shadowed elements
+
+set -e
+$NFT add table inet t
+$NFT add set inet t s { type ipv6_addr \; flags interval \; }
+$NFT add element inet t s { fe00::/64 }
+if $NFT add element inet t s { fe00::/48 } 2>/dev/null ; then
+ echo "E: accepted shadowed element in named set" >&2
+ exit 1
+fi
+exit 0
diff --git a/tests/shell/testcases/sets/0005named_interval_shadow_0 b/tests/shell/testcases/sets/0005named_interval_shadow_0
new file mode 100755
index 0000000..14fcbdc
--- /dev/null
+++ b/tests/shell/testcases/sets/0005named_interval_shadow_0
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# This testscase checks the nft checking of shadowed elements
+
+set -e
+$NFT add table inet t
+$NFT add set inet t s { type ipv6_addr \; flags interval \; }
+$NFT add element inet t s { fe00::/48 }
+if $NFT add element inet t s { fe00::/64 } 2>/dev/null ; then
+ echo "E: accepted shadowed element in named set" >&2
+ exit 1
+fi
+exit 0
diff --git a/tests/shell/testcases/sets/0006create_set_0 b/tests/shell/testcases/sets/0006create_set_0
new file mode 100755
index 0000000..ca36cf7
--- /dev/null
+++ b/tests/shell/testcases/sets/0006create_set_0
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+# This testscase checks for add and create set commands.
+
+set -e
+$NFT add table t
+$NFT add set t s { type ipv4_addr \; }
+if $NFT create set t s { type ipv4_addr \; } 2>/dev/null ; then
+ echo "E: accepted set creation that already exists" >&2
+ exit 1
+fi
+$NFT add set t s { type ipv4_addr \; }
+
+exit 0
diff --git a/tests/shell/testcases/sets/0007create_element_0 b/tests/shell/testcases/sets/0007create_element_0
new file mode 100755
index 0000000..47b3559
--- /dev/null
+++ b/tests/shell/testcases/sets/0007create_element_0
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+# This testcase checks for add and create element commands.
+
+set -e
+$NFT add table t
+$NFT add set t s { type ipv4_addr \; }
+$NFT add element t s { 1.1.1.1 }
+if $NFT create element t s { 1.1.1.1 } 2>/dev/null ; then
+ echo "E: accepted element creation that already exists" >&2
+ exit 1
+fi
+$NFT add element t s { 1.1.1.1 }
+
+exit 0
diff --git a/tests/shell/testcases/sets/0008comments_interval_0 b/tests/shell/testcases/sets/0008comments_interval_0
new file mode 100755
index 0000000..98c709c
--- /dev/null
+++ b/tests/shell/testcases/sets/0008comments_interval_0
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# This test netfilter bug #1090
+# https://bugzilla.netfilter.org/show_bug.cgi?id=1090
+
+$NFT add table t
+$NFT add set t s {type ipv4_addr \; flags interval \;}
+$NFT add element t s { 1.1.1.1 comment "test" }
+if ! $NFT list ruleset | grep test >/dev/null ; then
+ echo "E: missing comment in set element" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/sets/0008create_verdict_map_0 b/tests/shell/testcases/sets/0008create_verdict_map_0
new file mode 100755
index 0000000..e501049
--- /dev/null
+++ b/tests/shell/testcases/sets/0008create_verdict_map_0
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+RULESET="
+table ip t {
+ map sourcemap {
+ type ipv4_addr : verdict;
+ }
+ chain postrouting {
+ ip saddr vmap @sourcemap accept
+ }
+}
+add chain t c
+add element t sourcemap { 100.123.10.2 : jump c }
+"
+
+set -e
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/sets/0009comments_timeout_0 b/tests/shell/testcases/sets/0009comments_timeout_0
new file mode 100755
index 0000000..4e3f80c
--- /dev/null
+++ b/tests/shell/testcases/sets/0009comments_timeout_0
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# Test that comments are added to set elements in timemout sets.
+
+$NFT flush ruleset
+$NFT add table t
+$NFT add set t s {type ipv4_addr \; flags timeout \;}
+$NFT add element t s { 1.1.1.1 comment "test" }
+if ! $NFT list ruleset | grep test >/dev/null ; then
+ echo "E: missing comment in set element" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/sets/0010comments_0 b/tests/shell/testcases/sets/0010comments_0
new file mode 100755
index 0000000..4467a3b
--- /dev/null
+++ b/tests/shell/testcases/sets/0010comments_0
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# Test that comments are added to set elements in standard sets.
+
+$NFT add table inet t
+$NFT add set inet t s {type ipv6_addr \; }
+$NFT add element inet t s { ::1 comment "test" }
+if ! $NFT list ruleset | grep test >/dev/null ; then
+ echo "E: missing comment in set element" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/sets/0011add_many_elements_0 b/tests/shell/testcases/sets/0011add_many_elements_0
new file mode 100755
index 0000000..c37b2f0
--- /dev/null
+++ b/tests/shell/testcases/sets/0011add_many_elements_0
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# test adding many sets elements
+
+HOWMANY=255
+if [ "$NFT_TEST_HAS_SOCKET_LIMITS" = y ] ; then
+ # The socket limit /proc/sys/net/core/wmem_max may be unsuitable for
+ # the test.
+ #
+ # Run only a subset of the test and mark as skipped at the end.
+ HOWMANY=30
+fi
+
+
+tmpfile=$(mktemp)
+if [ ! -w $tmpfile ] ; then
+ echo "Failed to create tmp file" >&2
+ exit 0
+fi
+
+trap "rm -rf $tmpfile" EXIT # cleanup if aborted
+
+generate() {
+ echo -n "{"
+ for ((i=1; i<=HOWMANY; i++)) ; do
+ for ((j=1; j<=HOWMANY; j++)) ; do
+ echo -n "10.0.${i}.${j}"
+ [ "$i" == "$HOWMANY" ] && [ "$j" == "$HOWMANY" ] && break
+ echo -n ", "
+ done
+ done
+ echo -n "}"
+}
+
+echo "add table x
+add set x y { type ipv4_addr; }
+add element x y $(generate)" > $tmpfile
+
+set -e
+$NFT -f $tmpfile
+
+if [ "$HOWMANY" != 255 ] ; then
+ echo "NFT_TEST_HAS_SOCKET_LIMITS indicates that the socket limit for"
+ echo "/proc/sys/net/core/wmem_max is too small for this test. Mark as SKIPPED"
+ echo "You may bump the limit and rerun with \`NFT_TEST_HAS_SOCKET_LIMITS=n\`."
+ exit 77
+fi
diff --git a/tests/shell/testcases/sets/0012add_delete_many_elements_0 b/tests/shell/testcases/sets/0012add_delete_many_elements_0
new file mode 100755
index 0000000..6445160
--- /dev/null
+++ b/tests/shell/testcases/sets/0012add_delete_many_elements_0
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# test adding and deleting many sets elements
+
+HOWMANY=255
+if [ "$NFT_TEST_HAS_SOCKET_LIMITS" = y ] ; then
+ # The socket limit /proc/sys/net/core/wmem_max may be unsuitable for
+ # the test.
+ #
+ # Run only a subset of the test and mark as skipped at the end.
+ HOWMANY=30
+fi
+
+tmpfile=$(mktemp)
+if [ ! -w $tmpfile ] ; then
+ echo "Failed to create tmp file" >&2
+ exit 0
+fi
+
+trap "rm -rf $tmpfile" EXIT # cleanup if aborted
+
+generate() {
+ echo -n "{"
+ for ((i=1; i<=HOWMANY; i++)) ; do
+ for ((j=1; j<=HOWMANY; j++)) ; do
+ echo -n "10.0.${i}.${j}"
+ [ "$i" == "$HOWMANY" ] && [ "$j" == "$HOWMANY" ] && break
+ echo -n ", "
+ done
+ done
+ echo -n "}"
+}
+
+echo "add table x
+add set x y { type ipv4_addr; }
+add element x y $(generate)
+delete element x y $(generate)" > $tmpfile
+
+set -e
+$NFT -f $tmpfile
+
+if [ "$HOWMANY" != 255 ] ; then
+ echo "NFT_TEST_HAS_SOCKET_LIMITS indicates that the socket limit for"
+ echo "/proc/sys/net/core/wmem_max is too small for this test. Mark as SKIPPED"
+ echo "You may bump the limit and rerun with \`NFT_TEST_HAS_SOCKET_LIMITS=n\`."
+ exit 77
+fi
diff --git a/tests/shell/testcases/sets/0013add_delete_many_elements_0 b/tests/shell/testcases/sets/0013add_delete_many_elements_0
new file mode 100755
index 0000000..c0925dd
--- /dev/null
+++ b/tests/shell/testcases/sets/0013add_delete_many_elements_0
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+# test adding and deleting many sets elements in two nft -f runs.
+
+HOWMANY=255
+if [ "$NFT_TEST_HAS_SOCKET_LIMITS" = y ] ; then
+ # The socket limit /proc/sys/net/core/wmem_max may be unsuitable for
+ # the test.
+ #
+ # Run only a subset of the test and mark as skipped at the end.
+ HOWMANY=30
+fi
+
+tmpfile=$(mktemp)
+if [ ! -w $tmpfile ] ; then
+ echo "Failed to create tmp file" >&2
+ exit 0
+fi
+
+trap "rm -rf $tmpfile" EXIT # cleanup if aborted
+
+generate() {
+ echo -n "{"
+ for ((i=1; i<=HOWMANY; i++)) ; do
+ for ((j=1; j<=HOWMANY; j++)) ; do
+ echo -n "10.0.${i}.${j}"
+ [ "$i" == "$HOWMANY" ] && [ "$j" == "$HOWMANY" ] && break
+ echo -n ", "
+ done
+ done
+ echo -n "}"
+}
+
+set -e
+
+echo "add table x
+add set x y { type ipv4_addr; }
+add element x y $(generate)" > $tmpfile
+$NFT -f $tmpfile
+echo "delete element x y $(generate)" > $tmpfile
+$NFT -f $tmpfile
+
+if [ "$HOWMANY" != 255 ] ; then
+ echo "NFT_TEST_HAS_SOCKET_LIMITS indicates that the socket limit for"
+ echo "/proc/sys/net/core/wmem_max is too small for this test. Mark as SKIPPED"
+ echo "You may bump the limit and rerun with \`NFT_TEST_HAS_SOCKET_LIMITS=n\`."
+ exit 77
+fi
diff --git a/tests/shell/testcases/sets/0014malformed_set_is_not_defined_0 b/tests/shell/testcases/sets/0014malformed_set_is_not_defined_0
new file mode 100755
index 0000000..b34d71f
--- /dev/null
+++ b/tests/shell/testcases/sets/0014malformed_set_is_not_defined_0
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# This tests for the bug corrected in commit 5afa5a164ff1c066af1ec56d875b91562882bd50.
+# Sets were added to the table before checking for errors, and not removed from
+# the table on error, leading to an uninitialized set in the table, causing a
+# segfault for rules that tried to use it.
+# In this case, nft should error out because the set doesn't exist instead of
+# segfaulting
+
+RULESET="
+add table t
+add chain t c
+add set t s {type ipv4_addr\;}
+add rule t c ip saddr @s
+"
+
+$NFT -f - <<< "$RULESET"
+ret=$?
+
+trap - EXIT
+if [[ $ret -eq 1 ]]; then
+ exit 0
+else
+ exit 1
+fi
diff --git a/tests/shell/testcases/sets/0015rulesetflush_0 b/tests/shell/testcases/sets/0015rulesetflush_0
new file mode 100755
index 0000000..855d289
--- /dev/null
+++ b/tests/shell/testcases/sets/0015rulesetflush_0
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+RULESET="flush ruleset
+add table t
+add chain t c
+
+table inet filter {
+ set blacklist_v4 { type ipv4_addr; flags interval; }
+}
+
+add element inet filter blacklist_v4 {
+192.168.0.1/24,
+}"
+
+$NFT -f - <<< "$RULESET"
+
+# make sure flush ruleset works right
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/sets/0016element_leak_0 b/tests/shell/testcases/sets/0016element_leak_0
new file mode 100755
index 0000000..5675db3
--- /dev/null
+++ b/tests/shell/testcases/sets/0016element_leak_0
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# This tests for a bug where a repeated element is added and the set
+# elements counter is incorrectly increased.
+
+set -e
+$NFT add table x
+$NFT add set x s {type ipv4_addr\; size 2\;}
+$NFT add element x s {1.1.1.1}
+$NFT add element x s {1.1.1.1}
+$NFT add element x s {1.1.1.1}
diff --git a/tests/shell/testcases/sets/0017add_after_flush_0 b/tests/shell/testcases/sets/0017add_after_flush_0
new file mode 100755
index 0000000..0390b03
--- /dev/null
+++ b/tests/shell/testcases/sets/0017add_after_flush_0
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# This tests for a bug where elements can't be added after flushing a
+# full set with the flag NFTNL_SET_DESC_SIZE set
+
+set -e
+$NFT add table x
+$NFT add set x s {type ipv4_addr\; size 2\;}
+$NFT add element x s {1.1.1.1}
+$NFT add element x s {1.1.1.2}
+$NFT flush set x s
+$NFT add element x s {1.1.1.1}
diff --git a/tests/shell/testcases/sets/0018set_check_size_1 b/tests/shell/testcases/sets/0018set_check_size_1
new file mode 100755
index 0000000..bc70560
--- /dev/null
+++ b/tests/shell/testcases/sets/0018set_check_size_1
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -e
+$NFT add table x
+$NFT add set x s {type ipv4_addr\; size 2\;}
+$NFT add element x s {1.1.1.1}
+$NFT add element x s {1.1.1.2}
+
+$NFT add element x s {1.1.1.3} || exit 0
+echo "E: Accepted 3rd element in a table with max size of 2" 1>&2
+exit 1
diff --git a/tests/shell/testcases/sets/0019set_check_size_0 b/tests/shell/testcases/sets/0019set_check_size_0
new file mode 100755
index 0000000..c209708
--- /dev/null
+++ b/tests/shell/testcases/sets/0019set_check_size_0
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+$NFT add table x
+$NFT add set x s {type ipv4_addr\; size 2\;}
+$NFT add element x s {1.1.1.1}
+$NFT add element x s {1.1.1.2}
+
+$NFT add element x s { 1.1.1.3 } 2>/dev/null
+if [ $? -eq 0 ]; then
+ echo "E: set is full, but element was added" >&2
+ exit 1
+fi
+#
+# Try again, this helps us catch incorrect set->nelems decrement from abort path
+#
+$NFT add element x s { 1.1.1.3 } 2>/dev/null
+if [ $? -eq 0 ]; then
+ echo "E: set is full, but element was added" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/sets/0020comments_0 b/tests/shell/testcases/sets/0020comments_0
new file mode 100755
index 0000000..44d451a
--- /dev/null
+++ b/tests/shell/testcases/sets/0020comments_0
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# Test that comments are added to set elements in standard sets.
+# Explicitly test bitmap backend set implementation.
+
+$NFT add table inet t
+$NFT add set inet t s {type inet_service \; }
+$NFT add element inet t s { 22 comment "test" }
+if ! $NFT list ruleset | grep test >/dev/null ; then
+ echo "E: missing comment in set element" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/sets/0021nesting_0 b/tests/shell/testcases/sets/0021nesting_0
new file mode 100755
index 0000000..0b90dc7
--- /dev/null
+++ b/tests/shell/testcases/sets/0021nesting_0
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -e
+
+RULESET='
+define set1 = {
+ 2.2.2.0/24,
+ 3.3.3.0/24,
+}
+define set2 = {
+ $set1,
+ 1.1.1.0/24
+}
+table ip x {
+ chain y {
+ ip saddr { 3.3.3.0/24, $set2 }
+ }
+}'
+
+$NFT -f - <<< "$RULESET"
+if [ $? -ne 0 ] ; then
+ echo "E: unable to load ruleset" >&2
+ exit 1
+fi
diff --git a/tests/shell/testcases/sets/0022type_selective_flush_0 b/tests/shell/testcases/sets/0022type_selective_flush_0
new file mode 100755
index 0000000..6062913
--- /dev/null
+++ b/tests/shell/testcases/sets/0022type_selective_flush_0
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# This tests the selectiveness of flush command on structures that use the
+# generic set infrastructure (sets, maps and meters).
+
+RULESET="
+add table t
+add chain t c
+add set t s {type ipv4_addr;}
+add map t m {type ipv4_addr : inet_service;}
+add rule t c tcp dport 80 meter f size 1024 {ip saddr limit rate 10/second}
+"
+
+$NFT -f - <<< "$RULESET"
+
+# Commands that should be invalid
+
+declare -a cmds=(
+ "flush set t m" "flush set t f"
+ "flush map t s" "flush map t f"
+ "flush meter t s" "flush meter t m"
+ )
+
+for i in "${cmds[@]}"
+do
+ $NFT "$i" &>/dev/null
+ ret=$?
+
+ if [ $ret -eq 0 ]; then
+ exit 1
+ fi
+done
diff --git a/tests/shell/testcases/sets/0023incomplete_add_set_command_0 b/tests/shell/testcases/sets/0023incomplete_add_set_command_0
new file mode 100755
index 0000000..b7535f7
--- /dev/null
+++ b/tests/shell/testcases/sets/0023incomplete_add_set_command_0
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+# This testscase checks bug identified and fixed in the commit Id "c6cd7c22548a"
+# Before the commit c6cd7c22548a, nft returns 139 (i.e, segmentation fault) which
+# indicates the bug but after the commit it returns 1.
+
+$NFT add table t
+$NFT add set t c
+
+ret=$?
+if [ $ret -ne 1 ] ;
+then
+ echo "E: returned $ret instead of 1" >&2
+ exit 1
+fi
+
diff --git a/tests/shell/testcases/sets/0024named_objects_0 b/tests/shell/testcases/sets/0024named_objects_0
new file mode 100755
index 0000000..6d21e38
--- /dev/null
+++ b/tests/shell/testcases/sets/0024named_objects_0
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+# This is the testscase:
+# * creating valid named objects
+# * referencing them from a valid rule
+
+RULESET="
+table inet x {
+ counter user123 {
+ packets 12 bytes 1433
+ }
+ counter user321 {
+ packets 12 bytes 1433
+ }
+ quota user123 {
+ over 2000 bytes
+ }
+ 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
+ }
+ map test {
+ 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
+ }
+}"
+
+set -e
+$NFT -f - <<< "$RULESET"
+
+EXPECTED="table inet x {
+ counter user321 {
+ packets 12 bytes 1433
+ }
+}"
+
+GET="$($NFT reset counter inet x user321)"
+if [ "$EXPECTED" != "$GET" ] ; then
+ $DIFF -u <(echo "$EXPECTED") <(echo "$GET")
+ exit 1
+fi
diff --git a/tests/shell/testcases/sets/0025anonymous_set_0 b/tests/shell/testcases/sets/0025anonymous_set_0
new file mode 100755
index 0000000..74777d8
--- /dev/null
+++ b/tests/shell/testcases/sets/0025anonymous_set_0
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# Adding anonymous sets
+
+set -e
+
+$NFT add table t
+$NFT add chain t c { type filter hook output priority 0 \; }
+# set: IP addresses
+$NFT add rule t c ip daddr { \
+ 192.168.0.1, \
+ 192.168.0.2, \
+ 192.168.0.3, \
+}
+
+#set : tcp ports
+$NFT add rule t c meta oifname \"doesntexist\" tcp dport { 22, 23 } counter
diff --git a/tests/shell/testcases/sets/0026named_limit_0 b/tests/shell/testcases/sets/0026named_limit_0
new file mode 100755
index 0000000..11f1f5d
--- /dev/null
+++ b/tests/shell/testcases/sets/0026named_limit_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# This is the testscase:
+# * creating valid named limits
+# * referencing them from a valid rule
+
+RULESET="
+table ip filter {
+ limit http-traffic {
+ rate 1/second
+ }
+ chain input {
+ type filter hook input priority 0; policy accept;
+ limit name tcp dport map { 80 : "http-traffic", 443 : "http-traffic"}
+ }
+}"
+
+set -e
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/sets/0027ipv6_maps_ipv4_0 b/tests/shell/testcases/sets/0027ipv6_maps_ipv4_0
new file mode 100755
index 0000000..87603c5
--- /dev/null
+++ b/tests/shell/testcases/sets/0027ipv6_maps_ipv4_0
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# Tests IPv4 Mapped IPv6 addresses.
+
+set -e
+
+RULESET="
+table inet t {
+ set s {
+ type ipv6_addr
+ flags interval
+ elements = { ::ffff:0.0.0.0/96 }
+ }
+}
+"
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/sets/0028autoselect_0 b/tests/shell/testcases/sets/0028autoselect_0
new file mode 100755
index 0000000..23f43a2
--- /dev/null
+++ b/tests/shell/testcases/sets/0028autoselect_0
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# This testscase checks kernel picks a suitable set backends.
+# Ruleset attempts to update from packet path, so set backend
+# needs an ->update() implementation.
+
+set -e
+
+$NFT add table t
+$NFT add set t s1 { type inet_proto \; flags dynamic \; }
+$NFT add set t s2 { type ipv4_addr \; flags dynamic \; }
+$NFT add set t s3 { type ipv4_addr \; size 1024\; flags dynamic \; }
+$NFT add chain t c {type filter hook input priority 0 \; }
+
+$NFT add rule t c meta iifname foobar add @s1 { ip protocol }
+$NFT add rule t c meta iifname foobar add @s2 { ip daddr }
+$NFT add rule t c meta iifname foobar add @s3 { ip daddr }
diff --git a/tests/shell/testcases/sets/0028delete_handle_0 b/tests/shell/testcases/sets/0028delete_handle_0
new file mode 100755
index 0000000..c6d1253
--- /dev/null
+++ b/tests/shell/testcases/sets/0028delete_handle_0
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+set -e
+$NFT add table test-ip
+$NFT add set test-ip x { type ipv4_addr\; }
+$NFT add set test-ip y { type inet_service \; timeout 3h45s \;}
+$NFT add set test-ip z { type ipv4_addr\; flags constant , interval\;}
+$NFT add set test-ip c {type ipv4_addr \; flags timeout \; elements={192.168.1.1 timeout 10s, 192.168.1.2 timeout 30s} \;}
+
+set_handle=$($NFT -a list ruleset | awk '/set c/{print $NF}')
+$NFT delete set test-ip handle $set_handle
+
+EXPECTED="table ip test-ip {
+ set x {
+ type ipv4_addr
+ }
+
+ set y {
+ type inet_service
+ timeout 3h45s
+ }
+
+ set z {
+ type ipv4_addr
+ flags constant,interval
+ }
+}"
+
+GET="$($NFT list ruleset)"
+
+if [ "$EXPECTED" != "$GET" ] ; then
+ $DIFF -u <(echo "$EXPECTED") <(echo "$GET")
+ exit 1
+fi
diff --git a/tests/shell/testcases/sets/0029named_ifname_dtype_0 b/tests/shell/testcases/sets/0029named_ifname_dtype_0
new file mode 100755
index 0000000..2dbcd22
--- /dev/null
+++ b/tests/shell/testcases/sets/0029named_ifname_dtype_0
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+# support for ifname in named sets
+
+EXPECTED="table inet t {
+ set s {
+ type ifname
+ elements = { \"eth0\" }
+ }
+
+ set sc {
+ type inet_service . ifname
+ elements = { \"ssh\" . \"eth0\" }
+ }
+
+ set nv {
+ type ifname . mark
+ }
+
+ set z {
+ typeof ct zone
+ elements = { 1 }
+ }
+
+ set m {
+ typeof meta mark
+ elements = { 1 }
+ }
+
+ map cz {
+ typeof meta iifname : ct zone
+ elements = { \"veth4\" : 1 }
+ }
+
+ map cm {
+ typeof meta iifname : ct mark
+ elements = { \"veth4\" : 1 }
+ }
+
+ chain c {
+ iifname @s accept
+ oifname @s accept
+ tcp dport . meta iifname @sc accept
+ meta iifname . meta mark @nv accept
+ }
+}"
+
+set -e
+$NFT -f - <<< "$EXPECTED"
+$NFT add element inet t s '{ "eth1" }'
+$NFT add element inet t s '{ "eth2", "eth3", "veth1" }'
+
+$NFT add element inet t sc '{ 80 . "eth0" }'
+$NFT add element inet t sc '{ 80 . "eth0" }' || true
+$NFT add element inet t sc '{ 80 . "eth1" }'
+$NFT add element inet t sc '{ 81 . "eth0" }'
+
+$NFT add element inet t nv '{ "eth0" . 1 }'
+$NFT add element inet t nv '{ "eth0" . 2 }'
+
+$NFT add element inet t z '{ 2, 3, 4, 5, 6 }'
+$NFT add element inet t cz '{ "eth0" : 1, "eth1" : 2 }'
+
+$NFT add element inet t m '{ 2, 3, 4, 5, 6 }'
+$NFT add element inet t cm '{ "eth0" : 1, "eth1" : 2 }'
diff --git a/tests/shell/testcases/sets/0030add_many_elements_interval_0 b/tests/shell/testcases/sets/0030add_many_elements_interval_0
new file mode 100755
index 0000000..32a705b
--- /dev/null
+++ b/tests/shell/testcases/sets/0030add_many_elements_interval_0
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+HOWMANY=255
+if [ "$NFT_TEST_HAS_SOCKET_LIMITS" = y ] ; then
+ # The socket limit /proc/sys/net/core/wmem_max may be unsuitable for
+ # the test.
+ #
+ # Run only a subset of the test and mark as skipped at the end.
+ HOWMANY=30
+fi
+
+tmpfile=$(mktemp)
+if [ ! -w $tmpfile ] ; then
+ echo "Failed to create tmp file" >&2
+ exit 0
+fi
+
+trap "rm -rf $tmpfile" EXIT # cleanup if aborted
+
+generate() {
+ echo -n "{"
+ for ((i=1; i<=HOWMANY; i++)) ; do
+ for ((j=1; j<=HOWMANY; j++)) ; do
+ echo -n "10.${i}.${j}.0/24"
+ [ "$i" == "$HOWMANY" ] && [ "$j" == "$HOWMANY" ] && break
+ echo -n ", "
+ done
+ done
+ echo -n "}"
+}
+
+echo "add table x
+add set x y { type ipv4_addr; flags interval; }
+add element x y $(generate)" > $tmpfile
+
+set -e
+$NFT -f $tmpfile
+
+if [ "$HOWMANY" != 255 ] ; then
+ echo "NFT_TEST_HAS_SOCKET_LIMITS indicates that the socket limit for"
+ echo "/proc/sys/net/core/wmem_max is too small for this test. Mark as SKIPPED"
+ echo "You may bump the limit and rerun with \`NFT_TEST_HAS_SOCKET_LIMITS=n\`."
+ exit 77
+fi
diff --git a/tests/shell/testcases/sets/0031set_timeout_size_0 b/tests/shell/testcases/sets/0031set_timeout_size_0
new file mode 100755
index 0000000..9a4a27f
--- /dev/null
+++ b/tests/shell/testcases/sets/0031set_timeout_size_0
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+RULESET="add table x
+add set x y { type ipv4_addr; size 128; timeout 30s; flags dynamic; }
+add chain x test
+add rule x test set update ip saddr timeout 1d2h3m4s10ms @y
+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 1d2h3m4s\(10\|8\)ms }'
+$NFT list chain x test | grep -q 'update @y { ip daddr timeout 100ms }'
diff --git a/tests/shell/testcases/sets/0032restore_set_simple_0 b/tests/shell/testcases/sets/0032restore_set_simple_0
new file mode 100755
index 0000000..07820b7
--- /dev/null
+++ b/tests/shell/testcases/sets/0032restore_set_simple_0
@@ -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/0033add_set_simple_flat_0 b/tests/shell/testcases/sets/0033add_set_simple_flat_0
new file mode 100755
index 0000000..86be0c9
--- /dev/null
+++ b/tests/shell/testcases/sets/0033add_set_simple_flat_0
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+RULESET="add table ip x
+add set x setA {type ipv4_addr . inet_service . ipv4_addr; flags timeout;}
+add set x setB {type ipv4_addr . inet_service; flags timeout;}
+"
+
+set -e
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/sets/0034get_element_0 b/tests/shell/testcases/sets/0034get_element_0
new file mode 100755
index 0000000..3343529
--- /dev/null
+++ b/tests/shell/testcases/sets/0034get_element_0
@@ -0,0 +1,70 @@
+#!/bin/bash
+
+RC=0
+
+check() { # (set, elems, expected)
+ out=$($NFT get element ip t $1 "{ $2 }")
+ out=$(grep "elements =" <<< "$out")
+ out="${out#* \{ }"
+ out="${out% \}}"
+ [[ "$out" == "$3" ]] && return
+ echo "ERROR: asked for '$2' in set $1, expecting '$3' but got '$out'"
+ ((RC++))
+}
+
+RULESET="add table ip t
+add set ip t s { type inet_service; flags interval; }
+add element ip t s { 10, 20-30, 40, 50-60 }
+add set ip t ips { type ipv4_addr; flags interval; }
+add element ip t ips { 10.0.0.1, 10.0.0.5-10.0.0.8 }
+add element ip t ips { 10.0.0.128/25, 10.0.1.0/24, 10.0.2.3-10.0.2.12 }
+add set ip t cs { type ipv4_addr . inet_service; flags interval; }
+add element ip t cs { 10.0.0.1 . 22, 10.1.0.0/16 . 1-1024 }
+add element ip t cs { 10.2.0.1-10.2.0.8 . 1024-65535 }
+"
+
+$NFT -f - <<< "$RULESET"
+
+# simple cases, (non-)existing values and ranges
+check s 10 10
+check s 11 ""
+check s 20-30 20-30
+check s 15-18 ""
+
+# multiple single elements, ranges smaller than present
+check s "10, 40" "10, 40"
+check s "22-24, 26-28" "20-30, 20-30"
+check s 21-29 20-30
+
+# mixed single elements and ranges
+check s "10, 20" "10, 20-30"
+check s "10, 22" "10, 20-30"
+check s "10, 22-24" "10, 20-30"
+
+# non-existing ranges matching elements
+check s 10-40 ""
+check s 10-20 ""
+check s 10-25 ""
+check s 25-55 ""
+
+# playing with IPs, ranges and prefixes
+check ips 10.0.0.1 10.0.0.1
+check ips 10.0.0.2 ""
+check ips 10.0.1.0/24 10.0.1.0/24
+check ips 10.0.1.2/31 10.0.1.0/24
+check ips 10.0.1.0 10.0.1.0/24
+check ips 10.0.1.3 10.0.1.0/24
+check ips 10.0.1.255 10.0.1.0/24
+check ips 10.0.2.3-10.0.2.12 10.0.2.3-10.0.2.12
+check ips 10.0.2.10 10.0.2.3-10.0.2.12
+check ips 10.0.2.12 10.0.2.3-10.0.2.12
+
+# test concatenated ranges, i.e. Pi, Pa and Po
+check cs "10.0.0.1 . 22" "10.0.0.1 . 22"
+check cs "10.0.0.1 . 23" ""
+check cs "10.0.0.2 . 22" ""
+check cs "10.1.0.1 . 42" "10.1.0.0/16 . 1-1024"
+check cs "10.1.1.0/24 . 10-20" "10.1.0.0/16 . 1-1024"
+check cs "10.2.0.3 . 20000" "10.2.0.1-10.2.0.8 . 1024-65535"
+
+exit $RC
diff --git a/tests/shell/testcases/sets/0035add_set_elements_flat_0 b/tests/shell/testcases/sets/0035add_set_elements_flat_0
new file mode 100755
index 0000000..d914ba9
--- /dev/null
+++ b/tests/shell/testcases/sets/0035add_set_elements_flat_0
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+RULESET="add table ip x
+add set x y {type ipv4_addr; flags interval;}
+add element x y { 10.0.24.0/24 }
+"
+
+set -e
+$NFT -f - <<< "$RULESET"
+$NFT delete element x y { 10.0.24.0/24 }
diff --git a/tests/shell/testcases/sets/0036add_set_element_expiration_0 b/tests/shell/testcases/sets/0036add_set_element_expiration_0
new file mode 100755
index 0000000..0fd016e
--- /dev/null
+++ b/tests/shell/testcases/sets/0036add_set_element_expiration_0
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -e
+
+drop_seconds() {
+ sed -E 's/m[0-9]*s([0-9]*ms)?/m/g'
+}
+
+RULESET="add table ip x
+add set ip x y { type ipv4_addr; flags dynamic,timeout; }
+add element ip x y { 1.1.1.1 timeout 30m expires 15m59s }"
+
+EXPECTED="add table ip x
+add set ip x y { type ipv4_addr; flags dynamic,timeout; }
+add element ip x y { 1.1.1.1 timeout 30m expires 15m }"
+
+test_output=$($NFT -e -f - <<< "$RULESET" 2>&1 | grep -v '# new generation' | drop_seconds)
+
+if [ "$test_output" != "$EXPECTED" ] ; then
+ $DIFF -u <(echo "$test_output") <(echo "$EXPECTED")
+ exit 1
+fi
+
+$NFT "add chain ip x c; add rule ip x c ip saddr @y"
diff --git a/tests/shell/testcases/sets/0037_set_with_inet_service_0 b/tests/shell/testcases/sets/0037_set_with_inet_service_0
new file mode 100755
index 0000000..07820b7
--- /dev/null
+++ b/tests/shell/testcases/sets/0037_set_with_inet_service_0
@@ -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/0038meter_list_0 b/tests/shell/testcases/sets/0038meter_list_0
new file mode 100755
index 0000000..e9e0f6f
--- /dev/null
+++ b/tests/shell/testcases/sets/0038meter_list_0
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+#
+# Listing meters should not include dynamic sets in the output
+#
+
+set -e
+
+RULESET="
+ add table t
+ add set t s { type ipv4_addr; size 256; flags dynamic,timeout; }
+ add chain t c
+ add rule t c tcp dport 80 meter m size 128 { ip saddr limit rate 10/second }
+"
+
+expected_output="table ip t {
+ meter m {
+ type ipv4_addr
+ size 128
+ flags dynamic
+ }
+}"
+
+$NFT -f - <<< "$RULESET"
+
+test_output=$($NFT list meters)
+
+test "$test_output" = "$expected_output"
+
diff --git a/tests/shell/testcases/sets/0039delete_interval_0 b/tests/shell/testcases/sets/0039delete_interval_0
new file mode 100755
index 0000000..19df16e
--- /dev/null
+++ b/tests/shell/testcases/sets/0039delete_interval_0
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# Make sure nft allows to delete existing ranges only
+
+RULESET="
+table t {
+ set s {
+ type ipv4_addr
+ flags interval
+ elements = { 192.168.1.0-192.168.1.254, 192.168.1.255 }
+ }
+}"
+
+$NFT -f - <<< "$RULESET" || { echo "E: Can't load basic ruleset" 1>&2; exit 1; }
+
+$NFT delete element t s '{ 192.168.1.0/24 }' 2>/dev/null || exit 0
+echo "E: Deletion of non-existing range allowed" 1>&2
diff --git a/tests/shell/testcases/sets/0040get_host_endian_elements_0 b/tests/shell/testcases/sets/0040get_host_endian_elements_0
new file mode 100755
index 0000000..caf6a4a
--- /dev/null
+++ b/tests/shell/testcases/sets/0040get_host_endian_elements_0
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+RULESET="table ip t {
+ set s {
+ type mark
+ flags interval
+ elements = {
+ 0x23-0x42, 0x1337
+ }
+ }
+}"
+
+$NFT -f - <<< "$RULESET" || { echo "can't apply basic ruleset"; exit 1; }
+
+$NFT get element ip t s '{ 0x23-0x42 }' || {
+ echo "can't find existing range 0x23-0x42"
+ exit 1
+}
+
+$NFT get element ip t s '{ 0x26-0x28 }' || {
+ echo "can't find existing sub-range 0x26-0x28"
+ exit 1
+}
+
+$NFT get element ip t s '{ 0x26-0x99 }' && {
+ echo "found non-existing range 0x26-0x99"
+ exit 1
+}
+
+$NFT get element ip t s '{ 0x55-0x99 }' && {
+ echo "found non-existing range 0x55-0x99"
+ exit 1
+}
+
+$NFT get element ip t s '{ 0x55 }' && {
+ echo "found non-existing element 0x55"
+ exit 1
+}
+
+$NFT get element ip t s '{ 0x1337 }' || {
+ echo "can't find existing element 0x1337"
+ exit 1
+}
diff --git a/tests/shell/testcases/sets/0041interval_0 b/tests/shell/testcases/sets/0041interval_0
new file mode 100755
index 0000000..42fc6cc
--- /dev/null
+++ b/tests/shell/testcases/sets/0041interval_0
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+set -e
+
+RULESET="
+table ip t {
+ set s {
+ type ipv4_addr
+ flags interval
+ elements = { 192.168.2.195, 192.168.2.196,
+ 192.168.2.197, 192.168.2.198 }
+ }
+}"
+
+$NFT -f - <<< "$RULESET"
+
+$NFT 'delete element t s { 192.168.2.195, 192.168.2.196 }; add element t s { 192.168.2.196 }' 2>/dev/null
+$NFT get element t s { 192.168.2.196, 192.168.2.197, 192.168.2.198 } 1>/dev/null
+$NFT 'delete element t s { 192.168.2.196, 192.168.2.197 }; add element t s { 192.168.2.197 }' 2>/dev/null
+$NFT get element t s { 192.168.2.197, 192.168.2.198 } 1>/dev/null
+$NFT 'delete element t s { 192.168.2.198, 192.168.2.197 }; add element t s { 192.168.2.196, 192.168.2.197, 192.168.2.195 }' 1>/dev/null
+$NFT get element t s { 192.168.2.196, 192.168.2.197, 192.168.2.195 } 1>/dev/null
+$NFT delete element t s { 192.168.2.196, 192.168.2.197, 192.168.2.195 } 2>/dev/null
+$NFT create element t s { 192.168.2.196} 2>/dev/null
+$NFT get element t s { 192.168.2.196 } 1>/dev/null
diff --git a/tests/shell/testcases/sets/0042update_set_0 b/tests/shell/testcases/sets/0042update_set_0
new file mode 100755
index 0000000..a8e9e05
--- /dev/null
+++ b/tests/shell/testcases/sets/0042update_set_0
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip t {
+ set set1 {
+ type ether_addr
+ }
+
+ set set2 {
+ type ether_addr
+ size 65535
+ flags dynamic
+ }
+
+ chain c {
+ ether daddr @set1 add @set2 { ether daddr counter }
+ }
+}"
+
+$NFT -f - <<< "$RULESET" || { echo "can't apply basic ruleset"; exit 1; }
diff --git a/tests/shell/testcases/sets/0043concatenated_ranges_0 b/tests/shell/testcases/sets/0043concatenated_ranges_0
new file mode 100755
index 0000000..83d7435
--- /dev/null
+++ b/tests/shell/testcases/sets/0043concatenated_ranges_0
@@ -0,0 +1,194 @@
+#!/bin/bash -e
+#
+# NFT_TEST_SKIP(NFT_TEST_SKIP_slow)
+#
+# 0043concatenated_ranges_0 - Add, get, list, timeout for concatenated ranges
+#
+# Cycle over supported data types, forming concatenations of three fields, for
+# all possible permutations, and:
+# - add entries to set
+# - list them
+# - get entries by specifying a value matching ranges for all fields
+# - delete them
+# - check that they can't be deleted again
+# - add them with 1s timeout
+# - check that they are not listed after 1s, just once, for the first entry
+# - delete them
+# - make sure they can't be deleted again
+
+TYPES="ipv4_addr ipv6_addr ether_addr inet_proto inet_service mark"
+
+RULESPEC_ipv4_addr="ip saddr"
+ELEMS_ipv4_addr="192.0.2.1 198.51.100.0/25 203.0.113.0-203.0.113.129"
+ADD_ipv4_addr="192.0.2.252/31"
+GET_ipv4_addr="198.51.100.127 198.51.100.0/25"
+
+RULESPEC_ipv6_addr="ip6 daddr"
+ELEMS_ipv6_addr="2001:db8:c0c:c0de::1-2001:db8:cacc::a 2001:db8::1 2001:db8:dada:da::/64"
+ADD_ipv6_addr="2001:db8::d1ca:d1ca"
+GET_ipv6_addr="2001:db8::1 2001:db8::1"
+
+RULESPEC_ether_addr="ether saddr"
+ELEMS_ether_addr="00:0a:c1:d1:f1:ed-00:0a:c1:dd:ec:af 00:0b:0c:ca:cc:10-c1:a0:c1:cc:10:00 f0:ca:cc:1a:b0:1a"
+ADD_ether_addr="00:be:1d:ed:ab:e1"
+GET_ether_addr="ac:c1:ac:c0:ce:c0 00:0b:0c:ca:cc:10-c1:a0:c1:cc:10:00"
+
+RULESPEC_inet_proto="meta l4proto"
+ELEMS_inet_proto="tcp udp icmp"
+ADD_inet_proto="sctp"
+GET_inet_proto="udp udp"
+
+RULESPEC_inet_service="tcp dport"
+ELEMS_inet_service="22-23 1024-32768 31337"
+ADD_inet_service="32769-65535"
+GET_inet_service="32768 1024-32768"
+
+RULESPEC_mark="mark"
+ELEMS_mark="0x00000064-0x000000c8 0x0000006f 0x0000fffd-0x0000ffff"
+ADD_mark="0x0000002a"
+GET_mark="0x0000006f 0x0000006f"
+
+tmp="$(mktemp)"
+trap "rm -f ${tmp}" EXIT
+
+render() {
+ eval "echo \"$(cat ${1})\""
+}
+
+cat <<'EOF' > "${tmp}"
+flush ruleset
+
+table inet filter {
+ ${setmap} test {
+ type ${ta} . ${tb} . ${tc} ${mapt}
+ flags interval,timeout
+ elements = { ${a1} . ${b1} . ${c1} ${mapv},
+ ${a2} . ${b2} . ${c2} ${mapv},
+ ${a3} . ${b3} . ${c3} ${mapv}, }
+ }
+
+ chain output {
+ type filter hook output priority 0; policy accept;
+ ${rule} @test counter
+ }
+}
+EOF
+
+timeout_tested=0
+run_test()
+{
+setmap="$1"
+for ta in ${TYPES}; do
+ eval a=\$ELEMS_${ta}
+ a1=${a%% *}; a2=$(expr "$a" : ".* \(.*\) .*"); a3=${a##* }
+ eval sa=\$RULESPEC_${ta}
+
+ mark=0
+ for tb in ${TYPES}; do
+ [ "${tb}" = "${ta}" ] && continue
+ if [ "${tb}" = "ipv6_addr" ]; then
+ [ "${ta}" = "ipv4_addr" ] && continue
+ elif [ "${tb}" = "ipv4_addr" ]; then
+ [ "${ta}" = "ipv6_addr" ] && continue
+ fi
+
+ eval b=\$ELEMS_${tb}
+ b1=${b%% *}; b2=$(expr "$b" : ".* \(.*\) .*"); b3=${b##* }
+ eval sb=\$RULESPEC_${tb}
+
+ for tc in ${TYPES}; do
+ [ "${tc}" = "${ta}" ] && continue
+ [ "${tc}" = "${tb}" ] && continue
+ if [ "${tc}" = "ipv6_addr" ]; then
+ [ "${ta}" = "ipv4_addr" ] && continue
+ [ "${tb}" = "ipv4_addr" ] && continue
+ elif [ "${tc}" = "ipv4_addr" ]; then
+ [ "${ta}" = "ipv6_addr" ] && continue
+ [ "${tb}" = "ipv6_addr" ] && continue
+ fi
+
+ echo "$setmap TYPE: ${ta} ${tb} ${tc}"
+
+ eval c=\$ELEMS_${tc}
+ c1=${c%% *}; c2=$(expr "$c" : ".* \(.*\) .*"); c3=${c##* }
+ eval sc=\$RULESPEC_${tc}
+
+ case "${setmap}" in
+ "set")
+ mapt=""
+ mapv=""
+ rule="${sa} . ${sb} . ${sc}"
+ ;;
+ "map")
+ mapt=": mark"
+ mark=42
+ mapv=$(printf " : 0x%08x" ${mark})
+ rule="meta mark set ${sa} . ${sb} . ${sc} map"
+ ;;
+ esac
+
+ render ${tmp} | ${NFT} -f -
+
+ [ $(${NFT} list ${setmap} inet filter test | \
+ grep -c -e "${a1} . ${b1} . ${c1}${mapv}" \
+ -e "${a2} . ${b2} . ${c2}${mapv}" \
+ -e "${a3} . ${b3} . ${c3}${mapv}") -eq 3 ]
+
+ ${NFT} delete element inet filter test \
+ "{ ${a1} . ${b1} . ${c1}${mapv} }"
+ ${NFT} delete element inet filter test \
+ "{ ${a1} . ${b1} . ${c1}${mapv} }" \
+ 2>/dev/null && exit 1
+
+ eval add_a=\$ADD_${ta}
+ eval add_b=\$ADD_${tb}
+ eval add_c=\$ADD_${tc}
+ ${NFT} add element inet filter test \
+ "{ ${add_a} . ${add_b} . ${add_c} timeout 2m${mapv}}"
+ [ $(${NFT} list ${setmap} inet filter test | \
+ grep -c "${add_a} . ${add_b} . ${add_c}") -eq 1 ]
+
+ eval get_a=\$GET_${ta}
+ eval get_b=\$GET_${tb}
+ eval get_c=\$GET_${tc}
+ exp_a=${get_a##* }; get_a=${get_a%% *}
+ exp_b=${get_b##* }; get_b=${get_b%% *}
+ exp_c=${get_c##* }; get_c=${get_c%% *}
+ [ $(${NFT} get element inet filter test \
+ "{ ${get_a} . ${get_b} . ${get_c}${mapv} }" | \
+ grep -c "${exp_a} . ${exp_b} . ${exp_c}") -eq 1 ]
+
+ ${NFT} "delete element inet filter test \
+ { ${a2} . ${b2} . ${c2}${mapv} };
+ delete element inet filter test \
+ { ${a3} . ${b3} . ${c3}${mapv} }"
+ ${NFT} "delete element inet filter test \
+ { ${a2} . ${b2} . ${c2}${mapv} };
+ delete element inet filter test \
+ { ${a3} . ${b3} . ${c3} ${mapv} }" \
+ 2>/dev/null && exit 1
+
+ if [ ${timeout_tested} -eq 1 ]; then
+ ${NFT} delete element inet filter test \
+ "{ ${add_a} . ${add_b} . ${add_c} ${mapv} }"
+ ${NFT} delete element inet filter test \
+ "{ ${add_a} . ${add_b} . ${add_c} ${mapv} }" \
+ 2>/dev/null && exit 1
+ continue
+ fi
+
+ ${NFT} delete element inet filter test \
+ "{ ${add_a} . ${add_b} . ${add_c} ${mapv}}"
+ ${NFT} add element inet filter test \
+ "{ ${add_a} . ${add_b} . ${add_c} timeout 1s${mapv}}"
+ sleep 1
+ [ $(${NFT} list ${setmap} inet filter test | \
+ grep -c "${add_a} . ${add_b} . ${add_c} ${mapv}") -eq 0 ]
+ timeout_tested=1
+ done
+ done
+done
+}
+
+run_test "set"
+run_test "map"
diff --git a/tests/shell/testcases/sets/0043concatenated_ranges_1 b/tests/shell/testcases/sets/0043concatenated_ranges_1
new file mode 100755
index 0000000..1be2889
--- /dev/null
+++ b/tests/shell/testcases/sets/0043concatenated_ranges_1
@@ -0,0 +1,23 @@
+#!/bin/bash -e
+#
+# 0043concatenated_ranges_1 - Insert and list subnets of different sizes
+
+check() {
+ $NFT add element "${1}" t s "{ ${2} . ${3} }"
+ [ "$( $NFT list set "${1}" t s | grep -c "${2} . ${3}" )" = 1 ]
+}
+
+$NFT add table ip6 t
+$NFT add table ip t
+
+$NFT add set ip6 t s '{ type ipv6_addr . ipv6_addr ; flags interval ; }'
+$NFT add set ip t s '{ type ipv4_addr . ipv4_addr ; flags interval ; }'
+
+for n in $(seq 32 127); do
+ h="$(printf %x "${n}")"
+ check ip6 "2001:db8::/${n}" "2001:db8:${h}::-2001:db8:${h}::${h}:1"
+done
+
+for n in $(seq 24 31); do
+ check ip "192.0.2.0/${n}" "192.0.2.$((n * 3))-192.0.2.$((n * 3 + 2))"
+done
diff --git a/tests/shell/testcases/sets/0044interval_overlap_0 b/tests/shell/testcases/sets/0044interval_overlap_0
new file mode 100755
index 0000000..71bf334
--- /dev/null
+++ b/tests/shell/testcases/sets/0044interval_overlap_0
@@ -0,0 +1,166 @@
+#!/bin/bash -e
+#
+# NFT_TEST_SKIP(NFT_TEST_SKIP_slow)
+#
+# 0044interval_overlap_0 - Add overlapping and non-overlapping intervals
+#
+# Check that adding overlapping intervals to a set returns an error, unless:
+# - the inserted element overlaps entirely, that is, it's identical to an
+# existing one
+# - for concatenated ranges, the new element is less specific than any existing
+# overlapping element, as elements are evaluated in order of insertion
+#
+# Then, repeat the test with a set configured with a timeout, checking that:
+# - we can insert all the elements as described above
+# - once the timeout has expired, we can insert all the elements again, and old
+# elements are not present
+# - before the timeout expires again, we can re-add elements that are not
+# expected to fail, but old elements might be present
+#
+# If $NFT points to a libtool wrapper, and we're running on a slow machine or
+# kernel (e.g. KASan enabled), it might not be possible to execute hundreds of
+# commands within an otherwise reasonable 1 second timeout. Estimate a usable
+# timeout first, by counting commands and measuring against one nft rule timeout
+# itself, so that we can keep this fast for a binary $NFT on a reasonably fast
+# kernel.
+
+# Accept Interval List
+intervals_simple="
+ y 0 - 2 0-2
+ y 0 - 2 0-2
+ n 0 - 1 0-2
+ n 0 - 3 0-2
+ y 3 - 10 0-2, 3-10
+ n 3 - 9 0-2, 3-10
+ n 4 - 10 0-2, 3-10
+ n 4 - 9 0-2, 3-10
+ y 20 - 30 0-2, 3-10, 20-30
+ y 11 - 12 0-2, 3-10, 11-12, 20-30
+ y 13 - 19 0-2, 3-10, 11-12, 13-19, 20-30
+ n 25 - 40 0-2, 3-10, 11-12, 13-19, 20-30
+ y 50 - 60 0-2, 3-10, 11-12, 13-19, 20-30, 50-60
+ y 31 - 49 0-2, 3-10, 11-12, 13-19, 20-30, 31-49, 50-60
+ n 59 - 60 0-2, 3-10, 11-12, 13-19, 20-30, 31-49, 50-60
+"
+
+intervals_concat="
+ y 0-2 . 0-3 0-2 . 0-3
+ y 0-2 . 0-3 0-2 . 0-3
+ n 0-1 . 0-2 0-2 . 0-3
+ y 10-20 . 30-40 0-2 . 0-3, 10-20 . 30-40
+ y 15-20 . 50-60 0-2 . 0-3, 10-20 . 30-40, 15-20 . 50-60
+ y 3-9 . 4-29 0-2 . 0-3, 10-20 . 30-40, 15-20 . 50-60, 3-9 . 4-29
+ y 3-9 . 4-29 0-2 . 0-3, 10-20 . 30-40, 15-20 . 50-60, 3-9 . 4-29
+ n 11-19 . 30-40 0-2 . 0-3, 10-20 . 30-40, 15-20 . 50-60, 3-9 . 4-29
+ y 15-20 . 49-61 0-2 . 0-3, 10-20 . 30-40, 15-20 . 50-60, 3-9 . 4-29, 15-20 . 49-61
+"
+
+count_elements() {
+ pass=
+ interval=
+ elements=0
+ for t in ${intervals_simple} ${intervals_concat}; do
+ [ -z "${pass}" ] && pass="${t}" && continue
+ [ -z "${interval}" ] && interval="${t}" && continue
+ unset IFS
+
+ elements=$((elements + 1))
+
+ IFS='
+'
+ done
+ unset IFS
+}
+
+match_elements() {
+ skip=0
+ n=0
+ out=
+ for a in $($NFT list set t ${1})}; do
+ [ ${n} -eq 0 ] && { [ "${a}" = "elements" ] && n=1; continue; }
+ [ ${n} -eq 1 ] && { [ "${a}" = "=" ] && n=2; continue; }
+ [ ${n} -eq 2 ] && { [ "${a}" = "{" ] && n=3; continue; }
+
+ [ "${a}" = "}" ] && break
+
+ [ ${skip} -eq 1 ] && skip=0 && out="${out}," && continue
+ [ "${a}" = "expires" ] && skip=1 && continue
+
+ [ -n "${out}" ] && out="${out} ${a}" || out="${a}"
+
+ done
+
+ if [ "${out%,}" != "${2}" ]; then
+ echo "Expected: ${2}, got: ${out%,}"
+ return 1
+ fi
+}
+
+estimate_timeout() {
+ count_elements
+
+ $NFT add table t
+ $NFT add set t s '{ type inet_service ; flags timeout; timeout 1s; gc-interval 1s; }'
+ execs_1s=1
+ $NFT add element t s "{ 0 }"
+ while match_elements s "0" >/dev/null; do
+ execs_1s=$((execs_1s + 1))
+ done
+
+ timeout="$((elements / execs_1s * 3 / 2 + 1))"
+}
+
+add_elements() {
+ set="s"
+ pass=
+ interval=
+ IFS='
+'
+ for t in ${intervals_simple} switch ${intervals_concat}; do
+ [ "${t}" = "switch" ] && set="c" && continue
+ [ -z "${pass}" ] && pass="${t}" && continue
+ [ -z "${interval}" ] && interval="${t}" && continue
+ unset IFS
+
+ if [ "${pass}" = "y" ]; then
+ if ! $NFT add element t ${set} "{ ${interval} }"; then
+ echo "Failed to insert ${interval} given:"
+ $NFT list ruleset
+ exit 1
+ fi
+ else
+ if $NFT add element t ${set} "{ ${interval} }" 2>/dev/null; then
+ echo "Could insert ${interval} given:"
+ $NFT list ruleset
+ exit 1
+ fi
+ fi
+
+ [ "${1}" != "nomatch" ] && match_elements "${set}" "${t}"
+
+ pass=
+ interval=
+ IFS='
+'
+ done
+ unset IFS
+}
+
+$NFT add table t
+$NFT add set t s '{ type inet_service ; flags interval ; }'
+$NFT add set t c '{ type inet_service . inet_service ; flags interval ; }'
+add_elements
+
+$NFT flush ruleset
+estimate_timeout
+
+$NFT flush ruleset
+$NFT add table t
+$NFT add set t s "{ type inet_service ; flags interval,timeout; timeout ${timeout}s; gc-interval ${timeout}s; }"
+$NFT add set t c "{ type inet_service . inet_service ; flags interval,timeout ; timeout ${timeout}s; gc-interval ${timeout}s; }"
+add_elements
+
+sleep $((timeout * 3 / 2))
+add_elements
+
+add_elements nomatch
diff --git a/tests/shell/testcases/sets/0044interval_overlap_1 b/tests/shell/testcases/sets/0044interval_overlap_1
new file mode 100755
index 0000000..cdd0c84
--- /dev/null
+++ b/tests/shell/testcases/sets/0044interval_overlap_1
@@ -0,0 +1,38 @@
+#!/bin/bash -e
+#
+# NFT_TEST_SKIP(NFT_TEST_SKIP_slow)
+#
+# 0044interval_overlap_1 - Single-sized intervals can never overlap partially
+#
+# Check that inserting, deleting, and inserting single-sized intervals again
+# never leads to a partial overlap. Specifically trigger rbtree rebalancing in
+# the process, to ensure different tree shapes of equivalent sets don't lead to
+# false positives, by deleting every second inserted item.
+
+xorshift() {
+ # Adaptation of Xorshift algorithm from:
+ # Marsaglia, G. (2003). Xorshift RNGs.
+ # Journal of Statistical Software, 8(14), 1 - 6.
+ # doi:http://dx.doi.org/10.18637/jss.v008.i14
+ # with triplet (5, 3, 1), suitable for 16-bit ranges.
+
+ : $((port ^= port << 5))
+ : $((port ^= port >> 3))
+ : $((port ^= port << 1))
+}
+
+$NFT add table t
+$NFT add set t s '{ type inet_service ; flags interval ; }'
+
+for op in add delete add; do
+ port=1
+ skip=0
+ for i in $(seq 1 500); do
+ xorshift
+ if [ "${op}" = "delete" ]; then
+ [ ${skip} -eq 0 ] && skip=1 && continue
+ skip=0
+ fi
+ $NFT ${op} element t s "{ { $((port % 32768 + 32768)) } }"
+ done
+done
diff --git a/tests/shell/testcases/sets/0045concat_ipv4_service b/tests/shell/testcases/sets/0045concat_ipv4_service
new file mode 100755
index 0000000..5b40f97
--- /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
new file mode 100755
index 0000000..60bda40
--- /dev/null
+++ b/tests/shell/testcases/sets/0046netmap_0
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+EXPECTED="table ip x {
+ chain y {
+ type nat hook postrouting priority srcnat; policy accept;
+ 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 }
+ }
+ }
+"
+
+set -e
+$NFT -f - <<< $EXPECTED
diff --git a/tests/shell/testcases/sets/0047nat_0 b/tests/shell/testcases/sets/0047nat_0
new file mode 100755
index 0000000..4e53b7b
--- /dev/null
+++ b/tests/shell/testcases/sets/0047nat_0
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+EXPECTED="table ip x {
+ map y {
+ type ipv4_addr : interval ipv4_addr
+ flags interval
+ elements = { 10.141.10.0/24 : 192.168.2.2-192.168.2.4,
+ 10.141.11.0/24 : 192.168.4.2-192.168.4.3 }
+ }
+
+ chain x {
+ type nat hook prerouting priority dstnat; policy accept;
+ meta l4proto tcp dnat ip to iifname . ip saddr map { enp2s0 . 10.1.1.136 : 1.1.2.69 . 22, enp2s0 . 10.1.1.1-10.1.1.135 : 1.1.2.66-1.84.236.78 . 22 }
+ dnat ip to iifname . ip saddr map { enp2s0 . 10.1.1.136 : 1.1.2.69, enp2s0 . 10.1.1.1-10.1.1.135 : 1.1.2.66-1.84.236.78 }
+ }
+
+ chain y {
+ type nat hook postrouting priority srcnat; policy accept;
+ snat to ip saddr map @y
+ }
+ }
+"
+
+set -e
+$NFT -f - <<< $EXPECTED
+$NFT add element x y { 10.141.12.0/24 : 192.168.5.10-192.168.5.20 }
+
+EXPECTED="table inet x {
+ chain x {
+ type nat hook prerouting priority dstnat; policy accept;
+ dnat to ip daddr . tcp dport map { 10.141.10.1 . 22 : 192.168.2.2, 10.141.11.2 . 2222 : 192.168.4.2 }
+ }
+
+ chain y {
+ type nat hook postrouting priority srcnat; policy accept;
+ snat to ip saddr map { 10.141.10.0/24 : 192.168.2.2-192.168.2.4, 10.141.11.0/24 : 192.168.4.2-192.168.4.3 }
+ }
+}"
+
+$NFT -f - <<< $EXPECTED
diff --git a/tests/shell/testcases/sets/0048set_counters_0 b/tests/shell/testcases/sets/0048set_counters_0
new file mode 100755
index 0000000..e62d25d
--- /dev/null
+++ b/tests/shell/testcases/sets/0048set_counters_0
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+set -e
+
+EXPECTED="table ip x {
+ set y {
+ typeof ip saddr
+ counter
+ elements = { 192.168.10.35, 192.168.10.101, 192.168.10.135 }
+ }
+
+ chain z {
+ type filter hook output priority filter; policy accept;
+ ip daddr @y
+ }
+}"
+
+$NFT -f - <<< "$EXPECTED"
diff --git a/tests/shell/testcases/sets/0049set_define_0 b/tests/shell/testcases/sets/0049set_define_0
new file mode 100755
index 0000000..1d512f7
--- /dev/null
+++ b/tests/shell/testcases/sets/0049set_define_0
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+set -e
+
+EXPECTED="define BASE_ALLOWED_INCOMING_TCP_PORTS = {22, 80, 443}
+define EXTRA_ALLOWED_INCOMING_TCP_PORTS = {}
+
+table inet filter {
+ chain input {
+ type filter hook input priority 0; policy drop;
+ tcp dport {\$BASE_ALLOWED_INCOMING_TCP_PORTS, \$EXTRA_ALLOWED_INCOMING_TCP_PORTS} ct state new counter accept
+ }
+}
+"
+
+$NFT -f - <<< "$EXPECTED"
diff --git a/tests/shell/testcases/sets/0050set_define_1 b/tests/shell/testcases/sets/0050set_define_1
new file mode 100755
index 0000000..c12de17
--- /dev/null
+++ b/tests/shell/testcases/sets/0050set_define_1
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -e
+
+EXPECTED="define BASE_ALLOWED_INCOMING_TCP_PORTS = {}
+
+table inet filter {
+ chain input {
+ type filter hook input priority 0; policy drop;
+ tcp dport {\$BASE_ALLOWED_INCOMING_TCP_PORTS} ct state new counter accept
+ }
+}
+"
+
+$NFT -f - <<< "$EXPECTED" &> /dev/null || exit 0
+echo "E: Accepted empty set" 1>&2
+exit 1
diff --git a/tests/shell/testcases/sets/0051set_interval_counter_0 b/tests/shell/testcases/sets/0051set_interval_counter_0
new file mode 100755
index 0000000..ea90e26
--- /dev/null
+++ b/tests/shell/testcases/sets/0051set_interval_counter_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+set -e
+
+EXPECTED="table ip x {
+ set s {
+ type ipv4_addr
+ flags interval
+ counter
+ elements = { 192.168.2.0/24 }
+ }
+
+ chain y {
+ type filter hook output priority filter; policy accept;
+ ip daddr @s
+ }
+}"
+
+$NFT -f - <<< "$EXPECTED"
diff --git a/tests/shell/testcases/sets/0052overlap_0 b/tests/shell/testcases/sets/0052overlap_0
new file mode 100755
index 0000000..c296094
--- /dev/null
+++ b/tests/shell/testcases/sets/0052overlap_0
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+set -e
+
+EXPECTED="add table ip filter
+add set ip filter w_all {type ipv4_addr; flags interval; auto-merge}
+add element ip filter w_all {10.10.10.10, 10.10.10.11}
+"
+
+$NFT -f - <<< "$EXPECTED"
+
+EXPECTED="flush set ip filter w_all
+add element ip filter w_all {10.10.10.10, 10.10.10.253}
+"
+
+$NFT -f - <<< "$EXPECTED"
diff --git a/tests/shell/testcases/sets/0053echo_0 b/tests/shell/testcases/sets/0053echo_0
new file mode 100755
index 0000000..6bb03c2
--- /dev/null
+++ b/tests/shell/testcases/sets/0053echo_0
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+set -e
+
+EXPECTED="add table inet filter
+delete table inet filter
+
+table inet filter {
+ chain input {
+ type filter hook input priority filter; policy drop;
+ iifname { lo } ip saddr { 10.0.0.0/8 } ip daddr { 192.168.100.62 } tcp dport { 2001 } counter accept
+ }
+}
+"
+
+$NFT -ef - <<< "$EXPECTED"
diff --git a/tests/shell/testcases/sets/0054comments_set_0 b/tests/shell/testcases/sets/0054comments_set_0
new file mode 100755
index 0000000..9c8f787
--- /dev/null
+++ b/tests/shell/testcases/sets/0054comments_set_0
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+
+# Test that comments are added to sets
+
+$NFT add table t
+$NFT add set t s {type ipv4_addr \; flags interval \; comment "test" \;}
+$NFT add map t m {type ipv4_addr : ipv4_addr \; flags interval \; comment \"another test\" \;}
diff --git a/tests/shell/testcases/sets/0055tcpflags_0 b/tests/shell/testcases/sets/0055tcpflags_0
new file mode 100755
index 0000000..a2b24eb
--- /dev/null
+++ b/tests/shell/testcases/sets/0055tcpflags_0
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+EXPECTED="add table ip test
+
+add set ip test tcp_good_flags { type tcp_flag ; flags constant ; elements = {
+ ( 0 | 0 | 0 |ack| 0 | 0 ), \
+ ( 0 | 0 | 0 |ack| 0 |urg), \
+ ( 0 | 0 | 0 |ack|psh| 0 ), \
+ ( 0 | 0 | 0 |ack|psh|urg), \
+ ( 0 | 0 |rst| 0 | 0 | 0 ), \
+ ( 0 | 0 |rst|ack| 0 | 0 ), \
+ ( 0 | 0 |rst|ack| 0 |urg), \
+ ( 0 | 0 |rst|ack|psh| 0 ), \
+ ( 0 | 0 |rst|ack|psh|urg), \
+ ( 0 |syn| 0 | 0 | 0 | 0 ), \
+ ( 0 |syn| 0 |ack| 0 | 0 ), \
+ ( 0 |syn| 0 |ack| 0 |urg), \
+ ( 0 |syn| 0 |ack|psh| 0 ), \
+ ( 0 |syn| 0 |ack|psh|urg), \
+ (fin| 0 | 0 |ack| 0 | 0 ), \
+ (fin| 0 | 0 |ack| 0 |urg), \
+ (fin| 0 | 0 |ack|psh| 0 ), \
+ (fin| 0 | 0 |ack|psh|urg) \
+} ; }"
+
+set -e
+$NFT -f - <<< $EXPECTED
diff --git a/tests/shell/testcases/sets/0056dynamic_limit_0 b/tests/shell/testcases/sets/0056dynamic_limit_0
new file mode 100755
index 0000000..21fa0bf
--- /dev/null
+++ b/tests/shell/testcases/sets/0056dynamic_limit_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+RULESET="table inet filter {
+ set ssh_meter {
+ type ipv4_addr
+ size 65535
+ flags dynamic,timeout
+ timeout 1m
+ elements = { 127.0.0.1 expires 52s44ms limit rate over 1/minute }
+ }
+
+ chain output {
+ type filter hook output priority filter; policy accept;
+ ip protocol icmp add @ssh_meter { ip saddr timeout 1m limit rate over 1/minute }
+ }
+}"
+
+set -e
+$NFT -f - <<< $EXPECTED
diff --git a/tests/shell/testcases/sets/0057set_create_fails_0 b/tests/shell/testcases/sets/0057set_create_fails_0
new file mode 100755
index 0000000..5f0149a
--- /dev/null
+++ b/tests/shell/testcases/sets/0057set_create_fails_0
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+RULESET="table inet filter {
+ set test {
+ type ipv4_addr
+ size 65535
+ elements = { 1.1.1.1 }
+ }
+}"
+
+$NFT -f - <<< $RULESET
+
+CMD="create element inet filter test { 1.1.1.1, 1.1.1.2, 1.1.1.3, 1.1.1.4, 1.1.1.5, 1.1.1.6, 1.1.1.7, 1.1.1.8, 1.1.1.9, 1.1.1.10, 1.1.1.11, 1.1.1.12, 1.1.1.13, 1.1.1.14, 1.1.1.15, 1.1.1.16, 1.1.1.17, 1.1.1.18, 1.1.1.19, 1.1.1.20, 1.1.1.21, 1.1.1.22, 1.1.1.23, 1.1.1.24, 1.1.1.25, 1.1.1.26, 1.1.1.27, 1.1.1.28, 1.1.1.29, 1.1.1.30, 1.1.1.31, 1.1.1.32, 1.1.1.33, 1.1.1.34, 1.1.1.35, 1.1.1.36, 1.1.1.37, 1.1.1.38, 1.1.1.39, 1.1.1.40, 1.1.1.41, 1.1.1.42, 1.1.1.43, 1.1.1.44, 1.1.1.45, 1.1.1.46, 1.1.1.47, 1.1.1.48, 1.1.1.49, 1.1.1.50, 1.1.1.51, 1.1.1.52, 1.1.1.53, 1.1.1.54, 1.1.1.55, 1.1.1.56, 1.1.1.57, 1.1.1.58, 1.1.1.59, 1.1.1.60, 1.1.1.61, 1.1.1.62, 1.1.1.63, 1.1.1.64, 1.1.1.65, 1.1.1.66, 1.1.1.67, 1.1.1.68, 1.1.1.69, 1.1.1.70, 1.1.1.71, 1.1.1.72, 1.1.1.73, 1.1.1.74, 1.1.1.75, 1.1.1.76, 1.1.1.77, 1.1.1.78, 1.1.1.79, 1.1.1.80, 1.1.1.81, 1.1.1.82, 1.1.1.83, 1.1.1.84, 1.1.1.85, 1.1.1.86, 1.1.1.87, 1.1.1.88, 1.1.1.89, 1.1.1.90, 1.1.1.91, 1.1.1.92, 1.1.1.93, 1.1.1.94, 1.1.1.95, 1.1.1.96, 1.1.1.97, 1.1.1.98, 1.1.1.99, 1.1.1.100, 1.1.1.101, 1.1.1.102, 1.1.1.103, 1.1.1.104, 1.1.1.105, 1.1.1.106, 1.1.1.107, 1.1.1.108, 1.1.1.109, 1.1.1.110, 1.1.1.111, 1.1.1.112, 1.1.1.113, 1.1.1.114, 1.1.1.115, 1.1.1.116, 1.1.1.117, 1.1.1.118, 1.1.1.119, 1.1.1.120, 1.1.1.121, 1.1.1.122, 1.1.1.123, 1.1.1.124, 1.1.1.125, 1.1.1.126, 1.1.1.127, 1.1.1.128, 1.1.1.129, 1.1.1.130, 1.1.1.131, 1.1.1.132, 1.1.1.133, 1.1.1.134, 1.1.1.135, 1.1.1.136, 1.1.1.137, 1.1.1.138, 1.1.1.139, 1.1.1.140, 1.1.1.141, 1.1.1.142, 1.1.1.143, 1.1.1.144, 1.1.1.145, 1.1.1.146, 1.1.1.147, 1.1.1.148, 1.1.1.149, 1.1.1.150, 1.1.1.151, 1.1.1.152, 1.1.1.153, 1.1.1.154, 1.1.1.155, 1.1.1.156, 1.1.1.157, 1.1.1.158, 1.1.1.159, 1.1.1.160, 1.1.1.161, 1.1.1.162, 1.1.1.163, 1.1.1.164, 1.1.1.165, 1.1.1.166, 1.1.1.167, 1.1.1.168, 1.1.1.169, 1.1.1.170, 1.1.1.171, 1.1.1.172, 1.1.1.173, 1.1.1.174, 1.1.1.175, 1.1.1.176, 1.1.1.177, 1.1.1.178, 1.1.1.179, 1.1.1.180, 1.1.1.181, 1.1.1.182, 1.1.1.183, 1.1.1.184, 1.1.1.185, 1.1.1.186, 1.1.1.187, 1.1.1.188, 1.1.1.189, 1.1.1.190, 1.1.1.191, 1.1.1.192, 1.1.1.193, 1.1.1.194, 1.1.1.195, 1.1.1.196, 1.1.1.197, 1.1.1.198, 1.1.1.199, 1.1.1.200, 1.1.1.201, 1.1.1.202, 1.1.1.203, 1.1.1.204, 1.1.1.205, 1.1.1.206, 1.1.1.207, 1.1.1.208, 1.1.1.209, 1.1.1.210, 1.1.1.211, 1.1.1.212, 1.1.1.213, 1.1.1.214, 1.1.1.215, 1.1.1.216, 1.1.1.217, 1.1.1.218, 1.1.1.219, 1.1.1.220, 1.1.1.221, 1.1.1.222, 1.1.1.223, 1.1.1.224, 1.1.1.225, 1.1.1.226, 1.1.1.227, 1.1.1.228, 1.1.1.229, 1.1.1.230, 1.1.1.231, 1.1.1.232, 1.1.1.233, 1.1.1.234, 1.1.1.235, 1.1.1.236, 1.1.1.237, 1.1.1.238, 1.1.1.239, 1.1.1.240, 1.1.1.241, 1.1.1.242, 1.1.1.243, 1.1.1.244, 1.1.1.245, 1.1.1.246, 1.1.1.247, 1.1.1.248, 1.1.1.249, 1.1.1.250, 1.1.1.251, 1.1.1.252, 1.1.1.253 }"
+
+# If this returns ENOSPC, then nft is sending a netlink message that is larger
+# than NFT_MNL_ACK_MAXSIZE. Make sure this returns EEXIST.
+$NFT -f - <<< $CMD 2>&1 >/dev/null | grep "File exists"
+[ "$?" -eq 0 ] && exit 0
diff --git a/tests/shell/testcases/sets/0058_setupdate_timeout_0 b/tests/shell/testcases/sets/0058_setupdate_timeout_0
new file mode 100755
index 0000000..52a658e
--- /dev/null
+++ b/tests/shell/testcases/sets/0058_setupdate_timeout_0
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+RULESET="table inet filter {
+ set ssh_meter {
+ type ipv4_addr
+ size 65535
+ flags dynamic,timeout
+ timeout 30d
+ }
+
+ chain test {
+ add @ssh_meter { ip saddr timeout 30d }
+ }
+}"
+
+set -e
+$NFT -f - <<< $RULESET
diff --git a/tests/shell/testcases/sets/0059set_update_multistmt_0 b/tests/shell/testcases/sets/0059set_update_multistmt_0
new file mode 100755
index 0000000..2aeba2c
--- /dev/null
+++ b/tests/shell/testcases/sets/0059set_update_multistmt_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_set_with_two_expressions)
+
+RULESET="table x {
+ set y {
+ type ipv4_addr
+ size 65535
+ flags dynamic,timeout
+ timeout 1h
+ }
+ chain z {
+ type filter hook output priority 0;
+ update @y { ip daddr limit rate 1/second counter }
+ }
+}"
+
+set -e
+$NFT -f - <<< $RULESET
diff --git a/tests/shell/testcases/sets/0060set_multistmt_0 b/tests/shell/testcases/sets/0060set_multistmt_0
new file mode 100755
index 0000000..8e17444
--- /dev/null
+++ b/tests/shell/testcases/sets/0060set_multistmt_0
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_set_with_two_expressions)
+
+RULESET="table x {
+ set y {
+ type ipv4_addr
+ limit rate 1/second counter
+ elements = { 5.5.5.5 limit rate 1/second counter packets 0 bytes 0 }
+ }
+ chain y {
+ type filter hook output priority filter; policy accept;
+ ip daddr @y
+ }
+}"
+
+$NFT -f - <<< $RULESET
+# should work
+if [ $? -ne 0 ]
+then
+ exit 1
+fi
+
+# should work
+$NFT add element x y { 1.1.1.1 limit rate 1/second counter }
+if [ $? -ne 0 ]
+then
+ exit 1
+fi
+
+# should fail
+$NFT add element x y { 2.2.2.2 limit rate 1/second }
+if [ $? -eq 0 ]
+then
+ exit 1
+fi
+
+# should fail
+$NFT add element x y { 3.3.3.3 counter limit rate 1/second }
+if [ $? -eq 0 ]
+then
+ exit 1
+fi
+
+# should work
+$NFT add element x y { 4.4.4.4 }
+if [ $? -ne 0 ]
+then
+ exit 1
+fi
+
+exit 0
diff --git a/tests/shell/testcases/sets/0060set_multistmt_1 b/tests/shell/testcases/sets/0060set_multistmt_1
new file mode 100755
index 0000000..04ef047
--- /dev/null
+++ b/tests/shell/testcases/sets/0060set_multistmt_1
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_set_with_two_expressions)
+
+RULESET="table x {
+ set y {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ counter quota 500 bytes
+ elements = { 1.2.3.4 counter packets 9 bytes 756 quota 500 bytes used 500 bytes }
+ }
+ chain y {
+ type filter hook output priority filter; policy accept;
+ update @y { ip daddr }
+ }
+}"
+
+$NFT -f - <<< $RULESET
+# should work
+if [ $? -ne 0 ]
+then
+ exit 1
+fi
+
+# should work
+$NFT add element x y { 1.1.1.1 }
+if [ $? -ne 0 ]
+then
+ exit 1
+fi
+
+# should work
+$NFT add element x y { 2.2.2.2 counter quota 1000 bytes }
+if [ $? -ne 0 ]
+then
+ exit 1
+fi
+
+exit 0
diff --git a/tests/shell/testcases/sets/0061anonymous_automerge_0 b/tests/shell/testcases/sets/0061anonymous_automerge_0
new file mode 100755
index 0000000..2dfb800
--- /dev/null
+++ b/tests/shell/testcases/sets/0061anonymous_automerge_0
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip x {
+ chain y {
+ ip saddr { 1.1.1.1-1.1.1.2, 1.1.1.1 }
+ }
+}"
+
+$NFT -f - <<< $RULESET
diff --git a/tests/shell/testcases/sets/0062set_connlimit_0 b/tests/shell/testcases/sets/0062set_connlimit_0
new file mode 100755
index 0000000..48d589f
--- /dev/null
+++ b/tests/shell/testcases/sets/0062set_connlimit_0
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip x {
+ set est-connlimit {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ elements = { 84.245.120.167 ct count over 20 }
+ }
+}"
+
+$NFT -f - <<< $RULESET
+
+RULESET="table ip x {
+ set new-connlimit {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ ct count over 20
+ elements = { 84.245.120.167 }
+ }
+}"
+
+$NFT -f - <<< $RULESET
diff --git a/tests/shell/testcases/sets/0063set_catchall_0 b/tests/shell/testcases/sets/0063set_catchall_0
new file mode 100755
index 0000000..edd015d
--- /dev/null
+++ b/tests/shell/testcases/sets/0063set_catchall_0
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_catchall_element)
+
+set -e
+
+RULESET="table ip x {
+ set y {
+ type ipv4_addr
+ counter
+ elements = { 1.1.1.1, * }
+ }
+ set z {
+ type ipv4_addr
+ flags interval
+ counter
+ elements = { 1.1.1.0/24 , * }
+ }
+}"
+
+$NFT -f - <<< $RULESET
+$NFT delete element x y { \* }
+$NFT add element x y { \* }
diff --git a/tests/shell/testcases/sets/0064map_catchall_0 b/tests/shell/testcases/sets/0064map_catchall_0
new file mode 100755
index 0000000..fd28937
--- /dev/null
+++ b/tests/shell/testcases/sets/0064map_catchall_0
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_catchall_element)
+
+set -e
+
+RULESET="table ip x {
+ map y {
+ type ipv4_addr : ipv4_addr
+ elements = { 10.141.0.1 : 192.168.0.2, * : 192.168.0.3 }
+ }
+ map z {
+ type ipv4_addr : ipv4_addr
+ flags interval
+ elements = { 10.141.0.0/24 : 192.168.0.2, * : 192.168.0.3 }
+ }
+}"
+
+$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/0065_icmp_postprocessing b/tests/shell/testcases/sets/0065_icmp_postprocessing
new file mode 100755
index 0000000..f838c3e
--- /dev/null
+++ b/tests/shell/testcases/sets/0065_icmp_postprocessing
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip x {
+ chain foo {
+ icmp id 42
+ }
+}"
+
+$NFT -f - <<< $RULESET
+
+$NFT insert rule ip x foo index 0 accept
diff --git a/tests/shell/testcases/sets/0067nat_concat_interval_0 b/tests/shell/testcases/sets/0067nat_concat_interval_0
new file mode 100755
index 0000000..55cc0d4
--- /dev/null
+++ b/tests/shell/testcases/sets/0067nat_concat_interval_0
@@ -0,0 +1,71 @@
+#!/bin/bash
+
+set -e
+
+EXPECTED="table ip nat {
+ map ipportmap {
+ type ipv4_addr : interval ipv4_addr . inet_service
+ flags interval
+ elements = { 192.168.1.2 : 10.141.10.1-10.141.10.3 . 8888-8999 }
+ }
+ chain prerouting {
+ type nat hook prerouting priority dstnat; policy accept;
+ ip protocol tcp dnat ip to ip saddr map @ipportmap
+ }
+}"
+
+$NFT -f - <<< $EXPECTED
+$NFT add element ip nat ipportmap { 192.168.2.0/24 : 10.141.11.5-10.141.11.20 . 8888-8999 }
+
+EXPECTED="table ip nat {
+ map ipportmap2 {
+ type ipv4_addr . ipv4_addr : interval ipv4_addr . inet_service
+ flags interval
+ elements = { 192.168.1.2 . 192.168.2.2 : 127.0.0.1/8 . 42 - 43 }
+ }
+
+ chain prerouting {
+ type nat hook prerouting priority dstnat; policy accept;
+ ip protocol tcp dnat ip to ip saddr . ip daddr map @ipportmap2
+ }
+}"
+
+$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
+
+EXPECTED="table ip nat {
+ map ipportmap4 {
+ typeof iifname . ip saddr : interval ip daddr
+ flags interval
+ elements = { enp2s0 . 10.1.1.136 : 1.1.2.69, enp2s0 . 10.1.1.1-10.1.1.135 : 1.1.2.66-1.84.236.78 }
+ }
+ chain prerouting {
+ type nat hook prerouting priority dstnat; policy accept;
+ dnat to iifname . ip saddr map @ipportmap4
+ }
+}"
+
+$NFT -f - <<< $EXPECTED
+EXPECTED="table ip nat {
+ map ipportmap5 {
+ typeof iifname . ip saddr : interval ip daddr . tcp dport
+ flags interval
+ elements = { enp2s0 . 10.1.1.136 : 1.1.2.69 . 22, enp2s0 . 10.1.1.1-10.1.1.135 : 1.1.2.66-1.84.236.78 . 22 }
+ }
+ chain prerouting {
+ type nat hook prerouting priority dstnat; policy accept;
+ meta l4proto tcp dnat ip to iifname . ip saddr map @ipportmap5
+ }
+}"
+
+$NFT -f - <<< $EXPECTED
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 0000000..e61010c
--- /dev/null
+++ b/tests/shell/testcases/sets/0068interval_stack_overflow_0
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+set -e
+
+ruleset_file=$(mktemp)
+
+trap 'rm -f "$ruleset_file"' EXIT
+
+HOWMANY=255
+if [ "$NFT_TEST_HAS_SOCKET_LIMITS" = y ] ; then
+ # The socket limit /proc/sys/net/core/wmem_max may be unsuitable for
+ # the test.
+ #
+ # Run only a subset of the test and mark as skipped at the end.
+ HOWMANY=30
+fi
+
+{
+ echo 'define big_set = {'
+ for ((i = 1; i < $HOWMANY; 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" )
+
+if [ "$HOWMANY" != 255 ] ; then
+ echo "NFT_TEST_HAS_SOCKET_LIMITS indicates that the socket limit for"
+ echo "/proc/sys/net/core/wmem_max is too small for this test. Mark as SKIPPED"
+ echo "You may bump the limit and rerun with \`NFT_TEST_HAS_SOCKET_LIMITS=n\`."
+ exit 77
+fi
diff --git a/tests/shell/testcases/sets/0069interval_merge_0 b/tests/shell/testcases/sets/0069interval_merge_0
new file mode 100755
index 0000000..edb6422
--- /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 0000000..07820b7
--- /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 0000000..79e3ca7
--- /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/0072destroy_0 b/tests/shell/testcases/sets/0072destroy_0
new file mode 100755
index 0000000..9886a9b
--- /dev/null
+++ b/tests/shell/testcases/sets/0072destroy_0
@@ -0,0 +1,12 @@
+#!/bin/bash -e
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_destroy)
+
+$NFT add table x
+
+# pass for non-existent set
+$NFT destroy set x s
+
+# successfully delete existing set
+$NFT add set x s '{type ipv4_addr; size 2;}'
+$NFT destroy set x s
diff --git a/tests/shell/testcases/sets/0073flat_interval_set b/tests/shell/testcases/sets/0073flat_interval_set
new file mode 100755
index 0000000..0630595
--- /dev/null
+++ b/tests/shell/testcases/sets/0073flat_interval_set
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -e
+
+EXPECTED="flush ruleset
+add table inet filter
+add map inet filter testmap { type ipv4_addr : counter; flags interval;}
+add counter inet filter TEST
+add element inet filter testmap { 192.168.0.0/24 : \"TEST\" }"
+
+$NFT -f - <<< "$EXPECTED"
diff --git a/tests/shell/testcases/sets/0074nested_interval_set b/tests/shell/testcases/sets/0074nested_interval_set
new file mode 100755
index 0000000..e7f65fc
--- /dev/null
+++ b/tests/shell/testcases/sets/0074nested_interval_set
@@ -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/automerge_0 b/tests/shell/testcases/sets/automerge_0
new file mode 100755
index 0000000..1dbac0b
--- /dev/null
+++ b/tests/shell/testcases/sets/automerge_0
@@ -0,0 +1,131 @@
+#!/bin/bash
+
+# NFT_TEST_SKIP(NFT_TEST_SKIP_slow)
+
+set -e
+
+RULESET="table inet x {
+ set y {
+ type inet_service
+ flags interval
+ auto-merge
+ }
+}"
+
+HOWMANY=65535
+if [ "$NFT_TEST_HAS_SOCKET_LIMITS" = y ] ; then
+ # The socket limit /proc/sys/net/core/wmem_max may be unsuitable for
+ # the test.
+ #
+ # Run only a subset of the test and mark as skipped at the end.
+ HOWMANY=5000
+fi
+
+$NFT -f - <<< $RULESET
+
+tmpfile=$(mktemp)
+echo -n "add element inet x y { " > $tmpfile
+for ((i=0;i<$HOWMANY;i+=2))
+do
+ echo -n "$i, " >> $tmpfile
+ if [ $i -eq $((HOWMANY-1)) ]
+ then
+ echo -n "$i" >> $tmpfile
+ fi
+done
+echo "}" >> $tmpfile
+
+$NFT -f $tmpfile
+
+tmpfile2=$(mktemp)
+for ((i=1;i<$HOWMANY;i+=2))
+do
+ echo "$i" >> $tmpfile2
+done
+
+tmpfile3=$(mktemp)
+shuf "$tmpfile2" --random-source=<("$NFT_TEST_BASEDIR/helpers/random-source.sh" "automerge-shuf-tmpfile2" "$NFT_TEST_RANDOM_SEED") > "$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%$HOWMANY))
+ 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
+
+if [ "$HOWMANY" != 65535 ] ; then
+ echo "NFT_TEST_HAS_SOCKET_LIMITS indicates that the socket limit for"
+ echo "/proc/sys/net/core/wmem_max is too small for this test. Mark as SKIPPED"
+ echo "You may bump the limit and rerun with \`NFT_TEST_HAS_SOCKET_LIMITS=n\`."
+ exit 77
+fi
diff --git a/tests/shell/testcases/sets/collapse_elem_0 b/tests/shell/testcases/sets/collapse_elem_0
new file mode 100755
index 0000000..7699e9d
--- /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 0000000..4d90af9
--- /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/0001named_interval_0.nft b/tests/shell/testcases/sets/dumps/0001named_interval_0.nft
new file mode 100644
index 0000000..3049aa8
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0001named_interval_0.nft
@@ -0,0 +1,34 @@
+table inet t {
+ set s1 {
+ type ipv4_addr
+ flags interval
+ elements = { 10.0.0.0-11.0.0.0, 172.16.0.0/16 }
+ }
+
+ set s2 {
+ type ipv6_addr
+ flags interval
+ elements = { fe00::/64,
+ fe11::-fe22:: }
+ }
+
+ set s3 {
+ type inet_proto
+ flags interval
+ elements = { 10-20, 50-60 }
+ }
+
+ set s4 {
+ type inet_service
+ flags interval
+ elements = { 0-1024, 8080-8082, 10000-40000 }
+ }
+
+ chain c {
+ ip saddr @s1 accept
+ ip6 daddr @s2 accept
+ ip protocol @s3 accept
+ ip6 nexthdr @s3 accept
+ tcp dport @s4 accept
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0002named_interval_automerging_0.nft b/tests/shell/testcases/sets/dumps/0002named_interval_automerging_0.nft
new file mode 100644
index 0000000..452ee23
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0002named_interval_automerging_0.nft
@@ -0,0 +1,7 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ flags interval
+ elements = { 192.168.0.0/24, 192.168.1.0/24 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0003named_interval_missing_flag_0.nft b/tests/shell/testcases/sets/dumps/0003named_interval_missing_flag_0.nft
new file mode 100644
index 0000000..70c32a8
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0003named_interval_missing_flag_0.nft
@@ -0,0 +1,5 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0004named_interval_shadow_0.nft b/tests/shell/testcases/sets/dumps/0004named_interval_shadow_0.nft
new file mode 100644
index 0000000..940030a
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0004named_interval_shadow_0.nft
@@ -0,0 +1,7 @@
+table inet t {
+ set s {
+ type ipv6_addr
+ flags interval
+ elements = { fe00::/64 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0005named_interval_shadow_0.nft b/tests/shell/testcases/sets/dumps/0005named_interval_shadow_0.nft
new file mode 100644
index 0000000..4224d9d
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0005named_interval_shadow_0.nft
@@ -0,0 +1,7 @@
+table inet t {
+ set s {
+ type ipv6_addr
+ flags interval
+ elements = { fe00::/48 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0006create_set_0.nft b/tests/shell/testcases/sets/dumps/0006create_set_0.nft
new file mode 100644
index 0000000..70c32a8
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0006create_set_0.nft
@@ -0,0 +1,5 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0007create_element_0.nft b/tests/shell/testcases/sets/dumps/0007create_element_0.nft
new file mode 100644
index 0000000..169be11
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0007create_element_0.nft
@@ -0,0 +1,6 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ elements = { 1.1.1.1 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0008comments_interval_0.nft b/tests/shell/testcases/sets/dumps/0008comments_interval_0.nft
new file mode 100644
index 0000000..5e7a768
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0008comments_interval_0.nft
@@ -0,0 +1,7 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ flags interval
+ elements = { 1.1.1.1 comment "test" }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0008create_verdict_map_0.nft b/tests/shell/testcases/sets/dumps/0008create_verdict_map_0.nft
new file mode 100644
index 0000000..ab0fe80
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0008create_verdict_map_0.nft
@@ -0,0 +1,13 @@
+table ip t {
+ map sourcemap {
+ type ipv4_addr : verdict
+ elements = { 100.123.10.2 : jump c }
+ }
+
+ chain postrouting {
+ ip saddr vmap @sourcemap accept
+ }
+
+ chain c {
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0009comments_timeout_0.nft b/tests/shell/testcases/sets/dumps/0009comments_timeout_0.nft
new file mode 100644
index 0000000..455ebe3
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0009comments_timeout_0.nft
@@ -0,0 +1,7 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ flags timeout
+ elements = { 1.1.1.1 comment "test" }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0010comments_0.nft b/tests/shell/testcases/sets/dumps/0010comments_0.nft
new file mode 100644
index 0000000..6e42ec4
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0010comments_0.nft
@@ -0,0 +1,6 @@
+table inet t {
+ set s {
+ type ipv6_addr
+ elements = { ::1 comment "test" }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0011add_many_elements_0.nodump b/tests/shell/testcases/sets/dumps/0011add_many_elements_0.nodump
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0011add_many_elements_0.nodump
diff --git a/tests/shell/testcases/sets/dumps/0012add_delete_many_elements_0.nft b/tests/shell/testcases/sets/dumps/0012add_delete_many_elements_0.nft
new file mode 100644
index 0000000..e3d4aee
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0012add_delete_many_elements_0.nft
@@ -0,0 +1,5 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0013add_delete_many_elements_0.nft b/tests/shell/testcases/sets/dumps/0013add_delete_many_elements_0.nft
new file mode 100644
index 0000000..e3d4aee
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0013add_delete_many_elements_0.nft
@@ -0,0 +1,5 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0014malformed_set_is_not_defined_0.nft b/tests/shell/testcases/sets/dumps/0014malformed_set_is_not_defined_0.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0014malformed_set_is_not_defined_0.nft
diff --git a/tests/shell/testcases/sets/dumps/0015rulesetflush_0.nft b/tests/shell/testcases/sets/dumps/0015rulesetflush_0.nft
new file mode 100644
index 0000000..f6eddbf
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0015rulesetflush_0.nft
@@ -0,0 +1,11 @@
+table ip t {
+ chain c {
+ }
+}
+table inet filter {
+ set blacklist_v4 {
+ type ipv4_addr
+ flags interval
+ elements = { 192.168.0.0/24 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0016element_leak_0.nft b/tests/shell/testcases/sets/dumps/0016element_leak_0.nft
new file mode 100644
index 0000000..9d2b0af
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0016element_leak_0.nft
@@ -0,0 +1,7 @@
+table ip x {
+ set s {
+ type ipv4_addr
+ size 2
+ elements = { 1.1.1.1 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0017add_after_flush_0.nft b/tests/shell/testcases/sets/dumps/0017add_after_flush_0.nft
new file mode 100644
index 0000000..9d2b0af
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0017add_after_flush_0.nft
@@ -0,0 +1,7 @@
+table ip x {
+ set s {
+ type ipv4_addr
+ size 2
+ elements = { 1.1.1.1 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0018set_check_size_1.nft b/tests/shell/testcases/sets/dumps/0018set_check_size_1.nft
new file mode 100644
index 0000000..8cd3707
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0018set_check_size_1.nft
@@ -0,0 +1,7 @@
+table ip x {
+ set s {
+ type ipv4_addr
+ size 2
+ elements = { 1.1.1.1, 1.1.1.2 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0019set_check_size_0.nft b/tests/shell/testcases/sets/dumps/0019set_check_size_0.nft
new file mode 100644
index 0000000..8cd3707
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0019set_check_size_0.nft
@@ -0,0 +1,7 @@
+table ip x {
+ set s {
+ type ipv4_addr
+ size 2
+ elements = { 1.1.1.1, 1.1.1.2 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0020comments_0.nft b/tests/shell/testcases/sets/dumps/0020comments_0.nft
new file mode 100644
index 0000000..8b7d60a
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0020comments_0.nft
@@ -0,0 +1,6 @@
+table inet t {
+ set s {
+ type inet_service
+ elements = { 22 comment "test" }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0021nesting_0.nft b/tests/shell/testcases/sets/dumps/0021nesting_0.nft
new file mode 100644
index 0000000..6fd2a44
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0021nesting_0.nft
@@ -0,0 +1,5 @@
+table ip x {
+ chain y {
+ ip saddr { 1.1.1.0/24, 2.2.2.0/24, 3.3.3.0/24 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0022type_selective_flush_0.nft b/tests/shell/testcases/sets/dumps/0022type_selective_flush_0.nft
new file mode 100644
index 0000000..0a4cb0a
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0022type_selective_flush_0.nft
@@ -0,0 +1,13 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ }
+
+ map m {
+ type ipv4_addr : inet_service
+ }
+
+ chain c {
+ tcp dport 80 meter f size 1024 { ip saddr limit rate 10/second burst 5 packets }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0023incomplete_add_set_command_0.nft b/tests/shell/testcases/sets/dumps/0023incomplete_add_set_command_0.nft
new file mode 100644
index 0000000..985768b
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0023incomplete_add_set_command_0.nft
@@ -0,0 +1,2 @@
+table ip t {
+}
diff --git a/tests/shell/testcases/sets/dumps/0024named_objects_0.nft b/tests/shell/testcases/sets/dumps/0024named_objects_0.nft
new file mode 100644
index 0000000..52d1bf6
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0024named_objects_0.nft
@@ -0,0 +1,50 @@
+table inet x {
+ counter user123 {
+ packets 12 bytes 1433
+ }
+
+ counter user321 {
+ packets 0 bytes 0
+ }
+
+ quota user123 {
+ over 2000 bytes
+ }
+
+ 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
+ }
+
+ map test {
+ 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 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/0025anonymous_set_0.nft b/tests/shell/testcases/sets/dumps/0025anonymous_set_0.nft
new file mode 100644
index 0000000..5963699
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0025anonymous_set_0.nft
@@ -0,0 +1,7 @@
+table ip t {
+ chain c {
+ type filter hook output priority filter; policy accept;
+ ip daddr { 192.168.0.1, 192.168.0.2, 192.168.0.3 }
+ oifname "doesntexist" tcp dport { 22, 23 } counter packets 0 bytes 0
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0026named_limit_0.nft b/tests/shell/testcases/sets/dumps/0026named_limit_0.nft
new file mode 100644
index 0000000..e4daa28
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0026named_limit_0.nft
@@ -0,0 +1,10 @@
+table ip filter {
+ limit http-traffic {
+ rate 1/second
+ }
+
+ chain input {
+ type filter hook input priority filter; policy accept;
+ limit name tcp dport map { 80 : "http-traffic", 443 : "http-traffic" }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0027ipv6_maps_ipv4_0.nft b/tests/shell/testcases/sets/dumps/0027ipv6_maps_ipv4_0.nft
new file mode 100644
index 0000000..c49eefa
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0027ipv6_maps_ipv4_0.nft
@@ -0,0 +1,7 @@
+table inet t {
+ set s {
+ type ipv6_addr
+ flags interval
+ elements = { ::ffff:0.0.0.0/96 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0028autoselect_0.nft b/tests/shell/testcases/sets/dumps/0028autoselect_0.nft
new file mode 100644
index 0000000..0c60492
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0028autoselect_0.nft
@@ -0,0 +1,26 @@
+table ip t {
+ set s1 {
+ type inet_proto
+ size 65535
+ flags dynamic
+ }
+
+ set s2 {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ }
+
+ set s3 {
+ type ipv4_addr
+ size 1024
+ flags dynamic
+ }
+
+ chain c {
+ type filter hook input priority filter; policy accept;
+ iifname "foobar" add @s1 { ip protocol }
+ iifname "foobar" add @s2 { ip daddr }
+ iifname "foobar" add @s3 { ip daddr }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0028delete_handle_0.nft b/tests/shell/testcases/sets/dumps/0028delete_handle_0.nft
new file mode 100644
index 0000000..0f25c76
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0028delete_handle_0.nft
@@ -0,0 +1,15 @@
+table ip test-ip {
+ set x {
+ type ipv4_addr
+ }
+
+ set y {
+ type inet_service
+ timeout 3h45s
+ }
+
+ set z {
+ type ipv4_addr
+ flags constant,interval
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0029named_ifname_dtype_0.nft b/tests/shell/testcases/sets/dumps/0029named_ifname_dtype_0.nft
new file mode 100644
index 0000000..55cd4f2
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0029named_ifname_dtype_0.nft
@@ -0,0 +1,57 @@
+table inet t {
+ set s {
+ type ifname
+ elements = { "eth0",
+ "eth1",
+ "eth2",
+ "eth3",
+ "veth1" }
+ }
+
+ set sc {
+ type inet_service . ifname
+ elements = { 22 . "eth0",
+ 80 . "eth0",
+ 81 . "eth0",
+ 80 . "eth1" }
+ }
+
+ set nv {
+ type ifname . mark
+ elements = { "eth0" . 0x00000001,
+ "eth0" . 0x00000002 }
+ }
+
+ set z {
+ typeof ct zone
+ elements = { 1, 2, 3, 4, 5,
+ 6 }
+ }
+
+ set m {
+ typeof meta mark
+ elements = { 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005,
+ 0x00000006 }
+ }
+
+ map cz {
+ typeof iifname : ct zone
+ elements = { "eth0" : 1,
+ "eth1" : 2,
+ "veth4" : 1 }
+ }
+
+ map cm {
+ typeof iifname : ct mark
+ elements = { "eth0" : 0x00000001,
+ "eth1" : 0x00000002,
+ "veth4" : 0x00000001 }
+ }
+
+ chain c {
+ iifname @s accept
+ oifname @s accept
+ tcp dport . iifname @sc accept
+ iifname . meta mark @nv accept
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0030add_many_elements_interval_0.nodump b/tests/shell/testcases/sets/dumps/0030add_many_elements_interval_0.nodump
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0030add_many_elements_interval_0.nodump
diff --git a/tests/shell/testcases/sets/dumps/0031set_timeout_size_0.nodump b/tests/shell/testcases/sets/dumps/0031set_timeout_size_0.nodump
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0031set_timeout_size_0.nodump
diff --git a/tests/shell/testcases/sets/dumps/0032restore_set_simple_0.nft b/tests/shell/testcases/sets/dumps/0032restore_set_simple_0.nft
new file mode 100644
index 0000000..86c5549
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0032restore_set_simple_0.nft
@@ -0,0 +1,11 @@
+table ip filter {
+ set setA {
+ type ipv4_addr . inet_service . ipv4_addr
+ flags timeout
+ }
+
+ set setB {
+ type ipv4_addr . inet_service
+ flags timeout
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0033add_set_simple_flat_0.nft b/tests/shell/testcases/sets/dumps/0033add_set_simple_flat_0.nft
new file mode 100644
index 0000000..d6174c5
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0033add_set_simple_flat_0.nft
@@ -0,0 +1,11 @@
+table ip x {
+ set setA {
+ type ipv4_addr . inet_service . ipv4_addr
+ flags timeout
+ }
+
+ set setB {
+ type ipv4_addr . inet_service
+ flags timeout
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0034get_element_0.nft b/tests/shell/testcases/sets/dumps/0034get_element_0.nft
new file mode 100644
index 0000000..1c1dd97
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0034get_element_0.nft
@@ -0,0 +1,23 @@
+table ip t {
+ set s {
+ type inet_service
+ flags interval
+ elements = { 10, 20-30, 40, 50-60 }
+ }
+
+ set ips {
+ type ipv4_addr
+ flags interval
+ elements = { 10.0.0.1, 10.0.0.5-10.0.0.8,
+ 10.0.0.128/25, 10.0.1.0/24,
+ 10.0.2.3-10.0.2.12 }
+ }
+
+ set cs {
+ type ipv4_addr . inet_service
+ flags interval
+ elements = { 10.0.0.1 . 22,
+ 10.1.0.0/16 . 1-1024,
+ 10.2.0.1-10.2.0.8 . 1024-65535 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0035add_set_elements_flat_0.nft b/tests/shell/testcases/sets/dumps/0035add_set_elements_flat_0.nft
new file mode 100644
index 0000000..ca69cee
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0035add_set_elements_flat_0.nft
@@ -0,0 +1,6 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ flags interval
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0036add_set_element_expiration_0.nodump b/tests/shell/testcases/sets/dumps/0036add_set_element_expiration_0.nodump
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0036add_set_element_expiration_0.nodump
diff --git a/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft b/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft
new file mode 100644
index 0000000..68b1f7b
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0037_set_with_inet_service_0.nft
@@ -0,0 +1,16 @@
+table inet filter {
+ set myset {
+ type ipv4_addr . inet_proto . inet_service
+ elements = { 192.168.0.113 . tcp . 22,
+ 192.168.0.12 . tcp . 53,
+ 192.168.0.12 . udp . 53,
+ 192.168.0.12 . tcp . 80,
+ 192.168.0.13 . tcp . 80 }
+ }
+
+ chain forward {
+ type filter hook forward priority filter; policy drop;
+ ct state established,related accept
+ ct state new ip daddr . ip protocol . th dport @myset accept
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0038meter_list_0.nft b/tests/shell/testcases/sets/dumps/0038meter_list_0.nft
new file mode 100644
index 0000000..f274086
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0038meter_list_0.nft
@@ -0,0 +1,11 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ size 256
+ flags dynamic,timeout
+ }
+
+ chain c {
+ tcp dport 80 meter m size 128 { ip saddr limit rate 10/second burst 5 packets }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0039delete_interval_0.nft b/tests/shell/testcases/sets/dumps/0039delete_interval_0.nft
new file mode 100644
index 0000000..1fc7657
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0039delete_interval_0.nft
@@ -0,0 +1,7 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ flags interval
+ elements = { 192.168.1.0-192.168.1.254, 192.168.1.255 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0040get_host_endian_elements_0.nft b/tests/shell/testcases/sets/dumps/0040get_host_endian_elements_0.nft
new file mode 100644
index 0000000..f580c38
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0040get_host_endian_elements_0.nft
@@ -0,0 +1,7 @@
+table ip t {
+ set s {
+ type mark
+ flags interval
+ elements = { 0x00000023-0x00000042, 0x00001337 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0041interval_0.nft b/tests/shell/testcases/sets/dumps/0041interval_0.nft
new file mode 100644
index 0000000..222d4d7
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0041interval_0.nft
@@ -0,0 +1,7 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ flags interval
+ elements = { 192.168.2.196 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0042update_set_0.nft b/tests/shell/testcases/sets/dumps/0042update_set_0.nft
new file mode 100644
index 0000000..56cc875
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0042update_set_0.nft
@@ -0,0 +1,15 @@
+table ip t {
+ set set1 {
+ type ether_addr
+ }
+
+ set set2 {
+ type ether_addr
+ size 65535
+ flags dynamic
+ }
+
+ chain c {
+ ether daddr @set1 add @set2 { ether daddr counter }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0043concatenated_ranges_0.nft b/tests/shell/testcases/sets/dumps/0043concatenated_ranges_0.nft
new file mode 100644
index 0000000..f2077b9
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0043concatenated_ranges_0.nft
@@ -0,0 +1,11 @@
+table inet filter {
+ map test {
+ type mark . inet_service . inet_proto : mark
+ flags interval,timeout
+ }
+
+ chain output {
+ type filter hook output priority filter; policy accept;
+ meta mark set meta mark . tcp dport . meta l4proto map @test counter packets 0 bytes 0
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0043concatenated_ranges_1.nft b/tests/shell/testcases/sets/dumps/0043concatenated_ranges_1.nft
new file mode 100644
index 0000000..19d08d3
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0043concatenated_ranges_1.nft
@@ -0,0 +1,116 @@
+table ip6 t {
+ set s {
+ type ipv6_addr . ipv6_addr
+ flags interval
+ elements = { 2001:db8::/32 . 2001:db8:20::-2001:db8:20::20:1,
+ 2001:db8::/33 . 2001:db8:21::-2001:db8:21::21:1,
+ 2001:db8::/34 . 2001:db8:22::-2001:db8:22::22:1,
+ 2001:db8::/35 . 2001:db8:23::-2001:db8:23::23:1,
+ 2001:db8::/36 . 2001:db8:24::-2001:db8:24::24:1,
+ 2001:db8::/37 . 2001:db8:25::-2001:db8:25::25:1,
+ 2001:db8::/38 . 2001:db8:26::-2001:db8:26::26:1,
+ 2001:db8::/39 . 2001:db8:27::-2001:db8:27::27:1,
+ 2001:db8::/40 . 2001:db8:28::-2001:db8:28::28:1,
+ 2001:db8::/41 . 2001:db8:29::-2001:db8:29::29:1,
+ 2001:db8::/42 . 2001:db8:2a::-2001:db8:2a::2a:1,
+ 2001:db8::/43 . 2001:db8:2b::-2001:db8:2b::2b:1,
+ 2001:db8::/44 . 2001:db8:2c::-2001:db8:2c::2c:1,
+ 2001:db8::/45 . 2001:db8:2d::-2001:db8:2d::2d:1,
+ 2001:db8::/46 . 2001:db8:2e::-2001:db8:2e::2e:1,
+ 2001:db8::/47 . 2001:db8:2f::-2001:db8:2f::2f:1,
+ 2001:db8::/48 . 2001:db8:30::-2001:db8:30::30:1,
+ 2001:db8::/49 . 2001:db8:31::-2001:db8:31::31:1,
+ 2001:db8::/50 . 2001:db8:32::-2001:db8:32::32:1,
+ 2001:db8::/51 . 2001:db8:33::-2001:db8:33::33:1,
+ 2001:db8::/52 . 2001:db8:34::-2001:db8:34::34:1,
+ 2001:db8::/53 . 2001:db8:35::-2001:db8:35::35:1,
+ 2001:db8::/54 . 2001:db8:36::-2001:db8:36::36:1,
+ 2001:db8::/55 . 2001:db8:37::-2001:db8:37::37:1,
+ 2001:db8::/56 . 2001:db8:38::-2001:db8:38::38:1,
+ 2001:db8::/57 . 2001:db8:39::-2001:db8:39::39:1,
+ 2001:db8::/58 . 2001:db8:3a::-2001:db8:3a::3a:1,
+ 2001:db8::/59 . 2001:db8:3b::-2001:db8:3b::3b:1,
+ 2001:db8::/60 . 2001:db8:3c::-2001:db8:3c::3c:1,
+ 2001:db8::/61 . 2001:db8:3d::-2001:db8:3d::3d:1,
+ 2001:db8::/62 . 2001:db8:3e::-2001:db8:3e::3e:1,
+ 2001:db8::/63 . 2001:db8:3f::-2001:db8:3f::3f:1,
+ 2001:db8::/64 . 2001:db8:40::-2001:db8:40::40:1,
+ 2001:db8::/65 . 2001:db8:41::-2001:db8:41::41:1,
+ 2001:db8::/66 . 2001:db8:42::-2001:db8:42::42:1,
+ 2001:db8::/67 . 2001:db8:43::-2001:db8:43::43:1,
+ 2001:db8::/68 . 2001:db8:44::-2001:db8:44::44:1,
+ 2001:db8::/69 . 2001:db8:45::-2001:db8:45::45:1,
+ 2001:db8::/70 . 2001:db8:46::-2001:db8:46::46:1,
+ 2001:db8::/71 . 2001:db8:47::-2001:db8:47::47:1,
+ 2001:db8::/72 . 2001:db8:48::-2001:db8:48::48:1,
+ 2001:db8::/73 . 2001:db8:49::-2001:db8:49::49:1,
+ 2001:db8::/74 . 2001:db8:4a::-2001:db8:4a::4a:1,
+ 2001:db8::/75 . 2001:db8:4b::-2001:db8:4b::4b:1,
+ 2001:db8::/76 . 2001:db8:4c::-2001:db8:4c::4c:1,
+ 2001:db8::/77 . 2001:db8:4d::-2001:db8:4d::4d:1,
+ 2001:db8::/78 . 2001:db8:4e::-2001:db8:4e::4e:1,
+ 2001:db8::/79 . 2001:db8:4f::-2001:db8:4f::4f:1,
+ 2001:db8::/80 . 2001:db8:50::-2001:db8:50::50:1,
+ 2001:db8::/81 . 2001:db8:51::-2001:db8:51::51:1,
+ 2001:db8::/82 . 2001:db8:52::-2001:db8:52::52:1,
+ 2001:db8::/83 . 2001:db8:53::-2001:db8:53::53:1,
+ 2001:db8::/84 . 2001:db8:54::-2001:db8:54::54:1,
+ 2001:db8::/85 . 2001:db8:55::-2001:db8:55::55:1,
+ 2001:db8::/86 . 2001:db8:56::-2001:db8:56::56:1,
+ 2001:db8::/87 . 2001:db8:57::-2001:db8:57::57:1,
+ 2001:db8::/88 . 2001:db8:58::-2001:db8:58::58:1,
+ 2001:db8::/89 . 2001:db8:59::-2001:db8:59::59:1,
+ 2001:db8::/90 . 2001:db8:5a::-2001:db8:5a::5a:1,
+ 2001:db8::/91 . 2001:db8:5b::-2001:db8:5b::5b:1,
+ 2001:db8::/92 . 2001:db8:5c::-2001:db8:5c::5c:1,
+ 2001:db8::/93 . 2001:db8:5d::-2001:db8:5d::5d:1,
+ 2001:db8::/94 . 2001:db8:5e::-2001:db8:5e::5e:1,
+ 2001:db8::/95 . 2001:db8:5f::-2001:db8:5f::5f:1,
+ 2001:db8::/96 . 2001:db8:60::-2001:db8:60::60:1,
+ 2001:db8::/97 . 2001:db8:61::-2001:db8:61::61:1,
+ 2001:db8::/98 . 2001:db8:62::-2001:db8:62::62:1,
+ 2001:db8::/99 . 2001:db8:63::-2001:db8:63::63:1,
+ 2001:db8::/100 . 2001:db8:64::-2001:db8:64::64:1,
+ 2001:db8::/101 . 2001:db8:65::-2001:db8:65::65:1,
+ 2001:db8::/102 . 2001:db8:66::-2001:db8:66::66:1,
+ 2001:db8::/103 . 2001:db8:67::-2001:db8:67::67:1,
+ 2001:db8::/104 . 2001:db8:68::-2001:db8:68::68:1,
+ 2001:db8::/105 . 2001:db8:69::-2001:db8:69::69:1,
+ 2001:db8::/106 . 2001:db8:6a::-2001:db8:6a::6a:1,
+ 2001:db8::/107 . 2001:db8:6b::-2001:db8:6b::6b:1,
+ 2001:db8::/108 . 2001:db8:6c::-2001:db8:6c::6c:1,
+ 2001:db8::/109 . 2001:db8:6d::-2001:db8:6d::6d:1,
+ 2001:db8::/110 . 2001:db8:6e::-2001:db8:6e::6e:1,
+ 2001:db8::/111 . 2001:db8:6f::-2001:db8:6f::6f:1,
+ 2001:db8::/112 . 2001:db8:70::-2001:db8:70::70:1,
+ 2001:db8::/113 . 2001:db8:71::-2001:db8:71::71:1,
+ 2001:db8::/114 . 2001:db8:72::-2001:db8:72::72:1,
+ 2001:db8::/115 . 2001:db8:73::-2001:db8:73::73:1,
+ 2001:db8::/116 . 2001:db8:74::-2001:db8:74::74:1,
+ 2001:db8::/117 . 2001:db8:75::-2001:db8:75::75:1,
+ 2001:db8::/118 . 2001:db8:76::-2001:db8:76::76:1,
+ 2001:db8::/119 . 2001:db8:77::-2001:db8:77::77:1,
+ 2001:db8::/120 . 2001:db8:78::-2001:db8:78::78:1,
+ 2001:db8::/121 . 2001:db8:79::-2001:db8:79::79:1,
+ 2001:db8::/122 . 2001:db8:7a::-2001:db8:7a::7a:1,
+ 2001:db8::/123 . 2001:db8:7b::-2001:db8:7b::7b:1,
+ 2001:db8::/124 . 2001:db8:7c::-2001:db8:7c::7c:1,
+ 2001:db8::/125 . 2001:db8:7d::-2001:db8:7d::7d:1,
+ 2001:db8::/126 . 2001:db8:7e::-2001:db8:7e::7e:1,
+ 2001:db8::/127 . 2001:db8:7f::-2001:db8:7f::7f:1 }
+ }
+}
+table ip t {
+ set s {
+ type ipv4_addr . ipv4_addr
+ flags interval
+ elements = { 192.0.2.0/24 . 192.0.2.72-192.0.2.74,
+ 192.0.2.0/25 . 192.0.2.75-192.0.2.77,
+ 192.0.2.0/26 . 192.0.2.78-192.0.2.80,
+ 192.0.2.0/27 . 192.0.2.81-192.0.2.83,
+ 192.0.2.0/28 . 192.0.2.84-192.0.2.86,
+ 192.0.2.0/29 . 192.0.2.87-192.0.2.89,
+ 192.0.2.0/30 . 192.0.2.90-192.0.2.92,
+ 192.0.2.0/31 . 192.0.2.93-192.0.2.95 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0044interval_overlap_0.nodump b/tests/shell/testcases/sets/dumps/0044interval_overlap_0.nodump
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0044interval_overlap_0.nodump
diff --git a/tests/shell/testcases/sets/dumps/0044interval_overlap_1.nft b/tests/shell/testcases/sets/dumps/0044interval_overlap_1.nft
new file mode 100644
index 0000000..5b249a3
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0044interval_overlap_1.nft
@@ -0,0 +1,106 @@
+table ip t {
+ set s {
+ type inet_service
+ flags interval
+ elements = { 25, 30, 82, 119, 349,
+ 745, 748, 1165, 1233, 1476,
+ 1550, 1562, 1743, 1745, 1882,
+ 2070, 2194, 2238, 2450, 2455,
+ 2642, 2671, 2906, 3093, 3203,
+ 3287, 3348, 3411, 3540, 3892,
+ 3943, 4133, 4205, 4317, 4733,
+ 5095, 5156, 5223, 5230, 5432,
+ 5826, 5828, 6044, 6377, 6388,
+ 6491, 6952, 6986, 7012, 7187,
+ 7300, 7305, 7549, 7664, 8111,
+ 8206, 8396, 8782, 8920, 8981,
+ 9067, 9216, 9245, 9315, 9432,
+ 9587, 9689, 9844, 9991, 10045,
+ 10252, 10328, 10670, 10907, 11021,
+ 11337, 11427, 11497, 11502, 11523,
+ 11552, 11577, 11721, 11943, 12474,
+ 12718, 12764, 12794, 12922, 13186,
+ 13232, 13383, 13431, 13551, 13676,
+ 13685, 13747, 13925, 13935, 14015,
+ 14090, 14320, 14392, 14515, 14647,
+ 14911, 15096, 15105, 15154, 15440,
+ 15583, 15623, 15677, 15710, 15926,
+ 15934, 15960, 16068, 16166, 16486,
+ 16489, 16528, 16646, 16650, 16770,
+ 16882, 17052, 17237, 17387, 17431,
+ 17886, 17939, 17999, 18092, 18123,
+ 18238, 18562, 18698, 19004, 19229,
+ 19237, 19585, 19879, 19938, 19950,
+ 19958, 20031, 20138, 20157, 20205,
+ 20368, 20682, 20687, 20873, 20910,
+ 20919, 21019, 21068, 21115, 21188,
+ 21236, 21319, 21563, 21734, 21806,
+ 21810, 21959, 21982, 22078, 22181,
+ 22308, 22480, 22643, 22854, 22879,
+ 22961, 23397, 23534, 23845, 23893,
+ 24130, 24406, 24794, 24997, 25019,
+ 25143, 25179, 25439, 25603, 25718,
+ 25859, 25949, 26006, 26022, 26047,
+ 26170, 26193, 26725, 26747, 26924,
+ 27023, 27040, 27233, 27344, 27478,
+ 27593, 27600, 27664, 27678, 27818,
+ 27822, 28003, 28038, 28709, 28808,
+ 29010, 29057, 29228, 29485, 30132,
+ 30160, 30415, 30469, 30673, 30736,
+ 30776, 30780, 31450, 31537, 31669,
+ 31839, 31873, 32019, 32229, 32685,
+ 32879, 33318, 33337, 33404, 33517,
+ 33906, 34214, 34346, 34416, 34727,
+ 34848, 35325, 35400, 35451, 35501,
+ 35637, 35653, 35710, 35761, 35767,
+ 36238, 36258, 36279, 36464, 36586,
+ 36603, 36770, 36774, 36805, 36851,
+ 37079, 37189, 37209, 37565, 37570,
+ 37585, 37832, 37931, 37954, 38006,
+ 38015, 38045, 38109, 38114, 38200,
+ 38209, 38214, 38277, 38306, 38402,
+ 38606, 38697, 38960, 39004, 39006,
+ 39197, 39217, 39265, 39319, 39460,
+ 39550, 39615, 39871, 39886, 40088,
+ 40135, 40244, 40323, 40339, 40355,
+ 40385, 40428, 40538, 40791, 40848,
+ 40959, 41003, 41131, 41349, 41643,
+ 41710, 41826, 41904, 42027, 42148,
+ 42235, 42255, 42498, 42680, 42973,
+ 43118, 43135, 43233, 43349, 43411,
+ 43487, 43840, 43843, 43870, 44040,
+ 44204, 44817, 44883, 44894, 44958,
+ 45201, 45259, 45283, 45357, 45423,
+ 45473, 45498, 45519, 45561, 45611,
+ 45627, 45831, 46043, 46105, 46116,
+ 46147, 46169, 46349, 47147, 47252,
+ 47314, 47335, 47360, 47546, 47617,
+ 47648, 47772, 47793, 47846, 47913,
+ 47952, 48095, 48325, 48334, 48412,
+ 48419, 48540, 48569, 48628, 48751,
+ 48944, 48971, 49008, 49025, 49503,
+ 49505, 49613, 49767, 49839, 49925,
+ 50022, 50028, 50238, 51057, 51477,
+ 51617, 51910, 52044, 52482, 52550,
+ 52643, 52832, 53382, 53690, 53809,
+ 53858, 54001, 54198, 54280, 54327,
+ 54376, 54609, 54776, 54983, 54984,
+ 55019, 55038, 55094, 55368, 55737,
+ 55793, 55904, 55941, 55960, 55978,
+ 56063, 56121, 56314, 56505, 56548,
+ 56568, 56696, 56798, 56855, 57102,
+ 57236, 57333, 57334, 57441, 57574,
+ 57659, 57987, 58325, 58404, 58509,
+ 58782, 58876, 59116, 59544, 59685,
+ 59700, 59750, 59799, 59866, 59870,
+ 59894, 59984, 60343, 60481, 60564,
+ 60731, 61075, 61087, 61148, 61174,
+ 61655, 61679, 61691, 61723, 61730,
+ 61758, 61824, 62035, 62056, 62661,
+ 62768, 62946, 63059, 63116, 63338,
+ 63387, 63672, 63719, 63881, 63995,
+ 64197, 64374, 64377, 64472, 64606,
+ 64662, 64777, 64795, 64906, 65049,
+ 65122, 65318 }
+ }
+}
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 0000000..e548a17
--- /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
new file mode 100644
index 0000000..5ac6b34
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0046netmap_0.nft
@@ -0,0 +1,12 @@
+table ip x {
+ chain y {
+ type nat hook postrouting priority srcnat; policy accept;
+ 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/0047nat_0.nft b/tests/shell/testcases/sets/dumps/0047nat_0.nft
new file mode 100644
index 0000000..9fa9fc7
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0047nat_0.nft
@@ -0,0 +1,30 @@
+table ip x {
+ map y {
+ type ipv4_addr : interval ipv4_addr
+ flags interval
+ elements = { 10.141.10.0/24 : 192.168.2.2-192.168.2.4, 10.141.11.0/24 : 192.168.4.2/31,
+ 10.141.12.0/24 : 192.168.5.10-192.168.5.20 }
+ }
+
+ chain x {
+ type nat hook prerouting priority dstnat; policy accept;
+ meta l4proto tcp dnat ip to iifname . ip saddr map { "enp2s0" . 10.1.1.136 : 1.1.2.69 . 22, "enp2s0" . 10.1.1.1-10.1.1.135 : 1.1.2.66-1.84.236.78 . 22 }
+ dnat ip to iifname . ip saddr map { "enp2s0" . 10.1.1.136 : 1.1.2.69/32, "enp2s0" . 10.1.1.1-10.1.1.135 : 1.1.2.66-1.84.236.78 }
+ }
+
+ chain y {
+ type nat hook postrouting priority srcnat; policy accept;
+ snat ip to ip saddr map @y
+ }
+}
+table inet x {
+ chain x {
+ type nat hook prerouting priority dstnat; policy accept;
+ dnat ip to ip daddr . tcp dport map { 10.141.10.1 . 22 : 192.168.2.2, 10.141.11.2 . 2222 : 192.168.4.2 }
+ }
+
+ chain y {
+ type nat hook postrouting priority srcnat; policy accept;
+ snat ip to ip saddr map { 10.141.10.0/24 : 192.168.2.2-192.168.2.4, 10.141.11.0/24 : 192.168.4.2/31 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0048set_counters_0.nft b/tests/shell/testcases/sets/dumps/0048set_counters_0.nft
new file mode 100644
index 0000000..2145f6b
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0048set_counters_0.nft
@@ -0,0 +1,13 @@
+table ip x {
+ set y {
+ typeof ip saddr
+ counter
+ elements = { 192.168.10.35 counter packets 0 bytes 0, 192.168.10.101 counter packets 0 bytes 0,
+ 192.168.10.135 counter packets 0 bytes 0 }
+ }
+
+ chain z {
+ type filter hook output priority filter; policy accept;
+ ip daddr @y
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0049set_define_0.nft b/tests/shell/testcases/sets/dumps/0049set_define_0.nft
new file mode 100644
index 0000000..998b387
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0049set_define_0.nft
@@ -0,0 +1,6 @@
+table inet filter {
+ chain input {
+ type filter hook input priority filter; policy drop;
+ tcp dport { 22, 80, 443 } ct state new counter packets 0 bytes 0 accept
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0050set_define_1.nft b/tests/shell/testcases/sets/dumps/0050set_define_1.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0050set_define_1.nft
diff --git a/tests/shell/testcases/sets/dumps/0051set_interval_counter_0.nft b/tests/shell/testcases/sets/dumps/0051set_interval_counter_0.nft
new file mode 100644
index 0000000..fd488a7
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0051set_interval_counter_0.nft
@@ -0,0 +1,13 @@
+table ip x {
+ set s {
+ type ipv4_addr
+ flags interval
+ counter
+ elements = { 192.168.2.0/24 counter packets 0 bytes 0 }
+ }
+
+ chain y {
+ type filter hook output priority filter; policy accept;
+ ip daddr @s
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0052overlap_0.nft b/tests/shell/testcases/sets/dumps/0052overlap_0.nft
new file mode 100644
index 0000000..1cc02ad
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0052overlap_0.nft
@@ -0,0 +1,8 @@
+table ip filter {
+ set w_all {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ elements = { 10.10.10.10, 10.10.10.253 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0053echo_0.nft b/tests/shell/testcases/sets/dumps/0053echo_0.nft
new file mode 100644
index 0000000..bb7c551
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0053echo_0.nft
@@ -0,0 +1,6 @@
+table inet filter {
+ chain input {
+ type filter hook input priority filter; policy drop;
+ iifname "lo" ip saddr 10.0.0.0/8 ip daddr 192.168.100.62 tcp dport 2001 counter packets 0 bytes 0 accept
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0054comments_set_0.nft b/tests/shell/testcases/sets/dumps/0054comments_set_0.nft
new file mode 100644
index 0000000..7929924
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0054comments_set_0.nft
@@ -0,0 +1,13 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ flags interval
+ comment "test"
+ }
+
+ map m {
+ type ipv4_addr : ipv4_addr
+ flags interval
+ comment "another test"
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0055tcpflags_0.nft b/tests/shell/testcases/sets/dumps/0055tcpflags_0.nft
new file mode 100644
index 0000000..ffed542
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0055tcpflags_0.nft
@@ -0,0 +1,10 @@
+table ip test {
+ set tcp_good_flags {
+ type tcp_flag
+ flags constant
+ elements = { fin | psh | ack | urg, fin | psh | ack, fin | ack | urg, fin | ack, syn | psh | ack | urg,
+ syn | psh | ack, syn | ack | urg, syn | ack, syn, rst | psh | ack | urg,
+ rst | psh | ack, rst | ack | urg, rst | ack, rst, psh | ack | urg,
+ psh | ack, ack | urg, ack }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0056dynamic_limit_0.nft b/tests/shell/testcases/sets/dumps/0056dynamic_limit_0.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0056dynamic_limit_0.nft
diff --git a/tests/shell/testcases/sets/dumps/0057set_create_fails_0.nft b/tests/shell/testcases/sets/dumps/0057set_create_fails_0.nft
new file mode 100644
index 0000000..de43d56
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0057set_create_fails_0.nft
@@ -0,0 +1,7 @@
+table inet filter {
+ set test {
+ type ipv4_addr
+ size 65535
+ elements = { 1.1.1.1 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0058_setupdate_timeout_0.nft b/tests/shell/testcases/sets/dumps/0058_setupdate_timeout_0.nft
new file mode 100644
index 0000000..873adc6
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0058_setupdate_timeout_0.nft
@@ -0,0 +1,12 @@
+table inet filter {
+ set ssh_meter {
+ type ipv4_addr
+ size 65535
+ flags dynamic,timeout
+ timeout 30d
+ }
+
+ chain test {
+ add @ssh_meter { ip saddr timeout 30d }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0059set_update_multistmt_0.nft b/tests/shell/testcases/sets/dumps/0059set_update_multistmt_0.nft
new file mode 100644
index 0000000..c1cc3b5
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0059set_update_multistmt_0.nft
@@ -0,0 +1,13 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ size 65535
+ flags dynamic,timeout
+ timeout 1h
+ }
+
+ chain z {
+ type filter hook output priority filter; policy accept;
+ update @y { ip daddr limit rate 1/second burst 5 packets counter }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0060set_multistmt_0.nft b/tests/shell/testcases/sets/dumps/0060set_multistmt_0.nft
new file mode 100644
index 0000000..df68fcd
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0060set_multistmt_0.nft
@@ -0,0 +1,13 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ limit rate 1/second burst 5 packets counter
+ elements = { 1.1.1.1 limit rate 1/second burst 5 packets counter packets 0 bytes 0, 4.4.4.4 limit rate 1/second burst 5 packets counter packets 0 bytes 0,
+ 5.5.5.5 limit rate 1/second burst 5 packets counter packets 0 bytes 0 }
+ }
+
+ chain y {
+ type filter hook output priority filter; policy accept;
+ ip daddr @y
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0060set_multistmt_1.nft b/tests/shell/testcases/sets/dumps/0060set_multistmt_1.nft
new file mode 100644
index 0000000..ac1bd26
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0060set_multistmt_1.nft
@@ -0,0 +1,15 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ counter quota 500 bytes
+ elements = { 1.1.1.1 counter packets 0 bytes 0 quota 500 bytes, 1.2.3.4 counter packets 9 bytes 756 quota 500 bytes used 500 bytes,
+ 2.2.2.2 counter packets 0 bytes 0 quota 1000 bytes }
+ }
+
+ chain y {
+ type filter hook output priority filter; policy accept;
+ update @y { ip daddr }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0061anonymous_automerge_0.nft b/tests/shell/testcases/sets/dumps/0061anonymous_automerge_0.nft
new file mode 100644
index 0000000..04361f4
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0061anonymous_automerge_0.nft
@@ -0,0 +1,5 @@
+table ip x {
+ chain y {
+ ip saddr { 1.1.1.1-1.1.1.2 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0062set_connlimit_0.nft b/tests/shell/testcases/sets/dumps/0062set_connlimit_0.nft
new file mode 100644
index 0000000..080d675
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0062set_connlimit_0.nft
@@ -0,0 +1,16 @@
+table ip x {
+ set est-connlimit {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ elements = { 84.245.120.167 ct count over 20 }
+ }
+
+ set new-connlimit {
+ type ipv4_addr
+ size 65535
+ flags dynamic
+ ct count over 20
+ elements = { 84.245.120.167 ct count over 20 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0063set_catchall_0.nft b/tests/shell/testcases/sets/dumps/0063set_catchall_0.nft
new file mode 100644
index 0000000..f0d42cc
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0063set_catchall_0.nft
@@ -0,0 +1,14 @@
+table ip x {
+ set y {
+ type ipv4_addr
+ counter
+ elements = { 1.1.1.1 counter packets 0 bytes 0, * counter packets 0 bytes 0 }
+ }
+
+ set z {
+ type ipv4_addr
+ flags interval
+ counter
+ elements = { 1.1.1.0/24 counter packets 0 bytes 0, * counter packets 0 bytes 0 }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0064map_catchall_0.nft b/tests/shell/testcases/sets/dumps/0064map_catchall_0.nft
new file mode 100644
index 0000000..890ed2a
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0064map_catchall_0.nft
@@ -0,0 +1,18 @@
+table ip x {
+ map y {
+ type ipv4_addr : ipv4_addr
+ elements = { 10.141.0.1 : 192.168.0.2, * : 192.168.0.4 }
+ }
+
+ map z {
+ type ipv4_addr : ipv4_addr
+ 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/0065_icmp_postprocessing.nft b/tests/shell/testcases/sets/dumps/0065_icmp_postprocessing.nft
new file mode 100644
index 0000000..461c7a7
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0065_icmp_postprocessing.nft
@@ -0,0 +1,6 @@
+table ip x {
+ chain foo {
+ accept
+ icmp type { echo-reply, echo-request } icmp id 42
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0067nat_concat_interval_0.nft b/tests/shell/testcases/sets/dumps/0067nat_concat_interval_0.nft
new file mode 100644
index 0000000..0215691
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0067nat_concat_interval_0.nft
@@ -0,0 +1,42 @@
+table ip nat {
+ map ipportmap {
+ type ipv4_addr : interval ipv4_addr . inet_service
+ flags interval
+ elements = { 192.168.1.2 : 10.141.10.1-10.141.10.3 . 8888-8999, 192.168.2.0/24 : 10.141.11.5-10.141.11.20 . 8888-8999 }
+ }
+
+ map ipportmap2 {
+ type ipv4_addr . ipv4_addr : interval ipv4_addr . inet_service
+ flags interval
+ 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 }
+ }
+
+ map ipportmap4 {
+ typeof iifname . ip saddr : interval ip daddr
+ flags interval
+ elements = { "enp2s0" . 10.1.1.136 : 1.1.2.69/32,
+ "enp2s0" . 10.1.1.1-10.1.1.135 : 1.1.2.66-1.84.236.78 }
+ }
+
+ map ipportmap5 {
+ typeof iifname . ip saddr : interval ip daddr . tcp dport
+ flags interval
+ elements = { "enp2s0" . 10.1.1.136 : 1.1.2.69 . 22,
+ "enp2s0" . 10.1.1.1-10.1.1.135 : 1.1.2.66-1.84.236.78 . 22 }
+ }
+
+ 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
+ dnat ip to iifname . ip saddr map @ipportmap4
+ meta l4proto tcp dnat ip to iifname . ip saddr map @ipportmap5
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0068interval_stack_overflow_0.nodump b/tests/shell/testcases/sets/dumps/0068interval_stack_overflow_0.nodump
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0068interval_stack_overflow_0.nodump
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 0000000..2d4e170
--- /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 0000000..0057e9c
--- /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 0000000..4eed94c
--- /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/0072destroy_0.nft b/tests/shell/testcases/sets/dumps/0072destroy_0.nft
new file mode 100644
index 0000000..5d4d2ca
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0072destroy_0.nft
@@ -0,0 +1,2 @@
+table ip x {
+}
diff --git a/tests/shell/testcases/sets/dumps/0073flat_interval_set.nft b/tests/shell/testcases/sets/dumps/0073flat_interval_set.nft
new file mode 100644
index 0000000..20f5374
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0073flat_interval_set.nft
@@ -0,0 +1,11 @@
+table inet filter {
+ counter TEST {
+ packets 0 bytes 0
+ }
+
+ map testmap {
+ type ipv4_addr : counter
+ flags interval
+ elements = { 192.168.0.0/24 : "TEST" }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/0074nested_interval_set.nft b/tests/shell/testcases/sets/dumps/0074nested_interval_set.nft
new file mode 100644
index 0000000..20f5374
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0074nested_interval_set.nft
@@ -0,0 +1,11 @@
+table inet filter {
+ counter TEST {
+ packets 0 bytes 0
+ }
+
+ map testmap {
+ type ipv4_addr : counter
+ flags interval
+ elements = { 192.168.0.0/24 : "TEST" }
+ }
+}
diff --git a/tests/shell/testcases/sets/dumps/automerge_0.nodump b/tests/shell/testcases/sets/dumps/automerge_0.nodump
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/automerge_0.nodump
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 0000000..a3244fc
--- /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 0000000..61547c5
--- /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 0000000..6c8ed32
--- /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/errors_0.nft b/tests/shell/testcases/sets/dumps/errors_0.nft
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/errors_0.nft
diff --git a/tests/shell/testcases/sets/dumps/exact_overlap_0.nft b/tests/shell/testcases/sets/dumps/exact_overlap_0.nft
new file mode 100644
index 0000000..c903e3f
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/exact_overlap_0.nft
@@ -0,0 +1,13 @@
+table ip t {
+ set s {
+ type ipv4_addr
+ flags interval
+ elements = { 1.0.1.0/24, 1.0.2.0/23,
+ 1.0.8.0/21, 1.0.32.0/19,
+ 1.1.0.0/24, 1.1.2.0/23,
+ 1.1.4.0/22, 1.1.8.0/24,
+ 1.1.9.0/24, 1.1.10.0/23,
+ 1.1.12.0/22, 1.1.16.0/20,
+ 1.1.32.0/19 }
+ }
+}
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 0000000..925ca77
--- /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/reset_command_0.nodump b/tests/shell/testcases/sets/dumps/reset_command_0.nodump
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/reset_command_0.nodump
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 0000000..a45462b
--- /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 0000000..77a8baf
--- /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/type_set_symbol.nft b/tests/shell/testcases/sets/dumps/type_set_symbol.nft
new file mode 100644
index 0000000..21209f6
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/type_set_symbol.nft
@@ -0,0 +1,16 @@
+table ip t {
+ set s1 {
+ type ipv4_addr . ipv4_addr . inet_service
+ size 65535
+ flags dynamic,timeout
+ timeout 3h
+ }
+
+ chain c1 {
+ update @s1 { ip saddr . 10.180.0.4 . 80 }
+ }
+
+ chain c2 {
+ ip saddr . 1.2.3.4 . 80 @s1 goto c1
+ }
+}
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 0000000..4d6abaa
--- /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 . @nh,32,32 { 1.1.1.1 . 0x14, 2.2.2.2 . 0x1e }
+ ip daddr . @nh,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
new file mode 100644
index 0000000..6f5b83a
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/typeof_sets_0.nft
@@ -0,0 +1,97 @@
+table inet t {
+ set s1 {
+ typeof osf name
+ elements = { "Linux" }
+ }
+
+ set s2 {
+ typeof vlan id
+ elements = { 2, 3, 103 }
+ }
+
+ set s3 {
+ typeof meta ibrpvid
+ 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
+ }
+
+ 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 0000000..89cbc83
--- /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 0000000..dbaf7cd
--- /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 0000000..fdf5f49
--- /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 0000000..27f65df
--- /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 0000000..1ce9304
--- /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 0000000..39d91bd
--- /dev/null
+++ b/tests/shell/testcases/sets/inner_0
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_inner_matching)
+
+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/reset_command_0 b/tests/shell/testcases/sets/reset_command_0
new file mode 100755
index 0000000..e663dac
--- /dev/null
+++ b/tests/shell/testcases/sets/reset_command_0
@@ -0,0 +1,93 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_reset_set)
+
+set -e
+
+trap '[[ $? -eq 0 ]] || echo FAIL' EXIT
+
+RULESET="table t {
+ set s {
+ type ipv4_addr . inet_proto . inet_service
+ flags interval, timeout
+ counter
+ timeout 30m
+ elements = {
+ 1.0.0.1 . udp . 53 counter packets 5 bytes 30 expires 20m,
+ 2.0.0.2 . tcp . 22 counter packets 10 bytes 100 timeout 15m expires 10m
+ }
+ }
+ map m {
+ type ipv4_addr : ipv4_addr
+ quota 50 bytes
+ elements = {
+ 1.2.3.4 quota 50 bytes used 10 bytes : 10.2.3.4,
+ 5.6.7.8 quota 100 bytes used 50 bytes : 50.6.7.8
+ }
+ }
+}"
+
+echo -n "applying test ruleset: "
+$NFT -f - <<< "$RULESET"
+echo OK
+
+drop_seconds() {
+ sed 's/[0-9]\+m\?s//g'
+}
+expires_minutes() {
+ sed -n 's/.*expires \([0-9]*\)m.*/\1/p'
+}
+
+echo -n "get set elem matches reset set elem: "
+elem='element t s { 1.0.0.1 . udp . 53 }'
+[[ $($NFT "get $elem ; reset $elem" | \
+ grep 'elements = ' | drop_seconds | uniq | wc -l) == 1 ]]
+echo OK
+
+echo -n "counters and expiry are reset: "
+NEW=$($NFT "get $elem")
+grep -q 'counter packets 0 bytes 0' <<< "$NEW"
+[[ $(expires_minutes <<< "$NEW") -gt 20 ]]
+echo OK
+
+echo -n "get map elem matches reset map elem: "
+elem='element t m { 1.2.3.4 }'
+[[ $($NFT "get $elem ; reset $elem" | \
+ grep 'elements = ' | uniq | wc -l) == 1 ]]
+echo OK
+
+echo -n "quota value is reset: "
+$NFT get element t m '{ 1.2.3.4 }' | grep -q 'quota 50 bytes : 10.2.3.4'
+echo OK
+
+echo -n "other elements remain the same: "
+OUT=$($NFT get element t s '{ 2.0.0.2 . tcp . 22 }')
+grep -q 'counter packets 10 bytes 100 timeout 15m' <<< "$OUT"
+VAL=$(expires_minutes <<< "$OUT")
+[[ $val -lt 10 ]]
+$NFT get element t m '{ 5.6.7.8 }' | grep -q 'quota 100 bytes used 50 bytes'
+echo OK
+
+echo -n "list set matches reset set: "
+EXP=$($NFT list set t s | drop_seconds)
+OUT=$($NFT reset set t s | drop_seconds)
+$DIFF -u <(echo "$EXP") <(echo "$OUT")
+echo OK
+
+echo -n "list map matches reset map: "
+EXP=$($NFT list map t m)
+OUT=$($NFT reset map t m)
+$DIFF -u <(echo "$EXP") <(echo "$OUT")
+echo OK
+
+echo -n "reset command respects per-element timeout: "
+VAL=$($NFT get element t s '{ 2.0.0.2 . tcp . 22 }' | expires_minutes)
+[[ $VAL -lt 15 ]] # custom timeout applies
+[[ $VAL -gt 10 ]] # expires was reset
+echo OK
+
+echo -n "remaining elements are reset: "
+OUT=$($NFT list ruleset)
+grep -q '2.0.0.2 . tcp . 22 counter packets 0 bytes 0' <<< "$OUT"
+grep -q '5.6.7.8 quota 100 bytes : 50.6.7.8' <<< "$OUT"
+echo OK
diff --git a/tests/shell/testcases/sets/set_eval_0 b/tests/shell/testcases/sets/set_eval_0
new file mode 100755
index 0000000..82b6d3b
--- /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 0000000..9531c85
--- /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/type_set_symbol b/tests/shell/testcases/sets/type_set_symbol
new file mode 100755
index 0000000..07820b7
--- /dev/null
+++ b/tests/shell/testcases/sets/type_set_symbol
@@ -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/typeof_raw_0 b/tests/shell/testcases/sets/typeof_raw_0
new file mode 100755
index 0000000..66042eb
--- /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 . @nh,32,32 { 1.1.1.1 . 0x14, 2.2.2.2 . 0x1e }
+ ip daddr . @nh,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
new file mode 100755
index 0000000..35c572c
--- /dev/null
+++ b/tests/shell/testcases/sets/typeof_sets_0
@@ -0,0 +1,226 @@
+#!/bin/bash
+
+# support for strings/typeof in named sets.
+# s1 and s2 are identical, they just use different
+# ways for declaration.
+
+set -e
+
+die() {
+ printf '%s\n' "$*"
+ exit 1
+}
+
+INPUT_OSF_SET="
+ set s1 {
+ typeof osf name
+ elements = { \"Linux\" }
+ }
+"
+INPUT_OSF_CHAIN="
+ chain c1 {
+ osf name @s1 accept
+ }
+"
+
+INPUT_SCTP_CHAIN="
+ chain c7 {
+ sctp chunk init num-inbound-streams @s7 accept
+ }
+"
+
+if [ "$NFT_TEST_HAVE_sctp_chunks" = n ] ; then
+ INPUT_SCTP_CHAIN=
+fi
+
+if [ "$NFT_TEST_HAVE_osf" = n ] ; then
+ if [ "$((RANDOM % 2))" -eq 1 ] ; then
+ # Regardless of $NFT_TEST_HAVE_osf, we can define the set.
+ # Randomly do so.
+ INPUT_OSF_SET=
+ fi
+ INPUT_OSF_CHAIN=
+fi
+
+INPUT="table inet t {$INPUT_OSF_SET
+ set s2 {
+ typeof vlan id
+ elements = { 2, 3, 103 }
+ }
+
+ set s3 {
+ typeof meta ibrpvid
+ 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 }
+ }
+$INPUT_OSF_CHAIN
+ 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
+ }
+$INPUT_SCTP_CHAIN
+ 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
+ }
+}"
+
+EXPECTED="table inet t {$INPUT_OSF_SET
+ set s2 {
+ typeof vlan id
+ elements = { 2, 3, 103 }
+ }
+
+ set s3 {
+ typeof meta ibrpvid
+ 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 }
+ }
+$INPUT_OSF_CHAIN
+ 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
+ }
+$INPUT_SCTP_CHAIN
+ 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
+ }
+}"
+
+
+$NFT -f - <<< "$INPUT" || die $'nft command failed to process input:\n'">$INPUT<"
+
+$DIFF -u <($NFT list ruleset) - <<<"$EXPECTED" || die $'diff failed between ruleset and expected data.\nExpected:\n'">$EXPECTED<"
+
+if [ "$NFT_TEST_HAVE_osf" = n ] ; then
+ echo "Partial test due to NFT_TEST_HAVE_osf=n. Skip"
+ exit 77
+fi
+if [ "$NFT_TEST_HAVE_sctp_chunks" = n ] ; then
+ echo "Partial test due to NFT_TEST_HAVE_sctp_chunks=n. Skip"
+ exit 77
+fi
diff --git a/tests/shell/testcases/sets/typeof_sets_1 b/tests/shell/testcases/sets/typeof_sets_1
new file mode 100755
index 0000000..e520270
--- /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 0000000..07820b7
--- /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"