0001
0002
0003
0004
0005 ksft_skip=4
0006
0007
0008
0009
0010 if [[ ! -v DEVLINK_DEV ]]; then
0011 DEVLINK_DEV=$(devlink port show "${NETIFS[p1]:-$NETIF_NO_CABLE}" -j \
0012 | jq -r '.port | keys[]' | cut -d/ -f-2)
0013 if [ -z "$DEVLINK_DEV" ]; then
0014 echo "SKIP: ${NETIFS[p1]} has no devlink device registered for it"
0015 exit $ksft_skip
0016 fi
0017 if [[ "$(echo $DEVLINK_DEV | grep -c pci)" -eq 0 ]]; then
0018 echo "SKIP: devlink device's bus is not PCI"
0019 exit $ksft_skip
0020 fi
0021
0022 DEVLINK_VIDDID=$(lspci -s $(echo $DEVLINK_DEV | cut -d"/" -f2) \
0023 -n | cut -d" " -f3)
0024 elif [[ ! -z "$DEVLINK_DEV" ]]; then
0025 devlink dev show $DEVLINK_DEV &> /dev/null
0026 if [ $? -ne 0 ]; then
0027 echo "SKIP: devlink device \"$DEVLINK_DEV\" not found"
0028 exit $ksft_skip
0029 fi
0030 fi
0031
0032
0033
0034
0035 devlink help 2>&1 | grep resource &> /dev/null
0036 if [ $? -ne 0 ]; then
0037 echo "SKIP: iproute2 too old, missing devlink resource support"
0038 exit $ksft_skip
0039 fi
0040
0041 devlink help 2>&1 | grep trap &> /dev/null
0042 if [ $? -ne 0 ]; then
0043 echo "SKIP: iproute2 too old, missing devlink trap support"
0044 exit $ksft_skip
0045 fi
0046
0047 devlink dev help 2>&1 | grep info &> /dev/null
0048 if [ $? -ne 0 ]; then
0049 echo "SKIP: iproute2 too old, missing devlink dev info support"
0050 exit $ksft_skip
0051 fi
0052
0053
0054
0055
0056 devlink_resource_names_to_path()
0057 {
0058 local resource
0059 local path=""
0060
0061 for resource in "${@}"; do
0062 if [ "$path" == "" ]; then
0063 path="$resource"
0064 else
0065 path="${path}/$resource"
0066 fi
0067 done
0068
0069 echo "$path"
0070 }
0071
0072 devlink_resource_get()
0073 {
0074 local name=$1
0075 local resource_name=.[][\"$DEVLINK_DEV\"]
0076
0077 resource_name="$resource_name | .[] | select (.name == \"$name\")"
0078
0079 shift
0080 for resource in "${@}"; do
0081 resource_name="${resource_name} | .[\"resources\"][] | \
0082 select (.name == \"$resource\")"
0083 done
0084
0085 devlink -j resource show "$DEVLINK_DEV" | jq "$resource_name"
0086 }
0087
0088 devlink_resource_size_get()
0089 {
0090 local size=$(devlink_resource_get "$@" | jq '.["size_new"]')
0091
0092 if [ "$size" == "null" ]; then
0093 devlink_resource_get "$@" | jq '.["size"]'
0094 else
0095 echo "$size"
0096 fi
0097 }
0098
0099 devlink_resource_size_set()
0100 {
0101 local new_size=$1
0102 local path
0103
0104 shift
0105 path=$(devlink_resource_names_to_path "$@")
0106 devlink resource set "$DEVLINK_DEV" path "$path" size "$new_size"
0107 check_err $? "Failed setting path $path to size $size"
0108 }
0109
0110 devlink_resource_occ_get()
0111 {
0112 devlink_resource_get "$@" | jq '.["occ"]'
0113 }
0114
0115 devlink_reload()
0116 {
0117 local still_pending
0118
0119 devlink dev reload "$DEVLINK_DEV" &> /dev/null
0120 check_err $? "Failed reload"
0121
0122 still_pending=$(devlink resource show "$DEVLINK_DEV" | \
0123 grep -c "size_new")
0124 check_err $still_pending "Failed reload - There are still unset sizes"
0125 }
0126
0127 declare -A DEVLINK_ORIG
0128
0129
0130
0131
0132
0133
0134
0135 devlink_port_pool_threshold()
0136 {
0137 local port=$1; shift
0138 local pool=$1; shift
0139
0140 devlink sb port pool show $port pool $pool -j \
0141 | jq '.port_pool."'"$port"'"[].threshold'
0142 }
0143
0144 devlink_port_pool_th_save()
0145 {
0146 local port=$1; shift
0147 local pool=$1; shift
0148 local key="port_pool($port,$pool).threshold"
0149
0150 DEVLINK_ORIG[$key]=$(devlink_port_pool_threshold $port $pool)
0151 }
0152
0153 devlink_port_pool_th_set()
0154 {
0155 local port=$1; shift
0156 local pool=$1; shift
0157 local th=$1; shift
0158
0159 devlink sb port pool set $port pool $pool th $th
0160 }
0161
0162 devlink_port_pool_th_restore()
0163 {
0164 local port=$1; shift
0165 local pool=$1; shift
0166 local key="port_pool($port,$pool).threshold"
0167 local -a orig=(${DEVLINK_ORIG[$key]})
0168
0169 if [[ -z $orig ]]; then
0170 echo "WARNING: Mismatched devlink_port_pool_th_restore"
0171 else
0172 devlink sb port pool set $port pool $pool th $orig
0173 fi
0174 }
0175
0176 devlink_pool_size_thtype()
0177 {
0178 local pool=$1; shift
0179
0180 devlink sb pool show "$DEVLINK_DEV" pool $pool -j \
0181 | jq -r '.pool[][] | (.size, .thtype)'
0182 }
0183
0184 devlink_pool_size_thtype_save()
0185 {
0186 local pool=$1; shift
0187 local key="pool($pool).size_thtype"
0188
0189 DEVLINK_ORIG[$key]=$(devlink_pool_size_thtype $pool)
0190 }
0191
0192 devlink_pool_size_thtype_set()
0193 {
0194 local pool=$1; shift
0195 local thtype=$1; shift
0196 local size=$1; shift
0197
0198 devlink sb pool set "$DEVLINK_DEV" pool $pool size $size thtype $thtype
0199 }
0200
0201 devlink_pool_size_thtype_restore()
0202 {
0203 local pool=$1; shift
0204 local key="pool($pool).size_thtype"
0205 local -a orig=(${DEVLINK_ORIG[$key]})
0206
0207 if [[ -z ${orig[0]} ]]; then
0208 echo "WARNING: Mismatched devlink_pool_size_thtype_restore"
0209 else
0210 devlink sb pool set "$DEVLINK_DEV" pool $pool \
0211 size ${orig[0]} thtype ${orig[1]}
0212 fi
0213 }
0214
0215 devlink_tc_bind_pool_th()
0216 {
0217 local port=$1; shift
0218 local tc=$1; shift
0219 local dir=$1; shift
0220
0221 devlink sb tc bind show $port tc $tc type $dir -j \
0222 | jq -r '.tc_bind[][] | (.pool, .threshold)'
0223 }
0224
0225 devlink_tc_bind_pool_th_save()
0226 {
0227 local port=$1; shift
0228 local tc=$1; shift
0229 local dir=$1; shift
0230 local key="tc_bind($port,$dir,$tc).pool_th"
0231
0232 DEVLINK_ORIG[$key]=$(devlink_tc_bind_pool_th $port $tc $dir)
0233 }
0234
0235 devlink_tc_bind_pool_th_set()
0236 {
0237 local port=$1; shift
0238 local tc=$1; shift
0239 local dir=$1; shift
0240 local pool=$1; shift
0241 local th=$1; shift
0242
0243 devlink sb tc bind set $port tc $tc type $dir pool $pool th $th
0244 }
0245
0246 devlink_tc_bind_pool_th_restore()
0247 {
0248 local port=$1; shift
0249 local tc=$1; shift
0250 local dir=$1; shift
0251 local key="tc_bind($port,$dir,$tc).pool_th"
0252 local -a orig=(${DEVLINK_ORIG[$key]})
0253
0254 if [[ -z ${orig[0]} ]]; then
0255 echo "WARNING: Mismatched devlink_tc_bind_pool_th_restore"
0256 else
0257 devlink sb tc bind set $port tc $tc type $dir \
0258 pool ${orig[0]} th ${orig[1]}
0259 fi
0260 }
0261
0262 devlink_traps_num_get()
0263 {
0264 devlink -j trap | jq '.[]["'$DEVLINK_DEV'"] | length'
0265 }
0266
0267 devlink_traps_get()
0268 {
0269 devlink -j trap | jq -r '.[]["'$DEVLINK_DEV'"][].name'
0270 }
0271
0272 devlink_trap_type_get()
0273 {
0274 local trap_name=$1; shift
0275
0276 devlink -j trap show $DEVLINK_DEV trap $trap_name \
0277 | jq -r '.[][][].type'
0278 }
0279
0280 devlink_trap_action_set()
0281 {
0282 local trap_name=$1; shift
0283 local action=$1; shift
0284
0285
0286 devlink trap set $DEVLINK_DEV trap $trap_name \
0287 action $action &> /dev/null
0288 }
0289
0290 devlink_trap_action_get()
0291 {
0292 local trap_name=$1; shift
0293
0294 devlink -j trap show $DEVLINK_DEV trap $trap_name \
0295 | jq -r '.[][][].action'
0296 }
0297
0298 devlink_trap_group_get()
0299 {
0300 devlink -j trap show $DEVLINK_DEV trap $trap_name \
0301 | jq -r '.[][][].group'
0302 }
0303
0304 devlink_trap_metadata_test()
0305 {
0306 local trap_name=$1; shift
0307 local metadata=$1; shift
0308
0309 devlink -jv trap show $DEVLINK_DEV trap $trap_name \
0310 | jq -e '.[][][].metadata | contains(["'$metadata'"])' \
0311 &> /dev/null
0312 }
0313
0314 devlink_trap_rx_packets_get()
0315 {
0316 local trap_name=$1; shift
0317
0318 devlink -js trap show $DEVLINK_DEV trap $trap_name \
0319 | jq '.[][][]["stats"]["rx"]["packets"]'
0320 }
0321
0322 devlink_trap_rx_bytes_get()
0323 {
0324 local trap_name=$1; shift
0325
0326 devlink -js trap show $DEVLINK_DEV trap $trap_name \
0327 | jq '.[][][]["stats"]["rx"]["bytes"]'
0328 }
0329
0330 devlink_trap_drop_packets_get()
0331 {
0332 local trap_name=$1; shift
0333
0334 devlink -js trap show $DEVLINK_DEV trap $trap_name \
0335 | jq '.[][][]["stats"]["rx"]["dropped"]'
0336 }
0337
0338 devlink_trap_stats_idle_test()
0339 {
0340 local trap_name=$1; shift
0341 local t0_packets t0_bytes
0342 local t1_packets t1_bytes
0343
0344 t0_packets=$(devlink_trap_rx_packets_get $trap_name)
0345 t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)
0346
0347 sleep 1
0348
0349 t1_packets=$(devlink_trap_rx_packets_get $trap_name)
0350 t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)
0351
0352 if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then
0353 return 0
0354 else
0355 return 1
0356 fi
0357 }
0358
0359 devlink_trap_drop_stats_idle_test()
0360 {
0361 local trap_name=$1; shift
0362 local t0_packets t0_bytes
0363
0364 t0_packets=$(devlink_trap_drop_packets_get $trap_name)
0365
0366 sleep 1
0367
0368 t1_packets=$(devlink_trap_drop_packets_get $trap_name)
0369
0370 if [[ $t0_packets -eq $t1_packets ]]; then
0371 return 0
0372 else
0373 return 1
0374 fi
0375 }
0376
0377 devlink_traps_enable_all()
0378 {
0379 local trap_name
0380
0381 for trap_name in $(devlink_traps_get); do
0382 devlink_trap_action_set $trap_name "trap"
0383 done
0384 }
0385
0386 devlink_traps_disable_all()
0387 {
0388 for trap_name in $(devlink_traps_get); do
0389 devlink_trap_action_set $trap_name "drop"
0390 done
0391 }
0392
0393 devlink_trap_groups_get()
0394 {
0395 devlink -j trap group | jq -r '.[]["'$DEVLINK_DEV'"][].name'
0396 }
0397
0398 devlink_trap_group_action_set()
0399 {
0400 local group_name=$1; shift
0401 local action=$1; shift
0402
0403
0404 devlink trap group set $DEVLINK_DEV group $group_name action $action \
0405 &> /dev/null
0406 }
0407
0408 devlink_trap_group_rx_packets_get()
0409 {
0410 local group_name=$1; shift
0411
0412 devlink -js trap group show $DEVLINK_DEV group $group_name \
0413 | jq '.[][][]["stats"]["rx"]["packets"]'
0414 }
0415
0416 devlink_trap_group_rx_bytes_get()
0417 {
0418 local group_name=$1; shift
0419
0420 devlink -js trap group show $DEVLINK_DEV group $group_name \
0421 | jq '.[][][]["stats"]["rx"]["bytes"]'
0422 }
0423
0424 devlink_trap_group_stats_idle_test()
0425 {
0426 local group_name=$1; shift
0427 local t0_packets t0_bytes
0428 local t1_packets t1_bytes
0429
0430 t0_packets=$(devlink_trap_group_rx_packets_get $group_name)
0431 t0_bytes=$(devlink_trap_group_rx_bytes_get $group_name)
0432
0433 sleep 1
0434
0435 t1_packets=$(devlink_trap_group_rx_packets_get $group_name)
0436 t1_bytes=$(devlink_trap_group_rx_bytes_get $group_name)
0437
0438 if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then
0439 return 0
0440 else
0441 return 1
0442 fi
0443 }
0444
0445 devlink_trap_exception_test()
0446 {
0447 local trap_name=$1; shift
0448 local group_name
0449
0450 group_name=$(devlink_trap_group_get $trap_name)
0451
0452 devlink_trap_stats_idle_test $trap_name
0453 check_fail $? "Trap stats idle when packets should have been trapped"
0454
0455 devlink_trap_group_stats_idle_test $group_name
0456 check_fail $? "Trap group idle when packets should have been trapped"
0457 }
0458
0459 devlink_trap_drop_test()
0460 {
0461 local trap_name=$1; shift
0462 local dev=$1; shift
0463 local handle=$1; shift
0464 local group_name
0465
0466 group_name=$(devlink_trap_group_get $trap_name)
0467
0468
0469
0470
0471
0472 devlink_trap_stats_idle_test $trap_name
0473 check_err $? "Trap stats not idle with initial drop action"
0474 devlink_trap_group_stats_idle_test $group_name
0475 check_err $? "Trap group stats not idle with initial drop action"
0476
0477 devlink_trap_action_set $trap_name "trap"
0478 devlink_trap_stats_idle_test $trap_name
0479 check_fail $? "Trap stats idle after setting action to trap"
0480 devlink_trap_group_stats_idle_test $group_name
0481 check_fail $? "Trap group stats idle after setting action to trap"
0482
0483 devlink_trap_action_set $trap_name "drop"
0484
0485 devlink_trap_stats_idle_test $trap_name
0486 check_err $? "Trap stats not idle after setting action to drop"
0487 devlink_trap_group_stats_idle_test $group_name
0488 check_err $? "Trap group stats not idle after setting action to drop"
0489
0490 tc_check_packets "dev $dev egress" $handle 0
0491 check_err $? "Packets were not dropped"
0492 }
0493
0494 devlink_trap_drop_cleanup()
0495 {
0496 local mz_pid=$1; shift
0497 local dev=$1; shift
0498 local proto=$1; shift
0499 local pref=$1; shift
0500 local handle=$1; shift
0501
0502 kill $mz_pid && wait $mz_pid &> /dev/null
0503 tc filter del dev $dev egress protocol $proto pref $pref handle $handle flower
0504 }
0505
0506 devlink_trap_stats_test()
0507 {
0508 local test_name=$1; shift
0509 local trap_name=$1; shift
0510 local send_one="$@"
0511 local t0_packets
0512 local t1_packets
0513
0514 RET=0
0515
0516 t0_packets=$(devlink_trap_rx_packets_get $trap_name)
0517
0518 $send_one && sleep 1
0519
0520 t1_packets=$(devlink_trap_rx_packets_get $trap_name)
0521
0522 if [[ $t1_packets -eq $t0_packets ]]; then
0523 check_err 1 "Trap stats did not increase"
0524 fi
0525
0526 log_test "$test_name"
0527 }
0528
0529 devlink_trap_policers_num_get()
0530 {
0531 devlink -j -p trap policer show | jq '.[]["'$DEVLINK_DEV'"] | length'
0532 }
0533
0534 devlink_trap_policer_rate_get()
0535 {
0536 local policer_id=$1; shift
0537
0538 devlink -j -p trap policer show $DEVLINK_DEV policer $policer_id \
0539 | jq '.[][][]["rate"]'
0540 }
0541
0542 devlink_trap_policer_burst_get()
0543 {
0544 local policer_id=$1; shift
0545
0546 devlink -j -p trap policer show $DEVLINK_DEV policer $policer_id \
0547 | jq '.[][][]["burst"]'
0548 }
0549
0550 devlink_trap_policer_rx_dropped_get()
0551 {
0552 local policer_id=$1; shift
0553
0554 devlink -j -p -s trap policer show $DEVLINK_DEV policer $policer_id \
0555 | jq '.[][][]["stats"]["rx"]["dropped"]'
0556 }
0557
0558 devlink_trap_group_policer_get()
0559 {
0560 local group_name=$1; shift
0561
0562 devlink -j -p trap group show $DEVLINK_DEV group $group_name \
0563 | jq '.[][][]["policer"]'
0564 }
0565
0566 devlink_port_by_netdev()
0567 {
0568 local if_name=$1
0569
0570 devlink -j port show $if_name | jq -e '.[] | keys' | jq -r '.[]'
0571 }
0572
0573 devlink_cpu_port_get()
0574 {
0575 local cpu_dl_port_num=$(devlink port list | grep "$DEVLINK_DEV" |
0576 grep cpu | cut -d/ -f3 | cut -d: -f1 |
0577 sed -n '1p')
0578
0579 echo "$DEVLINK_DEV/$cpu_dl_port_num"
0580 }
0581
0582 devlink_cell_size_get()
0583 {
0584 devlink sb pool show "$DEVLINK_DEV" pool 0 -j \
0585 | jq '.pool[][].cell_size'
0586 }