Skip to content

Commit 8becfe1

Browse files
Dmitry Skorodumovkuba-moo
authored andcommitted
selftests: net: simple selftest for ipvtap
This is a simple ipvtap test to test handling IP-address add/remove on ipvlan interface. It creates a veth-interface and then creates several network-namespace with ipvlan0 interface in it linked to veth. Then it starts to add/remove addresses on ipvlan0 interfaces in several threads. At finish, it checks that there is no duplicated addresses. Signed-off-by: Dmitry Skorodumov <skorodumov.dmitry@huawei.com> Link: https://patch.msgid.link/20260112142417.4039566-3-skorodumov.dmitry@huawei.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent d3ba321 commit 8becfe1

3 files changed

Lines changed: 171 additions & 0 deletions

File tree

tools/testing/selftests/net/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ TEST_PROGS := \
4848
ipv6_flowlabel.sh \
4949
ipv6_force_forwarding.sh \
5050
ipv6_route_update_soft_lockup.sh \
51+
ipvtap_test.sh \
5152
l2_tos_ttl_inherit.sh \
5253
l2tp.sh \
5354
link_netns.py \

tools/testing/selftests/net/config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ CONFIG_IPV6_SEG6_LWTUNNEL=y
4848
CONFIG_IPV6_SIT=y
4949
CONFIG_IPV6_VTI=y
5050
CONFIG_IPVLAN=m
51+
CONFIG_IPVTAP=m
5152
CONFIG_KALLSYMS=y
5253
CONFIG_L2TP=m
5354
CONFIG_L2TP_ETH=m
@@ -116,6 +117,7 @@ CONFIG_PROC_SYSCTL=y
116117
CONFIG_PSAMPLE=m
117118
CONFIG_RPS=y
118119
CONFIG_SYSFS=y
120+
CONFIG_TAP=m
119121
CONFIG_TCP_MD5SIG=y
120122
CONFIG_TEST_BLACKHOLE_DEV=m
121123
CONFIG_TEST_BPF=m
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: GPL-2.0
3+
#
4+
# Simple tests for ipvtap
5+
6+
7+
#
8+
# The testing environment looks this way:
9+
#
10+
# |------HNS-------| |------PHY-------|
11+
# | veth<----------------->veth |
12+
# |------|--|------| |----------------|
13+
# | |
14+
# | | |-----TST0-------|
15+
# | |------------|----ipvlan |
16+
# | |----------------|
17+
# |
18+
# | |-----TST1-------|
19+
# |---------------|----ipvlan |
20+
# |----------------|
21+
#
22+
23+
ALL_TESTS="
24+
test_ip_set
25+
"
26+
27+
source lib.sh
28+
29+
DEBUG=0
30+
31+
VETH_HOST=vethtst.h
32+
VETH_PHY=vethtst.p
33+
34+
NS_COUNT=32
35+
IP_ITERATIONS=1024
36+
IPSET_TIMEOUT="60s"
37+
38+
ns_run() {
39+
ns=$1
40+
shift
41+
if [[ "$ns" == "global" ]]; then
42+
"$@" >/dev/null
43+
else
44+
ip netns exec "$ns" "$@" >/dev/null
45+
fi
46+
}
47+
48+
test_ip_setup_env() {
49+
setup_ns NS_PHY
50+
setup_ns HST_NS
51+
52+
# setup simulated other-host (phy) and host itself
53+
ns_run "$HST_NS" ip link add $VETH_HOST type veth peer name $VETH_PHY \
54+
netns "$NS_PHY" >/dev/null
55+
ns_run "$HST_NS" ip link set $VETH_HOST up
56+
ns_run "$NS_PHY" ip link set $VETH_PHY up
57+
58+
for ((i=0; i<NS_COUNT; i++)); do
59+
setup_ns ipvlan_ns_$i
60+
ns="ipvlan_ns_$i"
61+
if [ "$DEBUG" = "1" ]; then
62+
echo "created NS ${!ns}"
63+
fi
64+
if ! ns_run "$HST_NS" ip link add netns ${!ns} ipvlan0 \
65+
link $VETH_HOST \
66+
type ipvtap mode l2 bridge; then
67+
exit_error "FAIL: Failed to configure ipvlan link."
68+
fi
69+
done
70+
}
71+
72+
test_ip_cleanup_env() {
73+
ns_run "$HST_NS" ip link del $VETH_HOST
74+
cleanup_all_ns
75+
}
76+
77+
exit_error() {
78+
echo "$1"
79+
exit $ksft_fail
80+
}
81+
82+
rnd() {
83+
echo $(( RANDOM % 32 + 16 ))
84+
}
85+
86+
test_ip_set_thread() {
87+
# Here we are trying to create some IP conflicts between namespaces.
88+
# If just add/remove IP, nothing interesting will happen.
89+
# But if add random IP and then remove random IP,
90+
# eventually conflicts start to apear.
91+
ip link set ipvlan0 up
92+
for ((i=0; i<IP_ITERATIONS; i++)); do
93+
v=$(rnd)
94+
ip a a "172.25.0.$v/24" dev ipvlan0 2>/dev/null
95+
ip a a "fc00::$v/64" dev ipvlan0 2>/dev/null
96+
v=$(rnd)
97+
ip a d "172.25.0.$v/24" dev ipvlan0 2>/dev/null
98+
ip a d "fc00::$v/64" dev ipvlan0 2>/dev/null
99+
done
100+
}
101+
102+
test_ip_set() {
103+
RET=0
104+
105+
trap test_ip_cleanup_env EXIT
106+
107+
test_ip_setup_env
108+
109+
declare -A ns_pids
110+
for ((i=0; i<NS_COUNT; i++)); do
111+
ns="ipvlan_ns_$i"
112+
ns_run ${!ns} timeout "$IPSET_TIMEOUT" \
113+
bash -c "$0 test_ip_set_thread"&
114+
ns_pids[$i]=$!
115+
done
116+
117+
for ((i=0; i<NS_COUNT; i++)); do
118+
wait "${ns_pids[$i]}"
119+
done
120+
121+
declare -A all_ips
122+
for ((i=0; i<NS_COUNT; i++)); do
123+
ns="ipvlan_ns_$i"
124+
ip_output=$(ip netns exec ${!ns} ip a l dev ipvlan0 | grep inet)
125+
while IFS= read -r nsip_out; do
126+
if [[ -z $nsip_out ]]; then
127+
continue;
128+
fi
129+
nsip=$(awk '{print $2}' <<< "$nsip_out")
130+
if [[ -v all_ips[$nsip] ]]; then
131+
RET=$ksft_fail
132+
log_test "conflict for $nsip"
133+
return "$RET"
134+
else
135+
all_ips[$nsip]=$i
136+
fi
137+
done <<< "$ip_output"
138+
done
139+
140+
if [ "$DEBUG" = "1" ]; then
141+
for key in "${!all_ips[@]}"; do
142+
echo "$key: ${all_ips[$key]}"
143+
done
144+
fi
145+
146+
trap - EXIT
147+
test_ip_cleanup_env
148+
149+
log_test "test multithreaded ip set"
150+
}
151+
152+
if [[ "$1" == "-d" ]]; then
153+
DEBUG=1
154+
shift
155+
fi
156+
157+
if [[ "$1" == "-t" ]]; then
158+
shift
159+
TESTS="$*"
160+
fi
161+
162+
if [[ "$1" == "test_ip_set_thread" ]]; then
163+
test_ip_set_thread
164+
else
165+
require_command ip
166+
167+
tests_run
168+
fi

0 commit comments

Comments
 (0)