blob: 354ca7ce8584d8ada17839ad0bde817ce0ef7727 [file] [log] [blame] [edit]
#!/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