1481b56e0SHangbin Liu#!/bin/bash
2481b56e0SHangbin Liu# SPDX-License-Identifier: GPL-2.0
3481b56e0SHangbin Liu#
4481b56e0SHangbin Liu# Test bonding options with mode 1,5,6
5481b56e0SHangbin Liu
6481b56e0SHangbin LiuALL_TESTS="
7481b56e0SHangbin Liu	prio
82e825f8aSHangbin Liu	arp_validate
96cbe791cSHangbin Liu	num_grat_arp
10481b56e0SHangbin Liu"
11481b56e0SHangbin Liu
12481b56e0SHangbin Liulib_dir=$(dirname "$0")
13481b56e0SHangbin Liusource ${lib_dir}/bond_topo_3d1c.sh
14481b56e0SHangbin Liu
15481b56e0SHangbin Liuskip_prio()
16481b56e0SHangbin Liu{
17481b56e0SHangbin Liu	local skip=1
18481b56e0SHangbin Liu
19481b56e0SHangbin Liu	# check if iproute support prio option
20481b56e0SHangbin Liu	ip -n ${s_ns} link set eth0 type bond_slave prio 10
21481b56e0SHangbin Liu	[[ $? -ne 0 ]] && skip=0
22481b56e0SHangbin Liu
23481b56e0SHangbin Liu	# check if kernel support prio option
24481b56e0SHangbin Liu	ip -n ${s_ns} -d link show eth0 | grep -q "prio 10"
25481b56e0SHangbin Liu	[[ $? -ne 0 ]] && skip=0
26481b56e0SHangbin Liu
27481b56e0SHangbin Liu	return $skip
28481b56e0SHangbin Liu}
29481b56e0SHangbin Liu
30481b56e0SHangbin Liuskip_ns()
31481b56e0SHangbin Liu{
32481b56e0SHangbin Liu	local skip=1
33481b56e0SHangbin Liu
34481b56e0SHangbin Liu	# check if iproute support ns_ip6_target option
35481b56e0SHangbin Liu	ip -n ${s_ns} link add bond1 type bond ns_ip6_target ${g_ip6}
36481b56e0SHangbin Liu	[[ $? -ne 0 ]] && skip=0
37481b56e0SHangbin Liu
38481b56e0SHangbin Liu	# check if kernel support ns_ip6_target option
39481b56e0SHangbin Liu	ip -n ${s_ns} -d link show bond1 | grep -q "ns_ip6_target ${g_ip6}"
40481b56e0SHangbin Liu	[[ $? -ne 0 ]] && skip=0
41481b56e0SHangbin Liu
42481b56e0SHangbin Liu	ip -n ${s_ns} link del bond1
43481b56e0SHangbin Liu
44481b56e0SHangbin Liu	return $skip
45481b56e0SHangbin Liu}
46481b56e0SHangbin Liu
47481b56e0SHangbin Liuactive_slave=""
48481b56e0SHangbin Liucheck_active_slave()
49481b56e0SHangbin Liu{
50481b56e0SHangbin Liu	local target_active_slave=$1
51481b56e0SHangbin Liu	active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
52481b56e0SHangbin Liu	test "$active_slave" = "$target_active_slave"
53481b56e0SHangbin Liu	check_err $? "Current active slave is $active_slave but not $target_active_slave"
54481b56e0SHangbin Liu}
55481b56e0SHangbin Liu
56481b56e0SHangbin Liu
57481b56e0SHangbin Liu# Test bonding prio option
58481b56e0SHangbin Liuprio_test()
59481b56e0SHangbin Liu{
60481b56e0SHangbin Liu	local param="$1"
61481b56e0SHangbin Liu	RET=0
62481b56e0SHangbin Liu
63481b56e0SHangbin Liu	# create bond
64481b56e0SHangbin Liu	bond_reset "${param}"
65*3e831970SHangbin Liu	# set active_slave to primary eth1 specifically
66*3e831970SHangbin Liu	ip -n ${s_ns} link set bond0 type bond active_slave eth1
67481b56e0SHangbin Liu
68481b56e0SHangbin Liu	# check bonding member prio value
69481b56e0SHangbin Liu	ip -n ${s_ns} link set eth0 type bond_slave prio 0
70481b56e0SHangbin Liu	ip -n ${s_ns} link set eth1 type bond_slave prio 10
71481b56e0SHangbin Liu	ip -n ${s_ns} link set eth2 type bond_slave prio 11
72481b56e0SHangbin Liu	cmd_jq "ip -n ${s_ns} -d -j link show eth0" \
73481b56e0SHangbin Liu		".[].linkinfo.info_slave_data | select (.prio == 0)" "-e" &> /dev/null
74481b56e0SHangbin Liu	check_err $? "eth0 prio is not 0"
75481b56e0SHangbin Liu	cmd_jq "ip -n ${s_ns} -d -j link show eth1" \
76481b56e0SHangbin Liu		".[].linkinfo.info_slave_data | select (.prio == 10)" "-e" &> /dev/null
77481b56e0SHangbin Liu	check_err $? "eth1 prio is not 10"
78481b56e0SHangbin Liu	cmd_jq "ip -n ${s_ns} -d -j link show eth2" \
79481b56e0SHangbin Liu		".[].linkinfo.info_slave_data | select (.prio == 11)" "-e" &> /dev/null
80481b56e0SHangbin Liu	check_err $? "eth2 prio is not 11"
81481b56e0SHangbin Liu
82481b56e0SHangbin Liu	bond_check_connection "setup"
83481b56e0SHangbin Liu
84481b56e0SHangbin Liu	# active slave should be the primary slave
85481b56e0SHangbin Liu	check_active_slave eth1
86481b56e0SHangbin Liu
87481b56e0SHangbin Liu	# active slave should be the higher prio slave
88481b56e0SHangbin Liu	ip -n ${s_ns} link set $active_slave down
89481b56e0SHangbin Liu	bond_check_connection "fail over"
90481b56e0SHangbin Liu	check_active_slave eth2
91481b56e0SHangbin Liu
92481b56e0SHangbin Liu	# when only 1 slave is up
93481b56e0SHangbin Liu	ip -n ${s_ns} link set $active_slave down
94481b56e0SHangbin Liu	bond_check_connection "only 1 slave up"
95481b56e0SHangbin Liu	check_active_slave eth0
96481b56e0SHangbin Liu
97481b56e0SHangbin Liu	# when a higher prio slave change to up
98481b56e0SHangbin Liu	ip -n ${s_ns} link set eth2 up
99481b56e0SHangbin Liu	bond_check_connection "higher prio slave up"
100481b56e0SHangbin Liu	case $primary_reselect in
101481b56e0SHangbin Liu		"0")
102481b56e0SHangbin Liu			check_active_slave "eth2"
103481b56e0SHangbin Liu			;;
104481b56e0SHangbin Liu		"1")
105481b56e0SHangbin Liu			check_active_slave "eth0"
106481b56e0SHangbin Liu			;;
107481b56e0SHangbin Liu		"2")
108481b56e0SHangbin Liu			check_active_slave "eth0"
109481b56e0SHangbin Liu			;;
110481b56e0SHangbin Liu	esac
111481b56e0SHangbin Liu	local pre_active_slave=$active_slave
112481b56e0SHangbin Liu
113481b56e0SHangbin Liu	# when the primary slave change to up
114481b56e0SHangbin Liu	ip -n ${s_ns} link set eth1 up
115481b56e0SHangbin Liu	bond_check_connection "primary slave up"
116481b56e0SHangbin Liu	case $primary_reselect in
117481b56e0SHangbin Liu		"0")
118481b56e0SHangbin Liu			check_active_slave "eth1"
119481b56e0SHangbin Liu			;;
120481b56e0SHangbin Liu		"1")
121481b56e0SHangbin Liu			check_active_slave "$pre_active_slave"
122481b56e0SHangbin Liu			;;
123481b56e0SHangbin Liu		"2")
124481b56e0SHangbin Liu			check_active_slave "$pre_active_slave"
125481b56e0SHangbin Liu			ip -n ${s_ns} link set $active_slave down
126481b56e0SHangbin Liu			bond_check_connection "pre_active slave down"
127481b56e0SHangbin Liu			check_active_slave "eth1"
128481b56e0SHangbin Liu			;;
129481b56e0SHangbin Liu	esac
130481b56e0SHangbin Liu
131481b56e0SHangbin Liu	# Test changing bond slave prio
132481b56e0SHangbin Liu	if [[ "$primary_reselect" == "0" ]];then
133481b56e0SHangbin Liu		ip -n ${s_ns} link set eth0 type bond_slave prio 1000000
134481b56e0SHangbin Liu		ip -n ${s_ns} link set eth1 type bond_slave prio 0
135481b56e0SHangbin Liu		ip -n ${s_ns} link set eth2 type bond_slave prio -50
136481b56e0SHangbin Liu		ip -n ${s_ns} -d link show eth0 | grep -q 'prio 1000000'
137481b56e0SHangbin Liu		check_err $? "eth0 prio is not 1000000"
138481b56e0SHangbin Liu		ip -n ${s_ns} -d link show eth1 | grep -q 'prio 0'
139481b56e0SHangbin Liu		check_err $? "eth1 prio is not 0"
140481b56e0SHangbin Liu		ip -n ${s_ns} -d link show eth2 | grep -q 'prio -50'
141481b56e0SHangbin Liu		check_err $? "eth3 prio is not -50"
142481b56e0SHangbin Liu		check_active_slave "eth1"
143481b56e0SHangbin Liu
144481b56e0SHangbin Liu		ip -n ${s_ns} link set $active_slave down
145481b56e0SHangbin Liu		bond_check_connection "change slave prio"
146481b56e0SHangbin Liu		check_active_slave "eth0"
147481b56e0SHangbin Liu	fi
148481b56e0SHangbin Liu}
149481b56e0SHangbin Liu
150481b56e0SHangbin Liuprio_miimon()
151481b56e0SHangbin Liu{
152481b56e0SHangbin Liu	local primary_reselect
153481b56e0SHangbin Liu	local mode=$1
154481b56e0SHangbin Liu
155481b56e0SHangbin Liu	for primary_reselect in 0 1 2; do
156481b56e0SHangbin Liu		prio_test "mode $mode miimon 100 primary eth1 primary_reselect $primary_reselect"
157481b56e0SHangbin Liu		log_test "prio" "$mode miimon primary_reselect $primary_reselect"
158481b56e0SHangbin Liu	done
159481b56e0SHangbin Liu}
160481b56e0SHangbin Liu
161481b56e0SHangbin Liuprio_arp()
162481b56e0SHangbin Liu{
163481b56e0SHangbin Liu	local primary_reselect
164481b56e0SHangbin Liu	local mode=$1
165481b56e0SHangbin Liu
166481b56e0SHangbin Liu	for primary_reselect in 0 1 2; do
16709d60387SHangbin Liu		prio_test "mode $mode arp_interval 100 arp_ip_target ${g_ip4} primary eth1 primary_reselect $primary_reselect"
168481b56e0SHangbin Liu		log_test "prio" "$mode arp_ip_target primary_reselect $primary_reselect"
169481b56e0SHangbin Liu	done
170481b56e0SHangbin Liu}
171481b56e0SHangbin Liu
172481b56e0SHangbin Liuprio_ns()
173481b56e0SHangbin Liu{
174481b56e0SHangbin Liu	local primary_reselect
175481b56e0SHangbin Liu	local mode=$1
176481b56e0SHangbin Liu
177481b56e0SHangbin Liu	if skip_ns; then
178481b56e0SHangbin Liu		log_test_skip "prio ns" "Current iproute or kernel doesn't support bond option 'ns_ip6_target'."
179481b56e0SHangbin Liu		return 0
180481b56e0SHangbin Liu	fi
181481b56e0SHangbin Liu
182481b56e0SHangbin Liu	for primary_reselect in 0 1 2; do
18309d60387SHangbin Liu		prio_test "mode $mode arp_interval 100 ns_ip6_target ${g_ip6} primary eth1 primary_reselect $primary_reselect"
184481b56e0SHangbin Liu		log_test "prio" "$mode ns_ip6_target primary_reselect $primary_reselect"
185481b56e0SHangbin Liu	done
186481b56e0SHangbin Liu}
187481b56e0SHangbin Liu
188481b56e0SHangbin Liuprio()
189481b56e0SHangbin Liu{
190481b56e0SHangbin Liu	local mode modes="active-backup balance-tlb balance-alb"
191481b56e0SHangbin Liu
192481b56e0SHangbin Liu	if skip_prio; then
193481b56e0SHangbin Liu		log_test_skip "prio" "Current iproute or kernel doesn't support bond option 'prio'."
194481b56e0SHangbin Liu		return 0
195481b56e0SHangbin Liu	fi
196481b56e0SHangbin Liu
197481b56e0SHangbin Liu	for mode in $modes; do
198481b56e0SHangbin Liu		prio_miimon $mode
199481b56e0SHangbin Liu	done
20009d60387SHangbin Liu	prio_arp "active-backup"
20109d60387SHangbin Liu	prio_ns "active-backup"
202481b56e0SHangbin Liu}
203481b56e0SHangbin Liu
2042e825f8aSHangbin Liuarp_validate_test()
2052e825f8aSHangbin Liu{
2062e825f8aSHangbin Liu	local param="$1"
2072e825f8aSHangbin Liu	RET=0
2082e825f8aSHangbin Liu
2092e825f8aSHangbin Liu	# create bond
2102e825f8aSHangbin Liu	bond_reset "${param}"
2112e825f8aSHangbin Liu
2122e825f8aSHangbin Liu	bond_check_connection
2132e825f8aSHangbin Liu	[ $RET -ne 0 ] && log_test "arp_validate" "$retmsg"
2142e825f8aSHangbin Liu
2152e825f8aSHangbin Liu	# wait for a while to make sure the mii status stable
2162e825f8aSHangbin Liu	sleep 5
2172e825f8aSHangbin Liu	for i in $(seq 0 2); do
2182e825f8aSHangbin Liu		mii_status=$(cmd_jq "ip -n ${s_ns} -j -d link show eth$i" ".[].linkinfo.info_slave_data.mii_status")
2192e825f8aSHangbin Liu		if [ ${mii_status} != "UP" ]; then
2202e825f8aSHangbin Liu			RET=1
2212e825f8aSHangbin Liu			log_test "arp_validate" "interface eth$i mii_status $mii_status"
2222e825f8aSHangbin Liu		fi
2232e825f8aSHangbin Liu	done
2242e825f8aSHangbin Liu}
2252e825f8aSHangbin Liu
2262e825f8aSHangbin Liuarp_validate_arp()
2272e825f8aSHangbin Liu{
2282e825f8aSHangbin Liu	local mode=$1
2292e825f8aSHangbin Liu	local val
2302e825f8aSHangbin Liu	for val in $(seq 0 6); do
2312e825f8aSHangbin Liu		arp_validate_test "mode $mode arp_interval 100 arp_ip_target ${g_ip4} arp_validate $val"
2322e825f8aSHangbin Liu		log_test "arp_validate" "$mode arp_ip_target arp_validate $val"
2332e825f8aSHangbin Liu	done
2342e825f8aSHangbin Liu}
2352e825f8aSHangbin Liu
2362e825f8aSHangbin Liuarp_validate_ns()
2372e825f8aSHangbin Liu{
2382e825f8aSHangbin Liu	local mode=$1
2392e825f8aSHangbin Liu	local val
2402e825f8aSHangbin Liu
2412e825f8aSHangbin Liu	if skip_ns; then
2422e825f8aSHangbin Liu		log_test_skip "arp_validate ns" "Current iproute or kernel doesn't support bond option 'ns_ip6_target'."
2432e825f8aSHangbin Liu		return 0
2442e825f8aSHangbin Liu	fi
2452e825f8aSHangbin Liu
2462e825f8aSHangbin Liu	for val in $(seq 0 6); do
2472e825f8aSHangbin Liu		arp_validate_test "mode $mode arp_interval 100 ns_ip6_target ${g_ip6} arp_validate $val"
2482e825f8aSHangbin Liu		log_test "arp_validate" "$mode ns_ip6_target arp_validate $val"
2492e825f8aSHangbin Liu	done
2502e825f8aSHangbin Liu}
2512e825f8aSHangbin Liu
2522e825f8aSHangbin Liuarp_validate()
2532e825f8aSHangbin Liu{
2542e825f8aSHangbin Liu	arp_validate_arp "active-backup"
2552e825f8aSHangbin Liu	arp_validate_ns "active-backup"
2562e825f8aSHangbin Liu}
2572e825f8aSHangbin Liu
2586cbe791cSHangbin Liugarp_test()
2596cbe791cSHangbin Liu{
2606cbe791cSHangbin Liu	local param="$1"
2616cbe791cSHangbin Liu	local active_slave exp_num real_num i
2626cbe791cSHangbin Liu	RET=0
2636cbe791cSHangbin Liu
2646cbe791cSHangbin Liu	# create bond
2656cbe791cSHangbin Liu	bond_reset "${param}"
2666cbe791cSHangbin Liu
2676cbe791cSHangbin Liu	bond_check_connection
2686cbe791cSHangbin Liu	[ $RET -ne 0 ] && log_test "num_grat_arp" "$retmsg"
2696cbe791cSHangbin Liu
2706cbe791cSHangbin Liu
2716cbe791cSHangbin Liu	# Add tc rules to count GARP number
2726cbe791cSHangbin Liu	for i in $(seq 0 2); do
2736cbe791cSHangbin Liu		tc -n ${g_ns} filter add dev s$i ingress protocol arp pref 1 handle 101 \
2746cbe791cSHangbin Liu			flower skip_hw arp_op request arp_sip ${s_ip4} arp_tip ${s_ip4} action pass
2756cbe791cSHangbin Liu	done
2766cbe791cSHangbin Liu
2776cbe791cSHangbin Liu	# Do failover
2786cbe791cSHangbin Liu	active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
2796cbe791cSHangbin Liu	ip -n ${s_ns} link set ${active_slave} down
2806cbe791cSHangbin Liu
2816cbe791cSHangbin Liu	exp_num=$(echo "${param}" | cut -f6 -d ' ')
2826cbe791cSHangbin Liu	sleep $((exp_num + 2))
2836cbe791cSHangbin Liu
2846cbe791cSHangbin Liu	active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
2856cbe791cSHangbin Liu
2866cbe791cSHangbin Liu	# check result
2876cbe791cSHangbin Liu	real_num=$(tc_rule_handle_stats_get "dev s${active_slave#eth} ingress" 101 ".packets" "-n ${g_ns}")
2886cbe791cSHangbin Liu	if [ "${real_num}" -ne "${exp_num}" ]; then
2896cbe791cSHangbin Liu		echo "$real_num garp packets sent on active slave ${active_slave}"
2906cbe791cSHangbin Liu		RET=1
2916cbe791cSHangbin Liu	fi
2926cbe791cSHangbin Liu
2936cbe791cSHangbin Liu	for i in $(seq 0 2); do
2946cbe791cSHangbin Liu		tc -n ${g_ns} filter del dev s$i ingress
2956cbe791cSHangbin Liu	done
2966cbe791cSHangbin Liu}
2976cbe791cSHangbin Liu
2986cbe791cSHangbin Liunum_grat_arp()
2996cbe791cSHangbin Liu{
3006cbe791cSHangbin Liu	local val
3016cbe791cSHangbin Liu	for val in 10 20 30 50; do
3026cbe791cSHangbin Liu		garp_test "mode active-backup miimon 100 num_grat_arp $val peer_notify_delay 1000"
3036cbe791cSHangbin Liu		log_test "num_grat_arp" "active-backup miimon num_grat_arp $val"
3046cbe791cSHangbin Liu	done
3056cbe791cSHangbin Liu}
3066cbe791cSHangbin Liu
307481b56e0SHangbin Liutrap cleanup EXIT
308481b56e0SHangbin Liu
309481b56e0SHangbin Liusetup_prepare
310481b56e0SHangbin Liusetup_wait
311481b56e0SHangbin Liutests_run
312481b56e0SHangbin Liu
313481b56e0SHangbin Liuexit $EXIT_STATUS
314