diff options
Diffstat (limited to 'tests/shell/testcases/sets/0044interval_overlap_0')
-rwxr-xr-x | tests/shell/testcases/sets/0044interval_overlap_0 | 166 |
1 files changed, 166 insertions, 0 deletions
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 |