1*7ae23eddSAmit Cohen#!/bin/bash 2*7ae23eddSAmit Cohen# SPDX-License-Identifier: GPL-2.0 3*7ae23eddSAmit Cohen# 4*7ae23eddSAmit Cohen# Test VxLAN flooding. The device stores flood records in a singly linked list 5*7ae23eddSAmit Cohen# where each record stores up to five IPv6 addresses of remote VTEPs. The test 6*7ae23eddSAmit Cohen# verifies that packets are correctly flooded in various cases such as deletion 7*7ae23eddSAmit Cohen# of a record in the middle of the list. 8*7ae23eddSAmit Cohen# 9*7ae23eddSAmit Cohen# +-----------------------+ 10*7ae23eddSAmit Cohen# | H1 (vrf) | 11*7ae23eddSAmit Cohen# | + $h1 | 12*7ae23eddSAmit Cohen# | | 2001:db8:1::1/64 | 13*7ae23eddSAmit Cohen# +----|------------------+ 14*7ae23eddSAmit Cohen# | 15*7ae23eddSAmit Cohen# +----|----------------------------------------------------------------------+ 16*7ae23eddSAmit Cohen# | SW | | 17*7ae23eddSAmit Cohen# | +--|--------------------------------------------------------------------+ | 18*7ae23eddSAmit Cohen# | | + $swp1 BR0 (802.1d) | | 19*7ae23eddSAmit Cohen# | | | | 20*7ae23eddSAmit Cohen# | | + vxlan0 (vxlan) | | 21*7ae23eddSAmit Cohen# | | local 2001:db8:2::1 | | 22*7ae23eddSAmit Cohen# | | remote 2001:db8:2::{2..21} | | 23*7ae23eddSAmit Cohen# | | id 10 dstport 4789 | | 24*7ae23eddSAmit Cohen# | +-----------------------------------------------------------------------+ | 25*7ae23eddSAmit Cohen# | | 26*7ae23eddSAmit Cohen# | 2001:db8:2::0/64 via 2001:db8:3::2 | 27*7ae23eddSAmit Cohen# | | 28*7ae23eddSAmit Cohen# | + $rp1 | 29*7ae23eddSAmit Cohen# | | 2001:db8:3::1/64 | 30*7ae23eddSAmit Cohen# +----|----------------------------------------------------------------------+ 31*7ae23eddSAmit Cohen# | 32*7ae23eddSAmit Cohen# +----|--------------------------------------------------------+ 33*7ae23eddSAmit Cohen# | | R2 (vrf) | 34*7ae23eddSAmit Cohen# | + $rp2 | 35*7ae23eddSAmit Cohen# | 2001:db8:3::2/64 | 36*7ae23eddSAmit Cohen# | | 37*7ae23eddSAmit Cohen# +-------------------------------------------------------------+ 38*7ae23eddSAmit Cohen 39*7ae23eddSAmit Cohenlib_dir=$(dirname $0)/../../../../net/forwarding 40*7ae23eddSAmit Cohen 41*7ae23eddSAmit CohenALL_TESTS="flooding_test" 42*7ae23eddSAmit CohenNUM_NETIFS=4 43*7ae23eddSAmit Cohensource $lib_dir/tc_common.sh 44*7ae23eddSAmit Cohensource $lib_dir/lib.sh 45*7ae23eddSAmit Cohen 46*7ae23eddSAmit Cohenh1_create() 47*7ae23eddSAmit Cohen{ 48*7ae23eddSAmit Cohen simple_if_init $h1 2001:db8:1::1/64 49*7ae23eddSAmit Cohen} 50*7ae23eddSAmit Cohen 51*7ae23eddSAmit Cohenh1_destroy() 52*7ae23eddSAmit Cohen{ 53*7ae23eddSAmit Cohen simple_if_fini $h1 2001:db8:1::1/64 54*7ae23eddSAmit Cohen} 55*7ae23eddSAmit Cohen 56*7ae23eddSAmit Cohenswitch_create() 57*7ae23eddSAmit Cohen{ 58*7ae23eddSAmit Cohen # Make sure the bridge uses the MAC address of the local port and 59*7ae23eddSAmit Cohen # not that of the VxLAN's device 60*7ae23eddSAmit Cohen ip link add dev br0 type bridge mcast_snooping 0 61*7ae23eddSAmit Cohen ip link set dev br0 address $(mac_get $swp1) 62*7ae23eddSAmit Cohen 63*7ae23eddSAmit Cohen ip link add name vxlan0 type vxlan id 10 nolearning \ 64*7ae23eddSAmit Cohen udp6zerocsumrx udp6zerocsumtx ttl 20 tos inherit \ 65*7ae23eddSAmit Cohen local 2001:db8:2::1 dstport 4789 66*7ae23eddSAmit Cohen 67*7ae23eddSAmit Cohen ip address add 2001:db8:2::1/128 dev lo 68*7ae23eddSAmit Cohen 69*7ae23eddSAmit Cohen ip link set dev $swp1 master br0 70*7ae23eddSAmit Cohen ip link set dev vxlan0 master br0 71*7ae23eddSAmit Cohen 72*7ae23eddSAmit Cohen ip link set dev br0 up 73*7ae23eddSAmit Cohen ip link set dev $swp1 up 74*7ae23eddSAmit Cohen ip link set dev vxlan0 up 75*7ae23eddSAmit Cohen} 76*7ae23eddSAmit Cohen 77*7ae23eddSAmit Cohenswitch_destroy() 78*7ae23eddSAmit Cohen{ 79*7ae23eddSAmit Cohen ip link set dev vxlan0 down 80*7ae23eddSAmit Cohen ip link set dev $swp1 down 81*7ae23eddSAmit Cohen ip link set dev br0 down 82*7ae23eddSAmit Cohen 83*7ae23eddSAmit Cohen ip link set dev vxlan0 nomaster 84*7ae23eddSAmit Cohen ip link set dev $swp1 nomaster 85*7ae23eddSAmit Cohen 86*7ae23eddSAmit Cohen ip address del 2001:db8:2::1/128 dev lo 87*7ae23eddSAmit Cohen 88*7ae23eddSAmit Cohen ip link del dev vxlan0 89*7ae23eddSAmit Cohen 90*7ae23eddSAmit Cohen ip link del dev br0 91*7ae23eddSAmit Cohen} 92*7ae23eddSAmit Cohen 93*7ae23eddSAmit Cohenrouter1_create() 94*7ae23eddSAmit Cohen{ 95*7ae23eddSAmit Cohen # This router is in the default VRF, where the VxLAN device is 96*7ae23eddSAmit Cohen # performing the L3 lookup 97*7ae23eddSAmit Cohen ip link set dev $rp1 up 98*7ae23eddSAmit Cohen ip address add 2001:db8:3::1/64 dev $rp1 99*7ae23eddSAmit Cohen ip route add 2001:db8:2::0/64 via 2001:db8:3::2 100*7ae23eddSAmit Cohen} 101*7ae23eddSAmit Cohen 102*7ae23eddSAmit Cohenrouter1_destroy() 103*7ae23eddSAmit Cohen{ 104*7ae23eddSAmit Cohen ip route del 2001:db8:2::0/64 via 2001:db8:3::2 105*7ae23eddSAmit Cohen ip address del 2001:db8:3::1/64 dev $rp1 106*7ae23eddSAmit Cohen ip link set dev $rp1 down 107*7ae23eddSAmit Cohen} 108*7ae23eddSAmit Cohen 109*7ae23eddSAmit Cohenrouter2_create() 110*7ae23eddSAmit Cohen{ 111*7ae23eddSAmit Cohen # This router is not in the default VRF, so use simple_if_init() 112*7ae23eddSAmit Cohen simple_if_init $rp2 2001:db8:3::2/64 113*7ae23eddSAmit Cohen} 114*7ae23eddSAmit Cohen 115*7ae23eddSAmit Cohenrouter2_destroy() 116*7ae23eddSAmit Cohen{ 117*7ae23eddSAmit Cohen simple_if_fini $rp2 2001:db8:3::2/64 118*7ae23eddSAmit Cohen} 119*7ae23eddSAmit Cohen 120*7ae23eddSAmit Cohensetup_prepare() 121*7ae23eddSAmit Cohen{ 122*7ae23eddSAmit Cohen h1=${NETIFS[p1]} 123*7ae23eddSAmit Cohen swp1=${NETIFS[p2]} 124*7ae23eddSAmit Cohen 125*7ae23eddSAmit Cohen rp1=${NETIFS[p3]} 126*7ae23eddSAmit Cohen rp2=${NETIFS[p4]} 127*7ae23eddSAmit Cohen 128*7ae23eddSAmit Cohen vrf_prepare 129*7ae23eddSAmit Cohen 130*7ae23eddSAmit Cohen h1_create 131*7ae23eddSAmit Cohen 132*7ae23eddSAmit Cohen switch_create 133*7ae23eddSAmit Cohen 134*7ae23eddSAmit Cohen router1_create 135*7ae23eddSAmit Cohen router2_create 136*7ae23eddSAmit Cohen 137*7ae23eddSAmit Cohen forwarding_enable 138*7ae23eddSAmit Cohen} 139*7ae23eddSAmit Cohen 140*7ae23eddSAmit Cohencleanup() 141*7ae23eddSAmit Cohen{ 142*7ae23eddSAmit Cohen pre_cleanup 143*7ae23eddSAmit Cohen 144*7ae23eddSAmit Cohen forwarding_restore 145*7ae23eddSAmit Cohen 146*7ae23eddSAmit Cohen router2_destroy 147*7ae23eddSAmit Cohen router1_destroy 148*7ae23eddSAmit Cohen 149*7ae23eddSAmit Cohen switch_destroy 150*7ae23eddSAmit Cohen 151*7ae23eddSAmit Cohen h1_destroy 152*7ae23eddSAmit Cohen 153*7ae23eddSAmit Cohen vrf_cleanup 154*7ae23eddSAmit Cohen} 155*7ae23eddSAmit Cohen 156*7ae23eddSAmit Cohenflooding_remotes_add() 157*7ae23eddSAmit Cohen{ 158*7ae23eddSAmit Cohen local num_remotes=$1 159*7ae23eddSAmit Cohen local lsb 160*7ae23eddSAmit Cohen local i 161*7ae23eddSAmit Cohen 162*7ae23eddSAmit Cohen for i in $(eval echo {1..$num_remotes}); do 163*7ae23eddSAmit Cohen lsb=$((i + 1)) 164*7ae23eddSAmit Cohen 165*7ae23eddSAmit Cohen bridge fdb append 00:00:00:00:00:00 dev vxlan0 self \ 166*7ae23eddSAmit Cohen dst 2001:db8:2::$lsb 167*7ae23eddSAmit Cohen done 168*7ae23eddSAmit Cohen} 169*7ae23eddSAmit Cohen 170*7ae23eddSAmit Cohenflooding_filters_add() 171*7ae23eddSAmit Cohen{ 172*7ae23eddSAmit Cohen local num_remotes=$1 173*7ae23eddSAmit Cohen local lsb 174*7ae23eddSAmit Cohen local i 175*7ae23eddSAmit Cohen 176*7ae23eddSAmit Cohen tc qdisc add dev $rp2 clsact 177*7ae23eddSAmit Cohen 178*7ae23eddSAmit Cohen for i in $(eval echo {1..$num_remotes}); do 179*7ae23eddSAmit Cohen lsb=$((i + 1)) 180*7ae23eddSAmit Cohen 181*7ae23eddSAmit Cohen tc filter add dev $rp2 ingress protocol ipv6 pref $i handle $i \ 182*7ae23eddSAmit Cohen flower ip_proto udp dst_ip 2001:db8:2::$lsb \ 183*7ae23eddSAmit Cohen dst_port 4789 skip_sw action drop 184*7ae23eddSAmit Cohen done 185*7ae23eddSAmit Cohen} 186*7ae23eddSAmit Cohen 187*7ae23eddSAmit Cohenflooding_filters_del() 188*7ae23eddSAmit Cohen{ 189*7ae23eddSAmit Cohen local num_remotes=$1 190*7ae23eddSAmit Cohen local i 191*7ae23eddSAmit Cohen 192*7ae23eddSAmit Cohen for i in $(eval echo {1..$num_remotes}); do 193*7ae23eddSAmit Cohen tc filter del dev $rp2 ingress protocol ipv6 pref $i \ 194*7ae23eddSAmit Cohen handle $i flower 195*7ae23eddSAmit Cohen done 196*7ae23eddSAmit Cohen 197*7ae23eddSAmit Cohen tc qdisc del dev $rp2 clsact 198*7ae23eddSAmit Cohen} 199*7ae23eddSAmit Cohen 200*7ae23eddSAmit Cohenflooding_check_packets() 201*7ae23eddSAmit Cohen{ 202*7ae23eddSAmit Cohen local packets=("$@") 203*7ae23eddSAmit Cohen local num_remotes=${#packets[@]} 204*7ae23eddSAmit Cohen local i 205*7ae23eddSAmit Cohen 206*7ae23eddSAmit Cohen for i in $(eval echo {1..$num_remotes}); do 207*7ae23eddSAmit Cohen tc_check_packets "dev $rp2 ingress" $i ${packets[i - 1]} 208*7ae23eddSAmit Cohen check_err $? "remote $i - did not get expected number of packets" 209*7ae23eddSAmit Cohen done 210*7ae23eddSAmit Cohen} 211*7ae23eddSAmit Cohen 212*7ae23eddSAmit Cohenflooding_test() 213*7ae23eddSAmit Cohen{ 214*7ae23eddSAmit Cohen # Use 20 remote VTEPs that will be stored in 4 records. The array 215*7ae23eddSAmit Cohen # 'packets' will store how many packets are expected to be received 216*7ae23eddSAmit Cohen # by each remote VTEP at each stage of the test 217*7ae23eddSAmit Cohen declare -a packets=(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1) 218*7ae23eddSAmit Cohen local num_remotes=20 219*7ae23eddSAmit Cohen 220*7ae23eddSAmit Cohen RET=0 221*7ae23eddSAmit Cohen 222*7ae23eddSAmit Cohen # Add FDB entries for remote VTEPs and corresponding tc filters on the 223*7ae23eddSAmit Cohen # ingress of the nexthop router. These filters will count how many 224*7ae23eddSAmit Cohen # packets were flooded to each remote VTEP 225*7ae23eddSAmit Cohen flooding_remotes_add $num_remotes 226*7ae23eddSAmit Cohen flooding_filters_add $num_remotes 227*7ae23eddSAmit Cohen 228*7ae23eddSAmit Cohen # Send one packet and make sure it is flooded to all the remote VTEPs 229*7ae23eddSAmit Cohen $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 230*7ae23eddSAmit Cohen flooding_check_packets "${packets[@]}" 231*7ae23eddSAmit Cohen log_test "flood after 1 packet" 232*7ae23eddSAmit Cohen 233*7ae23eddSAmit Cohen # Delete the third record which corresponds to VTEPs with LSB 12..16 234*7ae23eddSAmit Cohen # and check that packet is flooded correctly when we remove a record 235*7ae23eddSAmit Cohen # from the middle of the list 236*7ae23eddSAmit Cohen RET=0 237*7ae23eddSAmit Cohen 238*7ae23eddSAmit Cohen packets=(2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2) 239*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::12 240*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::13 241*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::14 242*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::15 243*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::16 244*7ae23eddSAmit Cohen 245*7ae23eddSAmit Cohen $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 246*7ae23eddSAmit Cohen flooding_check_packets "${packets[@]}" 247*7ae23eddSAmit Cohen log_test "flood after 2 packets" 248*7ae23eddSAmit Cohen 249*7ae23eddSAmit Cohen # Delete the first record and make sure the packet is flooded correctly 250*7ae23eddSAmit Cohen RET=0 251*7ae23eddSAmit Cohen 252*7ae23eddSAmit Cohen packets=(2 2 2 2 2 3 3 3 3 3 1 1 1 1 1 3 3 3 3 3) 253*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::2 254*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::3 255*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::4 256*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::5 257*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::6 258*7ae23eddSAmit Cohen 259*7ae23eddSAmit Cohen $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 260*7ae23eddSAmit Cohen flooding_check_packets "${packets[@]}" 261*7ae23eddSAmit Cohen log_test "flood after 3 packets" 262*7ae23eddSAmit Cohen 263*7ae23eddSAmit Cohen # Delete the last record and make sure the packet is flooded correctly 264*7ae23eddSAmit Cohen RET=0 265*7ae23eddSAmit Cohen 266*7ae23eddSAmit Cohen packets=(2 2 2 2 2 4 4 4 4 4 1 1 1 1 1 3 3 3 3 3) 267*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::17 268*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::18 269*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::19 270*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::20 271*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::21 272*7ae23eddSAmit Cohen 273*7ae23eddSAmit Cohen $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 274*7ae23eddSAmit Cohen flooding_check_packets "${packets[@]}" 275*7ae23eddSAmit Cohen log_test "flood after 4 packets" 276*7ae23eddSAmit Cohen 277*7ae23eddSAmit Cohen # Delete the last record, one entry at a time and make sure single 278*7ae23eddSAmit Cohen # entries are correctly removed 279*7ae23eddSAmit Cohen RET=0 280*7ae23eddSAmit Cohen 281*7ae23eddSAmit Cohen packets=(2 2 2 2 2 4 5 5 5 5 1 1 1 1 1 3 3 3 3 3) 282*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::7 283*7ae23eddSAmit Cohen 284*7ae23eddSAmit Cohen $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 285*7ae23eddSAmit Cohen flooding_check_packets "${packets[@]}" 286*7ae23eddSAmit Cohen log_test "flood after 5 packets" 287*7ae23eddSAmit Cohen 288*7ae23eddSAmit Cohen RET=0 289*7ae23eddSAmit Cohen 290*7ae23eddSAmit Cohen packets=(2 2 2 2 2 4 5 6 6 6 1 1 1 1 1 3 3 3 3 3) 291*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::8 292*7ae23eddSAmit Cohen 293*7ae23eddSAmit Cohen $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 294*7ae23eddSAmit Cohen flooding_check_packets "${packets[@]}" 295*7ae23eddSAmit Cohen log_test "flood after 6 packets" 296*7ae23eddSAmit Cohen 297*7ae23eddSAmit Cohen RET=0 298*7ae23eddSAmit Cohen 299*7ae23eddSAmit Cohen packets=(2 2 2 2 2 4 5 6 7 7 1 1 1 1 1 3 3 3 3 3) 300*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::9 301*7ae23eddSAmit Cohen 302*7ae23eddSAmit Cohen $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 303*7ae23eddSAmit Cohen flooding_check_packets "${packets[@]}" 304*7ae23eddSAmit Cohen log_test "flood after 7 packets" 305*7ae23eddSAmit Cohen 306*7ae23eddSAmit Cohen RET=0 307*7ae23eddSAmit Cohen 308*7ae23eddSAmit Cohen packets=(2 2 2 2 2 4 5 6 7 8 1 1 1 1 1 3 3 3 3 3) 309*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::10 310*7ae23eddSAmit Cohen 311*7ae23eddSAmit Cohen $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 312*7ae23eddSAmit Cohen flooding_check_packets "${packets[@]}" 313*7ae23eddSAmit Cohen log_test "flood after 8 packets" 314*7ae23eddSAmit Cohen 315*7ae23eddSAmit Cohen RET=0 316*7ae23eddSAmit Cohen 317*7ae23eddSAmit Cohen packets=(2 2 2 2 2 4 5 6 7 8 1 1 1 1 1 3 3 3 3 3) 318*7ae23eddSAmit Cohen bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::11 319*7ae23eddSAmit Cohen 320*7ae23eddSAmit Cohen $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 321*7ae23eddSAmit Cohen flooding_check_packets "${packets[@]}" 322*7ae23eddSAmit Cohen log_test "flood after 9 packets" 323*7ae23eddSAmit Cohen 324*7ae23eddSAmit Cohen flooding_filters_del $num_remotes 325*7ae23eddSAmit Cohen} 326*7ae23eddSAmit Cohen 327*7ae23eddSAmit Cohentrap cleanup EXIT 328*7ae23eddSAmit Cohen 329*7ae23eddSAmit Cohensetup_prepare 330*7ae23eddSAmit Cohensetup_wait 331*7ae23eddSAmit Cohen 332*7ae23eddSAmit Cohentests_run 333*7ae23eddSAmit Cohen 334*7ae23eddSAmit Cohenexit $EXIT_STATUS 335