diff options
Diffstat (limited to 'tools/testing/selftests/net/ipvtap_test.sh')
| -rwxr-xr-x | tools/testing/selftests/net/ipvtap_test.sh | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/tools/testing/selftests/net/ipvtap_test.sh b/tools/testing/selftests/net/ipvtap_test.sh new file mode 100755 index 000000000000..354ca7ce8584 --- /dev/null +++ b/tools/testing/selftests/net/ipvtap_test.sh @@ -0,0 +1,168 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Simple tests for ipvtap + + +# +# The testing environment looks this way: +# +# |------HNS-------| |------PHY-------| +# | veth<----------------->veth | +# |------|--|------| |----------------| +# | | +# | | |-----TST0-------| +# | |------------|----ipvlan | +# | |----------------| +# | +# | |-----TST1-------| +# |---------------|----ipvlan | +# |----------------| +# + +ALL_TESTS=" + test_ip_set +" + +source lib.sh + +DEBUG=0 + +VETH_HOST=vethtst.h +VETH_PHY=vethtst.p + +NS_COUNT=32 +IP_ITERATIONS=1024 +IPSET_TIMEOUT="60s" + +ns_run() { + ns=$1 + shift + if [[ "$ns" == "global" ]]; then + "$@" >/dev/null + else + ip netns exec "$ns" "$@" >/dev/null + fi +} + +test_ip_setup_env() { + setup_ns NS_PHY + setup_ns HST_NS + + # setup simulated other-host (phy) and host itself + ns_run "$HST_NS" ip link add $VETH_HOST type veth peer name $VETH_PHY \ + netns "$NS_PHY" >/dev/null + ns_run "$HST_NS" ip link set $VETH_HOST up + ns_run "$NS_PHY" ip link set $VETH_PHY up + + for ((i=0; i<NS_COUNT; i++)); do + setup_ns ipvlan_ns_$i + ns="ipvlan_ns_$i" + if [ "$DEBUG" = "1" ]; then + echo "created NS ${!ns}" + fi + if ! ns_run "$HST_NS" ip link add netns ${!ns} ipvlan0 \ + link $VETH_HOST \ + type ipvtap mode l2 bridge; then + exit_error "FAIL: Failed to configure ipvlan link." + fi + done +} + +test_ip_cleanup_env() { + ns_run "$HST_NS" ip link del $VETH_HOST + cleanup_all_ns +} + +exit_error() { + echo "$1" + exit $ksft_fail +} + +rnd() { + echo $(( RANDOM % 32 + 16 )) +} + +test_ip_set_thread() { + # Here we are trying to create some IP conflicts between namespaces. + # If just add/remove IP, nothing interesting will happen. + # But if add random IP and then remove random IP, + # eventually conflicts start to apear. + ip link set ipvlan0 up + for ((i=0; i<IP_ITERATIONS; i++)); do + v=$(rnd) + ip a a "172.25.0.$v/24" dev ipvlan0 2>/dev/null + ip a a "fc00::$v/64" dev ipvlan0 2>/dev/null + v=$(rnd) + ip a d "172.25.0.$v/24" dev ipvlan0 2>/dev/null + ip a d "fc00::$v/64" dev ipvlan0 2>/dev/null + done +} + +test_ip_set() { + RET=0 + + trap test_ip_cleanup_env EXIT + + test_ip_setup_env + + declare -A ns_pids + for ((i=0; i<NS_COUNT; i++)); do + ns="ipvlan_ns_$i" + ns_run ${!ns} timeout "$IPSET_TIMEOUT" \ + bash -c "$0 test_ip_set_thread"& + ns_pids[$i]=$! + done + + for ((i=0; i<NS_COUNT; i++)); do + wait "${ns_pids[$i]}" + done + + declare -A all_ips + for ((i=0; i<NS_COUNT; i++)); do + ns="ipvlan_ns_$i" + ip_output=$(ip netns exec ${!ns} ip a l dev ipvlan0 | grep inet) + while IFS= read -r nsip_out; do + if [[ -z $nsip_out ]]; then + continue; + fi + nsip=$(awk '{print $2}' <<< "$nsip_out") + if [[ -v all_ips[$nsip] ]]; then + RET=$ksft_fail + log_test "conflict for $nsip" + return "$RET" + else + all_ips[$nsip]=$i + fi + done <<< "$ip_output" + done + + if [ "$DEBUG" = "1" ]; then + for key in "${!all_ips[@]}"; do + echo "$key: ${all_ips[$key]}" + done + fi + + trap - EXIT + test_ip_cleanup_env + + log_test "test multithreaded ip set" +} + +if [[ "$1" == "-d" ]]; then + DEBUG=1 + shift +fi + +if [[ "$1" == "-t" ]]; then + shift + TESTS="$*" +fi + +if [[ "$1" == "test_ip_set_thread" ]]; then + test_ip_set_thread +else + require_command ip + + tests_run +fi |
