Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 #
0004 # Test VxLAN flooding. The device stores flood records in a singly linked list
0005 # where each record stores up to three IPv4 addresses of remote VTEPs. The test
0006 # verifies that packets are correctly flooded in various cases such as deletion
0007 # of a record in the middle of the list.
0008 #
0009 # +--------------------+
0010 # | H1 (vrf)           |
0011 # |    + $h1           |
0012 # |    | 203.0.113.1/24|
0013 # +----|---------------+
0014 #      |
0015 # +----|----------------------------------------------------------------------+
0016 # | SW |                                                                      |
0017 # | +--|--------------------------------------------------------------------+ |
0018 # | |  + $swp1                   BR0 (802.1d)                               | |
0019 # | |                                                                       | |
0020 # | |  + vxlan0 (vxlan)                                                     | |
0021 # | |    local 198.51.100.1                                                 | |
0022 # | |    remote 198.51.100.{2..13}                                          | |
0023 # | |    id 10 dstport 4789                                                 | |
0024 # | +-----------------------------------------------------------------------+ |
0025 # |                                                                           |
0026 # |  198.51.100.0/24 via 192.0.2.2                                            |
0027 # |                                                                           |
0028 # |    + $rp1                                                                 |
0029 # |    | 192.0.2.1/24                                                         |
0030 # +----|----------------------------------------------------------------------+
0031 #      |
0032 # +----|--------------------------------------------------------+
0033 # |    |                                               R2 (vrf) |
0034 # |    + $rp2                                                   |
0035 # |      192.0.2.2/24                                           |
0036 # |                                                             |
0037 # +-------------------------------------------------------------+
0038 
0039 lib_dir=$(dirname $0)/../../../net/forwarding
0040 
0041 ALL_TESTS="flooding_test"
0042 NUM_NETIFS=4
0043 source $lib_dir/tc_common.sh
0044 source $lib_dir/lib.sh
0045 
0046 h1_create()
0047 {
0048         simple_if_init $h1 203.0.113.1/24
0049 }
0050 
0051 h1_destroy()
0052 {
0053         simple_if_fini $h1 203.0.113.1/24
0054 }
0055 
0056 switch_create()
0057 {
0058         # Make sure the bridge uses the MAC address of the local port and
0059         # not that of the VxLAN's device
0060         ip link add dev br0 type bridge mcast_snooping 0
0061         ip link set dev br0 address $(mac_get $swp1)
0062 
0063         ip link add name vxlan0 type vxlan id 10 nolearning noudpcsum \
0064                 ttl 20 tos inherit local 198.51.100.1 dstport 4789
0065 
0066         ip address add 198.51.100.1/32 dev lo
0067 
0068         ip link set dev $swp1 master br0
0069         ip link set dev vxlan0 master br0
0070 
0071         ip link set dev br0 up
0072         ip link set dev $swp1 up
0073         ip link set dev vxlan0 up
0074 }
0075 
0076 switch_destroy()
0077 {
0078         ip link set dev vxlan0 down
0079         ip link set dev $swp1 down
0080         ip link set dev br0 down
0081 
0082         ip link set dev vxlan0 nomaster
0083         ip link set dev $swp1 nomaster
0084 
0085         ip address del 198.51.100.1/32 dev lo
0086 
0087         ip link del dev vxlan0
0088 
0089         ip link del dev br0
0090 }
0091 
0092 router1_create()
0093 {
0094         # This router is in the default VRF, where the VxLAN device is
0095         # performing the L3 lookup
0096         ip link set dev $rp1 up
0097         ip address add 192.0.2.1/24 dev $rp1
0098         ip route add 198.51.100.0/24 via 192.0.2.2
0099 }
0100 
0101 router1_destroy()
0102 {
0103         ip route del 198.51.100.0/24 via 192.0.2.2
0104         ip address del 192.0.2.1/24 dev $rp1
0105         ip link set dev $rp1 down
0106 }
0107 
0108 router2_create()
0109 {
0110         # This router is not in the default VRF, so use simple_if_init()
0111         simple_if_init $rp2 192.0.2.2/24
0112 }
0113 
0114 router2_destroy()
0115 {
0116         simple_if_fini $rp2 192.0.2.2/24
0117 }
0118 
0119 setup_prepare()
0120 {
0121         h1=${NETIFS[p1]}
0122         swp1=${NETIFS[p2]}
0123 
0124         rp1=${NETIFS[p3]}
0125         rp2=${NETIFS[p4]}
0126 
0127         vrf_prepare
0128 
0129         h1_create
0130 
0131         switch_create
0132 
0133         router1_create
0134         router2_create
0135 
0136         forwarding_enable
0137 }
0138 
0139 cleanup()
0140 {
0141         pre_cleanup
0142 
0143         forwarding_restore
0144 
0145         router2_destroy
0146         router1_destroy
0147 
0148         switch_destroy
0149 
0150         h1_destroy
0151 
0152         vrf_cleanup
0153 }
0154 
0155 flooding_remotes_add()
0156 {
0157         local num_remotes=$1
0158         local lsb
0159         local i
0160 
0161         for i in $(eval echo {1..$num_remotes}); do
0162                 lsb=$((i + 1))
0163 
0164                 bridge fdb append 00:00:00:00:00:00 dev vxlan0 self \
0165                         dst 198.51.100.$lsb
0166         done
0167 }
0168 
0169 flooding_filters_add()
0170 {
0171         local num_remotes=$1
0172         local lsb
0173         local i
0174 
0175         # Prevent unwanted packets from entering the bridge and interfering
0176         # with the test.
0177         tc qdisc add dev br0 clsact
0178         tc filter add dev br0 egress protocol all pref 1 handle 1 \
0179                 matchall skip_hw action drop
0180         tc qdisc add dev $h1 clsact
0181         tc filter add dev $h1 egress protocol all pref 1 handle 1 \
0182                 flower skip_hw dst_mac de:ad:be:ef:13:37 action pass
0183         tc filter add dev $h1 egress protocol all pref 2 handle 2 \
0184                 matchall skip_hw action drop
0185 
0186         tc qdisc add dev $rp2 clsact
0187 
0188         for i in $(eval echo {1..$num_remotes}); do
0189                 lsb=$((i + 1))
0190 
0191                 tc filter add dev $rp2 ingress protocol ip pref $i handle $i \
0192                         flower ip_proto udp dst_ip 198.51.100.$lsb \
0193                         dst_port 4789 skip_sw action drop
0194         done
0195 }
0196 
0197 flooding_filters_del()
0198 {
0199         local num_remotes=$1
0200         local i
0201 
0202         for i in $(eval echo {1..$num_remotes}); do
0203                 tc filter del dev $rp2 ingress protocol ip pref $i \
0204                         handle $i flower
0205         done
0206 
0207         tc qdisc del dev $rp2 clsact
0208 
0209         tc filter del dev $h1 egress protocol all pref 2 handle 2 matchall
0210         tc filter del dev $h1 egress protocol all pref 1 handle 1 flower
0211         tc qdisc del dev $h1 clsact
0212         tc filter del dev br0 egress protocol all pref 1 handle 1 matchall
0213         tc qdisc del dev br0 clsact
0214 }
0215 
0216 flooding_check_packets()
0217 {
0218         local packets=("$@")
0219         local num_remotes=${#packets[@]}
0220         local i
0221 
0222         for i in $(eval echo {1..$num_remotes}); do
0223                 tc_check_packets "dev $rp2 ingress" $i ${packets[i - 1]}
0224                 check_err $? "remote $i - did not get expected number of packets"
0225         done
0226 }
0227 
0228 flooding_test()
0229 {
0230         # Use 12 remote VTEPs that will be stored in 4 records. The array
0231         # 'packets' will store how many packets are expected to be received
0232         # by each remote VTEP at each stage of the test
0233         declare -a packets=(1 1 1 1 1 1 1 1 1 1 1 1)
0234         local num_remotes=12
0235 
0236         RET=0
0237 
0238         # Add FDB entries for remote VTEPs and corresponding tc filters on the
0239         # ingress of the nexthop router. These filters will count how many
0240         # packets were flooded to each remote VTEP
0241         flooding_remotes_add $num_remotes
0242         flooding_filters_add $num_remotes
0243 
0244         # Send one packet and make sure it is flooded to all the remote VTEPs
0245         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
0246         flooding_check_packets "${packets[@]}"
0247         log_test "flood after 1 packet"
0248 
0249         # Delete the third record which corresponds to VTEPs with LSB 8..10
0250         # and check that packet is flooded correctly when we remove a record
0251         # from the middle of the list
0252         RET=0
0253 
0254         packets=(2 2 2 2 2 2 1 1 1 2 2 2)
0255         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.8
0256         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.9
0257         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.10
0258 
0259         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
0260         flooding_check_packets "${packets[@]}"
0261         log_test "flood after 2 packets"
0262 
0263         # Delete the first record and make sure the packet is flooded correctly
0264         RET=0
0265 
0266         packets=(2 2 2 3 3 3 1 1 1 3 3 3)
0267         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.2
0268         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.3
0269         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.4
0270 
0271         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
0272         flooding_check_packets "${packets[@]}"
0273         log_test "flood after 3 packets"
0274 
0275         # Delete the last record and make sure the packet is flooded correctly
0276         RET=0
0277 
0278         packets=(2 2 2 4 4 4 1 1 1 3 3 3)
0279         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.11
0280         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.12
0281         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.13
0282 
0283         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
0284         flooding_check_packets "${packets[@]}"
0285         log_test "flood after 4 packets"
0286 
0287         # Delete the last record, one entry at a time and make sure single
0288         # entries are correctly removed
0289         RET=0
0290 
0291         packets=(2 2 2 4 5 5 1 1 1 3 3 3)
0292         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.5
0293 
0294         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
0295         flooding_check_packets "${packets[@]}"
0296         log_test "flood after 5 packets"
0297 
0298         RET=0
0299 
0300         packets=(2 2 2 4 5 6 1 1 1 3 3 3)
0301         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.6
0302 
0303         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
0304         flooding_check_packets "${packets[@]}"
0305         log_test "flood after 6 packets"
0306 
0307         RET=0
0308 
0309         packets=(2 2 2 4 5 6 1 1 1 3 3 3)
0310         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.7
0311 
0312         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
0313         flooding_check_packets "${packets[@]}"
0314         log_test "flood after 7 packets"
0315 
0316         flooding_filters_del $num_remotes
0317 }
0318 
0319 trap cleanup EXIT
0320 
0321 setup_prepare
0322 setup_wait
0323 
0324 tests_run
0325 
0326 exit $EXIT_STATUS