xref: /linux/tools/testing/selftests/drivers/net/team/decoupled_enablement.sh (revision 91a4855d6c03e770e42f17c798a36a3c46e63de2)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# These tests verify the decoupled RX and TX enablement of team driver member
5# interfaces.
6#
7# Topology
8#
9#  +---------------------+  NS1
10#  |      test_team1     |
11#  |          |          |
12#  |        eth0         |
13#  |          |          |
14#  |          |          |
15#  +---------------------+
16#             |
17#  +---------------------+  NS2
18#  |          |          |
19#  |          |          |
20#  |        eth0         |
21#  |          |          |
22#  |      test_team2     |
23#  +---------------------+
24
25export ALL_TESTS="
26	team_test_tx_enablement
27	team_test_rx_enablement
28"
29
30test_dir="$(dirname "$0")"
31# shellcheck disable=SC1091
32source "${test_dir}/../../../net/lib.sh"
33# shellcheck disable=SC1091
34source "${test_dir}/team_lib.sh"
35
36NS1=""
37NS2=""
38export NODAD="nodad"
39PREFIX_LENGTH="64"
40NS1_IP="fd00::1"
41NS2_IP="fd00::2"
42NS1_IP4="192.168.0.1"
43NS2_IP4="192.168.0.2"
44MEMBERS=("eth0")
45PING_COUNT=5
46PING_TIMEOUT_S=1
47PING_INTERVAL=0.1
48
49while getopts "4" opt; do
50	case $opt in
51		4)
52			echo "IPv4 mode selected."
53			export NODAD=
54			PREFIX_LENGTH="24"
55			NS1_IP="${NS1_IP4}"
56			NS2_IP="${NS2_IP4}"
57			;;
58		\?)
59			echo "Invalid option: -$OPTARG" >&2
60			exit 1
61			;;
62	esac
63done
64
65# This has to be sourced after opts are gathered...
66export REQUIRE_MZ=no
67export NUM_NETIFS=0
68# shellcheck disable=SC1091
69source "${test_dir}/../../../net/forwarding/lib.sh"
70
71# Create the network namespaces, veth pair, and team devices in the specified
72# mode.
73# Globals:
74#   RET - Used by test infra, set by `check_err` functions.
75# Arguments:
76#   mode - The team driver mode to use for the team devices.
77environment_create()
78{
79	trap cleanup_all_ns EXIT
80	setup_ns ns1 ns2
81	NS1="${NS_LIST[0]}"
82	NS2="${NS_LIST[1]}"
83
84	# Create the interfaces.
85	ip -n "${NS1}" link add eth0 type veth peer name eth0 netns "${NS2}"
86	ip -n "${NS1}" link add test_team1 type team
87	ip -n "${NS2}" link add test_team2 type team
88
89	# Set up the receiving network namespace's team interface.
90	setup_team "${NS2}" test_team2 roundrobin "${NS2_IP}" \
91			"${PREFIX_LENGTH}" "${MEMBERS[@]}"
92}
93
94# Set a particular option value for team or team port.
95# Arguments:
96#   namespace - The namespace name that has the team.
97#   option_name - The option name to set.
98#   option_value - The value to set the option to.
99#   team_name - The name of team to set the option for.
100#   member_name - The (optional) optional name of the member port.
101set_option_value()
102{
103	local namespace="$1"
104	local option_name="$2"
105	local option_value="$3"
106	local team_name="$4"
107	local member_name="$5"
108	local port_flag="--port=${member_name}"
109
110	ip netns exec "${namespace}" teamnl "${team_name}" setoption \
111			"${option_name}" "${option_value}" "${port_flag}"
112	return $?
113}
114
115# Send some pings and return the ping command return value.
116try_ping()
117{
118	ip netns exec "${NS1}" ping -i "${PING_INTERVAL}" -c "${PING_COUNT}" \
119			"${NS2_IP}" -W "${PING_TIMEOUT_S}"
120}
121
122# Checks tcpdump output from net/forwarding lib, and checks if there are any
123# ICMP(4 or 6) packets.
124# Arguments:
125#   interface - The interface name to search for.
126#   ip_address - The destination IP address (4 or 6) to search for.
127did_interface_receive_icmp()
128{
129	local interface="$1"
130	local ip_address="$2"
131	local packet_count
132
133	packet_count=$(tcpdump_show "$interface" | grep -c \
134			"> ${ip_address}: ICMP")
135	echo "Packet count for ${interface} was ${packet_count}"
136
137	if [[ "$packet_count" -gt 0 ]]; then
138		true
139	else
140		false
141	fi
142}
143
144# Test JUST tx enablement with a given mode.
145# Globals:
146#   RET - Used by test infra, set by `check_err` functions.
147# Arguments:
148#   mode - The mode to set the team interfaces to.
149team_test_mode_tx_enablement()
150{
151	local mode="$1"
152	export RET=0
153
154	# Set up the sender team with the correct mode.
155	setup_team "${NS1}" test_team1 "${mode}" "${NS1_IP}" \
156			"${PREFIX_LENGTH}" "${MEMBERS[@]}"
157	check_err $? "Failed to set up sender team"
158
159	### Scenario 1: Member interface initially enabled.
160	# Expect ping to pass
161	try_ping
162	check_err $? "Ping failed when TX enabled"
163
164	### Scenario 2: One tx-side interface disabled.
165	# Expect ping to fail.
166	set_option_value "${NS1}" tx_enabled false test_team1 eth0
167	check_err $? "Failed to disable TX"
168	tcpdump_start eth0 "${NS2}"
169	try_ping
170	check_fail $? "Ping succeeded when TX disabled"
171	tcpdump_stop eth0
172	# Expect no packets to be transmitted, since TX is disabled.
173	did_interface_receive_icmp eth0 "${NS2_IP}"
174	check_fail $? "eth0 IS transmitting when TX disabled"
175	tcpdump_cleanup eth0
176
177	### Scenario 3: The interface has tx re-enabled.
178	# Expect ping to pass.
179	set_option_value "${NS1}" tx_enabled true test_team1 eth0
180	check_err $? "Failed to reenable TX"
181	try_ping
182	check_err $? "Ping failed when TX reenabled"
183
184	log_test "TX failover of '${mode}' test"
185}
186
187# Test JUST rx enablement with a given mode.
188# Globals:
189#   RET - Used by test infra, set by `check_err` functions.
190# Arguments:
191#   mode - The mode to set the team interfaces to.
192team_test_mode_rx_enablement()
193{
194	local mode="$1"
195	export RET=0
196
197	# Set up the sender team with the correct mode.
198	setup_team "${NS1}" test_team1 "${mode}" "${NS1_IP}" \
199			"${PREFIX_LENGTH}" "${MEMBERS[@]}"
200	check_err $? "Failed to set up sender team"
201
202	### Scenario 1: Member interface initially enabled.
203	# Expect ping to pass
204	try_ping
205	check_err $? "Ping failed when RX enabled"
206
207	### Scenario 2: One rx-side interface disabled.
208	# Expect ping to fail.
209	set_option_value "${NS1}" rx_enabled false test_team1 eth0
210	check_err $? "Failed to disable RX"
211	tcpdump_start eth0 "${NS2}"
212	try_ping
213	check_fail $? "Ping succeeded when RX disabled"
214	tcpdump_stop eth0
215	# Expect packets to be transmitted, since only RX is disabled.
216	did_interface_receive_icmp eth0 "${NS2_IP}"
217	check_err $? "eth0 not transmitting when RX disabled"
218	tcpdump_cleanup eth0
219
220	### Scenario 3: The interface has rx re-enabled.
221	# Expect ping to pass.
222	set_option_value "${NS1}" rx_enabled true test_team1 eth0
223	check_err $? "Failed to reenable RX"
224	try_ping
225	check_err $? "Ping failed when RX reenabled"
226
227	log_test "RX failover of '${mode}' test"
228}
229
230team_test_tx_enablement()
231{
232	team_test_mode_tx_enablement broadcast
233	team_test_mode_tx_enablement roundrobin
234	team_test_mode_tx_enablement random
235}
236
237team_test_rx_enablement()
238{
239	team_test_mode_rx_enablement broadcast
240	team_test_mode_rx_enablement roundrobin
241	team_test_mode_rx_enablement random
242}
243
244require_command teamnl
245require_command tcpdump
246require_command ping
247environment_create
248tests_run
249exit "${EXIT_STATUS}"
250