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