Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/drivers/net/team/teamd_activebackup.sh
171056 views
1
#!/bin/bash
2
# SPDX-License-Identifier: GPL-2.0
3
4
# These tests verify that teamd is able to enable and disable ports via the
5
# active backup runner.
6
#
7
# Topology:
8
#
9
# +-------------------------+ NS1
10
# | test_team1 |
11
# | + |
12
# | eth0 | eth1 |
13
# | +---+---+ |
14
# | | | |
15
# +-------------------------+
16
# | |
17
# +-------------------------+ NS2
18
# | | | |
19
# | +-------+ |
20
# | eth0 | eth1 |
21
# | + |
22
# | test_team2 |
23
# +-------------------------+
24
25
export ALL_TESTS="teamd_test_active_backup"
26
27
test_dir="$(dirname "$0")"
28
# shellcheck disable=SC1091
29
source "${test_dir}/../../../net/lib.sh"
30
# shellcheck disable=SC1091
31
source "${test_dir}/team_lib.sh"
32
33
NS1=""
34
NS2=""
35
export NODAD="nodad"
36
PREFIX_LENGTH="64"
37
NS1_IP="fd00::1"
38
NS2_IP="fd00::2"
39
NS1_IP4="192.168.0.1"
40
NS2_IP4="192.168.0.2"
41
NS1_TEAMD_CONF=""
42
NS2_TEAMD_CONF=""
43
NS1_TEAMD_PID=""
44
NS2_TEAMD_PID=""
45
46
while getopts "4" opt; do
47
case $opt in
48
4)
49
echo "IPv4 mode selected."
50
export NODAD=
51
PREFIX_LENGTH="24"
52
NS1_IP="${NS1_IP4}"
53
NS2_IP="${NS2_IP4}"
54
;;
55
\?)
56
echo "Invalid option: -${OPTARG}" >&2
57
exit 1
58
;;
59
esac
60
done
61
62
teamd_config_create()
63
{
64
local runner=$1
65
local dev=$2
66
local conf
67
68
conf=$(mktemp)
69
70
cat > "${conf}" <<-EOF
71
{
72
"device": "${dev}",
73
"runner": {"name": "${runner}"},
74
"ports": {
75
"eth0": {},
76
"eth1": {}
77
}
78
}
79
EOF
80
echo "${conf}"
81
}
82
83
# Create the network namespaces, veth pair, and team devices in the specified
84
# runner.
85
# Globals:
86
# RET - Used by test infra, set by `check_err` functions.
87
# Arguments:
88
# runner - The Teamd runner to use for the Team devices.
89
environment_create()
90
{
91
local runner=$1
92
93
echo "Setting up two-link aggregation for runner ${runner}"
94
echo "Teamd version is: $(teamd --version)"
95
trap environment_destroy EXIT
96
97
setup_ns ns1 ns2
98
NS1="${NS_LIST[0]}"
99
NS2="${NS_LIST[1]}"
100
101
for link in $(seq 0 1); do
102
ip -n "${NS1}" link add "eth${link}" type veth peer name \
103
"eth${link}" netns "${NS2}"
104
check_err $? "Failed to create veth pair"
105
done
106
107
NS1_TEAMD_CONF=$(teamd_config_create "${runner}" "test_team1")
108
NS2_TEAMD_CONF=$(teamd_config_create "${runner}" "test_team2")
109
echo "Conf files are ${NS1_TEAMD_CONF} and ${NS2_TEAMD_CONF}"
110
111
ip netns exec "${NS1}" teamd -d -f "${NS1_TEAMD_CONF}"
112
check_err $? "Failed to create team device in ${NS1}"
113
NS1_TEAMD_PID=$(pgrep -f "teamd -d -f ${NS1_TEAMD_CONF}")
114
115
ip netns exec "${NS2}" teamd -d -f "${NS2_TEAMD_CONF}"
116
check_err $? "Failed to create team device in ${NS2}"
117
NS2_TEAMD_PID=$(pgrep -f "teamd -d -f ${NS2_TEAMD_CONF}")
118
119
echo "Created team devices"
120
echo "Teamd PIDs are ${NS1_TEAMD_PID} and ${NS2_TEAMD_PID}"
121
122
ip -n "${NS1}" link set test_team1 up
123
check_err $? "Failed to set test_team1 up in ${NS1}"
124
ip -n "${NS2}" link set test_team2 up
125
check_err $? "Failed to set test_team2 up in ${NS2}"
126
127
ip -n "${NS1}" addr add "${NS1_IP}/${PREFIX_LENGTH}" "${NODAD}" dev \
128
test_team1
129
check_err $? "Failed to add address to team device in ${NS1}"
130
ip -n "${NS2}" addr add "${NS2_IP}/${PREFIX_LENGTH}" "${NODAD}" dev \
131
test_team2
132
check_err $? "Failed to add address to team device in ${NS2}"
133
134
slowwait 2 timeout 0.5 ip netns exec "${NS1}" ping -W 1 -c 1 "${NS2_IP}"
135
}
136
137
# Tear down the environment: kill teamd and delete network namespaces.
138
environment_destroy()
139
{
140
echo "Tearing down two-link aggregation"
141
142
rm "${NS1_TEAMD_CONF}"
143
rm "${NS2_TEAMD_CONF}"
144
145
# First, try graceful teamd teardown.
146
ip netns exec "${NS1}" teamd -k -t test_team1
147
ip netns exec "${NS2}" teamd -k -t test_team2
148
149
# If teamd can't be killed gracefully, then sigkill.
150
if kill -0 "${NS1_TEAMD_PID}" 2>/dev/null; then
151
echo "Sending sigkill to teamd for test_team1"
152
kill -9 "${NS1_TEAMD_PID}"
153
rm -f /var/run/teamd/test_team1.{pid,sock}
154
fi
155
if kill -0 "${NS2_TEAMD_PID}" 2>/dev/null; then
156
echo "Sending sigkill to teamd for test_team2"
157
kill -9 "${NS2_TEAMD_PID}"
158
rm -f /var/run/teamd/test_team2.{pid,sock}
159
fi
160
cleanup_all_ns
161
}
162
163
# Change the active port for an active-backup mode team.
164
# Arguments:
165
# namespace - The network namespace that the team is in.
166
# team - The name of the team.
167
# active_port - The port to make active.
168
set_active_port()
169
{
170
local namespace=$1
171
local team=$2
172
local active_port=$3
173
174
ip netns exec "${namespace}" teamdctl "${team}" state item set \
175
runner.active_port "${active_port}"
176
slowwait 2 bash -c "ip netns exec ${namespace} teamdctl ${team} state \
177
item get runner.active_port | grep -q ${active_port}"
178
}
179
180
# Wait for an interface to stop receiving traffic. If it keeps receiving traffic
181
# for the duration of the timeout, then return an error.
182
# Arguments:
183
# - namespace - The network namespace that the interface is in.
184
# - interface - The name of the interface.
185
wait_to_stop_receiving()
186
{
187
local namespace=$1
188
local interface=$2
189
190
echo "Waiting for ${interface} in ${namespace} to stop receiving"
191
slowwait 10 check_no_traffic "${interface}" "${NS2_IP}" \
192
"${namespace}"
193
}
194
195
# Test that active backup runner can change active ports.
196
# Globals:
197
# RET - Used by test infra, set by `check_err` functions.
198
teamd_test_active_backup()
199
{
200
export RET=0
201
202
start_listening_and_sending
203
204
### Scenario 1: Don't manually set active port, just make sure team
205
# works.
206
save_tcpdump_outputs "${NS2}" test_team2
207
did_interface_receive test_team2 "${NS2_IP}"
208
check_err $? "Traffic did not reach team interface in NS2."
209
clear_tcpdump_outputs test_team2
210
211
### Scenario 2: Choose active port.
212
set_active_port "${NS1}" test_team1 eth1
213
set_active_port "${NS2}" test_team2 eth1
214
215
wait_to_stop_receiving "${NS2}" eth0
216
save_tcpdump_outputs "${NS2}" eth0 eth1
217
did_interface_receive eth0 "${NS2_IP}"
218
check_fail $? "eth0 IS transmitting when inactive"
219
did_interface_receive eth1 "${NS2_IP}"
220
check_err $? "eth1 not transmitting when active"
221
clear_tcpdump_outputs eth0 eth1
222
223
### Scenario 3: Change active port.
224
set_active_port "${NS1}" test_team1 eth0
225
set_active_port "${NS2}" test_team2 eth0
226
227
wait_to_stop_receiving "${NS2}" eth1
228
save_tcpdump_outputs "${NS2}" eth0 eth1
229
did_interface_receive eth0 "${NS2_IP}"
230
check_err $? "eth0 not transmitting when active"
231
did_interface_receive eth1 "${NS2_IP}"
232
check_fail $? "eth1 IS transmitting when inactive"
233
clear_tcpdump_outputs eth0 eth1
234
235
log_test "teamd active backup runner test"
236
237
stop_sending_and_listening
238
}
239
240
require_command teamd
241
require_command teamdctl
242
require_command iperf3
243
require_command tcpdump
244
environment_create activebackup
245
tests_run
246
exit "${EXIT_STATUS}"
247
248