Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4##############################################################################
5# Defines
6
7# Can be overridden by the configuration file.
8PING=${PING:=ping}
9PING6=${PING6:=ping6}
10MZ=${MZ:=mausezahn}
11ARPING=${ARPING:=arping}
12TEAMD=${TEAMD:=teamd}
13WAIT_TIME=${WAIT_TIME:=5}
14PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
15PAUSE_ON_CLEANUP=${PAUSE_ON_CLEANUP:=no}
16NETIF_TYPE=${NETIF_TYPE:=veth}
17NETIF_CREATE=${NETIF_CREATE:=yes}
18
19relative_path="${BASH_SOURCE%/*}"
20if [[ "$relative_path" == "${BASH_SOURCE}" ]]; then
21 relative_path="."
22fi
23
24if [[ -f $relative_path/forwarding.config ]]; then
25 source "$relative_path/forwarding.config"
26fi
27
28##############################################################################
29# Sanity checks
30
31check_tc_version()
32{
33 tc -j &> /dev/null
34 if [[ $? -ne 0 ]]; then
35 echo "SKIP: iproute2 too old; tc is missing JSON support"
36 exit 1
37 fi
38}
39
40check_tc_shblock_support()
41{
42 tc filter help 2>&1 | grep block &> /dev/null
43 if [[ $? -ne 0 ]]; then
44 echo "SKIP: iproute2 too old; tc is missing shared block support"
45 exit 1
46 fi
47}
48
49check_tc_chain_support()
50{
51 tc help 2>&1|grep chain &> /dev/null
52 if [[ $? -ne 0 ]]; then
53 echo "SKIP: iproute2 too old; tc is missing chain support"
54 exit 1
55 fi
56}
57
58if [[ "$(id -u)" -ne 0 ]]; then
59 echo "SKIP: need root privileges"
60 exit 0
61fi
62
63if [[ "$CHECK_TC" = "yes" ]]; then
64 check_tc_version
65fi
66
67require_command()
68{
69 local cmd=$1; shift
70
71 if [[ ! -x "$(command -v "$cmd")" ]]; then
72 echo "SKIP: $cmd not installed"
73 exit 1
74 fi
75}
76
77require_command jq
78require_command $MZ
79
80if [[ ! -v NUM_NETIFS ]]; then
81 echo "SKIP: importer does not define \"NUM_NETIFS\""
82 exit 1
83fi
84
85##############################################################################
86# Command line options handling
87
88count=0
89
90while [[ $# -gt 0 ]]; do
91 if [[ "$count" -eq "0" ]]; then
92 unset NETIFS
93 declare -A NETIFS
94 fi
95 count=$((count + 1))
96 NETIFS[p$count]="$1"
97 shift
98done
99
100##############################################################################
101# Network interfaces configuration
102
103create_netif_veth()
104{
105 local i
106
107 for i in $(eval echo {1..$NUM_NETIFS}); do
108 local j=$((i+1))
109
110 ip link show dev ${NETIFS[p$i]} &> /dev/null
111 if [[ $? -ne 0 ]]; then
112 ip link add ${NETIFS[p$i]} type veth \
113 peer name ${NETIFS[p$j]}
114 if [[ $? -ne 0 ]]; then
115 echo "Failed to create netif"
116 exit 1
117 fi
118 fi
119 i=$j
120 done
121}
122
123create_netif()
124{
125 case "$NETIF_TYPE" in
126 veth) create_netif_veth
127 ;;
128 *) echo "Can not create interfaces of type \'$NETIF_TYPE\'"
129 exit 1
130 ;;
131 esac
132}
133
134if [[ "$NETIF_CREATE" = "yes" ]]; then
135 create_netif
136fi
137
138for i in $(eval echo {1..$NUM_NETIFS}); do
139 ip link show dev ${NETIFS[p$i]} &> /dev/null
140 if [[ $? -ne 0 ]]; then
141 echo "SKIP: could not find all required interfaces"
142 exit 1
143 fi
144done
145
146##############################################################################
147# Helpers
148
149# Exit status to return at the end. Set in case one of the tests fails.
150EXIT_STATUS=0
151# Per-test return value. Clear at the beginning of each test.
152RET=0
153
154check_err()
155{
156 local err=$1
157 local msg=$2
158
159 if [[ $RET -eq 0 && $err -ne 0 ]]; then
160 RET=$err
161 retmsg=$msg
162 fi
163}
164
165check_fail()
166{
167 local err=$1
168 local msg=$2
169
170 if [[ $RET -eq 0 && $err -eq 0 ]]; then
171 RET=1
172 retmsg=$msg
173 fi
174}
175
176check_err_fail()
177{
178 local should_fail=$1; shift
179 local err=$1; shift
180 local what=$1; shift
181
182 if ((should_fail)); then
183 check_fail $err "$what succeeded, but should have failed"
184 else
185 check_err $err "$what failed"
186 fi
187}
188
189log_test()
190{
191 local test_name=$1
192 local opt_str=$2
193
194 if [[ $# -eq 2 ]]; then
195 opt_str="($opt_str)"
196 fi
197
198 if [[ $RET -ne 0 ]]; then
199 EXIT_STATUS=1
200 printf "TEST: %-60s [FAIL]\n" "$test_name $opt_str"
201 if [[ ! -z "$retmsg" ]]; then
202 printf "\t%s\n" "$retmsg"
203 fi
204 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
205 echo "Hit enter to continue, 'q' to quit"
206 read a
207 [ "$a" = "q" ] && exit 1
208 fi
209 return 1
210 fi
211
212 printf "TEST: %-60s [PASS]\n" "$test_name $opt_str"
213 return 0
214}
215
216log_info()
217{
218 local msg=$1
219
220 echo "INFO: $msg"
221}
222
223setup_wait_dev()
224{
225 local dev=$1; shift
226
227 while true; do
228 ip link show dev $dev up \
229 | grep 'state UP' &> /dev/null
230 if [[ $? -ne 0 ]]; then
231 sleep 1
232 else
233 break
234 fi
235 done
236}
237
238setup_wait()
239{
240 local num_netifs=${1:-$NUM_NETIFS}
241
242 for ((i = 1; i <= num_netifs; ++i)); do
243 setup_wait_dev ${NETIFS[p$i]}
244 done
245
246 # Make sure links are ready.
247 sleep $WAIT_TIME
248}
249
250lldpad_app_wait_set()
251{
252 local dev=$1; shift
253
254 while lldptool -t -i $dev -V APP -c app | grep -Eq "pending|unknown"; do
255 echo "$dev: waiting for lldpad to push pending APP updates"
256 sleep 5
257 done
258}
259
260lldpad_app_wait_del()
261{
262 # Give lldpad a chance to push down the changes. If the device is downed
263 # too soon, the updates will be left pending. However, they will have
264 # been struck off the lldpad's DB already, so we won't be able to tell
265 # they are pending. Then on next test iteration this would cause
266 # weirdness as newly-added APP rules conflict with the old ones,
267 # sometimes getting stuck in an "unknown" state.
268 sleep 5
269}
270
271pre_cleanup()
272{
273 if [ "${PAUSE_ON_CLEANUP}" = "yes" ]; then
274 echo "Pausing before cleanup, hit any key to continue"
275 read
276 fi
277}
278
279vrf_prepare()
280{
281 ip -4 rule add pref 32765 table local
282 ip -4 rule del pref 0
283 ip -6 rule add pref 32765 table local
284 ip -6 rule del pref 0
285}
286
287vrf_cleanup()
288{
289 ip -6 rule add pref 0 table local
290 ip -6 rule del pref 32765
291 ip -4 rule add pref 0 table local
292 ip -4 rule del pref 32765
293}
294
295__last_tb_id=0
296declare -A __TB_IDS
297
298__vrf_td_id_assign()
299{
300 local vrf_name=$1
301
302 __last_tb_id=$((__last_tb_id + 1))
303 __TB_IDS[$vrf_name]=$__last_tb_id
304 return $__last_tb_id
305}
306
307__vrf_td_id_lookup()
308{
309 local vrf_name=$1
310
311 return ${__TB_IDS[$vrf_name]}
312}
313
314vrf_create()
315{
316 local vrf_name=$1
317 local tb_id
318
319 __vrf_td_id_assign $vrf_name
320 tb_id=$?
321
322 ip link add dev $vrf_name type vrf table $tb_id
323 ip -4 route add table $tb_id unreachable default metric 4278198272
324 ip -6 route add table $tb_id unreachable default metric 4278198272
325}
326
327vrf_destroy()
328{
329 local vrf_name=$1
330 local tb_id
331
332 __vrf_td_id_lookup $vrf_name
333 tb_id=$?
334
335 ip -6 route del table $tb_id unreachable default metric 4278198272
336 ip -4 route del table $tb_id unreachable default metric 4278198272
337 ip link del dev $vrf_name
338}
339
340__addr_add_del()
341{
342 local if_name=$1
343 local add_del=$2
344 local array
345
346 shift
347 shift
348 array=("${@}")
349
350 for addrstr in "${array[@]}"; do
351 ip address $add_del $addrstr dev $if_name
352 done
353}
354
355__simple_if_init()
356{
357 local if_name=$1; shift
358 local vrf_name=$1; shift
359 local addrs=("${@}")
360
361 ip link set dev $if_name master $vrf_name
362 ip link set dev $if_name up
363
364 __addr_add_del $if_name add "${addrs[@]}"
365}
366
367__simple_if_fini()
368{
369 local if_name=$1; shift
370 local addrs=("${@}")
371
372 __addr_add_del $if_name del "${addrs[@]}"
373
374 ip link set dev $if_name down
375 ip link set dev $if_name nomaster
376}
377
378simple_if_init()
379{
380 local if_name=$1
381 local vrf_name
382 local array
383
384 shift
385 vrf_name=v$if_name
386 array=("${@}")
387
388 vrf_create $vrf_name
389 ip link set dev $vrf_name up
390 __simple_if_init $if_name $vrf_name "${array[@]}"
391}
392
393simple_if_fini()
394{
395 local if_name=$1
396 local vrf_name
397 local array
398
399 shift
400 vrf_name=v$if_name
401 array=("${@}")
402
403 __simple_if_fini $if_name "${array[@]}"
404 vrf_destroy $vrf_name
405}
406
407tunnel_create()
408{
409 local name=$1; shift
410 local type=$1; shift
411 local local=$1; shift
412 local remote=$1; shift
413
414 ip link add name $name type $type \
415 local $local remote $remote "$@"
416 ip link set dev $name up
417}
418
419tunnel_destroy()
420{
421 local name=$1; shift
422
423 ip link del dev $name
424}
425
426vlan_create()
427{
428 local if_name=$1; shift
429 local vid=$1; shift
430 local vrf=$1; shift
431 local ips=("${@}")
432 local name=$if_name.$vid
433
434 ip link add name $name link $if_name type vlan id $vid
435 if [ "$vrf" != "" ]; then
436 ip link set dev $name master $vrf
437 fi
438 ip link set dev $name up
439 __addr_add_del $name add "${ips[@]}"
440}
441
442vlan_destroy()
443{
444 local if_name=$1; shift
445 local vid=$1; shift
446 local name=$if_name.$vid
447
448 ip link del dev $name
449}
450
451team_create()
452{
453 local if_name=$1; shift
454 local mode=$1; shift
455
456 require_command $TEAMD
457 $TEAMD -t $if_name -d -c '{"runner": {"name": "'$mode'"}}'
458 for slave in "$@"; do
459 ip link set dev $slave down
460 ip link set dev $slave master $if_name
461 ip link set dev $slave up
462 done
463 ip link set dev $if_name up
464}
465
466team_destroy()
467{
468 local if_name=$1; shift
469
470 $TEAMD -t $if_name -k
471}
472
473master_name_get()
474{
475 local if_name=$1
476
477 ip -j link show dev $if_name | jq -r '.[]["master"]'
478}
479
480link_stats_tx_packets_get()
481{
482 local if_name=$1
483
484 ip -j -s link show dev $if_name | jq '.[]["stats64"]["tx"]["packets"]'
485}
486
487tc_rule_stats_get()
488{
489 local dev=$1; shift
490 local pref=$1; shift
491 local dir=$1; shift
492
493 tc -j -s filter show dev $dev ${dir:-ingress} pref $pref \
494 | jq '.[1].options.actions[].stats.packets'
495}
496
497ethtool_stats_get()
498{
499 local dev=$1; shift
500 local stat=$1; shift
501
502 ethtool -S $dev | grep "^ *$stat:" | head -n 1 | cut -d: -f2
503}
504
505mac_get()
506{
507 local if_name=$1
508
509 ip -j link show dev $if_name | jq -r '.[]["address"]'
510}
511
512bridge_ageing_time_get()
513{
514 local bridge=$1
515 local ageing_time
516
517 # Need to divide by 100 to convert to seconds.
518 ageing_time=$(ip -j -d link show dev $bridge \
519 | jq '.[]["linkinfo"]["info_data"]["ageing_time"]')
520 echo $((ageing_time / 100))
521}
522
523declare -A SYSCTL_ORIG
524sysctl_set()
525{
526 local key=$1; shift
527 local value=$1; shift
528
529 SYSCTL_ORIG[$key]=$(sysctl -n $key)
530 sysctl -qw $key=$value
531}
532
533sysctl_restore()
534{
535 local key=$1; shift
536
537 sysctl -qw $key=${SYSCTL_ORIG["$key"]}
538}
539
540forwarding_enable()
541{
542 sysctl_set net.ipv4.conf.all.forwarding 1
543 sysctl_set net.ipv6.conf.all.forwarding 1
544}
545
546forwarding_restore()
547{
548 sysctl_restore net.ipv6.conf.all.forwarding
549 sysctl_restore net.ipv4.conf.all.forwarding
550}
551
552declare -A MTU_ORIG
553mtu_set()
554{
555 local dev=$1; shift
556 local mtu=$1; shift
557
558 MTU_ORIG["$dev"]=$(ip -j link show dev $dev | jq -e '.[].mtu')
559 ip link set dev $dev mtu $mtu
560}
561
562mtu_restore()
563{
564 local dev=$1; shift
565
566 ip link set dev $dev mtu ${MTU_ORIG["$dev"]}
567}
568
569tc_offload_check()
570{
571 local num_netifs=${1:-$NUM_NETIFS}
572
573 for ((i = 1; i <= num_netifs; ++i)); do
574 ethtool -k ${NETIFS[p$i]} \
575 | grep "hw-tc-offload: on" &> /dev/null
576 if [[ $? -ne 0 ]]; then
577 return 1
578 fi
579 done
580
581 return 0
582}
583
584trap_install()
585{
586 local dev=$1; shift
587 local direction=$1; shift
588
589 # Some devices may not support or need in-hardware trapping of traffic
590 # (e.g. the veth pairs that this library creates for non-existent
591 # loopbacks). Use continue instead, so that there is a filter in there
592 # (some tests check counters), and so that other filters are still
593 # processed.
594 tc filter add dev $dev $direction pref 1 \
595 flower skip_sw action trap 2>/dev/null \
596 || tc filter add dev $dev $direction pref 1 \
597 flower action continue
598}
599
600trap_uninstall()
601{
602 local dev=$1; shift
603 local direction=$1; shift
604
605 tc filter del dev $dev $direction pref 1 flower
606}
607
608slow_path_trap_install()
609{
610 # For slow-path testing, we need to install a trap to get to
611 # slow path the packets that would otherwise be switched in HW.
612 if [ "${tcflags/skip_hw}" != "$tcflags" ]; then
613 trap_install "$@"
614 fi
615}
616
617slow_path_trap_uninstall()
618{
619 if [ "${tcflags/skip_hw}" != "$tcflags" ]; then
620 trap_uninstall "$@"
621 fi
622}
623
624__icmp_capture_add_del()
625{
626 local add_del=$1; shift
627 local pref=$1; shift
628 local vsuf=$1; shift
629 local tundev=$1; shift
630 local filter=$1; shift
631
632 tc filter $add_del dev "$tundev" ingress \
633 proto ip$vsuf pref $pref \
634 flower ip_proto icmp$vsuf $filter \
635 action pass
636}
637
638icmp_capture_install()
639{
640 __icmp_capture_add_del add 100 "" "$@"
641}
642
643icmp_capture_uninstall()
644{
645 __icmp_capture_add_del del 100 "" "$@"
646}
647
648icmp6_capture_install()
649{
650 __icmp_capture_add_del add 100 v6 "$@"
651}
652
653icmp6_capture_uninstall()
654{
655 __icmp_capture_add_del del 100 v6 "$@"
656}
657
658__vlan_capture_add_del()
659{
660 local add_del=$1; shift
661 local pref=$1; shift
662 local dev=$1; shift
663 local filter=$1; shift
664
665 tc filter $add_del dev "$dev" ingress \
666 proto 802.1q pref $pref \
667 flower $filter \
668 action pass
669}
670
671vlan_capture_install()
672{
673 __vlan_capture_add_del add 100 "$@"
674}
675
676vlan_capture_uninstall()
677{
678 __vlan_capture_add_del del 100 "$@"
679}
680
681__dscp_capture_add_del()
682{
683 local add_del=$1; shift
684 local dev=$1; shift
685 local base=$1; shift
686 local dscp;
687
688 for prio in {0..7}; do
689 dscp=$((base + prio))
690 __icmp_capture_add_del $add_del $((dscp + 100)) "" $dev \
691 "skip_hw ip_tos $((dscp << 2))"
692 done
693}
694
695dscp_capture_install()
696{
697 local dev=$1; shift
698 local base=$1; shift
699
700 __dscp_capture_add_del add $dev $base
701}
702
703dscp_capture_uninstall()
704{
705 local dev=$1; shift
706 local base=$1; shift
707
708 __dscp_capture_add_del del $dev $base
709}
710
711dscp_fetch_stats()
712{
713 local dev=$1; shift
714 local base=$1; shift
715
716 for prio in {0..7}; do
717 local dscp=$((base + prio))
718 local t=$(tc_rule_stats_get $dev $((dscp + 100)))
719 echo "[$dscp]=$t "
720 done
721}
722
723matchall_sink_create()
724{
725 local dev=$1; shift
726
727 tc qdisc add dev $dev clsact
728 tc filter add dev $dev ingress \
729 pref 10000 \
730 matchall \
731 action drop
732}
733
734tests_run()
735{
736 local current_test
737
738 for current_test in ${TESTS:-$ALL_TESTS}; do
739 $current_test
740 done
741}
742
743multipath_eval()
744{
745 local desc="$1"
746 local weight_rp12=$2
747 local weight_rp13=$3
748 local packets_rp12=$4
749 local packets_rp13=$5
750 local weights_ratio packets_ratio diff
751
752 RET=0
753
754 if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then
755 weights_ratio=$(echo "scale=2; $weight_rp12 / $weight_rp13" \
756 | bc -l)
757 else
758 weights_ratio=$(echo "scale=2; $weight_rp13 / $weight_rp12" \
759 | bc -l)
760 fi
761
762 if [[ "$packets_rp12" -eq "0" || "$packets_rp13" -eq "0" ]]; then
763 check_err 1 "Packet difference is 0"
764 log_test "Multipath"
765 log_info "Expected ratio $weights_ratio"
766 return
767 fi
768
769 if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then
770 packets_ratio=$(echo "scale=2; $packets_rp12 / $packets_rp13" \
771 | bc -l)
772 else
773 packets_ratio=$(echo "scale=2; $packets_rp13 / $packets_rp12" \
774 | bc -l)
775 fi
776
777 diff=$(echo $weights_ratio - $packets_ratio | bc -l)
778 diff=${diff#-}
779
780 test "$(echo "$diff / $weights_ratio > 0.15" | bc -l)" -eq 0
781 check_err $? "Too large discrepancy between expected and measured ratios"
782 log_test "$desc"
783 log_info "Expected ratio $weights_ratio Measured ratio $packets_ratio"
784}
785
786##############################################################################
787# Tests
788
789ping_do()
790{
791 local if_name=$1
792 local dip=$2
793 local vrf_name
794
795 vrf_name=$(master_name_get $if_name)
796 ip vrf exec $vrf_name $PING $dip -c 10 -i 0.1 -w 2 &> /dev/null
797}
798
799ping_test()
800{
801 RET=0
802
803 ping_do $1 $2
804 check_err $?
805 log_test "ping"
806}
807
808ping6_do()
809{
810 local if_name=$1
811 local dip=$2
812 local vrf_name
813
814 vrf_name=$(master_name_get $if_name)
815 ip vrf exec $vrf_name $PING6 $dip -c 10 -i 0.1 -w 2 &> /dev/null
816}
817
818ping6_test()
819{
820 RET=0
821
822 ping6_do $1 $2
823 check_err $?
824 log_test "ping6"
825}
826
827learning_test()
828{
829 local bridge=$1
830 local br_port1=$2 # Connected to `host1_if`.
831 local host1_if=$3
832 local host2_if=$4
833 local mac=de:ad:be:ef:13:37
834 local ageing_time
835
836 RET=0
837
838 bridge -j fdb show br $bridge brport $br_port1 \
839 | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null
840 check_fail $? "Found FDB record when should not"
841
842 # Disable unknown unicast flooding on `br_port1` to make sure
843 # packets are only forwarded through the port after a matching
844 # FDB entry was installed.
845 bridge link set dev $br_port1 flood off
846
847 tc qdisc add dev $host1_if ingress
848 tc filter add dev $host1_if ingress protocol ip pref 1 handle 101 \
849 flower dst_mac $mac action drop
850
851 $MZ $host2_if -c 1 -p 64 -b $mac -t ip -q
852 sleep 1
853
854 tc -j -s filter show dev $host1_if ingress \
855 | jq -e ".[] | select(.options.handle == 101) \
856 | select(.options.actions[0].stats.packets == 1)" &> /dev/null
857 check_fail $? "Packet reached second host when should not"
858
859 $MZ $host1_if -c 1 -p 64 -a $mac -t ip -q
860 sleep 1
861
862 bridge -j fdb show br $bridge brport $br_port1 \
863 | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null
864 check_err $? "Did not find FDB record when should"
865
866 $MZ $host2_if -c 1 -p 64 -b $mac -t ip -q
867 sleep 1
868
869 tc -j -s filter show dev $host1_if ingress \
870 | jq -e ".[] | select(.options.handle == 101) \
871 | select(.options.actions[0].stats.packets == 1)" &> /dev/null
872 check_err $? "Packet did not reach second host when should"
873
874 # Wait for 10 seconds after the ageing time to make sure FDB
875 # record was aged-out.
876 ageing_time=$(bridge_ageing_time_get $bridge)
877 sleep $((ageing_time + 10))
878
879 bridge -j fdb show br $bridge brport $br_port1 \
880 | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null
881 check_fail $? "Found FDB record when should not"
882
883 bridge link set dev $br_port1 learning off
884
885 $MZ $host1_if -c 1 -p 64 -a $mac -t ip -q
886 sleep 1
887
888 bridge -j fdb show br $bridge brport $br_port1 \
889 | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null
890 check_fail $? "Found FDB record when should not"
891
892 bridge link set dev $br_port1 learning on
893
894 tc filter del dev $host1_if ingress protocol ip pref 1 handle 101 flower
895 tc qdisc del dev $host1_if ingress
896
897 bridge link set dev $br_port1 flood on
898
899 log_test "FDB learning"
900}
901
902flood_test_do()
903{
904 local should_flood=$1
905 local mac=$2
906 local ip=$3
907 local host1_if=$4
908 local host2_if=$5
909 local err=0
910
911 # Add an ACL on `host2_if` which will tell us whether the packet
912 # was flooded to it or not.
913 tc qdisc add dev $host2_if ingress
914 tc filter add dev $host2_if ingress protocol ip pref 1 handle 101 \
915 flower dst_mac $mac action drop
916
917 $MZ $host1_if -c 1 -p 64 -b $mac -B $ip -t ip -q
918 sleep 1
919
920 tc -j -s filter show dev $host2_if ingress \
921 | jq -e ".[] | select(.options.handle == 101) \
922 | select(.options.actions[0].stats.packets == 1)" &> /dev/null
923 if [[ $? -ne 0 && $should_flood == "true" || \
924 $? -eq 0 && $should_flood == "false" ]]; then
925 err=1
926 fi
927
928 tc filter del dev $host2_if ingress protocol ip pref 1 handle 101 flower
929 tc qdisc del dev $host2_if ingress
930
931 return $err
932}
933
934flood_unicast_test()
935{
936 local br_port=$1
937 local host1_if=$2
938 local host2_if=$3
939 local mac=de:ad:be:ef:13:37
940 local ip=192.0.2.100
941
942 RET=0
943
944 bridge link set dev $br_port flood off
945
946 flood_test_do false $mac $ip $host1_if $host2_if
947 check_err $? "Packet flooded when should not"
948
949 bridge link set dev $br_port flood on
950
951 flood_test_do true $mac $ip $host1_if $host2_if
952 check_err $? "Packet was not flooded when should"
953
954 log_test "Unknown unicast flood"
955}
956
957flood_multicast_test()
958{
959 local br_port=$1
960 local host1_if=$2
961 local host2_if=$3
962 local mac=01:00:5e:00:00:01
963 local ip=239.0.0.1
964
965 RET=0
966
967 bridge link set dev $br_port mcast_flood off
968
969 flood_test_do false $mac $ip $host1_if $host2_if
970 check_err $? "Packet flooded when should not"
971
972 bridge link set dev $br_port mcast_flood on
973
974 flood_test_do true $mac $ip $host1_if $host2_if
975 check_err $? "Packet was not flooded when should"
976
977 log_test "Unregistered multicast flood"
978}
979
980flood_test()
981{
982 # `br_port` is connected to `host2_if`
983 local br_port=$1
984 local host1_if=$2
985 local host2_if=$3
986
987 flood_unicast_test $br_port $host1_if $host2_if
988 flood_multicast_test $br_port $host1_if $host2_if
989}