projects/linux·blob master · refs

168 lines · 3.2 KiB

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
23ALL_TESTS="
24 test_ip_set
25"
26
27source lib.sh
28
29DEBUG=0
30
31VETH_HOST=vethtst.h
32VETH_PHY=vethtst.p
33
34NS_COUNT=32
35IP_ITERATIONS=1024
36IPSET_TIMEOUT="60s"
37
38ns_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
48test_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
72test_ip_cleanup_env() {
73 ns_run "$HST_NS" ip link del $VETH_HOST
74 cleanup_all_ns
75}
76
77exit_error() {
78 echo "$1"
79 exit $ksft_fail
80}
81
82rnd() {
83 echo $(( RANDOM % 32 + 16 ))
84}
85
86test_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
102test_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
152if [[ "$1" == "-d" ]]; then
153 DEBUG=1
154 shift
155fi
156
157if [[ "$1" == "-t" ]]; then
158 shift
159 TESTS="$*"
160fi
161
162if [[ "$1" == "test_ip_set_thread" ]]; then
163 test_ip_set_thread
164else
165 require_command ip
166
167 tests_run
168fi