Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/drivers/net/bonding/bond_options.sh
29271 views
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
fail_over_mac
11
vlan_over_bond
12
"
13
14
lib_dir=$(dirname "$0")
15
source ${lib_dir}/bond_topo_3d1c.sh
16
c_maddr="33:33:ff:00:00:10"
17
g_maddr="33:33:ff:00:02:54"
18
19
skip_prio()
20
{
21
local skip=1
22
23
# check if iproute support prio option
24
ip -n ${s_ns} link set eth0 type bond_slave prio 10
25
[[ $? -ne 0 ]] && skip=0
26
27
# check if kernel support prio option
28
ip -n ${s_ns} -d link show eth0 | grep -q "prio 10"
29
[[ $? -ne 0 ]] && skip=0
30
31
return $skip
32
}
33
34
skip_ns()
35
{
36
local skip=1
37
38
# check if iproute support ns_ip6_target option
39
ip -n ${s_ns} link add bond1 type bond ns_ip6_target ${g_ip6}
40
[[ $? -ne 0 ]] && skip=0
41
42
# check if kernel support ns_ip6_target option
43
ip -n ${s_ns} -d link show bond1 | grep -q "ns_ip6_target ${g_ip6}"
44
[[ $? -ne 0 ]] && skip=0
45
46
ip -n ${s_ns} link del bond1
47
48
return $skip
49
}
50
51
active_slave=""
52
active_slave_changed()
53
{
54
local old_active_slave=$1
55
local new_active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" \
56
".[].linkinfo.info_data.active_slave")
57
[ "$new_active_slave" != "$old_active_slave" -a "$new_active_slave" != "null" ]
58
}
59
60
check_active_slave()
61
{
62
local target_active_slave=$1
63
slowwait 5 active_slave_changed $active_slave
64
active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
65
test "$active_slave" = "$target_active_slave"
66
check_err $? "Current active slave is $active_slave but not $target_active_slave"
67
}
68
69
# Test bonding prio option
70
prio_test()
71
{
72
local param="$1"
73
RET=0
74
75
# create bond
76
bond_reset "${param}"
77
# set active_slave to primary eth1 specifically
78
ip -n ${s_ns} link set bond0 type bond active_slave eth1
79
80
# check bonding member prio value
81
ip -n ${s_ns} link set eth0 type bond_slave prio 0
82
ip -n ${s_ns} link set eth1 type bond_slave prio 10
83
ip -n ${s_ns} link set eth2 type bond_slave prio 11
84
cmd_jq "ip -n ${s_ns} -d -j link show eth0" \
85
".[].linkinfo.info_slave_data | select (.prio == 0)" "-e" &> /dev/null
86
check_err $? "eth0 prio is not 0"
87
cmd_jq "ip -n ${s_ns} -d -j link show eth1" \
88
".[].linkinfo.info_slave_data | select (.prio == 10)" "-e" &> /dev/null
89
check_err $? "eth1 prio is not 10"
90
cmd_jq "ip -n ${s_ns} -d -j link show eth2" \
91
".[].linkinfo.info_slave_data | select (.prio == 11)" "-e" &> /dev/null
92
check_err $? "eth2 prio is not 11"
93
94
bond_check_connection "setup"
95
96
# active slave should be the primary slave
97
check_active_slave eth1
98
99
# active slave should be the higher prio slave
100
ip -n ${s_ns} link set $active_slave down
101
check_active_slave eth2
102
bond_check_connection "fail over"
103
104
# when only 1 slave is up
105
ip -n ${s_ns} link set $active_slave down
106
check_active_slave eth0
107
bond_check_connection "only 1 slave up"
108
109
# when a higher prio slave change to up
110
ip -n ${s_ns} link set eth2 up
111
bond_check_connection "higher prio slave up"
112
case $primary_reselect in
113
"0")
114
check_active_slave "eth2"
115
;;
116
"1")
117
check_active_slave "eth0"
118
;;
119
"2")
120
check_active_slave "eth0"
121
;;
122
esac
123
local pre_active_slave=$active_slave
124
125
# when the primary slave change to up
126
ip -n ${s_ns} link set eth1 up
127
bond_check_connection "primary slave up"
128
case $primary_reselect in
129
"0")
130
check_active_slave "eth1"
131
;;
132
"1")
133
check_active_slave "$pre_active_slave"
134
;;
135
"2")
136
check_active_slave "$pre_active_slave"
137
ip -n ${s_ns} link set $active_slave down
138
bond_check_connection "pre_active slave down"
139
check_active_slave "eth1"
140
;;
141
esac
142
143
# Test changing bond slave prio
144
if [[ "$primary_reselect" == "0" ]];then
145
ip -n ${s_ns} link set eth0 type bond_slave prio 1000000
146
ip -n ${s_ns} link set eth1 type bond_slave prio 0
147
ip -n ${s_ns} link set eth2 type bond_slave prio -50
148
ip -n ${s_ns} -d link show eth0 | grep -q 'prio 1000000'
149
check_err $? "eth0 prio is not 1000000"
150
ip -n ${s_ns} -d link show eth1 | grep -q 'prio 0'
151
check_err $? "eth1 prio is not 0"
152
ip -n ${s_ns} -d link show eth2 | grep -q 'prio -50'
153
check_err $? "eth3 prio is not -50"
154
check_active_slave "eth1"
155
156
ip -n ${s_ns} link set $active_slave down
157
check_active_slave "eth0"
158
bond_check_connection "change slave prio"
159
fi
160
}
161
162
prio_miimon()
163
{
164
local primary_reselect
165
local mode=$1
166
167
for primary_reselect in 0 1 2; do
168
prio_test "mode $mode miimon 100 primary eth1 primary_reselect $primary_reselect"
169
log_test "prio" "$mode miimon primary_reselect $primary_reselect"
170
done
171
}
172
173
prio_arp()
174
{
175
local primary_reselect
176
local mode=$1
177
178
for primary_reselect in 0 1 2; do
179
prio_test "mode $mode arp_interval 100 arp_ip_target ${g_ip4} primary eth1 primary_reselect $primary_reselect"
180
log_test "prio" "$mode arp_ip_target primary_reselect $primary_reselect"
181
done
182
}
183
184
prio_ns()
185
{
186
local primary_reselect
187
local mode=$1
188
189
if skip_ns; then
190
log_test_skip "prio ns" "Current iproute or kernel doesn't support bond option 'ns_ip6_target'."
191
return 0
192
fi
193
194
for primary_reselect in 0 1 2; do
195
prio_test "mode $mode arp_interval 100 ns_ip6_target ${g_ip6} primary eth1 primary_reselect $primary_reselect"
196
log_test "prio" "$mode ns_ip6_target primary_reselect $primary_reselect"
197
done
198
}
199
200
prio()
201
{
202
local mode modes="active-backup balance-tlb balance-alb"
203
204
if skip_prio; then
205
log_test_skip "prio" "Current iproute or kernel doesn't support bond option 'prio'."
206
return 0
207
fi
208
209
for mode in $modes; do
210
prio_miimon $mode
211
done
212
prio_arp "active-backup"
213
prio_ns "active-backup"
214
}
215
216
wait_mii_up()
217
{
218
for i in $(seq 0 2); do
219
mii_status=$(cmd_jq "ip -n ${s_ns} -j -d link show eth$i" ".[].linkinfo.info_slave_data.mii_status")
220
[ ${mii_status} != "UP" ] && return 1
221
done
222
return 0
223
}
224
225
arp_validate_test()
226
{
227
local param="$1"
228
RET=0
229
230
# create bond
231
bond_reset "${param}"
232
233
bond_check_connection
234
[ $RET -ne 0 ] && log_test "arp_validate" "$retmsg"
235
236
# wait for a while to make sure the mii status stable
237
slowwait 5 wait_mii_up
238
for i in $(seq 0 2); do
239
mii_status=$(cmd_jq "ip -n ${s_ns} -j -d link show eth$i" ".[].linkinfo.info_slave_data.mii_status")
240
if [ ${mii_status} != "UP" ]; then
241
RET=1
242
log_test "arp_validate" "interface eth$i mii_status $mii_status"
243
fi
244
done
245
}
246
247
# Testing correct multicast groups are added to slaves for ns targets
248
arp_validate_mcast()
249
{
250
RET=0
251
local arp_valid=$(cmd_jq "ip -n ${s_ns} -j -d link show bond0" ".[].linkinfo.info_data.arp_validate")
252
local active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
253
254
for i in $(seq 0 2); do
255
maddr_list=$(ip -n ${s_ns} maddr show dev eth${i})
256
257
# arp_valid == 0 or active_slave should not join any maddrs
258
if { [ "$arp_valid" == "null" ] || [ "eth${i}" == ${active_slave} ]; } && \
259
echo "$maddr_list" | grep -qE "${c_maddr}|${g_maddr}"; then
260
RET=1
261
check_err 1 "arp_valid $arp_valid active_slave $active_slave, eth$i has mcast group"
262
# arp_valid != 0 and backup_slave should join both maddrs
263
elif [ "$arp_valid" != "null" ] && [ "eth${i}" != ${active_slave} ] && \
264
( ! echo "$maddr_list" | grep -q "${c_maddr}" || \
265
! echo "$maddr_list" | grep -q "${m_maddr}"); then
266
RET=1
267
check_err 1 "arp_valid $arp_valid active_slave $active_slave, eth$i has mcast group"
268
fi
269
done
270
271
# Do failover
272
ip -n ${s_ns} link set ${active_slave} down
273
# wait for active link change
274
slowwait 2 active_slave_changed $active_slave
275
active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
276
277
for i in $(seq 0 2); do
278
maddr_list=$(ip -n ${s_ns} maddr show dev eth${i})
279
280
# arp_valid == 0 or active_slave should not join any maddrs
281
if { [ "$arp_valid" == "null" ] || [ "eth${i}" == ${active_slave} ]; } && \
282
echo "$maddr_list" | grep -qE "${c_maddr}|${g_maddr}"; then
283
RET=1
284
check_err 1 "arp_valid $arp_valid active_slave $active_slave, eth$i has mcast group"
285
# arp_valid != 0 and backup_slave should join both maddrs
286
elif [ "$arp_valid" != "null" ] && [ "eth${i}" != ${active_slave} ] && \
287
( ! echo "$maddr_list" | grep -q "${c_maddr}" || \
288
! echo "$maddr_list" | grep -q "${m_maddr}"); then
289
RET=1
290
check_err 1 "arp_valid $arp_valid active_slave $active_slave, eth$i has mcast group"
291
fi
292
done
293
}
294
295
arp_validate_arp()
296
{
297
local mode=$1
298
local val
299
for val in $(seq 0 6); do
300
arp_validate_test "mode $mode arp_interval 100 arp_ip_target ${g_ip4} arp_validate $val"
301
log_test "arp_validate" "$mode arp_ip_target arp_validate $val"
302
done
303
}
304
305
arp_validate_ns()
306
{
307
local mode=$1
308
local val
309
310
if skip_ns; then
311
log_test_skip "arp_validate ns" "Current iproute or kernel doesn't support bond option 'ns_ip6_target'."
312
return 0
313
fi
314
315
for val in $(seq 0 6); do
316
arp_validate_test "mode $mode arp_interval 100 ns_ip6_target ${g_ip6},${c_ip6} arp_validate $val"
317
log_test "arp_validate" "$mode ns_ip6_target arp_validate $val"
318
arp_validate_mcast
319
log_test "arp_validate" "join mcast group"
320
done
321
}
322
323
arp_validate()
324
{
325
arp_validate_arp "active-backup"
326
arp_validate_ns "active-backup"
327
}
328
329
garp_test()
330
{
331
local param="$1"
332
local active_slave exp_num real_num i
333
RET=0
334
335
# create bond
336
bond_reset "${param}"
337
338
bond_check_connection
339
[ $RET -ne 0 ] && log_test "num_grat_arp" "$retmsg"
340
341
342
# Add tc rules to count GARP number
343
for i in $(seq 0 2); do
344
tc -n ${g_ns} filter add dev s$i ingress protocol arp pref 1 handle 101 \
345
flower skip_hw arp_op request arp_sip ${s_ip4} arp_tip ${s_ip4} action pass
346
done
347
348
# Do failover
349
active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
350
ip -n ${s_ns} link set ${active_slave} down
351
352
# wait for active link change
353
slowwait 2 active_slave_changed $active_slave
354
355
exp_num=$(echo "${param}" | cut -f6 -d ' ')
356
active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
357
slowwait_for_counter $((exp_num + 5)) $exp_num tc_rule_handle_stats_get \
358
"dev s${active_slave#eth} ingress" 101 ".packets" "-n ${g_ns}" &> /dev/null
359
360
# check result
361
real_num=$(tc_rule_handle_stats_get "dev s${active_slave#eth} ingress" 101 ".packets" "-n ${g_ns}")
362
if [ "${real_num}" -ne "${exp_num}" ]; then
363
echo "$real_num garp packets sent on active slave ${active_slave}"
364
RET=1
365
fi
366
367
for i in $(seq 0 2); do
368
tc -n ${g_ns} filter del dev s$i ingress
369
done
370
}
371
372
num_grat_arp()
373
{
374
local val
375
for val in 10 20 30; do
376
garp_test "mode active-backup miimon 10 num_grat_arp $val peer_notify_delay 100"
377
log_test "num_grat_arp" "active-backup miimon num_grat_arp $val"
378
done
379
}
380
381
check_all_mac_same()
382
{
383
RET=0
384
# all slaves should have same mac address (with the first port's mac)
385
local bond_mac=$(ip -n "$s_ns" -j link show bond0 | jq -r '.[]["address"]')
386
local eth0_mac=$(ip -n "$s_ns" -j link show eth0 | jq -r '.[]["address"]')
387
local eth1_mac=$(ip -n "$s_ns" -j link show eth1 | jq -r '.[]["address"]')
388
local eth2_mac=$(ip -n "$s_ns" -j link show eth2 | jq -r '.[]["address"]')
389
if [ "$bond_mac" != "${mac[0]}" ] || [ "$eth0_mac" != "$bond_mac" ] || \
390
[ "$eth1_mac" != "$bond_mac" ] || [ "$eth2_mac" != "$bond_mac" ]; then
391
RET=1
392
fi
393
}
394
395
check_bond_mac_same_with_first()
396
{
397
RET=0
398
# bond mac address should be same with the first added slave
399
local bond_mac=$(ip -n "$s_ns" -j link show bond0 | jq -r '.[]["address"]')
400
if [ "$bond_mac" != "${mac[0]}" ]; then
401
RET=1
402
fi
403
}
404
405
check_bond_mac_same_with_active()
406
{
407
RET=0
408
# bond mac address should be same with active slave
409
local bond_mac=$(ip -n "$s_ns" -j link show bond0 | jq -r '.[]["address"]')
410
local active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
411
local active_slave_mac=$(ip -n "$s_ns" -j link show "$active_slave" | jq -r '.[]["address"]')
412
if [ "$bond_mac" != "$active_slave_mac" ]; then
413
RET=1
414
fi
415
}
416
417
check_backup_slave_mac_not_change()
418
{
419
RET=0
420
# backup slave's mac address is not changed
421
if ip -n "$s_ns" -d -j link show type bond_slave | jq -e '.[]
422
| select(.linkinfo.info_slave_data.state=="BACKUP")
423
| select(.address != .linkinfo.info_slave_data.perm_hwaddr)' &> /dev/null; then
424
RET=1
425
fi
426
}
427
428
check_backup_slave_mac_inherit()
429
{
430
local backup_mac
431
RET=0
432
433
# backup slaves should use mac[1] or mac[2]
434
local backup_macs=$(ip -n "$s_ns" -d -j link show type bond_slave | \
435
jq -r '.[] | select(.linkinfo.info_slave_data.state=="BACKUP") | .address')
436
for backup_mac in $backup_macs; do
437
if [ "$backup_mac" != "${mac[1]}" ] && [ "$backup_mac" != "${mac[2]}" ]; then
438
RET=1
439
fi
440
done
441
}
442
443
check_first_slave_random_mac()
444
{
445
RET=0
446
# remove the first added slave and added it back
447
ip -n "$s_ns" link set eth0 nomaster
448
ip -n "$s_ns" link set eth0 master bond0
449
450
# the first slave should use random mac address
451
eth0_mac=$(ip -n "$s_ns" -j link show eth0 | jq -r '.[]["address"]')
452
[ "$eth0_mac" = "${mac[0]}" ] && RET=1
453
log_test "bond fail_over_mac follow" "random first slave mac"
454
455
# remove the first slave, the permanent MAC address should be restored back
456
ip -n "$s_ns" link set eth0 nomaster
457
eth0_mac=$(ip -n "$s_ns" -j link show eth0 | jq -r '.[]["address"]')
458
[ "$eth0_mac" != "${mac[0]}" ] && RET=1
459
}
460
461
do_active_backup_failover()
462
{
463
local active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
464
ip -n ${s_ns} link set ${active_slave} down
465
slowwait 2 active_slave_changed $active_slave
466
ip -n ${s_ns} link set ${active_slave} up
467
}
468
469
fail_over_mac()
470
{
471
# Bring down the first interface on the switch to force the bond to
472
# select another active interface instead of the first one that joined.
473
ip -n "$g_ns" link set s0 down
474
475
# fail_over_mac none
476
bond_reset "mode active-backup miimon 100 fail_over_mac 0"
477
check_all_mac_same
478
log_test "fail_over_mac 0" "all slaves have same mac"
479
do_active_backup_failover
480
check_all_mac_same
481
log_test "fail_over_mac 0" "failover: all slaves have same mac"
482
483
# fail_over_mac active
484
bond_reset "mode active-backup miimon 100 fail_over_mac 1"
485
check_bond_mac_same_with_active
486
log_test "fail_over_mac 1" "bond mac is same with active slave mac"
487
check_backup_slave_mac_not_change
488
log_test "fail_over_mac 1" "backup slave mac is not changed"
489
do_active_backup_failover
490
check_bond_mac_same_with_active
491
log_test "fail_over_mac 1" "failover: bond mac is same with active slave mac"
492
check_backup_slave_mac_not_change
493
log_test "fail_over_mac 1" "failover: backup slave mac is not changed"
494
495
# fail_over_mac follow
496
bond_reset "mode active-backup miimon 100 fail_over_mac 2"
497
check_bond_mac_same_with_first
498
log_test "fail_over_mac 2" "bond mac is same with first slave mac"
499
check_bond_mac_same_with_active
500
log_test "fail_over_mac 2" "bond mac is same with active slave mac"
501
check_backup_slave_mac_inherit
502
log_test "fail_over_mac 2" "backup slave mac inherit"
503
do_active_backup_failover
504
check_bond_mac_same_with_first
505
log_test "fail_over_mac 2" "failover: bond mac is same with first slave mac"
506
check_bond_mac_same_with_active
507
log_test "fail_over_mac 2" "failover: bond mac is same with active slave mac"
508
check_backup_slave_mac_inherit
509
log_test "fail_over_mac 2" "failover: backup slave mac inherit"
510
check_first_slave_random_mac
511
log_test "fail_over_mac 2" "first slave mac random"
512
}
513
514
vlan_over_bond_arp()
515
{
516
local mode="$1"
517
RET=0
518
519
bond_reset "mode $mode arp_interval 100 arp_ip_target 192.0.3.10"
520
ip -n "${s_ns}" link add bond0.3 link bond0 type vlan id 3
521
ip -n "${s_ns}" link set bond0.3 up
522
ip -n "${s_ns}" addr add 192.0.3.1/24 dev bond0.3
523
ip -n "${s_ns}" addr add 2001:db8::3:1/64 dev bond0.3
524
525
slowwait_for_counter 5 5 tc_rule_handle_stats_get \
526
"dev eth0.3 ingress" 101 ".packets" "-n ${c_ns}" &> /dev/null || RET=1
527
log_test "vlan over bond arp" "$mode"
528
}
529
530
vlan_over_bond_ns()
531
{
532
local mode="$1"
533
RET=0
534
535
if skip_ns; then
536
log_test_skip "vlan_over_bond ns" "$mode"
537
return 0
538
fi
539
540
bond_reset "mode $mode arp_interval 100 ns_ip6_target 2001:db8::3:10"
541
ip -n "${s_ns}" link add bond0.3 link bond0 type vlan id 3
542
ip -n "${s_ns}" link set bond0.3 up
543
ip -n "${s_ns}" addr add 192.0.3.1/24 dev bond0.3
544
ip -n "${s_ns}" addr add 2001:db8::3:1/64 dev bond0.3
545
546
slowwait_for_counter 5 5 tc_rule_handle_stats_get \
547
"dev eth0.3 ingress" 102 ".packets" "-n ${c_ns}" &> /dev/null || RET=1
548
log_test "vlan over bond ns" "$mode"
549
}
550
551
vlan_over_bond()
552
{
553
# add vlan 3 for client
554
ip -n "${c_ns}" link add eth0.3 link eth0 type vlan id 3
555
ip -n "${c_ns}" link set eth0.3 up
556
ip -n "${c_ns}" addr add 192.0.3.10/24 dev eth0.3
557
ip -n "${c_ns}" addr add 2001:db8::3:10/64 dev eth0.3
558
559
# Add tc rule to check the vlan pkts
560
tc -n "${c_ns}" qdisc add dev eth0.3 clsact
561
tc -n "${c_ns}" filter add dev eth0.3 ingress protocol arp \
562
handle 101 flower skip_hw arp_op request \
563
arp_sip 192.0.3.1 arp_tip 192.0.3.10 action pass
564
tc -n "${c_ns}" filter add dev eth0.3 ingress protocol ipv6 \
565
handle 102 flower skip_hw ip_proto icmpv6 \
566
type 135 src_ip 2001:db8::3:1 action pass
567
568
vlan_over_bond_arp "active-backup"
569
vlan_over_bond_ns "active-backup"
570
}
571
572
trap cleanup EXIT
573
574
setup_prepare
575
setup_wait
576
tests_run
577
578
exit $EXIT_STATUS
579
580