xsk: Fix possible crash when multiple sockets are created
[sfrench/cifs-2.6.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         tc qdisc add dev $rp2 clsact
176
177         for i in $(eval echo {1..$num_remotes}); do
178                 lsb=$((i + 1))
179
180                 tc filter add dev $rp2 ingress protocol ip pref $i handle $i \
181                         flower ip_proto udp dst_ip 198.51.100.$lsb \
182                         dst_port 4789 skip_sw action drop
183         done
184 }
185
186 flooding_filters_del()
187 {
188         local num_remotes=$1
189         local i
190
191         for i in $(eval echo {1..$num_remotes}); do
192                 tc filter del dev $rp2 ingress protocol ip pref $i \
193                         handle $i flower
194         done
195
196         tc qdisc del dev $rp2 clsact
197 }
198
199 flooding_check_packets()
200 {
201         local packets=("$@")
202         local num_remotes=${#packets[@]}
203         local i
204
205         for i in $(eval echo {1..$num_remotes}); do
206                 tc_check_packets "dev $rp2 ingress" $i ${packets[i - 1]}
207                 check_err $? "remote $i - did not get expected number of packets"
208         done
209 }
210
211 flooding_test()
212 {
213         # Use 12 remote VTEPs that will be stored in 4 records. The array
214         # 'packets' will store how many packets are expected to be received
215         # by each remote VTEP at each stage of the test
216         declare -a packets=(1 1 1 1 1 1 1 1 1 1 1 1)
217         local num_remotes=12
218
219         RET=0
220
221         # Add FDB entries for remote VTEPs and corresponding tc filters on the
222         # ingress of the nexthop router. These filters will count how many
223         # packets were flooded to each remote VTEP
224         flooding_remotes_add $num_remotes
225         flooding_filters_add $num_remotes
226
227         # Send one packet and make sure it is flooded to all the remote VTEPs
228         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
229         flooding_check_packets "${packets[@]}"
230         log_test "flood after 1 packet"
231
232         # Delete the third record which corresponds to VTEPs with LSB 8..10
233         # and check that packet is flooded correctly when we remove a record
234         # from the middle of the list
235         RET=0
236
237         packets=(2 2 2 2 2 2 1 1 1 2 2 2)
238         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.8
239         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.9
240         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.10
241
242         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
243         flooding_check_packets "${packets[@]}"
244         log_test "flood after 2 packets"
245
246         # Delete the first record and make sure the packet is flooded correctly
247         RET=0
248
249         packets=(2 2 2 3 3 3 1 1 1 3 3 3)
250         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.2
251         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.3
252         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.4
253
254         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
255         flooding_check_packets "${packets[@]}"
256         log_test "flood after 3 packets"
257
258         # Delete the last record and make sure the packet is flooded correctly
259         RET=0
260
261         packets=(2 2 2 4 4 4 1 1 1 3 3 3)
262         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.11
263         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.12
264         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.13
265
266         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
267         flooding_check_packets "${packets[@]}"
268         log_test "flood after 4 packets"
269
270         # Delete the last record, one entry at a time and make sure single
271         # entries are correctly removed
272         RET=0
273
274         packets=(2 2 2 4 5 5 1 1 1 3 3 3)
275         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.5
276
277         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
278         flooding_check_packets "${packets[@]}"
279         log_test "flood after 5 packets"
280
281         RET=0
282
283         packets=(2 2 2 4 5 6 1 1 1 3 3 3)
284         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.6
285
286         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
287         flooding_check_packets "${packets[@]}"
288         log_test "flood after 6 packets"
289
290         RET=0
291
292         packets=(2 2 2 4 5 6 1 1 1 3 3 3)
293         bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.7
294
295         $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
296         flooding_check_packets "${packets[@]}"
297         log_test "flood after 7 packets"
298
299         flooding_filters_del $num_remotes
300 }
301
302 trap cleanup EXIT
303
304 setup_prepare
305 setup_wait
306
307 tests_run
308
309 exit $EXIT_STATUS