selftests: devlink_lib: Remove double blank line
[linux-2.6-microblaze.git] / tools / testing / selftests / net / forwarding / devlink_lib.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3
4 ##############################################################################
5 # Defines
6
7 if [[ ! -v DEVLINK_DEV ]]; then
8         DEVLINK_DEV=$(devlink port show "${NETIFS[p1]}" -j \
9                              | jq -r '.port | keys[]' | cut -d/ -f-2)
10         if [ -z "$DEVLINK_DEV" ]; then
11                 echo "SKIP: ${NETIFS[p1]} has no devlink device registered for it"
12                 exit 1
13         fi
14         if [[ "$(echo $DEVLINK_DEV | grep -c pci)" -eq 0 ]]; then
15                 echo "SKIP: devlink device's bus is not PCI"
16                 exit 1
17         fi
18
19         DEVLINK_VIDDID=$(lspci -s $(echo $DEVLINK_DEV | cut -d"/" -f2) \
20                          -n | cut -d" " -f3)
21 fi
22
23 ##############################################################################
24 # Sanity checks
25
26 devlink help 2>&1 | grep resource &> /dev/null
27 if [ $? -ne 0 ]; then
28         echo "SKIP: iproute2 too old, missing devlink resource support"
29         exit 1
30 fi
31
32 devlink help 2>&1 | grep trap &> /dev/null
33 if [ $? -ne 0 ]; then
34         echo "SKIP: iproute2 too old, missing devlink trap support"
35         exit 1
36 fi
37
38 devlink dev help 2>&1 | grep info &> /dev/null
39 if [ $? -ne 0 ]; then
40         echo "SKIP: iproute2 too old, missing devlink dev info support"
41         exit 1
42 fi
43
44 ##############################################################################
45 # Devlink helpers
46
47 devlink_resource_names_to_path()
48 {
49         local resource
50         local path=""
51
52         for resource in "${@}"; do
53                 if [ "$path" == "" ]; then
54                         path="$resource"
55                 else
56                         path="${path}/$resource"
57                 fi
58         done
59
60         echo "$path"
61 }
62
63 devlink_resource_get()
64 {
65         local name=$1
66         local resource_name=.[][\"$DEVLINK_DEV\"]
67
68         resource_name="$resource_name | .[] | select (.name == \"$name\")"
69
70         shift
71         for resource in "${@}"; do
72                 resource_name="${resource_name} | .[\"resources\"][] | \
73                                select (.name == \"$resource\")"
74         done
75
76         devlink -j resource show "$DEVLINK_DEV" | jq "$resource_name"
77 }
78
79 devlink_resource_size_get()
80 {
81         local size=$(devlink_resource_get "$@" | jq '.["size_new"]')
82
83         if [ "$size" == "null" ]; then
84                 devlink_resource_get "$@" | jq '.["size"]'
85         else
86                 echo "$size"
87         fi
88 }
89
90 devlink_resource_size_set()
91 {
92         local new_size=$1
93         local path
94
95         shift
96         path=$(devlink_resource_names_to_path "$@")
97         devlink resource set "$DEVLINK_DEV" path "$path" size "$new_size"
98         check_err $? "Failed setting path $path to size $size"
99 }
100
101 devlink_reload()
102 {
103         local still_pending
104
105         devlink dev reload "$DEVLINK_DEV" &> /dev/null
106         check_err $? "Failed reload"
107
108         still_pending=$(devlink resource show "$DEVLINK_DEV" | \
109                         grep -c "size_new")
110         check_err $still_pending "Failed reload - There are still unset sizes"
111 }
112
113 declare -A DEVLINK_ORIG
114
115 devlink_port_pool_threshold()
116 {
117         local port=$1; shift
118         local pool=$1; shift
119
120         devlink sb port pool show $port pool $pool -j \
121                 | jq '.port_pool."'"$port"'"[].threshold'
122 }
123
124 devlink_port_pool_th_set()
125 {
126         local port=$1; shift
127         local pool=$1; shift
128         local th=$1; shift
129         local key="port_pool($port,$pool).threshold"
130
131         DEVLINK_ORIG[$key]=$(devlink_port_pool_threshold $port $pool)
132         devlink sb port pool set $port pool $pool th $th
133 }
134
135 devlink_port_pool_th_restore()
136 {
137         local port=$1; shift
138         local pool=$1; shift
139         local key="port_pool($port,$pool).threshold"
140
141         devlink sb port pool set $port pool $pool th ${DEVLINK_ORIG[$key]}
142 }
143
144 devlink_pool_size_thtype()
145 {
146         local pool=$1; shift
147
148         devlink sb pool show "$DEVLINK_DEV" pool $pool -j \
149             | jq -r '.pool[][] | (.size, .thtype)'
150 }
151
152 devlink_pool_size_thtype_set()
153 {
154         local pool=$1; shift
155         local thtype=$1; shift
156         local size=$1; shift
157         local key="pool($pool).size_thtype"
158
159         DEVLINK_ORIG[$key]=$(devlink_pool_size_thtype $pool)
160         devlink sb pool set "$DEVLINK_DEV" pool $pool size $size thtype $thtype
161 }
162
163 devlink_pool_size_thtype_restore()
164 {
165         local pool=$1; shift
166         local key="pool($pool).size_thtype"
167         local -a orig=(${DEVLINK_ORIG[$key]})
168
169         devlink sb pool set "$DEVLINK_DEV" pool $pool \
170                 size ${orig[0]} thtype ${orig[1]}
171 }
172
173 devlink_tc_bind_pool_th()
174 {
175         local port=$1; shift
176         local tc=$1; shift
177         local dir=$1; shift
178
179         devlink sb tc bind show $port tc $tc type $dir -j \
180             | jq -r '.tc_bind[][] | (.pool, .threshold)'
181 }
182
183 devlink_tc_bind_pool_th_set()
184 {
185         local port=$1; shift
186         local tc=$1; shift
187         local dir=$1; shift
188         local pool=$1; shift
189         local th=$1; shift
190         local key="tc_bind($port,$dir,$tc).pool_th"
191
192         DEVLINK_ORIG[$key]=$(devlink_tc_bind_pool_th $port $tc $dir)
193         devlink sb tc bind set $port tc $tc type $dir pool $pool th $th
194 }
195
196 devlink_tc_bind_pool_th_restore()
197 {
198         local port=$1; shift
199         local tc=$1; shift
200         local dir=$1; shift
201         local key="tc_bind($port,$dir,$tc).pool_th"
202         local -a orig=(${DEVLINK_ORIG[$key]})
203
204         devlink sb tc bind set $port tc $tc type $dir \
205                 pool ${orig[0]} th ${orig[1]}
206 }
207
208 devlink_traps_num_get()
209 {
210         devlink -j trap | jq '.[]["'$DEVLINK_DEV'"] | length'
211 }
212
213 devlink_traps_get()
214 {
215         devlink -j trap | jq -r '.[]["'$DEVLINK_DEV'"][].name'
216 }
217
218 devlink_trap_type_get()
219 {
220         local trap_name=$1; shift
221
222         devlink -j trap show $DEVLINK_DEV trap $trap_name \
223                 | jq -r '.[][][].type'
224 }
225
226 devlink_trap_action_set()
227 {
228         local trap_name=$1; shift
229         local action=$1; shift
230
231         # Pipe output to /dev/null to avoid expected warnings.
232         devlink trap set $DEVLINK_DEV trap $trap_name \
233                 action $action &> /dev/null
234 }
235
236 devlink_trap_action_get()
237 {
238         local trap_name=$1; shift
239
240         devlink -j trap show $DEVLINK_DEV trap $trap_name \
241                 | jq -r '.[][][].action'
242 }
243
244 devlink_trap_group_get()
245 {
246         devlink -j trap show $DEVLINK_DEV trap $trap_name \
247                 | jq -r '.[][][].group'
248 }
249
250 devlink_trap_metadata_test()
251 {
252         local trap_name=$1; shift
253         local metadata=$1; shift
254
255         devlink -jv trap show $DEVLINK_DEV trap $trap_name \
256                 | jq -e '.[][][].metadata | contains(["'$metadata'"])' \
257                 &> /dev/null
258 }
259
260 devlink_trap_rx_packets_get()
261 {
262         local trap_name=$1; shift
263
264         devlink -js trap show $DEVLINK_DEV trap $trap_name \
265                 | jq '.[][][]["stats"]["rx"]["packets"]'
266 }
267
268 devlink_trap_rx_bytes_get()
269 {
270         local trap_name=$1; shift
271
272         devlink -js trap show $DEVLINK_DEV trap $trap_name \
273                 | jq '.[][][]["stats"]["rx"]["bytes"]'
274 }
275
276 devlink_trap_stats_idle_test()
277 {
278         local trap_name=$1; shift
279         local t0_packets t0_bytes
280         local t1_packets t1_bytes
281
282         t0_packets=$(devlink_trap_rx_packets_get $trap_name)
283         t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)
284
285         sleep 1
286
287         t1_packets=$(devlink_trap_rx_packets_get $trap_name)
288         t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)
289
290         if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then
291                 return 0
292         else
293                 return 1
294         fi
295 }
296
297 devlink_traps_enable_all()
298 {
299         local trap_name
300
301         for trap_name in $(devlink_traps_get); do
302                 devlink_trap_action_set $trap_name "trap"
303         done
304 }
305
306 devlink_traps_disable_all()
307 {
308         for trap_name in $(devlink_traps_get); do
309                 devlink_trap_action_set $trap_name "drop"
310         done
311 }
312
313 devlink_trap_groups_get()
314 {
315         devlink -j trap group | jq -r '.[]["'$DEVLINK_DEV'"][].name'
316 }
317
318 devlink_trap_group_action_set()
319 {
320         local group_name=$1; shift
321         local action=$1; shift
322
323         # Pipe output to /dev/null to avoid expected warnings.
324         devlink trap group set $DEVLINK_DEV group $group_name action $action \
325                 &> /dev/null
326 }
327
328 devlink_trap_group_rx_packets_get()
329 {
330         local group_name=$1; shift
331
332         devlink -js trap group show $DEVLINK_DEV group $group_name \
333                 | jq '.[][][]["stats"]["rx"]["packets"]'
334 }
335
336 devlink_trap_group_rx_bytes_get()
337 {
338         local group_name=$1; shift
339
340         devlink -js trap group show $DEVLINK_DEV group $group_name \
341                 | jq '.[][][]["stats"]["rx"]["bytes"]'
342 }
343
344 devlink_trap_group_stats_idle_test()
345 {
346         local group_name=$1; shift
347         local t0_packets t0_bytes
348         local t1_packets t1_bytes
349
350         t0_packets=$(devlink_trap_group_rx_packets_get $group_name)
351         t0_bytes=$(devlink_trap_group_rx_bytes_get $group_name)
352
353         sleep 1
354
355         t1_packets=$(devlink_trap_group_rx_packets_get $group_name)
356         t1_bytes=$(devlink_trap_group_rx_bytes_get $group_name)
357
358         if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then
359                 return 0
360         else
361                 return 1
362         fi
363 }
364
365 devlink_trap_exception_test()
366 {
367         local trap_name=$1; shift
368         local group_name=$1; shift
369
370         devlink_trap_stats_idle_test $trap_name
371         check_fail $? "Trap stats idle when packets should have been trapped"
372
373         devlink_trap_group_stats_idle_test $group_name
374         check_fail $? "Trap group idle when packets should have been trapped"
375 }
376
377 devlink_trap_drop_test()
378 {
379         local trap_name=$1; shift
380         local group_name=$1; shift
381         local dev=$1; shift
382         local handle=$1; shift
383
384         # This is the common part of all the tests. It checks that stats are
385         # initially idle, then non-idle after changing the trap action and
386         # finally idle again. It also makes sure the packets are dropped and
387         # never forwarded.
388         devlink_trap_stats_idle_test $trap_name
389         check_err $? "Trap stats not idle with initial drop action"
390         devlink_trap_group_stats_idle_test $group_name
391         check_err $? "Trap group stats not idle with initial drop action"
392
393         devlink_trap_action_set $trap_name "trap"
394         devlink_trap_stats_idle_test $trap_name
395         check_fail $? "Trap stats idle after setting action to trap"
396         devlink_trap_group_stats_idle_test $group_name
397         check_fail $? "Trap group stats idle after setting action to trap"
398
399         devlink_trap_action_set $trap_name "drop"
400
401         devlink_trap_stats_idle_test $trap_name
402         check_err $? "Trap stats not idle after setting action to drop"
403         devlink_trap_group_stats_idle_test $group_name
404         check_err $? "Trap group stats not idle after setting action to drop"
405
406         tc_check_packets "dev $dev egress" $handle 0
407         check_err $? "Packets were not dropped"
408 }
409
410 devlink_trap_drop_cleanup()
411 {
412         local mz_pid=$1; shift
413         local dev=$1; shift
414         local proto=$1; shift
415         local pref=$1; shift
416         local handle=$1; shift
417
418         kill $mz_pid && wait $mz_pid &> /dev/null
419         tc filter del dev $dev egress protocol $proto pref $pref handle $handle flower
420 }
421
422 devlink_trap_policers_num_get()
423 {
424         devlink -j -p trap policer show | jq '.[]["'$DEVLINK_DEV'"] | length'
425 }
426
427 devlink_trap_policer_rate_get()
428 {
429         local policer_id=$1; shift
430
431         devlink -j -p trap policer show $DEVLINK_DEV policer $policer_id \
432                 | jq '.[][][]["rate"]'
433 }
434
435 devlink_trap_policer_burst_get()
436 {
437         local policer_id=$1; shift
438
439         devlink -j -p trap policer show $DEVLINK_DEV policer $policer_id \
440                 | jq '.[][][]["burst"]'
441 }
442
443 devlink_trap_policer_rx_dropped_get()
444 {
445         local policer_id=$1; shift
446
447         devlink -j -p -s trap policer show $DEVLINK_DEV policer $policer_id \
448                 | jq '.[][][]["stats"]["rx"]["dropped"]'
449 }
450
451 devlink_trap_group_policer_get()
452 {
453         local group_name=$1; shift
454
455         devlink -j -p trap group show $DEVLINK_DEV group $group_name \
456                 | jq '.[][][]["policer"]'
457 }
458
459 devlink_trap_policer_ids_get()
460 {
461         devlink -j -p trap policer show \
462                 | jq '.[]["'$DEVLINK_DEV'"][]["policer"]'
463 }
464
465 devlink_port_by_netdev()
466 {
467         local if_name=$1
468
469         devlink -j port show $if_name | jq -e '.[] | keys' | jq -r '.[]'
470 }
471
472 devlink_cpu_port_get()
473 {
474         local cpu_dl_port_num=$(devlink port list | grep "$DEVLINK_DEV" |
475                                 grep cpu | cut -d/ -f3 | cut -d: -f1 |
476                                 sed -n '1p')
477
478         echo "$DEVLINK_DEV/$cpu_dl_port_num"
479 }