diff options
Diffstat (limited to 'iptables/tests/shell')
31 files changed, 959 insertions, 193 deletions
diff --git a/iptables/tests/shell/run-tests.sh b/iptables/tests/shell/run-tests.sh index d71c1372..65c37adb 100755 --- a/iptables/tests/shell/run-tests.sh +++ b/iptables/tests/shell/run-tests.sh @@ -4,6 +4,21 @@ TESTDIR="./$(dirname $0)/" RETURNCODE_SEPARATOR="_" +usage() { + cat <<EOF +Usage: $(basename $0) [-v|--verbose] [-H|--host] [-V|--valgrind] + [[-l|--legacy]|[-n|--nft]] [testscript ...] + +-v | --verbose Enable verbose mode (do not drop testscript output). +-H | --host Run tests against installed binaries in \$PATH, + not those built in this source tree. +-V | --valgrind Enable leak checking via valgrind. +-l | --legacy Test legacy variant only. Conflicts with --nft. +-n | --nft Test nft variant only. Conflicts with --legacy. +testscript Run only specific test(s). Implies --verbose. +EOF +} + msg_error() { echo "E: $1 ..." >&2 exit 1 @@ -46,6 +61,14 @@ while [ -n "$1" ]; do NFT_ONLY=y shift ;; + -V|--valgrind) + VALGRIND=y + shift + ;; + -h|--help) + usage + exit 0 + ;; *${RETURNCODE_SEPARATOR}+([0-9])) SINGLE+=" $1" VERBOSE=y @@ -67,6 +90,49 @@ else XTABLES_LEGACY_MULTI="xtables-legacy-multi" fi +printscript() { # (cmd, tmpd) + cat <<EOF +#!/bin/bash + +CMD="$1" + +# note: valgrind man page warns about --log-file with --trace-children, the +# last child executed overwrites previous reports unless %p or %q is used. +# Since libtool wrapper calls exec but none of the iptables tools do, this is +# perfect for us as it effectively hides bash-related errors + +valgrind --log-file=$2/valgrind.log --trace-children=yes \ + --leak-check=full --show-leak-kinds=all \$CMD "\$@" +RC=\$? + +# don't keep uninteresting logs +if grep -q 'no leaks are possible' $2/valgrind.log; then + rm $2/valgrind.log +else + mv $2/valgrind.log $2/valgrind_\$\$.log +fi + +# drop logs for failing commands for now +[ \$RC -eq 0 ] || rm $2/valgrind_\$\$.log + +exit \$RC +EOF +} + +if [ "$VALGRIND" == "y" ]; then + tmpd=$(mktemp -d) + msg_info "writing valgrind logs to $tmpd" + chmod a+rx $tmpd + printscript "$XTABLES_NFT_MULTI" "$tmpd" >${tmpd}/xtables-nft-multi + printscript "$XTABLES_LEGACY_MULTI" "$tmpd" >${tmpd}/xtables-legacy-multi + trap "rm ${tmpd}/xtables-*-multi" EXIT + chmod a+x ${tmpd}/xtables-nft-multi ${tmpd}/xtables-legacy-multi + + XTABLES_NFT_MULTI="${tmpd}/xtables-nft-multi" + XTABLES_LEGACY_MULTI="${tmpd}/xtables-legacy-multi" + +fi + find_tests() { if [ ! -z "$SINGLE" ] ; then echo $SINGLE diff --git a/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 b/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 index bf04dc0a..e64e9142 100755 --- a/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 +++ b/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 @@ -4,7 +4,7 @@ set -e #set -x # there is no legacy backend to test -[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } # fill arptables manually diff --git a/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 b/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 index 38d387f3..afd0fcb4 100755 --- a/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 +++ b/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 @@ -3,7 +3,7 @@ set -e # there is no legacy backend to test -[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } # arptables-restore reuses preloaded targets and matches, make sure defaults # apply to consecutive rules using the same target/match as a previous one diff --git a/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 b/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 index 10c5ec33..952cfa78 100755 --- a/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 +++ b/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 @@ -4,7 +4,7 @@ set -e set -x # there is no legacy backend to test -[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } $XT_MULTI arptables -N foo diff --git a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 b/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 index c7f24a38..6f11bd12 100755 --- a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 +++ b/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 @@ -1,86 +1,93 @@ #!/bin/sh +case "$XT_MULTI" in +*xtables-nft-multi) + ;; +*) + echo "skip $XT_MULTI" + exit 0 + ;; +esac + get_entries_count() { # (chain) $XT_MULTI ebtables -L $1 | sed -n 's/.*entries: \([0-9]*\).*/\1/p' } set -x -case "$XT_MULTI" in -*/xtables-nft-multi) - for t in filter nat;do - $XT_MULTI ebtables -t $t -L || exit 1 - $XT_MULTI ebtables -t $t -X || exit 1 - $XT_MULTI ebtables -t $t -F || exit 1 - done - - for t in broute foobar ;do - $XT_MULTI ebtables -t $t -L && - $XT_MULTI ebtables -t $t -X && - $XT_MULTI ebtables -t $t -F - if [ $? -eq 0 ]; then - echo "Expect nonzero return for unsupported table" - exit 1 - fi - done - - - $XT_MULTI ebtables -t filter -N FOO || exit 1 - $XT_MULTI ebtables -t filter -N FOO + +for t in filter nat;do + $XT_MULTI ebtables -t $t -L || exit 1 + $XT_MULTI ebtables -t $t -X || exit 1 + $XT_MULTI ebtables -t $t -F || exit 1 +done + +for t in broute foobar ;do + $XT_MULTI ebtables -t $t -L && + $XT_MULTI ebtables -t $t -X && + $XT_MULTI ebtables -t $t -F if [ $? -eq 0 ]; then - echo "Duplicate chain FOO" - $XT_MULTI ebtables -t filter -L + echo "Expect nonzero return for unsupported table" exit 1 fi +done - entries=$(get_entries_count FOO) - if [ $entries -ne 0 ]; then - echo "Unexpected entries count in empty unreferenced chain (expected 0, have $entries)" - $XT_MULTI ebtables -L - exit 1 - fi - $XT_MULTI ebtables -A FORWARD -j FOO - entries=$(get_entries_count FORWARD) - if [ $entries -ne 1 ]; then - echo "Unexpected entries count in FORWARD chain (expected 1, have $entries)" - $XT_MULTI ebtables -L - exit 1 - fi +$XT_MULTI ebtables -t filter -N FOO || exit 1 +$XT_MULTI ebtables -t filter -N FOO +if [ $? -eq 0 ]; then + echo "Duplicate chain FOO" + $XT_MULTI ebtables -t filter -L + exit 1 +fi - entries=$(get_entries_count FOO) - if [ $entries -ne 0 ]; then - echo "Unexpected entries count in empty referenced chain (expected 0, have $entries)" - $XT_MULTI ebtables -L - exit 1 - fi +entries=$(get_entries_count FOO) +if [ $entries -ne 0 ]; then + echo "Unexpected entries count in empty unreferenced chain (expected 0, have $entries)" + $XT_MULTI ebtables -L + exit 1 +fi - $XT_MULTI ebtables -A FOO -j ACCEPT - entries=$(get_entries_count FOO) - if [ $entries -ne 1 ]; then - echo "Unexpected entries count in non-empty referenced chain (expected 1, have $entries)" - $XT_MULTI ebtables -L - exit 1 - fi +$XT_MULTI ebtables -A FORWARD -j FOO +entries=$(get_entries_count FORWARD) +if [ $entries -ne 1 ]; then + echo "Unexpected entries count in FORWARD chain (expected 1, have $entries)" + $XT_MULTI ebtables -L + exit 1 +fi - $XT_MULTI ebtables -t filter -N BAR || exit 1 - $XT_MULTI ebtables -t filter -N BAZ || exit 1 +entries=$(get_entries_count FOO) +if [ $entries -ne 0 ]; then + echo "Unexpected entries count in empty referenced chain (expected 0, have $entries)" + $XT_MULTI ebtables -L + exit 1 +fi - $XT_MULTI ebtables -t filter -L | grep -q FOO || exit 1 - $XT_MULTI ebtables -t filter -L | grep -q BAR || exit 1 - $XT_MULTI ebtables -t filter -L | grep -q BAZ || exit 1 +$XT_MULTI ebtables -A FOO -j ACCEPT +entries=$(get_entries_count FOO) +if [ $entries -ne 1 ]; then + echo "Unexpected entries count in non-empty referenced chain (expected 1, have $entries)" + $XT_MULTI ebtables -L + exit 1 +fi - $XT_MULTI ebtables -t filter -L BAZ || exit 1 - $XT_MULTI ebtables -t filter -X BAZ || exit 1 - $XT_MULTI ebtables -t filter -L BAZ | grep -q BAZ - if [ $? -eq 0 ]; then - echo "Deleted chain -L BAZ ok, expected failure" - $XT_MULTI ebtables -t filter -L - exit 1 - fi +$XT_MULTI ebtables -t filter -N BAR || exit 1 +$XT_MULTI ebtables -t filter -N BAZ || exit 1 - $XT_MULTI ebtables -t $t -F || exit 0 - ;; -*) - echo "skip $XT_MULTI" - ;; -esac +$XT_MULTI ebtables -t filter -L | grep -q FOO || exit 1 +$XT_MULTI ebtables -t filter -L | grep -q BAR || exit 1 +$XT_MULTI ebtables -t filter -L | grep -q BAZ || exit 1 + +$XT_MULTI ebtables -t filter -L BAZ || exit 1 +$XT_MULTI ebtables -t filter -X BAZ || exit 1 +$XT_MULTI ebtables -t filter -L BAZ | grep -q BAZ +if [ $? -eq 0 ]; then + echo "Deleted chain -L BAZ ok, expected failure" + $XT_MULTI ebtables -t filter -L + exit 1 +fi + +$XT_MULTI ebtables -t filter -E FOO BAZ || exit 1 +$XT_MULTI ebtables -t filter -L | grep -q FOO && exit 1 +$XT_MULTI ebtables -t filter -L | grep -q BAZ || exit 1 + +$XT_MULTI ebtables -t $t -F || exit 0 diff --git a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 b/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 index e18d4655..ccdef19c 100755 --- a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 +++ b/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 @@ -4,7 +4,7 @@ set -e #set -x # there is no legacy backend to test -[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } # fill ebtables manually @@ -70,8 +70,8 @@ DUMP='*filter :INPUT ACCEPT :FORWARD DROP :OUTPUT ACCEPT -:foo ACCEPT :bar RETURN +:foo ACCEPT -A INPUT -p IPv4 -i lo -j ACCEPT -A FORWARD -j foo -A OUTPUT -s Broadcast -j DROP diff --git a/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0 b/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0 index 62d22413..63891c1b 100755 --- a/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0 +++ b/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0 @@ -3,7 +3,7 @@ set -e # there is no legacy backend to test -[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } # ebtables-restore reuses preloaded targets and matches, make sure defaults # apply to consecutive rules using the same target/match as a previous one diff --git a/iptables/tests/shell/testcases/ebtables/0004-save-counters_0 b/iptables/tests/shell/testcases/ebtables/0004-save-counters_0 index 46966f43..d52db900 100755 --- a/iptables/tests/shell/testcases/ebtables/0004-save-counters_0 +++ b/iptables/tests/shell/testcases/ebtables/0004-save-counters_0 @@ -3,7 +3,7 @@ set -e # there is no legacy backend to test -[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } $XT_MULTI ebtables --init-table $XT_MULTI ebtables -A FORWARD -i nodev123 -o nodev432 -j ACCEPT diff --git a/iptables/tests/shell/testcases/ebtables/0005-ifnamechecks_0 b/iptables/tests/shell/testcases/ebtables/0005-ifnamechecks_0 index 2163d364..0b3acfd7 100755 --- a/iptables/tests/shell/testcases/ebtables/0005-ifnamechecks_0 +++ b/iptables/tests/shell/testcases/ebtables/0005-ifnamechecks_0 @@ -3,7 +3,7 @@ set -e # there is no legacy backend to test -[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } EXPECT='*filter :INPUT ACCEPT diff --git a/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 b/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 index 8bf0c2c6..4900554e 100755 --- a/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 +++ b/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 @@ -230,21 +230,8 @@ for table in nat mangle raw filter;do $XT_MULTI iptables-save -t $table | grep -v '^#' >> "$tmpfile" done -case "$XT_MULTI" in -*/xtables-nft-multi) - # nft-multi displays chain names in different order, work around this for now - tmpfile2=$(mktemp) - sort "$tmpfile" > "$tmpfile2" - sort $(dirname "$0")/dumps/ipt-save-completed.txt > "$tmpfile" - diff -u $tmpfile $tmpfile2 - RET=$? - rm -f "$tmpfile2" - ;; -*) - diff -u $tmpfile $(dirname "$0")/dumps/ipt-save-completed.txt - RET=$? - ;; -esac +diff -u $tmpfile $(dirname "$0")/dumps/ipt-save-completed.txt +RET=$? rm -f "$tmpfile" diff --git a/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 b/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 deleted file mode 100755 index f023b791..00000000 --- a/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -# make sure error return codes are as expected useful cases -# (e.g. commands to check ruleset state) - -global_rc=0 - -cmd() { # (rc, cmd, [args ...]) - rc_exp=$1; shift - - $XT_MULTI "$@" - rc=$? - - [ $rc -eq $rc_exp ] || { - echo "---> expected $rc_exp, got $rc for command '$@'" - global_rc=1 - } -} - -# test chain creation -cmd 0 ip6tables -N foo -cmd 1 ip6tables -N foo -# iptables-nft allows this - bug or feature? -#cmd 2 ip6tables -N "invalid name" - -# test rule adding -cmd 0 ip6tables -A INPUT -j ACCEPT -cmd 1 ip6tables -A noexist -j ACCEPT - -# test rule checking -cmd 0 ip6tables -C INPUT -j ACCEPT -cmd 1 ip6tables -C FORWARD -j ACCEPT -cmd 1 ip6tables -C nonexist -j ACCEPT -cmd 2 ip6tables -C INPUT -j foobar -cmd 2 ip6tables -C INPUT -m foobar -j ACCEPT -cmd 3 ip6tables -t foobar -C INPUT -j ACCEPT - -exit $global_rc diff --git a/iptables/tests/shell/testcases/ipt-restore/0001load-specific-table_0 b/iptables/tests/shell/testcases/ipt-restore/0001load-specific-table_0 index ce3bef3a..3f443a98 100755 --- a/iptables/tests/shell/testcases/ipt-restore/0001load-specific-table_0 +++ b/iptables/tests/shell/testcases/ipt-restore/0001load-specific-table_0 @@ -22,7 +22,7 @@ do_simple() table="${2}" dumpfile="$(dirname "${0}")/dumps/${iptables}.dump" - "$XT_MULTI" "${iptables}-restore" --table="${table}" <"${dumpfile}"; rv=$? + "$XT_MULTI" "${iptables}-restore" --table="${table}" "${dumpfile}"; rv=$? if [ "${rv}" -ne 0 ]; then RET=1 diff --git a/iptables/tests/shell/testcases/ipt-restore/0004-restore-race_0 b/iptables/tests/shell/testcases/ipt-restore/0004-restore-race_0 index 96a5e66d..a7fae41d 100755 --- a/iptables/tests/shell/testcases/ipt-restore/0004-restore-race_0 +++ b/iptables/tests/shell/testcases/ipt-restore/0004-restore-race_0 @@ -45,8 +45,7 @@ get_target() make_dummy_rules() { - - echo "*filter" + echo "*${1:-filter}" echo ":INPUT ACCEPT [0:0]" echo ":FORWARD ACCEPT [0:0]" echo ":OUTPUT ACCEPT [0:0]" @@ -74,7 +73,7 @@ make_dummy_rules() tmpfile=$(mktemp) || exit 1 dumpfile=$(mktemp) || exit 1 -make_dummy_rules > $dumpfile +(make_dummy_rules; make_dummy_rules security) > $dumpfile $XT_MULTI iptables-restore -w < $dumpfile LINES1=$(wc -l < $dumpfile) $XT_MULTI iptables-save | grep -v '^#' > $dumpfile @@ -86,7 +85,7 @@ if [ $LINES1 -ne $LINES2 ]; then fi case "$XT_MULTI" in -*/xtables-nft-multi) +*xtables-nft-multi) attempts=$((RANDOM%10)) attempts=$((attempts+1)) ;; diff --git a/iptables/tests/shell/testcases/ipt-restore/0007-flush-noflush_0 b/iptables/tests/shell/testcases/ipt-restore/0007-flush-noflush_0 index 029db223..e705b28c 100755 --- a/iptables/tests/shell/testcases/ipt-restore/0007-flush-noflush_0 +++ b/iptables/tests/shell/testcases/ipt-restore/0007-flush-noflush_0 @@ -18,7 +18,7 @@ EXPECT="*nat :POSTROUTING ACCEPT [0:0] -A POSTROUTING -j ACCEPT COMMIT" -diff -u -Z <(echo -e "$EXPECT" | sort) <($XT_MULTI iptables-save | grep -v '^#' | sort) +diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables-save | grep -v '^#') $XT_MULTI iptables-restore <<EOF *filter @@ -39,4 +39,4 @@ COMMIT :POSTROUTING ACCEPT [0:0] -A POSTROUTING -j ACCEPT COMMIT" -diff -u -Z <(echo -e "$EXPECT" | sort) <($XT_MULTI iptables-save | grep -v '^#' | sort) +diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables-save | grep -v '^#') diff --git a/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 b/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 new file mode 100755 index 00000000..2817376e --- /dev/null +++ b/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 @@ -0,0 +1,11 @@ +#!/bin/sh -e + +# assert input feed from buffer doesn't trip over +# added nul-chars from parsing chain line. + +$XT_MULTI iptables-restore --noflush <<EOF +*filter +:foobar - [0:0] +-A foobar -j ACCEPT +COMMIT +EOF diff --git a/iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0 b/iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0 new file mode 100755 index 00000000..bea1a690 --- /dev/null +++ b/iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0 @@ -0,0 +1,16 @@ +#!/bin/bash -e + +# make sure empty lines won't break --noflush + +cat <<EOF | $XT_MULTI iptables-restore --noflush +# just a comment followed by innocent empty line + +*filter +-A FORWARD -j ACCEPT +COMMIT +EOF + +EXPECT='Chain FORWARD (policy ACCEPT) +target prot opt source destination +ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ' +diff -u <(echo "$EXPECT") <($XT_MULTI iptables -n -L FORWARD) diff --git a/iptables/tests/shell/testcases/ipt-restore/0012-dash-F_0 b/iptables/tests/shell/testcases/ipt-restore/0012-dash-F_0 new file mode 100755 index 00000000..fd82afa1 --- /dev/null +++ b/iptables/tests/shell/testcases/ipt-restore/0012-dash-F_0 @@ -0,0 +1,12 @@ +#!/bin/bash -e + +# make sure -F lines don't cause segfaults + +RULESET='*nat +-F PREROUTING +-A PREROUTING -j ACCEPT +-F PREROUTING +COMMIT' + +echo -e "$RULESET" | $XT_MULTI iptables-restore +echo -e "$RULESET" | $XT_MULTI iptables-restore -n diff --git a/iptables/tests/shell/testcases/ipt-restore/0013-test-mode_0 b/iptables/tests/shell/testcases/ipt-restore/0013-test-mode_0 new file mode 100755 index 00000000..65c3b9a1 --- /dev/null +++ b/iptables/tests/shell/testcases/ipt-restore/0013-test-mode_0 @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +# segfault with --test reported in nfbz#1391 + +printf '%s\nCOMMIT\n' '*nat' '*raw' '*filter' | $XT_MULTI iptables-restore --test diff --git a/iptables/tests/shell/testcases/ipt-restore/0014-verbose-restore_0 b/iptables/tests/shell/testcases/ipt-restore/0014-verbose-restore_0 new file mode 100755 index 00000000..fc8559c5 --- /dev/null +++ b/iptables/tests/shell/testcases/ipt-restore/0014-verbose-restore_0 @@ -0,0 +1,76 @@ +#!/bin/bash + +set -e + +DUMP="*filter +:foo - [0:0] +:bar - [0:0] +-A foo -j ACCEPT +COMMIT +*nat +:natfoo - [0:0] +:natbar - [0:0] +-A natfoo -j ACCEPT +COMMIT +*raw +:rawfoo - [0:0] +COMMIT +*mangle +:manglefoo - [0:0] +COMMIT +*security +:secfoo - [0:0] +COMMIT +" + +$XT_MULTI iptables-restore <<< "$DUMP" +$XT_MULTI ip6tables-restore <<< "$DUMP" + +EXPECT="Flushing chain \`INPUT' +Flushing chain \`FORWARD' +Flushing chain \`OUTPUT' +Flushing chain \`bar' +Flushing chain \`foo' +Deleting chain \`bar' +Deleting chain \`foo' +Flushing chain \`PREROUTING' +Flushing chain \`INPUT' +Flushing chain \`OUTPUT' +Flushing chain \`POSTROUTING' +Flushing chain \`natbar' +Flushing chain \`natfoo' +Deleting chain \`natbar' +Deleting chain \`natfoo' +Flushing chain \`PREROUTING' +Flushing chain \`OUTPUT' +Flushing chain \`rawfoo' +Deleting chain \`rawfoo' +Flushing chain \`PREROUTING' +Flushing chain \`INPUT' +Flushing chain \`FORWARD' +Flushing chain \`OUTPUT' +Flushing chain \`POSTROUTING' +Flushing chain \`manglefoo' +Deleting chain \`manglefoo' +Flushing chain \`INPUT' +Flushing chain \`FORWARD' +Flushing chain \`OUTPUT' +Flushing chain \`secfoo' +Deleting chain \`secfoo'" + +for ipt in iptables-restore ip6tables-restore; do + diff -u -Z <(echo "$EXPECT") <($XT_MULTI $ipt -v <<< "$DUMP") +done + +DUMP="*filter +:baz - [0:0] +-F foo +-X bar +-A foo -j ACCEPT +COMMIT +" + +EXPECT="" +for ipt in iptables-restore ip6tables-restore; do + diff -u -Z <(echo -ne "$EXPECT") <($XT_MULTI $ipt -v --noflush <<< "$DUMP") +done diff --git a/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 b/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 new file mode 100755 index 00000000..aa746ab4 --- /dev/null +++ b/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 @@ -0,0 +1,67 @@ +#!/bin/bash + +# test for iptables-restore --noflush skipping an explicitly requested chain +# flush because the chain did not exist when cache was fetched. In order to +# expect for that chain to appear when refreshing the transaction (due to a +# concurrent ruleset change), the chain flush job has to be present in batch +# job list (although disabled at first). +# The input line requesting chain flush is ':FOO - [0:0]'. RS1 and RS2 contents +# are crafted to cause EBUSY when deleting the BAR* chains if FOO is not +# flushed in the same transaction. + +set -e + +RS="*filter +:INPUT ACCEPT [12024:3123388] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [12840:2144421] +:FOO - [0:0] +:BAR0 - [0:0] +:BAR1 - [0:0] +:BAR2 - [0:0] +:BAR3 - [0:0] +:BAR4 - [0:0] +:BAR5 - [0:0] +:BAR6 - [0:0] +:BAR7 - [0:0] +:BAR8 - [0:0] +:BAR9 - [0:0] +" + +RS1="$RS +-X BAR3 +-X BAR6 +-X BAR9 +-A FOO -s 9.9.0.1/32 -j BAR1 +-A FOO -s 9.9.0.2/32 -j BAR2 +-A FOO -s 9.9.0.4/32 -j BAR4 +-A FOO -s 9.9.0.5/32 -j BAR5 +-A FOO -s 9.9.0.7/32 -j BAR7 +-A FOO -s 9.9.0.8/32 -j BAR8 +COMMIT +" + +RS2="$RS +-X BAR2 +-X BAR5 +-X BAR7 +-A FOO -s 9.9.0.1/32 -j BAR1 +-A FOO -s 9.9.0.3/32 -j BAR3 +-A FOO -s 9.9.0.4/32 -j BAR4 +-A FOO -s 9.9.0.6/32 -j BAR6 +-A FOO -s 9.9.0.8/32 -j BAR8 +-A FOO -s 9.9.0.9/32 -j BAR9 +COMMIT +" + +NORS="*filter +COMMIT +" + +for n in $(seq 1 10); do + $XT_MULTI iptables-restore <<< "$NORS" + $XT_MULTI iptables-restore --noflush -w <<< "$RS1" & + $XT_MULTI iptables-restore --noflush -w <<< "$RS2" & + wait -n + wait -n +done diff --git a/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0 b/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0 new file mode 100755 index 00000000..cf73de32 --- /dev/null +++ b/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0 @@ -0,0 +1,25 @@ +#!/bin/bash + +# A bug in extension registration would leave unsupported older extension +# revisions in pending list and get compatibility checked again for each rule +# using them. With SELinux enabled, the resulting socket() call per rule leads +# to significant slowdown (~50% performance in worst cases). + +set -e + +strace --version >/dev/null || { echo "skip for missing strace"; exit 0; } + +RULESET="$( + echo "*filter" + for ((i = 0; i < 100; i++)); do + echo "-A FORWARD -m conntrack --ctstate NEW" + done + echo "COMMIT" +)" + +cmd="$XT_MULTI iptables-restore" +socketcount=$(strace -esocket $cmd <<< "$RULESET" 2>&1 | wc -l) + +# unpatched iptables-restore would open 111 sockets, +# patched only 12 but keep a certain margin for future changes +[[ $socketcount -lt 20 ]] diff --git a/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt b/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt index bfb6bdda..6e42de78 100644 --- a/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt +++ b/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt @@ -40,8 +40,8 @@ -A OUTPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -o lo -j ACCEPT -A OUTPUT -o wlan0 -j wlanout -A OUTPUT -j block --A WLAN -s 192.168.200.4/32 -m mac --mac-source 00:00:F1:05:A0:E0 -j RETURN --A WLAN -s 192.168.200.9/32 -m mac --mac-source 00:00:F1:05:99:85 -j RETURN +-A WLAN -s 192.168.200.4/32 -m mac --mac-source 00:00:f1:05:a0:e0 -j RETURN +-A WLAN -s 192.168.200.9/32 -m mac --mac-source 00:00:f1:05:99:85 -j RETURN -A WLAN -m limit --limit 12/min -j LOG --log-prefix "UNKNOWN WLAN dropped:" -A WLAN -j DROP -A accept_log -i ppp0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 1/sec -j LOG --log-prefix "TCPConnect on ppp0:" diff --git a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 b/iptables/tests/shell/testcases/iptables/0004-return-codes_0 index ce02e0bc..dcd9dfd3 100755 --- a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 +++ b/iptables/tests/shell/testcases/iptables/0004-return-codes_0 @@ -13,69 +13,84 @@ cmd() { # (rc, msg, cmd, [args ...]) msg_exp="$1"; shift } - msg="$($XT_MULTI "$@" 2>&1 >/dev/null)" - rc=$? + for ipt in iptables ip6tables; do + msg="$($XT_MULTI $ipt "$@" 2>&1 >/dev/null)" + rc=$? - [ $rc -eq $rc_exp ] || { - echo "---> expected return code $rc_exp, got $rc for command '$@'" - global_rc=1 - } + [ $rc -eq $rc_exp ] || { + echo "---> expected return code $rc_exp, got $rc for command '$ipt $@'" + global_rc=1 + } - [ -n "$msg_exp" ] || return - grep -q "$msg_exp" <<< $msg || { - echo "---> expected error message '$msg_exp', got '$msg' for command '$@'" - global_rc=1 - } + [ -n "$msg_exp" ] || continue + msg_exp_full="${ipt}$msg_exp" + grep -q "$msg_exp_full" <<< $msg || { + echo "---> expected error message '$msg_exp_full', got '$msg' for command '$ipt $@'" + global_rc=1 + } + done } -EEXIST_F="File exists." -EEXIST="Chain already exists." -ENOENT="No chain/target/match by that name." -E2BIG_I="Index of insertion too big." -E2BIG_D="Index of deletion too big." -E2BIG_R="Index of replacement too big." -EBADRULE="Bad rule (does a matching rule exist in that chain?)." -ENOTGT="Couldn't load target \`foobar':No such file or directory" -ENOMTH="Couldn't load match \`foobar':No such file or directory" -ENOTBL="can't initialize iptables table \`foobar': Table does not exist" +EEXIST_F=": File exists." +EEXIST=": Chain already exists." +ENOENT=": No chain/target/match by that name." +E2BIG_I=": Index of insertion too big." +E2BIG_D=": Index of deletion too big." +E2BIG_R=": Index of replacement too big." +EBADRULE=": Bad rule (does a matching rule exist in that chain?)." +#ENOTGT=" v[0-9\.]* [^ ]*: Couldn't load target \`foobar':No such file or directory" +ENOMTH=" v[0-9\.]* [^ ]*: Couldn't load match \`foobar':No such file or directory" +ENOTBL=": can't initialize iptables table \`foobar': Table does not exist" # test chain creation -cmd 0 iptables -N foo -cmd 1 "$EEXIST" iptables -N foo +cmd 0 -N foo +cmd 1 "$EEXIST" -N foo # iptables-nft allows this - bug or feature? -#cmd 2 iptables -N "invalid name" +#cmd 2 -N "invalid name" # test chain flushing/zeroing -cmd 0 iptables -F foo -cmd 0 iptables -Z foo -cmd 1 "$ENOENT" iptables -F bar -cmd 1 "$ENOENT" iptables -Z bar +cmd 0 -F foo +cmd 0 -Z foo +cmd 1 "$ENOENT" -F bar +cmd 1 "$ENOENT" -Z bar # test chain rename -cmd 0 iptables -E foo bar -cmd 1 "$EEXIST_F" iptables -E foo bar +cmd 0 -E foo bar +cmd 1 "$EEXIST_F" -E foo bar +cmd 1 "$ENOENT" -E foo bar2 +cmd 0 -N foo2 +cmd 1 "$EEXIST_F" -E foo2 bar # test rule adding -cmd 0 iptables -A INPUT -j ACCEPT -cmd 1 "$ENOENT" iptables -A noexist -j ACCEPT +cmd 0 -A INPUT -j ACCEPT +cmd 1 "$ENOENT" -A noexist -j ACCEPT +# next three differ: +# legacy: Couldn't load target `foobar':No such file or directory +# nft: Chain 'foobar' does not exist +cmd 2 "" -I INPUT -j foobar +cmd 2 "" -R INPUT 1 -j foobar +cmd 2 "" -D INPUT -j foobar +cmd 1 "$EBADRULE" -D INPUT -p tcp --dport 22 -j ACCEPT # test rulenum commands -cmd 1 "$E2BIG_I" iptables -I INPUT 23 -j ACCEPT -cmd 1 "$E2BIG_D" iptables -D INPUT 23 -cmd 1 "$E2BIG_R" iptables -R INPUT 23 -j ACCEPT -cmd 1 "$ENOENT" iptables -I nonexist 23 -j ACCEPT -cmd 1 "$ENOENT" iptables -D nonexist 23 -cmd 1 "$ENOENT" iptables -R nonexist 23 -j ACCEPT +cmd 1 "$E2BIG_I" -I INPUT 23 -j ACCEPT +cmd 1 "$E2BIG_D" -D INPUT 23 +cmd 1 "$E2BIG_R" -R INPUT 23 -j ACCEPT +cmd 1 "$ENOENT" -I nonexist 23 -j ACCEPT +cmd 1 "$ENOENT" -D nonexist 23 +cmd 1 "$ENOENT" -R nonexist 23 -j ACCEPT # test rule checking -cmd 0 iptables -C INPUT -j ACCEPT -cmd 1 "$EBADRULE" iptables -C FORWARD -j ACCEPT -cmd 1 "$BADRULE" iptables -C nonexist -j ACCEPT -cmd 2 "$ENOMTH" iptables -C INPUT -m foobar -j ACCEPT +cmd 0 -C INPUT -j ACCEPT +cmd 1 "$EBADRULE" -C FORWARD -j ACCEPT +cmd 1 "$BADRULE" -C nonexist -j ACCEPT +cmd 2 "$ENOMTH" -C INPUT -m foobar -j ACCEPT # messages of those don't match, but iptables-nft ones are actually nicer. -#cmd 2 "$ENOTGT" iptables -C INPUT -j foobar -#cmd 3 "$ENOTBL" iptables -t foobar -C INPUT -j ACCEPT -cmd 2 "" iptables -C INPUT -j foobar -cmd 3 "" iptables -t foobar -C INPUT -j ACCEPT +# legacy: Couldn't load target `foobar':No such file or directory +# nft: Chain 'foobar' does not exist +cmd 2 "" -C INPUT -j foobar +# legacy: can't initialize ip6tables table `foobar': Table does not exist (do you need to insmod?) +# nft: table 'foobar' does not exist +cmd 3 "" -t foobar -C INPUT -j ACCEPT exit $global_rc diff --git a/iptables/tests/shell/testcases/iptables/0006-46-args_0 b/iptables/tests/shell/testcases/iptables/0006-46-args_0 new file mode 100755 index 00000000..17a0a018 --- /dev/null +++ b/iptables/tests/shell/testcases/iptables/0006-46-args_0 @@ -0,0 +1,88 @@ +#!/bin/bash + +RC=0 + +$XT_MULTI iptables -6 -A FORWARD -j ACCEPT +rc=$? +if [[ $rc -ne 2 ]]; then + echo "'iptables -6' returned $rc instead of 2" + RC=1 +fi + +$XT_MULTI ip6tables -4 -A FORWARD -j ACCEPT +rc=$? +if [[ $rc -ne 2 ]]; then + echo "'ip6tables -4' returned $rc instead of 2" + RC=1 +fi + +RULESET='*filter +-4 -A FORWARD -d 10.0.0.1 -j ACCEPT +-6 -A FORWARD -d fec0:10::1 -j ACCEPT +COMMIT +' +EXPECT4='-P FORWARD ACCEPT +-A FORWARD -d 10.0.0.1/32 -j ACCEPT' +EXPECT6='-P FORWARD ACCEPT +-A FORWARD -d fec0:10::1/128 -j ACCEPT' +EXPECT_EMPTY='-P FORWARD ACCEPT' + +echo "$RULESET" | $XT_MULTI iptables-restore || { + echo "iptables-restore failed!" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT4") <($XT_MULTI iptables -S FORWARD) || { + echo "unexpected iptables ruleset" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI ip6tables -S FORWARD) || { + echo "unexpected non-empty ip6tables ruleset" + RC=1 +} + +$XT_MULTI iptables -F FORWARD + +echo "$RULESET" | $XT_MULTI ip6tables-restore || { + echo "ip6tables-restore failed!" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT6") <($XT_MULTI ip6tables -S FORWARD) || { + echo "unexpected ip6tables ruleset" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI iptables -S FORWARD) || { + echo "unexpected non-empty iptables ruleset" + RC=1 +} + +$XT_MULTI ip6tables -F FORWARD + +$XT_MULTI iptables -4 -A FORWARD -d 10.0.0.1 -j ACCEPT || { + echo "iptables failed!" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT4") <($XT_MULTI iptables -S FORWARD) || { + echo "unexpected iptables ruleset" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI ip6tables -S FORWARD) || { + echo "unexpected non-empty ip6tables ruleset" + RC=1 +} + +$XT_MULTI iptables -F FORWARD + +$XT_MULTI ip6tables -6 -A FORWARD -d fec0:10::1 -j ACCEPT || { + echo "ip6tables failed!" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT6") <($XT_MULTI ip6tables -S FORWARD) || { + echo "unexpected ip6tables ruleset" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI iptables -S FORWARD) || { + echo "unexpected non-empty iptables ruleset" + RC=1 +} + +exit $RC diff --git a/iptables/tests/shell/testcases/nft-only/0001compat_0 b/iptables/tests/shell/testcases/nft-only/0001compat_0 index 4319ea5a..a617c52f 100755 --- a/iptables/tests/shell/testcases/nft-only/0001compat_0 +++ b/iptables/tests/shell/testcases/nft-only/0001compat_0 @@ -5,17 +5,18 @@ # xtables: avoid bogus 'is incompatible' warning case "$XT_MULTI" in -*/xtables-nft-multi) - nft -v >/dev/null || exit 0 - nft 'add table ip nft-test; add chain ip nft-test foobar { type filter hook forward priority 42; }' || exit 1 - nft 'add table ip6 nft-test; add chain ip6 nft-test foobar { type filter hook forward priority 42; }' || exit 1 - - $XT_MULTI iptables -L -t filter || exit 1 - $XT_MULTI ip6tables -L -t filter || exit 1 +*xtables-nft-multi) ;; *) echo skip $XT_MULTI + exit 0 ;; esac +nft -v >/dev/null || exit 0 +nft 'add table ip nft-test; add chain ip nft-test foobar { type filter hook forward priority 42; }' || exit 1 +nft 'add table ip6 nft-test; add chain ip6 nft-test foobar { type filter hook forward priority 42; }' || exit 1 + +$XT_MULTI iptables -L -t filter || exit 1 +$XT_MULTI ip6tables -L -t filter || exit 1 exit 0 diff --git a/iptables/tests/shell/testcases/nft-only/0002invflags_0 b/iptables/tests/shell/testcases/nft-only/0002invflags_0 index 406b6081..fe33874d 100755 --- a/iptables/tests/shell/testcases/nft-only/0002invflags_0 +++ b/iptables/tests/shell/testcases/nft-only/0002invflags_0 @@ -2,7 +2,7 @@ set -e -[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } $XT_MULTI iptables -A INPUT -p tcp --dport 53 ! -s 192.168.0.1 -j ACCEPT $XT_MULTI ip6tables -A INPUT -p tcp --dport 53 ! -s feed:babe::1 -j ACCEPT diff --git a/iptables/tests/shell/testcases/nft-only/0003delete-with-comment_0 b/iptables/tests/shell/testcases/nft-only/0003delete-with-comment_0 index 67af9fd8..ccb009e4 100755 --- a/iptables/tests/shell/testcases/nft-only/0003delete-with-comment_0 +++ b/iptables/tests/shell/testcases/nft-only/0003delete-with-comment_0 @@ -2,7 +2,7 @@ set -e -[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } comment1="foo bar" comment2="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/iptables/tests/shell/testcases/nft-only/0006-policy-override_0 b/iptables/tests/shell/testcases/nft-only/0006-policy-override_0 new file mode 100755 index 00000000..68e2019b --- /dev/null +++ b/iptables/tests/shell/testcases/nft-only/0006-policy-override_0 @@ -0,0 +1,29 @@ +#!/bin/bash + +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } + +# make sure none of the commands invoking nft_xt_builtin_init() override +# non-default chain policies via needless chain add. + +RC=0 + +do_test() { + $XT_MULTI $@ + $XT_MULTI iptables -S | grep -q -- '-P FORWARD DROP' && return + + echo "command '$@' kills chain policies" + $XT_MULTI iptables -P FORWARD DROP + RC=1 +} + +$XT_MULTI iptables -P FORWARD DROP + +do_test iptables -A OUTPUT -j ACCEPT +do_test iptables -F +do_test iptables -N foo +do_test iptables -E foo foo2 +do_test iptables -I OUTPUT -j ACCEPT +do_test iptables -nL +do_test iptables -S + +exit $RC diff --git a/iptables/tests/shell/testcases/nft-only/0007-mid-restore-flush_0 b/iptables/tests/shell/testcases/nft-only/0007-mid-restore-flush_0 new file mode 100755 index 00000000..43880ffb --- /dev/null +++ b/iptables/tests/shell/testcases/nft-only/0007-mid-restore-flush_0 @@ -0,0 +1,23 @@ +#!/bin/bash + +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +nft -v >/dev/null || { echo "skip $XT_MULTI (no nft)"; exit 0; } + +coproc $XT_MULTI iptables-restore --noflush + +cat >&"${COPROC[1]}" <<EOF +*filter +:foo [0:0] +COMMIT +*filter +:foo [0:0] +EOF + +$XT_MULTI iptables-save | grep -q ':foo' +nft flush ruleset + +echo "COMMIT" >&"${COPROC[1]}" +sleep 1 + +[[ -n $COPROC_PID ]] && kill $COPROC_PID +wait diff --git a/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0 b/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0 new file mode 100755 index 00000000..a81e9bad --- /dev/null +++ b/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0 @@ -0,0 +1,29 @@ +#!/bin/bash + +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +set -e + +$XT_MULTI iptables -t raw -P OUTPUT DROP + +# make sure iptables-nft-restore can correctly handle basechain policies when +# they aren't set with --noflush +# +$XT_MULTI iptables-restore --noflush <<EOF +*raw +:OUTPUT - [0:0] +:PREROUTING - [0:0] +:neutron-linuxbri-OUTPUT - [0:0] +:neutron-linuxbri-PREROUTING - [0:0] +-I OUTPUT 1 -j neutron-linuxbri-OUTPUT +-I PREROUTING 1 -j neutron-linuxbri-PREROUTING +-I neutron-linuxbri-PREROUTING 1 -m physdev --physdev-in brq7425e328-56 -j CT --zone 4097 +-I neutron-linuxbri-PREROUTING 2 -i brq7425e328-56 -j CT --zone 4097 +-I neutron-linuxbri-PREROUTING 3 -m physdev --physdev-in tap7f101a28-1d -j CT --zone 4097 + +COMMIT +EOF + +$XT_MULTI iptables-save | grep -C2 raw | grep OUTPUT | grep DROP +if [ $? -ne 0 ]; then + exit 1 +fi diff --git a/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 new file mode 100755 index 00000000..41588a10 --- /dev/null +++ b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 @@ -0,0 +1,346 @@ +#!/bin/bash -x + +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +set -e + +nft flush ruleset + +( + echo "*filter" + for plen in "" 32 30 24 16 8 0; do + addr="10.1.2.3${plen:+/}$plen" + echo "-A OUTPUT -d $addr" + done + echo "COMMIT" +) | $XT_MULTI iptables-restore + +( + echo "*filter" + for plen in "" 128 124 120 112 88 80 64 48 16 8 0; do + addr="feed:c0ff:ee00:0102:0304:0506:0708:090A${plen:+/}$plen" + echo "-A OUTPUT -d $addr" + done + echo "COMMIT" +) | $XT_MULTI ip6tables-restore + +masks=" +ff:ff:ff:ff:ff:ff +ff:ff:ff:ff:ff:f0 +ff:ff:ff:ff:ff:00 +ff:ff:ff:ff:00:00 +ff:ff:ff:00:00:00 +ff:ff:00:00:00:00 +ff:00:00:00:00:00 +" +( + echo "*filter" + for plen in "" 32 30 24 16 8 0; do + addr="10.1.2.3${plen:+/}$plen" + echo "-A OUTPUT -d $addr" + done + for mask in $masks; do + echo "-A OUTPUT --destination-mac fe:ed:00:c0:ff:ee/$mask" + done + echo "COMMIT" +) | $XT_MULTI arptables-restore + +( + echo "*filter" + for mask in $masks; do + echo "-A OUTPUT -d fe:ed:00:c0:ff:ee/$mask" + done + echo "COMMIT" +) | $XT_MULTI ebtables-restore + +EXPECT="ip filter OUTPUT 4 + [ payload load 4b @ network header + 16 => reg 1 ] + [ cmp eq reg 1 0x0302010a ] + [ counter pkts 0 bytes 0 ] + +ip filter OUTPUT 5 4 + [ payload load 4b @ network header + 16 => reg 1 ] + [ cmp eq reg 1 0x0302010a ] + [ counter pkts 0 bytes 0 ] + +ip filter OUTPUT 6 5 + [ payload load 4b @ network header + 16 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0xfcffffff ) ^ 0x00000000 ] + [ cmp eq reg 1 0x0002010a ] + [ counter pkts 0 bytes 0 ] + +ip filter OUTPUT 7 6 + [ payload load 3b @ network header + 16 => reg 1 ] + [ cmp eq reg 1 0x0002010a ] + [ counter pkts 0 bytes 0 ] + +ip filter OUTPUT 8 7 + [ payload load 2b @ network header + 16 => reg 1 ] + [ cmp eq reg 1 0x0000010a ] + [ counter pkts 0 bytes 0 ] + +ip filter OUTPUT 9 8 + [ payload load 1b @ network header + 16 => reg 1 ] + [ cmp eq reg 1 0x0000000a ] + [ counter pkts 0 bytes 0 ] + +ip filter OUTPUT 10 9 + [ counter pkts 0 bytes 0 ] + +ip6 filter OUTPUT 4 + [ payload load 16b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x0a090807 ] + [ counter pkts 0 bytes 0 ] + +ip6 filter OUTPUT 5 4 + [ payload load 16b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x0a090807 ] + [ counter pkts 0 bytes 0 ] + +ip6 filter OUTPUT 6 5 + [ payload load 16b @ network header + 24 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0xffffffff 0xffffffff 0xffffffff 0xf0ffffff ) ^ 0x00000000 0x00000000 0x00000000 0x00000000 ] + [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00090807 ] + [ counter pkts 0 bytes 0 ] + +ip6 filter OUTPUT 7 6 + [ payload load 15b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00090807 ] + [ counter pkts 0 bytes 0 ] + +ip6 filter OUTPUT 8 7 + [ payload load 14b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00000807 ] + [ counter pkts 0 bytes 0 ] + +ip6 filter OUTPUT 9 8 + [ payload load 11b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x00050403 ] + [ counter pkts 0 bytes 0 ] + +ip6 filter OUTPUT 10 9 + [ payload load 10b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x00000403 ] + [ counter pkts 0 bytes 0 ] + +ip6 filter OUTPUT 11 10 + [ payload load 8b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0xffc0edfe 0x020100ee ] + [ counter pkts 0 bytes 0 ] + +ip6 filter OUTPUT 12 11 + [ payload load 6b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0xffc0edfe 0x000000ee ] + [ counter pkts 0 bytes 0 ] + +ip6 filter OUTPUT 13 12 + [ payload load 2b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0x0000edfe ] + [ counter pkts 0 bytes 0 ] + +ip6 filter OUTPUT 14 13 + [ payload load 1b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0x000000fe ] + [ counter pkts 0 bytes 0 ] + +ip6 filter OUTPUT 15 14 + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 3 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 4b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0x0302010a ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 4 3 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 4b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0x0302010a ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 5 4 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 4b @ network header + 24 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0xfcffffff ) ^ 0x00000000 ] + [ cmp eq reg 1 0x0002010a ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 6 5 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 3b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0x0002010a ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 7 6 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 2b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0x0000010a ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 8 7 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 1b @ network header + 24 => reg 1 ] + [ cmp eq reg 1 0x0000000a ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 9 8 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 10 9 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 6b @ network header + 18 => reg 1 ] + [ cmp eq reg 1 0xc000edfe 0x0000eeff ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 11 10 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 6b @ network header + 18 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0xffffffff 0x0000f0ff ) ^ 0x00000000 0x00000000 ] + [ cmp eq reg 1 0xc000edfe 0x0000e0ff ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 12 11 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 5b @ network header + 18 => reg 1 ] + [ cmp eq reg 1 0xc000edfe 0x000000ff ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 13 12 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 4b @ network header + 18 => reg 1 ] + [ cmp eq reg 1 0xc000edfe ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 14 13 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 3b @ network header + 18 => reg 1 ] + [ cmp eq reg 1 0x0000edfe ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 15 14 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 2b @ network header + 18 => reg 1 ] + [ cmp eq reg 1 0x0000edfe ] + [ counter pkts 0 bytes 0 ] + +arp filter OUTPUT 16 15 + [ payload load 2b @ network header + 0 => reg 1 ] + [ cmp eq reg 1 0x00000100 ] + [ payload load 1b @ network header + 4 => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 1b @ network header + 18 => reg 1 ] + [ cmp eq reg 1 0x000000fe ] + [ counter pkts 0 bytes 0 ] + +bridge filter OUTPUT 4 + [ payload load 6b @ link header + 0 => reg 1 ] + [ cmp eq reg 1 0xc000edfe 0x0000eeff ] + [ counter pkts 0 bytes 0 ] + +bridge filter OUTPUT 5 4 + [ payload load 6b @ link header + 0 => reg 1 ] + [ bitwise reg 1 = ( reg 1 & 0xffffffff 0x0000f0ff ) ^ 0x00000000 0x00000000 ] + [ cmp eq reg 1 0xc000edfe 0x0000e0ff ] + [ counter pkts 0 bytes 0 ] + +bridge filter OUTPUT 6 5 + [ payload load 5b @ link header + 0 => reg 1 ] + [ cmp eq reg 1 0xc000edfe 0x000000ff ] + [ counter pkts 0 bytes 0 ] + +bridge filter OUTPUT 7 6 + [ payload load 4b @ link header + 0 => reg 1 ] + [ cmp eq reg 1 0xc000edfe ] + [ counter pkts 0 bytes 0 ] + +bridge filter OUTPUT 8 7 + [ payload load 3b @ link header + 0 => reg 1 ] + [ cmp eq reg 1 0x0000edfe ] + [ counter pkts 0 bytes 0 ] + +bridge filter OUTPUT 9 8 + [ payload load 2b @ link header + 0 => reg 1 ] + [ cmp eq reg 1 0x0000edfe ] + [ counter pkts 0 bytes 0 ] + +bridge filter OUTPUT 10 9 + [ payload load 1b @ link header + 0 => reg 1 ] + [ cmp eq reg 1 0x000000fe ] + [ counter pkts 0 bytes 0 ] +" + +# print nothing but: +# - lines with bytecode (starting with ' [') +# - empty lines (so printed diff is not a complete mess) +filter() { + awk '/^( \[|$)/{print}' +} + +diff -u -Z <(filter <<< "$EXPECT") <(nft --debug=netlink list ruleset | filter) |