Merge https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
[sfrench/cifs-2.6.git] / tools / testing / selftests / drivers / net / mlxsw / spectrum-2 / vxlan_flooding_ipv6.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 four IPv6 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 # |    | 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..17}                                         | |
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
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 2001:db8:1::1/64
49 }
50
51 h1_destroy()
52 {
53         simple_if_fini $h1 2001:db8:1::1/64
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 \
64                 udp6zerocsumrx udp6zerocsumtx ttl 20 tos inherit \
65                 local 2001:db8:2::1 dstport 4789
66
67         ip address add 2001:db8:2::1/128 dev lo
68
69         ip link set dev $swp1 master br0
70         ip link set dev vxlan0 master br0
71
72         ip link set dev br0 up
73         ip link set dev $swp1 up
74         ip link set dev vxlan0 up
75 }
76
77 switch_destroy()
78 {
79         ip link set dev vxlan0 down
80         ip link set dev $swp1 down
81         ip link set dev br0 down
82
83         ip link set dev vxlan0 nomaster
84         ip link set dev $swp1 nomaster
85
86         ip address del 2001:db8:2::1/128 dev lo
87
88         ip link del dev vxlan0
89
90         ip link del dev br0
91 }
92
93 router1_create()
94 {
95         # This router is in the default VRF, where the VxLAN device is
96         # performing the L3 lookup
97         ip link set dev $rp1 up
98         ip address add 2001:db8:3::1/64 dev $rp1
99         ip route add 2001:db8:2::0/64 via 2001:db8:3::2
100 }
101
102 router1_destroy()
103 {
104         ip route del 2001:db8:2::0/64 via 2001:db8:3::2
105         ip address del 2001:db8:3::1/64 dev $rp1
106         ip link set dev $rp1 down
107 }
108
109 router2_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/64
113 }
114
115 router2_destroy()
116 {
117         simple_if_fini $rp2 2001:db8:3::2/64
118 }
119
120 setup_prepare()
121 {
122         h1=${NETIFS[p1]}
123         swp1=${NETIFS[p2]}
124
125         rp1=${NETIFS[p3]}
126         rp2=${NETIFS[p4]}
127
128         vrf_prepare
129
130         h1_create
131
132         switch_create
133
134         router1_create
135         router2_create
136
137         forwarding_enable
138 }
139
140 cleanup()
141 {
142         pre_cleanup
143
144         forwarding_restore
145
146         router2_destroy
147         router1_destroy
148
149         switch_destroy
150
151         h1_destroy
152
153         vrf_cleanup
154 }
155
156 flooding_remotes_add()
157 {
158         local num_remotes=$1
159         local lsb
160         local i
161
162         # Prevent unwanted packets from entering the bridge and interfering
163         # with the test.
164         tc qdisc add dev br0 clsact
165         tc filter add dev br0 egress protocol all pref 1 handle 1 \
166                 matchall skip_hw action drop
167         tc qdisc add dev $h1 clsact
168         tc filter add dev $h1 egress protocol all pref 1 handle 1 \
169                 flower skip_hw dst_mac de:ad:be:ef:13:37 action pass
170         tc filter add dev $h1 egress protocol all pref 2 handle 2 \
171                 matchall skip_hw action drop
172
173         for i in $(eval echo {1..$num_remotes}); do
174                 lsb=$((i + 1))
175
176                 bridge fdb append 00:00:00:00:00:00 dev vxlan0 self \
177                         dst 2001:db8:2::$lsb
178         done
179 }
180
181 flooding_filters_add()
182 {
183         local num_remotes=$1
184         local lsb
185         local i
186
187         tc qdisc add dev $rp2 clsact
188
189         for i in $(eval echo {1..$num_remotes}); do
190                 lsb=$((i + 1))
191
192                 tc filter add dev $rp2 ingress protocol ipv6 pref $i handle $i \
193                         flower ip_proto udp dst_ip 2001:db8:2::$lsb \
194                         dst_port 4789 skip_sw action drop
195         done
196 }
197
198 flooding_filters_del()
199 {
200         local num_remotes=$1
201         local i
202
203         for i in $(eval echo {1..$num_remotes}); do
204                 tc filter del dev $rp2 ingress protocol ipv6 pref $i \
205                         handle $i flower
206         done
207
208         tc qdisc del dev $rp2 clsact
209
210         tc filter del dev $h1 egress protocol all pref 2 handle 2 matchall
211         tc filter del dev $h1 egress protocol all pref 1 handle 1 flower
212         tc qdisc del dev $h1 clsact
213         tc filter del dev br0 egress protocol all pref 1 handle 1 matchall
214         tc qdisc del dev br0 clsact
215 }
216
217 flooding_check_packets()
218 {
219         local packets=("$@")
220         local num_remotes=${#packets[@]}
221         local i
222
223         for i in $(eval echo {1..$num_remotes}); do
224                 tc_check_packets "dev $rp2 ingress" $i ${packets[i - 1]}
225                 check_err $? "remote $i - did not get expected number of packets"
226         done
227 }
228
229 flooding_test()
230 {
231         # Use 16 remote VTEPs that will be stored in 4 records. The array
232         # 'packets' will store how many packets are expected to be received
233         # by each remote VTEP at each stage of the test
234         declare -a packets=(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
235         local num_remotes=16
236
237         RET=0
238
239         # Add FDB entries for remote VTEPs and corresponding tc filters on the
240         # ingress of the nexthop router. These filters will count how many
241         # packets were flooded to each remote VTEP
242         flooding_remotes_add $num_remotes
243         flooding_filters_add $num_remotes
244
245         # Send one packet and make sure it is flooded to all the remote VTEPs
246         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
247         flooding_check_packets "${packets[@]}"
248         log_test "flood after 1 packet"
249
250         # Delete the third record which corresponds to VTEPs with LSB 10..13
251         # and check that packet is flooded correctly when we remove a record
252         # from the middle of the list
253         RET=0
254
255         packets=(2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2)
256         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::10
257         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::11
258         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::12
259         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::13
260
261         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
262         flooding_check_packets "${packets[@]}"
263         log_test "flood after 2 packets"
264
265         # Delete the first record and make sure the packet is flooded correctly
266         RET=0
267
268         packets=(2 2 2 2 3 3 3 3 1 1 1 1 3 3 3 3)
269         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::2
270         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::3
271         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::4
272         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::5
273
274         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
275         flooding_check_packets "${packets[@]}"
276         log_test "flood after 3 packets"
277
278         # Delete the last record and make sure the packet is flooded correctly
279         RET=0
280
281         packets=(2 2 2 2 4 4 4 4 1 1 1 1 3 3 3 3)
282         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::14
283         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::15
284         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::16
285         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::17
286
287         $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
288         flooding_check_packets "${packets[@]}"
289         log_test "flood after 4 packets"
290
291         # Delete the last record, one entry at a time and make sure single
292         # entries are correctly removed
293         RET=0
294
295         packets=(2 2 2 2 4 5 5 5 1 1 1 1 3 3 3 3)
296         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::6
297
298         $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
299         flooding_check_packets "${packets[@]}"
300         log_test "flood after 5 packets"
301
302         RET=0
303
304         packets=(2 2 2 2 4 5 6 6 1 1 1 1 3 3 3 3)
305         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::7
306
307         $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
308         flooding_check_packets "${packets[@]}"
309         log_test "flood after 6 packets"
310
311         RET=0
312
313         packets=(2 2 2 2 4 5 6 7 1 1 1 1 3 3 3 3)
314         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::8
315
316         $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
317         flooding_check_packets "${packets[@]}"
318         log_test "flood after 7 packets"
319
320         RET=0
321
322         packets=(2 2 2 2 4 5 6 7 1 1 1 1 3 3 3 3)
323         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::9
324
325         $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
326         flooding_check_packets "${packets[@]}"
327         log_test "flood after 8 packets"
328
329         flooding_filters_del $num_remotes
330 }
331
332 trap cleanup EXIT
333
334 setup_prepare
335 setup_wait
336
337 tests_run
338
339 exit $EXIT_STATUS