194d302deSIdo Schimmel#!/bin/bash 294d302deSIdo Schimmel# SPDX-License-Identifier: GPL-2.0 394d302deSIdo Schimmel# 494d302deSIdo Schimmel# Test VxLAN flooding. The device stores flood records in a singly linked list 594d302deSIdo Schimmel# where each record stores up to three IPv4 addresses of remote VTEPs. The test 694d302deSIdo Schimmel# verifies that packets are correctly flooded in various cases such as deletion 794d302deSIdo Schimmel# of a record in the middle of the list. 894d302deSIdo Schimmel# 994d302deSIdo Schimmel# +--------------------+ 1094d302deSIdo Schimmel# | H1 (vrf) | 1194d302deSIdo Schimmel# | + $h1 | 1294d302deSIdo Schimmel# | | 203.0.113.1/24| 1394d302deSIdo Schimmel# +----|---------------+ 1494d302deSIdo Schimmel# | 1594d302deSIdo Schimmel# +----|----------------------------------------------------------------------+ 1694d302deSIdo Schimmel# | SW | | 1794d302deSIdo Schimmel# | +--|--------------------------------------------------------------------+ | 1894d302deSIdo Schimmel# | | + $swp1 BR0 (802.1d) | | 1994d302deSIdo Schimmel# | | | | 2094d302deSIdo Schimmel# | | + vxlan0 (vxlan) | | 2194d302deSIdo Schimmel# | | local 198.51.100.1 | | 2294d302deSIdo Schimmel# | | remote 198.51.100.{2..13} | | 2394d302deSIdo Schimmel# | | id 10 dstport 4789 | | 2494d302deSIdo Schimmel# | +-----------------------------------------------------------------------+ | 2594d302deSIdo Schimmel# | | 2694d302deSIdo Schimmel# | 198.51.100.0/24 via 192.0.2.2 | 2794d302deSIdo Schimmel# | | 2894d302deSIdo Schimmel# | + $rp1 | 2994d302deSIdo Schimmel# | | 192.0.2.1/24 | 3094d302deSIdo Schimmel# +----|----------------------------------------------------------------------+ 3194d302deSIdo Schimmel# | 3294d302deSIdo Schimmel# +----|--------------------------------------------------------+ 3394d302deSIdo Schimmel# | | R2 (vrf) | 3494d302deSIdo Schimmel# | + $rp2 | 3594d302deSIdo Schimmel# | 192.0.2.2/24 | 3694d302deSIdo Schimmel# | | 3794d302deSIdo Schimmel# +-------------------------------------------------------------+ 3894d302deSIdo Schimmel 3994d302deSIdo Schimmellib_dir=$(dirname $0)/../../../net/forwarding 4094d302deSIdo Schimmel 4194d302deSIdo SchimmelALL_TESTS="flooding_test" 4294d302deSIdo SchimmelNUM_NETIFS=4 4394d302deSIdo Schimmelsource $lib_dir/tc_common.sh 4494d302deSIdo Schimmelsource $lib_dir/lib.sh 4594d302deSIdo Schimmel 4694d302deSIdo Schimmelh1_create() 4794d302deSIdo Schimmel{ 4894d302deSIdo Schimmel simple_if_init $h1 203.0.113.1/24 4994d302deSIdo Schimmel} 5094d302deSIdo Schimmel 5194d302deSIdo Schimmelh1_destroy() 5294d302deSIdo Schimmel{ 5394d302deSIdo Schimmel simple_if_fini $h1 203.0.113.1/24 5494d302deSIdo Schimmel} 5594d302deSIdo Schimmel 5694d302deSIdo Schimmelswitch_create() 5794d302deSIdo Schimmel{ 5894d302deSIdo Schimmel # Make sure the bridge uses the MAC address of the local port and 5994d302deSIdo Schimmel # not that of the VxLAN's device 6094d302deSIdo Schimmel ip link add dev br0 type bridge mcast_snooping 0 6194d302deSIdo Schimmel ip link set dev br0 address $(mac_get $swp1) 6294d302deSIdo Schimmel 6394d302deSIdo Schimmel ip link add name vxlan0 type vxlan id 10 nolearning noudpcsum \ 6494d302deSIdo Schimmel ttl 20 tos inherit local 198.51.100.1 dstport 4789 6594d302deSIdo Schimmel 6694d302deSIdo Schimmel ip address add 198.51.100.1/32 dev lo 6794d302deSIdo Schimmel 6894d302deSIdo Schimmel ip link set dev $swp1 master br0 6994d302deSIdo Schimmel ip link set dev vxlan0 master br0 7094d302deSIdo Schimmel 7194d302deSIdo Schimmel ip link set dev br0 up 7294d302deSIdo Schimmel ip link set dev $swp1 up 7394d302deSIdo Schimmel ip link set dev vxlan0 up 7494d302deSIdo Schimmel} 7594d302deSIdo Schimmel 7694d302deSIdo Schimmelswitch_destroy() 7794d302deSIdo Schimmel{ 7894d302deSIdo Schimmel ip link set dev vxlan0 down 7994d302deSIdo Schimmel ip link set dev $swp1 down 8094d302deSIdo Schimmel ip link set dev br0 down 8194d302deSIdo Schimmel 8294d302deSIdo Schimmel ip link set dev vxlan0 nomaster 8394d302deSIdo Schimmel ip link set dev $swp1 nomaster 8494d302deSIdo Schimmel 8594d302deSIdo Schimmel ip address del 198.51.100.1/32 dev lo 8694d302deSIdo Schimmel 8794d302deSIdo Schimmel ip link del dev vxlan0 8894d302deSIdo Schimmel 8994d302deSIdo Schimmel ip link del dev br0 9094d302deSIdo Schimmel} 9194d302deSIdo Schimmel 9294d302deSIdo Schimmelrouter1_create() 9394d302deSIdo Schimmel{ 9494d302deSIdo Schimmel # This router is in the default VRF, where the VxLAN device is 9594d302deSIdo Schimmel # performing the L3 lookup 9694d302deSIdo Schimmel ip link set dev $rp1 up 9794d302deSIdo Schimmel ip address add 192.0.2.1/24 dev $rp1 9894d302deSIdo Schimmel ip route add 198.51.100.0/24 via 192.0.2.2 9994d302deSIdo Schimmel} 10094d302deSIdo Schimmel 10194d302deSIdo Schimmelrouter1_destroy() 10294d302deSIdo Schimmel{ 10394d302deSIdo Schimmel ip route del 198.51.100.0/24 via 192.0.2.2 10494d302deSIdo Schimmel ip address del 192.0.2.1/24 dev $rp1 10594d302deSIdo Schimmel ip link set dev $rp1 down 10694d302deSIdo Schimmel} 10794d302deSIdo Schimmel 10894d302deSIdo Schimmelrouter2_create() 10994d302deSIdo Schimmel{ 11094d302deSIdo Schimmel # This router is not in the default VRF, so use simple_if_init() 11194d302deSIdo Schimmel simple_if_init $rp2 192.0.2.2/24 11294d302deSIdo Schimmel} 11394d302deSIdo Schimmel 11494d302deSIdo Schimmelrouter2_destroy() 11594d302deSIdo Schimmel{ 11694d302deSIdo Schimmel simple_if_fini $rp2 192.0.2.2/24 11794d302deSIdo Schimmel} 11894d302deSIdo Schimmel 11994d302deSIdo Schimmelsetup_prepare() 12094d302deSIdo Schimmel{ 12194d302deSIdo Schimmel h1=${NETIFS[p1]} 12294d302deSIdo Schimmel swp1=${NETIFS[p2]} 12394d302deSIdo Schimmel 12494d302deSIdo Schimmel rp1=${NETIFS[p3]} 12594d302deSIdo Schimmel rp2=${NETIFS[p4]} 12694d302deSIdo Schimmel 12794d302deSIdo Schimmel vrf_prepare 12894d302deSIdo Schimmel 12994d302deSIdo Schimmel h1_create 13094d302deSIdo Schimmel 13194d302deSIdo Schimmel switch_create 13294d302deSIdo Schimmel 13394d302deSIdo Schimmel router1_create 13494d302deSIdo Schimmel router2_create 13594d302deSIdo Schimmel 13694d302deSIdo Schimmel forwarding_enable 13794d302deSIdo Schimmel} 13894d302deSIdo Schimmel 13994d302deSIdo Schimmelcleanup() 14094d302deSIdo Schimmel{ 14194d302deSIdo Schimmel pre_cleanup 14294d302deSIdo Schimmel 14394d302deSIdo Schimmel forwarding_restore 14494d302deSIdo Schimmel 14594d302deSIdo Schimmel router2_destroy 14694d302deSIdo Schimmel router1_destroy 14794d302deSIdo Schimmel 14894d302deSIdo Schimmel switch_destroy 14994d302deSIdo Schimmel 15094d302deSIdo Schimmel h1_destroy 15194d302deSIdo Schimmel 15294d302deSIdo Schimmel vrf_cleanup 15394d302deSIdo Schimmel} 15494d302deSIdo Schimmel 15594d302deSIdo Schimmelflooding_remotes_add() 15694d302deSIdo Schimmel{ 15794d302deSIdo Schimmel local num_remotes=$1 15894d302deSIdo Schimmel local lsb 15994d302deSIdo Schimmel local i 16094d302deSIdo Schimmel 16194d302deSIdo Schimmel for i in $(eval echo {1..$num_remotes}); do 16294d302deSIdo Schimmel lsb=$((i + 1)) 16394d302deSIdo Schimmel 16494d302deSIdo Schimmel bridge fdb append 00:00:00:00:00:00 dev vxlan0 self \ 16594d302deSIdo Schimmel dst 198.51.100.$lsb 16694d302deSIdo Schimmel done 16794d302deSIdo Schimmel} 16894d302deSIdo Schimmel 16994d302deSIdo Schimmelflooding_filters_add() 17094d302deSIdo Schimmel{ 17194d302deSIdo Schimmel local num_remotes=$1 17294d302deSIdo Schimmel local lsb 17394d302deSIdo Schimmel local i 17494d302deSIdo Schimmel 175*044011fdSIdo Schimmel # Prevent unwanted packets from entering the bridge and interfering 176*044011fdSIdo Schimmel # with the test. 177*044011fdSIdo Schimmel tc qdisc add dev br0 clsact 178*044011fdSIdo Schimmel tc filter add dev br0 egress protocol all pref 1 handle 1 \ 179*044011fdSIdo Schimmel matchall skip_hw action drop 180*044011fdSIdo Schimmel tc qdisc add dev $h1 clsact 181*044011fdSIdo Schimmel tc filter add dev $h1 egress protocol all pref 1 handle 1 \ 182*044011fdSIdo Schimmel flower skip_hw dst_mac de:ad:be:ef:13:37 action pass 183*044011fdSIdo Schimmel tc filter add dev $h1 egress protocol all pref 2 handle 2 \ 184*044011fdSIdo Schimmel matchall skip_hw action drop 185*044011fdSIdo Schimmel 18694d302deSIdo Schimmel tc qdisc add dev $rp2 clsact 18794d302deSIdo Schimmel 18894d302deSIdo Schimmel for i in $(eval echo {1..$num_remotes}); do 18994d302deSIdo Schimmel lsb=$((i + 1)) 19094d302deSIdo Schimmel 19194d302deSIdo Schimmel tc filter add dev $rp2 ingress protocol ip pref $i handle $i \ 19294d302deSIdo Schimmel flower ip_proto udp dst_ip 198.51.100.$lsb \ 19394d302deSIdo Schimmel dst_port 4789 skip_sw action drop 19494d302deSIdo Schimmel done 19594d302deSIdo Schimmel} 19694d302deSIdo Schimmel 19794d302deSIdo Schimmelflooding_filters_del() 19894d302deSIdo Schimmel{ 19994d302deSIdo Schimmel local num_remotes=$1 20094d302deSIdo Schimmel local i 20194d302deSIdo Schimmel 20294d302deSIdo Schimmel for i in $(eval echo {1..$num_remotes}); do 20394d302deSIdo Schimmel tc filter del dev $rp2 ingress protocol ip pref $i \ 20494d302deSIdo Schimmel handle $i flower 20594d302deSIdo Schimmel done 20694d302deSIdo Schimmel 20794d302deSIdo Schimmel tc qdisc del dev $rp2 clsact 208*044011fdSIdo Schimmel 209*044011fdSIdo Schimmel tc filter del dev $h1 egress protocol all pref 2 handle 2 matchall 210*044011fdSIdo Schimmel tc filter del dev $h1 egress protocol all pref 1 handle 1 flower 211*044011fdSIdo Schimmel tc qdisc del dev $h1 clsact 212*044011fdSIdo Schimmel tc filter del dev br0 egress protocol all pref 1 handle 1 matchall 213*044011fdSIdo Schimmel tc qdisc del dev br0 clsact 21494d302deSIdo Schimmel} 21594d302deSIdo Schimmel 21694d302deSIdo Schimmelflooding_check_packets() 21794d302deSIdo Schimmel{ 21894d302deSIdo Schimmel local packets=("$@") 21994d302deSIdo Schimmel local num_remotes=${#packets[@]} 22094d302deSIdo Schimmel local i 22194d302deSIdo Schimmel 22294d302deSIdo Schimmel for i in $(eval echo {1..$num_remotes}); do 22394d302deSIdo Schimmel tc_check_packets "dev $rp2 ingress" $i ${packets[i - 1]} 22494d302deSIdo Schimmel check_err $? "remote $i - did not get expected number of packets" 22594d302deSIdo Schimmel done 22694d302deSIdo Schimmel} 22794d302deSIdo Schimmel 22894d302deSIdo Schimmelflooding_test() 22994d302deSIdo Schimmel{ 23094d302deSIdo Schimmel # Use 12 remote VTEPs that will be stored in 4 records. The array 23194d302deSIdo Schimmel # 'packets' will store how many packets are expected to be received 23294d302deSIdo Schimmel # by each remote VTEP at each stage of the test 23394d302deSIdo Schimmel declare -a packets=(1 1 1 1 1 1 1 1 1 1 1 1) 23494d302deSIdo Schimmel local num_remotes=12 23594d302deSIdo Schimmel 23694d302deSIdo Schimmel RET=0 23794d302deSIdo Schimmel 23894d302deSIdo Schimmel # Add FDB entries for remote VTEPs and corresponding tc filters on the 23994d302deSIdo Schimmel # ingress of the nexthop router. These filters will count how many 24094d302deSIdo Schimmel # packets were flooded to each remote VTEP 24194d302deSIdo Schimmel flooding_remotes_add $num_remotes 24294d302deSIdo Schimmel flooding_filters_add $num_remotes 24394d302deSIdo Schimmel 24494d302deSIdo Schimmel # Send one packet and make sure it is flooded to all the remote VTEPs 24594d302deSIdo Schimmel $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 24694d302deSIdo Schimmel flooding_check_packets "${packets[@]}" 24794d302deSIdo Schimmel log_test "flood after 1 packet" 24894d302deSIdo Schimmel 24994d302deSIdo Schimmel # Delete the third record which corresponds to VTEPs with LSB 8..10 25094d302deSIdo Schimmel # and check that packet is flooded correctly when we remove a record 25194d302deSIdo Schimmel # from the middle of the list 25294d302deSIdo Schimmel RET=0 25394d302deSIdo Schimmel 25494d302deSIdo Schimmel packets=(2 2 2 2 2 2 1 1 1 2 2 2) 25594d302deSIdo Schimmel bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.8 25694d302deSIdo Schimmel bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.9 25794d302deSIdo Schimmel bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.10 25894d302deSIdo Schimmel 25994d302deSIdo Schimmel $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 26094d302deSIdo Schimmel flooding_check_packets "${packets[@]}" 26194d302deSIdo Schimmel log_test "flood after 2 packets" 26294d302deSIdo Schimmel 26394d302deSIdo Schimmel # Delete the first record and make sure the packet is flooded correctly 26494d302deSIdo Schimmel RET=0 26594d302deSIdo Schimmel 26694d302deSIdo Schimmel packets=(2 2 2 3 3 3 1 1 1 3 3 3) 26794d302deSIdo Schimmel bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.2 26894d302deSIdo Schimmel bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.3 26994d302deSIdo Schimmel bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.4 27094d302deSIdo Schimmel 27194d302deSIdo Schimmel $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 27294d302deSIdo Schimmel flooding_check_packets "${packets[@]}" 27394d302deSIdo Schimmel log_test "flood after 3 packets" 27494d302deSIdo Schimmel 27594d302deSIdo Schimmel # Delete the last record and make sure the packet is flooded correctly 27694d302deSIdo Schimmel RET=0 27794d302deSIdo Schimmel 27894d302deSIdo Schimmel packets=(2 2 2 4 4 4 1 1 1 3 3 3) 27994d302deSIdo Schimmel bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.11 28094d302deSIdo Schimmel bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.12 28194d302deSIdo Schimmel bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.13 28294d302deSIdo Schimmel 28394d302deSIdo Schimmel $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 28494d302deSIdo Schimmel flooding_check_packets "${packets[@]}" 28594d302deSIdo Schimmel log_test "flood after 4 packets" 28694d302deSIdo Schimmel 28794d302deSIdo Schimmel # Delete the last record, one entry at a time and make sure single 28894d302deSIdo Schimmel # entries are correctly removed 28994d302deSIdo Schimmel RET=0 29094d302deSIdo Schimmel 29194d302deSIdo Schimmel packets=(2 2 2 4 5 5 1 1 1 3 3 3) 29294d302deSIdo Schimmel bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.5 29394d302deSIdo Schimmel 29494d302deSIdo Schimmel $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 29594d302deSIdo Schimmel flooding_check_packets "${packets[@]}" 29694d302deSIdo Schimmel log_test "flood after 5 packets" 29794d302deSIdo Schimmel 29894d302deSIdo Schimmel RET=0 29994d302deSIdo Schimmel 30094d302deSIdo Schimmel packets=(2 2 2 4 5 6 1 1 1 3 3 3) 30194d302deSIdo Schimmel bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.6 30294d302deSIdo Schimmel 30394d302deSIdo Schimmel $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 30494d302deSIdo Schimmel flooding_check_packets "${packets[@]}" 30594d302deSIdo Schimmel log_test "flood after 6 packets" 30694d302deSIdo Schimmel 30794d302deSIdo Schimmel RET=0 30894d302deSIdo Schimmel 30994d302deSIdo Schimmel packets=(2 2 2 4 5 6 1 1 1 3 3 3) 31094d302deSIdo Schimmel bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.7 31194d302deSIdo Schimmel 31294d302deSIdo Schimmel $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 31394d302deSIdo Schimmel flooding_check_packets "${packets[@]}" 31494d302deSIdo Schimmel log_test "flood after 7 packets" 31594d302deSIdo Schimmel 31694d302deSIdo Schimmel flooding_filters_del $num_remotes 31794d302deSIdo Schimmel} 31894d302deSIdo Schimmel 31994d302deSIdo Schimmeltrap cleanup EXIT 32094d302deSIdo Schimmel 32194d302deSIdo Schimmelsetup_prepare 32294d302deSIdo Schimmelsetup_wait 32394d302deSIdo Schimmel 32494d302deSIdo Schimmeltests_run 32594d302deSIdo Schimmel 32694d302deSIdo Schimmelexit $EXIT_STATUS 327