hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
....@@ -2,39 +2,42 @@
22 # SPDX-License-Identifier: GPL-2.0
33
44 ##############################################################################
5
-# Source library
6
-
7
-relative_path="${BASH_SOURCE%/*}"
8
-if [[ "$relative_path" == "${BASH_SOURCE}" ]]; then
9
- relative_path="."
10
-fi
11
-
12
-source "$relative_path/lib.sh"
13
-
14
-##############################################################################
155 # Defines
166
17
-DEVLINK_DEV=$(devlink port show | grep "${NETIFS[p1]}" | \
18
- grep -v "${NETIFS[p1]}[0-9]" | cut -d" " -f1 | \
19
- rev | cut -d"/" -f2- | rev)
20
-if [ -z "$DEVLINK_DEV" ]; then
21
- echo "SKIP: ${NETIFS[p1]} has no devlink device registered for it"
22
- exit 1
23
-fi
24
-if [[ "$(echo $DEVLINK_DEV | grep -c pci)" -eq 0 ]]; then
25
- echo "SKIP: devlink device's bus is not PCI"
26
- exit 1
27
-fi
7
+if [[ ! -v DEVLINK_DEV ]]; then
8
+ DEVLINK_DEV=$(devlink port show "${NETIFS[p1]:-$NETIF_NO_CABLE}" -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
2818
29
-DEVLINK_VIDDID=$(lspci -s $(echo $DEVLINK_DEV | cut -d"/" -f2) \
30
- -n | cut -d" " -f3)
19
+ DEVLINK_VIDDID=$(lspci -s $(echo $DEVLINK_DEV | cut -d"/" -f2) \
20
+ -n | cut -d" " -f3)
21
+fi
3122
3223 ##############################################################################
3324 # Sanity checks
3425
35
-devlink -j resource show "$DEVLINK_DEV" &> /dev/null
26
+devlink help 2>&1 | grep resource &> /dev/null
3627 if [ $? -ne 0 ]; then
3728 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"
3841 exit 1
3942 fi
4043
....@@ -95,6 +98,11 @@
9598 check_err $? "Failed setting path $path to size $size"
9699 }
97100
101
+devlink_resource_occ_get()
102
+{
103
+ devlink_resource_get "$@" | jq '.["occ"]'
104
+}
105
+
98106 devlink_reload()
99107 {
100108 local still_pending
....@@ -106,3 +114,444 @@
106114 grep -c "size_new")
107115 check_err $still_pending "Failed reload - There are still unset sizes"
108116 }
117
+
118
+declare -A DEVLINK_ORIG
119
+
120
+# Changing pool type from static to dynamic causes reinterpretation of threshold
121
+# values. They therefore need to be saved before pool type is changed, then the
122
+# pool type can be changed, and then the new values need to be set up. Therefore
123
+# instead of saving the current state implicitly in the _set call, provide
124
+# functions for all three primitives: save, set, and restore.
125
+
126
+devlink_port_pool_threshold()
127
+{
128
+ local port=$1; shift
129
+ local pool=$1; shift
130
+
131
+ devlink sb port pool show $port pool $pool -j \
132
+ | jq '.port_pool."'"$port"'"[].threshold'
133
+}
134
+
135
+devlink_port_pool_th_save()
136
+{
137
+ local port=$1; shift
138
+ local pool=$1; shift
139
+ local key="port_pool($port,$pool).threshold"
140
+
141
+ DEVLINK_ORIG[$key]=$(devlink_port_pool_threshold $port $pool)
142
+}
143
+
144
+devlink_port_pool_th_set()
145
+{
146
+ local port=$1; shift
147
+ local pool=$1; shift
148
+ local th=$1; shift
149
+
150
+ devlink sb port pool set $port pool $pool th $th
151
+}
152
+
153
+devlink_port_pool_th_restore()
154
+{
155
+ local port=$1; shift
156
+ local pool=$1; shift
157
+ local key="port_pool($port,$pool).threshold"
158
+ local -a orig=(${DEVLINK_ORIG[$key]})
159
+
160
+ if [[ -z $orig ]]; then
161
+ echo "WARNING: Mismatched devlink_port_pool_th_restore"
162
+ else
163
+ devlink sb port pool set $port pool $pool th $orig
164
+ fi
165
+}
166
+
167
+devlink_pool_size_thtype()
168
+{
169
+ local pool=$1; shift
170
+
171
+ devlink sb pool show "$DEVLINK_DEV" pool $pool -j \
172
+ | jq -r '.pool[][] | (.size, .thtype)'
173
+}
174
+
175
+devlink_pool_size_thtype_save()
176
+{
177
+ local pool=$1; shift
178
+ local key="pool($pool).size_thtype"
179
+
180
+ DEVLINK_ORIG[$key]=$(devlink_pool_size_thtype $pool)
181
+}
182
+
183
+devlink_pool_size_thtype_set()
184
+{
185
+ local pool=$1; shift
186
+ local thtype=$1; shift
187
+ local size=$1; shift
188
+
189
+ devlink sb pool set "$DEVLINK_DEV" pool $pool size $size thtype $thtype
190
+}
191
+
192
+devlink_pool_size_thtype_restore()
193
+{
194
+ local pool=$1; shift
195
+ local key="pool($pool).size_thtype"
196
+ local -a orig=(${DEVLINK_ORIG[$key]})
197
+
198
+ if [[ -z ${orig[0]} ]]; then
199
+ echo "WARNING: Mismatched devlink_pool_size_thtype_restore"
200
+ else
201
+ devlink sb pool set "$DEVLINK_DEV" pool $pool \
202
+ size ${orig[0]} thtype ${orig[1]}
203
+ fi
204
+}
205
+
206
+devlink_tc_bind_pool_th()
207
+{
208
+ local port=$1; shift
209
+ local tc=$1; shift
210
+ local dir=$1; shift
211
+
212
+ devlink sb tc bind show $port tc $tc type $dir -j \
213
+ | jq -r '.tc_bind[][] | (.pool, .threshold)'
214
+}
215
+
216
+devlink_tc_bind_pool_th_save()
217
+{
218
+ local port=$1; shift
219
+ local tc=$1; shift
220
+ local dir=$1; shift
221
+ local key="tc_bind($port,$dir,$tc).pool_th"
222
+
223
+ DEVLINK_ORIG[$key]=$(devlink_tc_bind_pool_th $port $tc $dir)
224
+}
225
+
226
+devlink_tc_bind_pool_th_set()
227
+{
228
+ local port=$1; shift
229
+ local tc=$1; shift
230
+ local dir=$1; shift
231
+ local pool=$1; shift
232
+ local th=$1; shift
233
+
234
+ devlink sb tc bind set $port tc $tc type $dir pool $pool th $th
235
+}
236
+
237
+devlink_tc_bind_pool_th_restore()
238
+{
239
+ local port=$1; shift
240
+ local tc=$1; shift
241
+ local dir=$1; shift
242
+ local key="tc_bind($port,$dir,$tc).pool_th"
243
+ local -a orig=(${DEVLINK_ORIG[$key]})
244
+
245
+ if [[ -z ${orig[0]} ]]; then
246
+ echo "WARNING: Mismatched devlink_tc_bind_pool_th_restore"
247
+ else
248
+ devlink sb tc bind set $port tc $tc type $dir \
249
+ pool ${orig[0]} th ${orig[1]}
250
+ fi
251
+}
252
+
253
+devlink_traps_num_get()
254
+{
255
+ devlink -j trap | jq '.[]["'$DEVLINK_DEV'"] | length'
256
+}
257
+
258
+devlink_traps_get()
259
+{
260
+ devlink -j trap | jq -r '.[]["'$DEVLINK_DEV'"][].name'
261
+}
262
+
263
+devlink_trap_type_get()
264
+{
265
+ local trap_name=$1; shift
266
+
267
+ devlink -j trap show $DEVLINK_DEV trap $trap_name \
268
+ | jq -r '.[][][].type'
269
+}
270
+
271
+devlink_trap_action_set()
272
+{
273
+ local trap_name=$1; shift
274
+ local action=$1; shift
275
+
276
+ # Pipe output to /dev/null to avoid expected warnings.
277
+ devlink trap set $DEVLINK_DEV trap $trap_name \
278
+ action $action &> /dev/null
279
+}
280
+
281
+devlink_trap_action_get()
282
+{
283
+ local trap_name=$1; shift
284
+
285
+ devlink -j trap show $DEVLINK_DEV trap $trap_name \
286
+ | jq -r '.[][][].action'
287
+}
288
+
289
+devlink_trap_group_get()
290
+{
291
+ devlink -j trap show $DEVLINK_DEV trap $trap_name \
292
+ | jq -r '.[][][].group'
293
+}
294
+
295
+devlink_trap_metadata_test()
296
+{
297
+ local trap_name=$1; shift
298
+ local metadata=$1; shift
299
+
300
+ devlink -jv trap show $DEVLINK_DEV trap $trap_name \
301
+ | jq -e '.[][][].metadata | contains(["'$metadata'"])' \
302
+ &> /dev/null
303
+}
304
+
305
+devlink_trap_rx_packets_get()
306
+{
307
+ local trap_name=$1; shift
308
+
309
+ devlink -js trap show $DEVLINK_DEV trap $trap_name \
310
+ | jq '.[][][]["stats"]["rx"]["packets"]'
311
+}
312
+
313
+devlink_trap_rx_bytes_get()
314
+{
315
+ local trap_name=$1; shift
316
+
317
+ devlink -js trap show $DEVLINK_DEV trap $trap_name \
318
+ | jq '.[][][]["stats"]["rx"]["bytes"]'
319
+}
320
+
321
+devlink_trap_stats_idle_test()
322
+{
323
+ local trap_name=$1; shift
324
+ local t0_packets t0_bytes
325
+ local t1_packets t1_bytes
326
+
327
+ t0_packets=$(devlink_trap_rx_packets_get $trap_name)
328
+ t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)
329
+
330
+ sleep 1
331
+
332
+ t1_packets=$(devlink_trap_rx_packets_get $trap_name)
333
+ t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)
334
+
335
+ if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then
336
+ return 0
337
+ else
338
+ return 1
339
+ fi
340
+}
341
+
342
+devlink_traps_enable_all()
343
+{
344
+ local trap_name
345
+
346
+ for trap_name in $(devlink_traps_get); do
347
+ devlink_trap_action_set $trap_name "trap"
348
+ done
349
+}
350
+
351
+devlink_traps_disable_all()
352
+{
353
+ for trap_name in $(devlink_traps_get); do
354
+ devlink_trap_action_set $trap_name "drop"
355
+ done
356
+}
357
+
358
+devlink_trap_groups_get()
359
+{
360
+ devlink -j trap group | jq -r '.[]["'$DEVLINK_DEV'"][].name'
361
+}
362
+
363
+devlink_trap_group_action_set()
364
+{
365
+ local group_name=$1; shift
366
+ local action=$1; shift
367
+
368
+ # Pipe output to /dev/null to avoid expected warnings.
369
+ devlink trap group set $DEVLINK_DEV group $group_name action $action \
370
+ &> /dev/null
371
+}
372
+
373
+devlink_trap_group_rx_packets_get()
374
+{
375
+ local group_name=$1; shift
376
+
377
+ devlink -js trap group show $DEVLINK_DEV group $group_name \
378
+ | jq '.[][][]["stats"]["rx"]["packets"]'
379
+}
380
+
381
+devlink_trap_group_rx_bytes_get()
382
+{
383
+ local group_name=$1; shift
384
+
385
+ devlink -js trap group show $DEVLINK_DEV group $group_name \
386
+ | jq '.[][][]["stats"]["rx"]["bytes"]'
387
+}
388
+
389
+devlink_trap_group_stats_idle_test()
390
+{
391
+ local group_name=$1; shift
392
+ local t0_packets t0_bytes
393
+ local t1_packets t1_bytes
394
+
395
+ t0_packets=$(devlink_trap_group_rx_packets_get $group_name)
396
+ t0_bytes=$(devlink_trap_group_rx_bytes_get $group_name)
397
+
398
+ sleep 1
399
+
400
+ t1_packets=$(devlink_trap_group_rx_packets_get $group_name)
401
+ t1_bytes=$(devlink_trap_group_rx_bytes_get $group_name)
402
+
403
+ if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then
404
+ return 0
405
+ else
406
+ return 1
407
+ fi
408
+}
409
+
410
+devlink_trap_exception_test()
411
+{
412
+ local trap_name=$1; shift
413
+ local group_name
414
+
415
+ group_name=$(devlink_trap_group_get $trap_name)
416
+
417
+ devlink_trap_stats_idle_test $trap_name
418
+ check_fail $? "Trap stats idle when packets should have been trapped"
419
+
420
+ devlink_trap_group_stats_idle_test $group_name
421
+ check_fail $? "Trap group idle when packets should have been trapped"
422
+}
423
+
424
+devlink_trap_drop_test()
425
+{
426
+ local trap_name=$1; shift
427
+ local dev=$1; shift
428
+ local handle=$1; shift
429
+ local group_name
430
+
431
+ group_name=$(devlink_trap_group_get $trap_name)
432
+
433
+ # This is the common part of all the tests. It checks that stats are
434
+ # initially idle, then non-idle after changing the trap action and
435
+ # finally idle again. It also makes sure the packets are dropped and
436
+ # never forwarded.
437
+ devlink_trap_stats_idle_test $trap_name
438
+ check_err $? "Trap stats not idle with initial drop action"
439
+ devlink_trap_group_stats_idle_test $group_name
440
+ check_err $? "Trap group stats not idle with initial drop action"
441
+
442
+ devlink_trap_action_set $trap_name "trap"
443
+ devlink_trap_stats_idle_test $trap_name
444
+ check_fail $? "Trap stats idle after setting action to trap"
445
+ devlink_trap_group_stats_idle_test $group_name
446
+ check_fail $? "Trap group stats idle after setting action to trap"
447
+
448
+ devlink_trap_action_set $trap_name "drop"
449
+
450
+ devlink_trap_stats_idle_test $trap_name
451
+ check_err $? "Trap stats not idle after setting action to drop"
452
+ devlink_trap_group_stats_idle_test $group_name
453
+ check_err $? "Trap group stats not idle after setting action to drop"
454
+
455
+ tc_check_packets "dev $dev egress" $handle 0
456
+ check_err $? "Packets were not dropped"
457
+}
458
+
459
+devlink_trap_drop_cleanup()
460
+{
461
+ local mz_pid=$1; shift
462
+ local dev=$1; shift
463
+ local proto=$1; shift
464
+ local pref=$1; shift
465
+ local handle=$1; shift
466
+
467
+ kill $mz_pid && wait $mz_pid &> /dev/null
468
+ tc filter del dev $dev egress protocol $proto pref $pref handle $handle flower
469
+}
470
+
471
+devlink_trap_stats_test()
472
+{
473
+ local test_name=$1; shift
474
+ local trap_name=$1; shift
475
+ local send_one="$@"
476
+ local t0_packets
477
+ local t1_packets
478
+
479
+ RET=0
480
+
481
+ t0_packets=$(devlink_trap_rx_packets_get $trap_name)
482
+
483
+ $send_one && sleep 1
484
+
485
+ t1_packets=$(devlink_trap_rx_packets_get $trap_name)
486
+
487
+ if [[ $t1_packets -eq $t0_packets ]]; then
488
+ check_err 1 "Trap stats did not increase"
489
+ fi
490
+
491
+ log_test "$test_name"
492
+}
493
+
494
+devlink_trap_policers_num_get()
495
+{
496
+ devlink -j -p trap policer show | jq '.[]["'$DEVLINK_DEV'"] | length'
497
+}
498
+
499
+devlink_trap_policer_rate_get()
500
+{
501
+ local policer_id=$1; shift
502
+
503
+ devlink -j -p trap policer show $DEVLINK_DEV policer $policer_id \
504
+ | jq '.[][][]["rate"]'
505
+}
506
+
507
+devlink_trap_policer_burst_get()
508
+{
509
+ local policer_id=$1; shift
510
+
511
+ devlink -j -p trap policer show $DEVLINK_DEV policer $policer_id \
512
+ | jq '.[][][]["burst"]'
513
+}
514
+
515
+devlink_trap_policer_rx_dropped_get()
516
+{
517
+ local policer_id=$1; shift
518
+
519
+ devlink -j -p -s trap policer show $DEVLINK_DEV policer $policer_id \
520
+ | jq '.[][][]["stats"]["rx"]["dropped"]'
521
+}
522
+
523
+devlink_trap_group_policer_get()
524
+{
525
+ local group_name=$1; shift
526
+
527
+ devlink -j -p trap group show $DEVLINK_DEV group $group_name \
528
+ | jq '.[][][]["policer"]'
529
+}
530
+
531
+devlink_trap_policer_ids_get()
532
+{
533
+ devlink -j -p trap policer show \
534
+ | jq '.[]["'$DEVLINK_DEV'"][]["policer"]'
535
+}
536
+
537
+devlink_port_by_netdev()
538
+{
539
+ local if_name=$1
540
+
541
+ devlink -j port show $if_name | jq -e '.[] | keys' | jq -r '.[]'
542
+}
543
+
544
+devlink_cpu_port_get()
545
+{
546
+ local cpu_dl_port_num=$(devlink port list | grep "$DEVLINK_DEV" |
547
+ grep cpu | cut -d/ -f3 | cut -d: -f1 |
548
+ sed -n '1p')
549
+
550
+ echo "$DEVLINK_DEV/$cpu_dl_port_num"
551
+}
552
+
553
+devlink_cell_size_get()
554
+{
555
+ devlink sb pool show "$DEVLINK_DEV" pool 0 -j \
556
+ | jq '.pool[][].cell_size'
557
+}