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