xref: /linux/tools/testing/selftests/drivers/net/bonding/bond_options.sh (revision a1f4cf5791e7914f3e42f5462669353104fef8a9)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# Test bonding options with mode 1,5,6
5
6ALL_TESTS="
7	prio
8	arp_validate
9	num_grat_arp
10"
11
12lib_dir=$(dirname "$0")
13source ${lib_dir}/bond_topo_3d1c.sh
14
15skip_prio()
16{
17	local skip=1
18
19	# check if iproute support prio option
20	ip -n ${s_ns} link set eth0 type bond_slave prio 10
21	[[ $? -ne 0 ]] && skip=0
22
23	# check if kernel support prio option
24	ip -n ${s_ns} -d link show eth0 | grep -q "prio 10"
25	[[ $? -ne 0 ]] && skip=0
26
27	return $skip
28}
29
30skip_ns()
31{
32	local skip=1
33
34	# check if iproute support ns_ip6_target option
35	ip -n ${s_ns} link add bond1 type bond ns_ip6_target ${g_ip6}
36	[[ $? -ne 0 ]] && skip=0
37
38	# check if kernel support ns_ip6_target option
39	ip -n ${s_ns} -d link show bond1 | grep -q "ns_ip6_target ${g_ip6}"
40	[[ $? -ne 0 ]] && skip=0
41
42	ip -n ${s_ns} link del bond1
43
44	return $skip
45}
46
47active_slave=""
48active_slave_changed()
49{
50	local old_active_slave=$1
51	local new_active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" \
52				".[].linkinfo.info_data.active_slave")
53	[ "$new_active_slave" != "$old_active_slave" -a "$new_active_slave" != "null" ]
54}
55
56check_active_slave()
57{
58	local target_active_slave=$1
59	slowwait 5 active_slave_changed $active_slave
60	active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
61	test "$active_slave" = "$target_active_slave"
62	check_err $? "Current active slave is $active_slave but not $target_active_slave"
63}
64
65# Test bonding prio option
66prio_test()
67{
68	local param="$1"
69	RET=0
70
71	# create bond
72	bond_reset "${param}"
73
74	# check bonding member prio value
75	ip -n ${s_ns} link set eth0 type bond_slave prio 0
76	ip -n ${s_ns} link set eth1 type bond_slave prio 10
77	ip -n ${s_ns} link set eth2 type bond_slave prio 11
78	cmd_jq "ip -n ${s_ns} -d -j link show eth0" \
79		".[].linkinfo.info_slave_data | select (.prio == 0)" "-e" &> /dev/null
80	check_err $? "eth0 prio is not 0"
81	cmd_jq "ip -n ${s_ns} -d -j link show eth1" \
82		".[].linkinfo.info_slave_data | select (.prio == 10)" "-e" &> /dev/null
83	check_err $? "eth1 prio is not 10"
84	cmd_jq "ip -n ${s_ns} -d -j link show eth2" \
85		".[].linkinfo.info_slave_data | select (.prio == 11)" "-e" &> /dev/null
86	check_err $? "eth2 prio is not 11"
87
88	bond_check_connection "setup"
89
90	# active slave should be the primary slave
91	check_active_slave eth1
92
93	# active slave should be the higher prio slave
94	ip -n ${s_ns} link set $active_slave down
95	check_active_slave eth2
96	bond_check_connection "fail over"
97
98	# when only 1 slave is up
99	ip -n ${s_ns} link set $active_slave down
100	check_active_slave eth0
101	bond_check_connection "only 1 slave up"
102
103	# when a higher prio slave change to up
104	ip -n ${s_ns} link set eth2 up
105	bond_check_connection "higher prio slave up"
106	case $primary_reselect in
107		"0")
108			check_active_slave "eth2"
109			;;
110		"1")
111			check_active_slave "eth0"
112			;;
113		"2")
114			check_active_slave "eth0"
115			;;
116	esac
117	local pre_active_slave=$active_slave
118
119	# when the primary slave change to up
120	ip -n ${s_ns} link set eth1 up
121	bond_check_connection "primary slave up"
122	case $primary_reselect in
123		"0")
124			check_active_slave "eth1"
125			;;
126		"1")
127			check_active_slave "$pre_active_slave"
128			;;
129		"2")
130			check_active_slave "$pre_active_slave"
131			ip -n ${s_ns} link set $active_slave down
132			bond_check_connection "pre_active slave down"
133			check_active_slave "eth1"
134			;;
135	esac
136
137	# Test changing bond slave prio
138	if [[ "$primary_reselect" == "0" ]];then
139		ip -n ${s_ns} link set eth0 type bond_slave prio 1000000
140		ip -n ${s_ns} link set eth1 type bond_slave prio 0
141		ip -n ${s_ns} link set eth2 type bond_slave prio -50
142		ip -n ${s_ns} -d link show eth0 | grep -q 'prio 1000000'
143		check_err $? "eth0 prio is not 1000000"
144		ip -n ${s_ns} -d link show eth1 | grep -q 'prio 0'
145		check_err $? "eth1 prio is not 0"
146		ip -n ${s_ns} -d link show eth2 | grep -q 'prio -50'
147		check_err $? "eth3 prio is not -50"
148		check_active_slave "eth1"
149
150		ip -n ${s_ns} link set $active_slave down
151		check_active_slave "eth0"
152		bond_check_connection "change slave prio"
153	fi
154}
155
156prio_miimon()
157{
158	local primary_reselect
159	local mode=$1
160
161	for primary_reselect in 0 1 2; do
162		prio_test "mode $mode miimon 100 primary eth1 primary_reselect $primary_reselect"
163		log_test "prio" "$mode miimon primary_reselect $primary_reselect"
164	done
165}
166
167prio_arp()
168{
169	local primary_reselect
170	local mode=$1
171
172	for primary_reselect in 0 1 2; do
173		prio_test "mode $mode arp_interval 100 arp_ip_target ${g_ip4} primary eth1 primary_reselect $primary_reselect"
174		log_test "prio" "$mode arp_ip_target primary_reselect $primary_reselect"
175	done
176}
177
178prio_ns()
179{
180	local primary_reselect
181	local mode=$1
182
183	if skip_ns; then
184		log_test_skip "prio ns" "Current iproute or kernel doesn't support bond option 'ns_ip6_target'."
185		return 0
186	fi
187
188	for primary_reselect in 0 1 2; do
189		prio_test "mode $mode arp_interval 100 ns_ip6_target ${g_ip6} primary eth1 primary_reselect $primary_reselect"
190		log_test "prio" "$mode ns_ip6_target primary_reselect $primary_reselect"
191	done
192}
193
194prio()
195{
196	local mode modes="active-backup balance-tlb balance-alb"
197
198	if skip_prio; then
199		log_test_skip "prio" "Current iproute or kernel doesn't support bond option 'prio'."
200		return 0
201	fi
202
203	for mode in $modes; do
204		prio_miimon $mode
205	done
206	prio_arp "active-backup"
207	prio_ns "active-backup"
208}
209
210wait_mii_up()
211{
212	for i in $(seq 0 2); do
213		mii_status=$(cmd_jq "ip -n ${s_ns} -j -d link show eth$i" ".[].linkinfo.info_slave_data.mii_status")
214		[ ${mii_status} != "UP" ] && return 1
215	done
216	return 0
217}
218
219arp_validate_test()
220{
221	local param="$1"
222	RET=0
223
224	# create bond
225	bond_reset "${param}"
226
227	bond_check_connection
228	[ $RET -ne 0 ] && log_test "arp_validate" "$retmsg"
229
230	# wait for a while to make sure the mii status stable
231	slowwait 5 wait_mii_up
232	for i in $(seq 0 2); do
233		mii_status=$(cmd_jq "ip -n ${s_ns} -j -d link show eth$i" ".[].linkinfo.info_slave_data.mii_status")
234		if [ ${mii_status} != "UP" ]; then
235			RET=1
236			log_test "arp_validate" "interface eth$i mii_status $mii_status"
237		fi
238	done
239}
240
241arp_validate_arp()
242{
243	local mode=$1
244	local val
245	for val in $(seq 0 6); do
246		arp_validate_test "mode $mode arp_interval 100 arp_ip_target ${g_ip4} arp_validate $val"
247		log_test "arp_validate" "$mode arp_ip_target arp_validate $val"
248	done
249}
250
251arp_validate_ns()
252{
253	local mode=$1
254	local val
255
256	if skip_ns; then
257		log_test_skip "arp_validate ns" "Current iproute or kernel doesn't support bond option 'ns_ip6_target'."
258		return 0
259	fi
260
261	for val in $(seq 0 6); do
262		arp_validate_test "mode $mode arp_interval 100 ns_ip6_target ${g_ip6} arp_validate $val"
263		log_test "arp_validate" "$mode ns_ip6_target arp_validate $val"
264	done
265}
266
267arp_validate()
268{
269	arp_validate_arp "active-backup"
270	arp_validate_ns "active-backup"
271}
272
273garp_test()
274{
275	local param="$1"
276	local active_slave exp_num real_num i
277	RET=0
278
279	# create bond
280	bond_reset "${param}"
281
282	bond_check_connection
283	[ $RET -ne 0 ] && log_test "num_grat_arp" "$retmsg"
284
285
286	# Add tc rules to count GARP number
287	for i in $(seq 0 2); do
288		tc -n ${g_ns} filter add dev s$i ingress protocol arp pref 1 handle 101 \
289			flower skip_hw arp_op request arp_sip ${s_ip4} arp_tip ${s_ip4} action pass
290	done
291
292	# Do failover
293	active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
294	ip -n ${s_ns} link set ${active_slave} down
295
296	# wait for active link change
297	slowwait 2 active_slave_changed $active_slave
298
299	exp_num=$(echo "${param}" | cut -f6 -d ' ')
300	active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
301	slowwait_for_counter $((exp_num + 5)) $exp_num \
302		tc_rule_handle_stats_get "dev s${active_slave#eth} ingress" 101 ".packets" "-n ${g_ns}"
303
304	# check result
305	real_num=$(tc_rule_handle_stats_get "dev s${active_slave#eth} ingress" 101 ".packets" "-n ${g_ns}")
306	if [ "${real_num}" -ne "${exp_num}" ]; then
307		echo "$real_num garp packets sent on active slave ${active_slave}"
308		RET=1
309	fi
310
311	for i in $(seq 0 2); do
312		tc -n ${g_ns} filter del dev s$i ingress
313	done
314}
315
316num_grat_arp()
317{
318	local val
319	for val in 10 20 30; do
320		garp_test "mode active-backup miimon 10 num_grat_arp $val peer_notify_delay 100"
321		log_test "num_grat_arp" "active-backup miimon num_grat_arp $val"
322	done
323}
324
325trap cleanup EXIT
326
327setup_prepare
328setup_wait
329tests_run
330
331exit $EXIT_STATUS
332