Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 
0004 # Kselftest framework requirement - SKIP code is 4.
0005 ksft_skip=4
0006 
0007 ##############################################################################
0008 # Defines
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 # Sanity checks
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 # Devlink helpers
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 # Changing pool type from static to dynamic causes reinterpretation of threshold
0130 # values. They therefore need to be saved before pool type is changed, then the
0131 # pool type can be changed, and then the new values need to be set up. Therefore
0132 # instead of saving the current state implicitly in the _set call, provide
0133 # functions for all three primitives: save, set, and restore.
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         # Pipe output to /dev/null to avoid expected warnings.
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         # Pipe output to /dev/null to avoid expected warnings.
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         # This is the common part of all the tests. It checks that stats are
0469         # initially idle, then non-idle after changing the trap action and
0470         # finally idle again. It also makes sure the packets are dropped and
0471         # never forwarded.
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 }