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