335 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03#4# Test VxLAN flooding. The device stores flood records in a singly linked list5# where each record stores up to five IPv6 addresses of remote VTEPs. The test6# verifies that packets are correctly flooded in various cases such as deletion7# 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/forwarding40 41ALL_TESTS="flooding_test"42NUM_NETIFS=443source $lib_dir/tc_common.sh44source $lib_dir/lib.sh45 46h1_create()47{48 simple_if_init $h1 2001:db8:1::1/6449}50 51h1_destroy()52{53 simple_if_fini $h1 2001:db8:1::1/6454}55 56switch_create()57{58 # Make sure the bridge uses the MAC address of the local port and59 # not that of the VxLAN's device60 ip link add dev br0 type bridge mcast_snooping 061 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 478966 67 ip address add 2001:db8:2::1/128 dev lo68 69 ip link set dev $swp1 master br070 ip link set dev vxlan0 master br071 72 ip link set dev br0 up73 ip link set dev $swp1 up74 ip link set dev vxlan0 up75}76 77switch_destroy()78{79 ip link set dev vxlan0 down80 ip link set dev $swp1 down81 ip link set dev br0 down82 83 ip link set dev vxlan0 nomaster84 ip link set dev $swp1 nomaster85 86 ip address del 2001:db8:2::1/128 dev lo87 88 ip link del dev vxlan089 90 ip link del dev br091}92 93router1_create()94{95 # This router is in the default VRF, where the VxLAN device is96 # performing the L3 lookup97 ip link set dev $rp1 up98 ip address add 2001:db8:3::1/64 dev $rp199 ip route add 2001:db8:2::0/64 via 2001:db8:3::2100}101 102router1_destroy()103{104 ip route del 2001:db8:2::0/64 via 2001:db8:3::2105 ip address del 2001:db8:3::1/64 dev $rp1106 ip link set dev $rp1 down107}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/64113}114 115router2_destroy()116{117 simple_if_fini $rp2 2001:db8:3::2/64118}119 120setup_prepare()121{122 h1=${NETIFS[p1]}123 swp1=${NETIFS[p2]}124 125 rp1=${NETIFS[p3]}126 rp2=${NETIFS[p4]}127 128 vrf_prepare129 130 h1_create131 132 switch_create133 134 router1_create135 router2_create136 137 forwarding_enable138}139 140cleanup()141{142 pre_cleanup143 144 forwarding_restore145 146 router2_destroy147 router1_destroy148 149 switch_destroy150 151 h1_destroy152 153 vrf_cleanup154}155 156flooding_remotes_add()157{158 local num_remotes=$1159 local lsb160 local i161 162 for i in $(eval echo {1..$num_remotes}); do163 lsb=$((i + 1))164 165 bridge fdb append 00:00:00:00:00:00 dev vxlan0 self \166 dst 2001:db8:2::$lsb167 done168}169 170flooding_filters_add()171{172 local num_remotes=$1173 local lsb174 local i175 176 tc qdisc add dev $rp2 clsact177 178 for i in $(eval echo {1..$num_remotes}); do179 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 drop184 done185}186 187flooding_filters_del()188{189 local num_remotes=$1190 local i191 192 for i in $(eval echo {1..$num_remotes}); do193 tc filter del dev $rp2 ingress protocol ipv6 pref $i \194 handle $i flower195 done196 197 tc qdisc del dev $rp2 clsact198}199 200flooding_check_packets()201{202 local packets=("$@")203 local num_remotes=${#packets[@]}204 local i205 206 for i in $(eval echo {1..$num_remotes}); do207 tc_check_packets "dev $rp2 ingress" $i ${packets[i - 1]}208 check_err $? "remote $i - did not get expected number of packets"209 done210}211 212flooding_test()213{214 # Use 20 remote VTEPs that will be stored in 4 records. The array215 # 'packets' will store how many packets are expected to be received216 # by each remote VTEP at each stage of the test217 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=20219 220 RET=0221 222 # Add FDB entries for remote VTEPs and corresponding tc filters on the223 # ingress of the nexthop router. These filters will count how many224 # packets were flooded to each remote VTEP225 flooding_remotes_add $num_remotes226 flooding_filters_add $num_remotes227 228 # Send one packet and make sure it is flooded to all the remote VTEPs229 $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1230 flooding_check_packets "${packets[@]}"231 log_test "flood after 1 packet"232 233 # Delete the third record which corresponds to VTEPs with LSB 12..16234 # and check that packet is flooded correctly when we remove a record235 # from the middle of the list236 RET=0237 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::12240 bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::13241 bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::14242 bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::15243 bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::16244 245 $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1246 flooding_check_packets "${packets[@]}"247 log_test "flood after 2 packets"248 249 # Delete the first record and make sure the packet is flooded correctly250 RET=0251 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::2254 bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::3255 bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::4256 bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::5257 bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::6258 259 $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1260 flooding_check_packets "${packets[@]}"261 log_test "flood after 3 packets"262 263 # Delete the last record and make sure the packet is flooded correctly264 RET=0265 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::17268 bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::18269 bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::19270 bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::20271 bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::21272 273 $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1274 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 single278 # entries are correctly removed279 RET=0280 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::7283 284 $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1285 flooding_check_packets "${packets[@]}"286 log_test "flood after 5 packets"287 288 RET=0289 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::8292 293 $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1294 flooding_check_packets "${packets[@]}"295 log_test "flood after 6 packets"296 297 RET=0298 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::9301 302 $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1303 flooding_check_packets "${packets[@]}"304 log_test "flood after 7 packets"305 306 RET=0307 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::10310 311 $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1312 flooding_check_packets "${packets[@]}"313 log_test "flood after 8 packets"314 315 RET=0316 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::11319 320 $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1321 flooding_check_packets "${packets[@]}"322 log_test "flood after 9 packets"323 324 flooding_filters_del $num_remotes325}326 327trap cleanup EXIT328 329setup_prepare330setup_wait331 332tests_run333 334exit $EXIT_STATUS335