Merge branches 'acpi-pm', 'acpi-pci', 'acpi-sysfs' and 'acpi-tables'
[linux-2.6-microblaze.git] / tools / testing / selftests / drivers / net / mlxsw / vxlan_flooding.sh
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