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