Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 #
0004 # This test is for checking devlink-trap functionality. It makes use of
0005 # netdevsim which implements the required callbacks.
0006 
0007 lib_dir=$(dirname $0)/../../../net/forwarding
0008 
0009 ALL_TESTS="
0010         init_test
0011         trap_action_test
0012         trap_metadata_test
0013         bad_trap_test
0014         bad_trap_action_test
0015         trap_stats_test
0016         trap_group_action_test
0017         bad_trap_group_test
0018         trap_group_stats_test
0019         trap_policer_test
0020         trap_policer_bind_test
0021         port_del_test
0022         dev_del_test
0023 "
0024 NETDEVSIM_PATH=/sys/bus/netdevsim/
0025 DEV_ADDR=1337
0026 DEV=netdevsim${DEV_ADDR}
0027 DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/
0028 SLEEP_TIME=1
0029 NETDEV=""
0030 NUM_NETIFS=0
0031 source $lib_dir/lib.sh
0032 
0033 DEVLINK_DEV=
0034 source $lib_dir/devlink_lib.sh
0035 DEVLINK_DEV=netdevsim/${DEV}
0036 
0037 require_command udevadm
0038 
0039 modprobe netdevsim &> /dev/null
0040 if [ ! -d "$NETDEVSIM_PATH" ]; then
0041         echo "SKIP: No netdevsim support"
0042         exit 1
0043 fi
0044 
0045 if [ -d "${NETDEVSIM_PATH}/devices/netdevsim${DEV_ADDR}" ]; then
0046         echo "SKIP: Device netdevsim${DEV_ADDR} already exists"
0047         exit 1
0048 fi
0049 
0050 init_test()
0051 {
0052         RET=0
0053 
0054         test $(devlink_traps_num_get) -ne 0
0055         check_err $? "No traps were registered"
0056 
0057         log_test "Initialization"
0058 }
0059 
0060 trap_action_test()
0061 {
0062         local orig_action
0063         local trap_name
0064         local action
0065 
0066         RET=0
0067 
0068         for trap_name in $(devlink_traps_get); do
0069                 # The action of non-drop traps cannot be changed.
0070                 if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then
0071                         devlink_trap_action_set $trap_name "trap"
0072                         action=$(devlink_trap_action_get $trap_name)
0073                         if [ $action != "trap" ]; then
0074                                 check_err 1 "Trap $trap_name did not change action to trap"
0075                         fi
0076 
0077                         devlink_trap_action_set $trap_name "drop"
0078                         action=$(devlink_trap_action_get $trap_name)
0079                         if [ $action != "drop" ]; then
0080                                 check_err 1 "Trap $trap_name did not change action to drop"
0081                         fi
0082                 else
0083                         orig_action=$(devlink_trap_action_get $trap_name)
0084 
0085                         devlink_trap_action_set $trap_name "trap"
0086                         action=$(devlink_trap_action_get $trap_name)
0087                         if [ $action != $orig_action ]; then
0088                                 check_err 1 "Trap $trap_name changed action when should not"
0089                         fi
0090 
0091                         devlink_trap_action_set $trap_name "drop"
0092                         action=$(devlink_trap_action_get $trap_name)
0093                         if [ $action != $orig_action ]; then
0094                                 check_err 1 "Trap $trap_name changed action when should not"
0095                         fi
0096                 fi
0097         done
0098 
0099         log_test "Trap action"
0100 }
0101 
0102 trap_metadata_test()
0103 {
0104         local trap_name
0105 
0106         RET=0
0107 
0108         for trap_name in $(devlink_traps_get); do
0109                 devlink_trap_metadata_test $trap_name "input_port"
0110                 check_err $? "Input port not reported as metadata of trap $trap_name"
0111                 if [ $trap_name == "ingress_flow_action_drop" ] ||
0112                    [ $trap_name == "egress_flow_action_drop" ]; then
0113                         devlink_trap_metadata_test $trap_name "flow_action_cookie"
0114                         check_err $? "Flow action cookie not reported as metadata of trap $trap_name"
0115                 fi
0116         done
0117 
0118         log_test "Trap metadata"
0119 }
0120 
0121 bad_trap_test()
0122 {
0123         RET=0
0124 
0125         devlink_trap_action_set "made_up_trap" "drop"
0126         check_fail $? "Did not get an error for non-existing trap"
0127 
0128         log_test "Non-existing trap"
0129 }
0130 
0131 bad_trap_action_test()
0132 {
0133         local traps_arr
0134         local trap_name
0135 
0136         RET=0
0137 
0138         # Pick first trap.
0139         traps_arr=($(devlink_traps_get))
0140         trap_name=${traps_arr[0]}
0141 
0142         devlink_trap_action_set $trap_name "made_up_action"
0143         check_fail $? "Did not get an error for non-existing trap action"
0144 
0145         log_test "Non-existing trap action"
0146 }
0147 
0148 trap_stats_test()
0149 {
0150         local trap_name
0151 
0152         RET=0
0153 
0154         for trap_name in $(devlink_traps_get); do
0155                 devlink_trap_stats_idle_test $trap_name
0156                 check_err $? "Stats of trap $trap_name not idle when netdev down"
0157 
0158                 ip link set dev $NETDEV up
0159 
0160                 if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then
0161                         devlink_trap_action_set $trap_name "trap"
0162                         devlink_trap_stats_idle_test $trap_name
0163                         check_fail $? "Stats of trap $trap_name idle when action is trap"
0164 
0165                         devlink_trap_action_set $trap_name "drop"
0166                         devlink_trap_stats_idle_test $trap_name
0167                         check_err $? "Stats of trap $trap_name not idle when action is drop"
0168 
0169                         echo "y"> $DEBUGFS_DIR/fail_trap_drop_counter_get
0170                         devlink -s trap show $DEVLINK_DEV trap $trap_name &> /dev/null
0171                         check_fail $? "Managed to read trap (hard dropped) statistics when should not"
0172                         echo "n"> $DEBUGFS_DIR/fail_trap_drop_counter_get
0173                         devlink -s trap show $DEVLINK_DEV trap $trap_name &> /dev/null
0174                         check_err $? "Did not manage to read trap (hard dropped) statistics when should"
0175 
0176                         devlink_trap_drop_stats_idle_test $trap_name
0177                         check_fail $? "Drop stats of trap $trap_name idle when should not"
0178                 else
0179                         devlink_trap_stats_idle_test $trap_name
0180                         check_fail $? "Stats of non-drop trap $trap_name idle when should not"
0181                 fi
0182 
0183                 ip link set dev $NETDEV down
0184         done
0185 
0186         log_test "Trap statistics"
0187 }
0188 
0189 trap_group_action_test()
0190 {
0191         local curr_group group_name
0192         local trap_name
0193         local trap_type
0194         local action
0195 
0196         RET=0
0197 
0198         for group_name in $(devlink_trap_groups_get); do
0199                 devlink_trap_group_action_set $group_name "trap"
0200 
0201                 for trap_name in $(devlink_traps_get); do
0202                         curr_group=$(devlink_trap_group_get $trap_name)
0203                         if [ $curr_group != $group_name ]; then
0204                                 continue
0205                         fi
0206 
0207                         trap_type=$(devlink_trap_type_get $trap_name)
0208                         if [ $trap_type != "drop" ]; then
0209                                 continue
0210                         fi
0211 
0212                         action=$(devlink_trap_action_get $trap_name)
0213                         if [ $action != "trap" ]; then
0214                                 check_err 1 "Trap $trap_name did not change action to trap"
0215                         fi
0216                 done
0217 
0218                 devlink_trap_group_action_set $group_name "drop"
0219 
0220                 for trap_name in $(devlink_traps_get); do
0221                         curr_group=$(devlink_trap_group_get $trap_name)
0222                         if [ $curr_group != $group_name ]; then
0223                                 continue
0224                         fi
0225 
0226                         trap_type=$(devlink_trap_type_get $trap_name)
0227                         if [ $trap_type != "drop" ]; then
0228                                 continue
0229                         fi
0230 
0231                         action=$(devlink_trap_action_get $trap_name)
0232                         if [ $action != "drop" ]; then
0233                                 check_err 1 "Trap $trap_name did not change action to drop"
0234                         fi
0235                 done
0236         done
0237 
0238         log_test "Trap group action"
0239 }
0240 
0241 bad_trap_group_test()
0242 {
0243         RET=0
0244 
0245         devlink_trap_group_action_set "made_up_trap_group" "drop"
0246         check_fail $? "Did not get an error for non-existing trap group"
0247 
0248         log_test "Non-existing trap group"
0249 }
0250 
0251 trap_group_stats_test()
0252 {
0253         local group_name
0254 
0255         RET=0
0256 
0257         for group_name in $(devlink_trap_groups_get); do
0258                 devlink_trap_group_stats_idle_test $group_name
0259                 check_err $? "Stats of trap group $group_name not idle when netdev down"
0260 
0261                 ip link set dev $NETDEV up
0262 
0263                 devlink_trap_group_action_set $group_name "trap"
0264                 devlink_trap_group_stats_idle_test $group_name
0265                 check_fail $? "Stats of trap group $group_name idle when action is trap"
0266 
0267                 devlink_trap_group_action_set $group_name "drop"
0268                 ip link set dev $NETDEV down
0269         done
0270 
0271         log_test "Trap group statistics"
0272 }
0273 
0274 trap_policer_test()
0275 {
0276         local packets_t0
0277         local packets_t1
0278 
0279         RET=0
0280 
0281         if [ $(devlink_trap_policers_num_get) -eq 0 ]; then
0282                 check_err 1 "Failed to dump policers"
0283         fi
0284 
0285         devlink trap policer set $DEVLINK_DEV policer 1337 &> /dev/null
0286         check_fail $? "Did not get an error for setting a non-existing policer"
0287         devlink trap policer show $DEVLINK_DEV policer 1337 &> /dev/null
0288         check_fail $? "Did not get an error for getting a non-existing policer"
0289 
0290         devlink trap policer set $DEVLINK_DEV policer 1 rate 2000 burst 16
0291         check_err $? "Failed to set valid parameters for a valid policer"
0292         if [ $(devlink_trap_policer_rate_get 1) -ne 2000 ]; then
0293                 check_err 1 "Policer rate was not changed"
0294         fi
0295         if [ $(devlink_trap_policer_burst_get 1) -ne 16 ]; then
0296                 check_err 1 "Policer burst size was not changed"
0297         fi
0298 
0299         devlink trap policer set $DEVLINK_DEV policer 1 rate 0 &> /dev/null
0300         check_fail $? "Policer rate was changed to rate lower than limit"
0301         devlink trap policer set $DEVLINK_DEV policer 1 rate 9000 &> /dev/null
0302         check_fail $? "Policer rate was changed to rate higher than limit"
0303         devlink trap policer set $DEVLINK_DEV policer 1 burst 2 &> /dev/null
0304         check_fail $? "Policer burst size was changed to burst size lower than limit"
0305         devlink trap policer set $DEVLINK_DEV policer 1 rate 65537 &> /dev/null
0306         check_fail $? "Policer burst size was changed to burst size higher than limit"
0307         echo "y" > $DEBUGFS_DIR/fail_trap_policer_set
0308         devlink trap policer set $DEVLINK_DEV policer 1 rate 3000 &> /dev/null
0309         check_fail $? "Managed to set policer rate when should not"
0310         echo "n" > $DEBUGFS_DIR/fail_trap_policer_set
0311         if [ $(devlink_trap_policer_rate_get 1) -ne 2000 ]; then
0312                 check_err 1 "Policer rate was changed to an invalid value"
0313         fi
0314         if [ $(devlink_trap_policer_burst_get 1) -ne 16 ]; then
0315                 check_err 1 "Policer burst size was changed to an invalid value"
0316         fi
0317 
0318         packets_t0=$(devlink_trap_policer_rx_dropped_get 1)
0319         sleep .5
0320         packets_t1=$(devlink_trap_policer_rx_dropped_get 1)
0321         if [ ! $packets_t1 -gt $packets_t0 ]; then
0322                 check_err 1 "Policer drop counter was not incremented"
0323         fi
0324 
0325         echo "y"> $DEBUGFS_DIR/fail_trap_policer_counter_get
0326         devlink -s trap policer show $DEVLINK_DEV policer 1 &> /dev/null
0327         check_fail $? "Managed to read policer drop counter when should not"
0328         echo "n"> $DEBUGFS_DIR/fail_trap_policer_counter_get
0329         devlink -s trap policer show $DEVLINK_DEV policer 1 &> /dev/null
0330         check_err $? "Did not manage to read policer drop counter when should"
0331 
0332         log_test "Trap policer"
0333 }
0334 
0335 trap_group_check_policer()
0336 {
0337         local group_name=$1; shift
0338 
0339         devlink -j -p trap group show $DEVLINK_DEV group $group_name \
0340                 | jq -e '.[][][]["policer"]' &> /dev/null
0341 }
0342 
0343 trap_policer_bind_test()
0344 {
0345         RET=0
0346 
0347         devlink trap group set $DEVLINK_DEV group l2_drops policer 1
0348         check_err $? "Failed to bind a valid policer"
0349         if [ $(devlink_trap_group_policer_get "l2_drops") -ne 1 ]; then
0350                 check_err 1 "Bound policer was not changed"
0351         fi
0352 
0353         devlink trap group set $DEVLINK_DEV group l2_drops policer 1337 \
0354                 &> /dev/null
0355         check_fail $? "Did not get an error for binding a non-existing policer"
0356         if [ $(devlink_trap_group_policer_get "l2_drops") -ne 1 ]; then
0357                 check_err 1 "Bound policer was changed when should not"
0358         fi
0359 
0360         devlink trap group set $DEVLINK_DEV group l2_drops policer 0
0361         check_err $? "Failed to unbind a policer when using ID 0"
0362         trap_group_check_policer "l2_drops"
0363         check_fail $? "Trap group has a policer after unbinding with ID 0"
0364 
0365         devlink trap group set $DEVLINK_DEV group l2_drops policer 1
0366         check_err $? "Failed to bind a valid policer"
0367 
0368         devlink trap group set $DEVLINK_DEV group l2_drops nopolicer
0369         check_err $? "Failed to unbind a policer when using 'nopolicer' keyword"
0370         trap_group_check_policer "l2_drops"
0371         check_fail $? "Trap group has a policer after unbinding with 'nopolicer' keyword"
0372 
0373         devlink trap group set $DEVLINK_DEV group l2_drops policer 1
0374         check_err $? "Failed to bind a valid policer"
0375 
0376         echo "y"> $DEBUGFS_DIR/fail_trap_group_set
0377         devlink trap group set $DEVLINK_DEV group l2_drops policer 2 \
0378                 &> /dev/null
0379         check_fail $? "Managed to bind a policer when should not"
0380         echo "n"> $DEBUGFS_DIR/fail_trap_group_set
0381         devlink trap group set $DEVLINK_DEV group l2_drops policer 2
0382         check_err $? "Did not manage to bind a policer when should"
0383 
0384         devlink trap group set $DEVLINK_DEV group l2_drops action drop \
0385                 policer 1337 &> /dev/null
0386         check_fail $? "Did not get an error for partially modified trap group"
0387 
0388         log_test "Trap policer binding"
0389 }
0390 
0391 port_del_test()
0392 {
0393         local group_name
0394         local i
0395 
0396         # The test never fails. It is meant to exercise different code paths
0397         # and make sure we properly dismantle a port while packets are
0398         # in-flight.
0399         RET=0
0400 
0401         devlink_traps_enable_all
0402 
0403         for i in $(seq 1 10); do
0404                 ip link set dev $NETDEV up
0405 
0406                 sleep $SLEEP_TIME
0407 
0408                 netdevsim_port_destroy
0409                 netdevsim_port_create
0410                 udevadm settle
0411         done
0412 
0413         devlink_traps_disable_all
0414 
0415         log_test "Port delete"
0416 }
0417 
0418 dev_del_test()
0419 {
0420         local group_name
0421         local i
0422 
0423         # The test never fails. It is meant to exercise different code paths
0424         # and make sure we properly unregister traps while packets are
0425         # in-flight.
0426         RET=0
0427 
0428         devlink_traps_enable_all
0429 
0430         for i in $(seq 1 10); do
0431                 ip link set dev $NETDEV up
0432 
0433                 sleep $SLEEP_TIME
0434 
0435                 cleanup
0436                 setup_prepare
0437         done
0438 
0439         devlink_traps_disable_all
0440 
0441         log_test "Device delete"
0442 }
0443 
0444 netdevsim_dev_create()
0445 {
0446         echo "$DEV_ADDR 0" > ${NETDEVSIM_PATH}/new_device
0447 }
0448 
0449 netdevsim_dev_destroy()
0450 {
0451         echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device
0452 }
0453 
0454 netdevsim_port_create()
0455 {
0456         echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/new_port
0457 }
0458 
0459 netdevsim_port_destroy()
0460 {
0461         echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/del_port
0462 }
0463 
0464 setup_prepare()
0465 {
0466         local netdev
0467 
0468         netdevsim_dev_create
0469 
0470         if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}" ]; then
0471                 echo "Failed to create netdevsim device"
0472                 exit 1
0473         fi
0474 
0475         netdevsim_port_create
0476 
0477         if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}/net/" ]; then
0478                 echo "Failed to create netdevsim port"
0479                 exit 1
0480         fi
0481 
0482         # Wait for udev to rename newly created netdev.
0483         udevadm settle
0484 
0485         NETDEV=$(ls ${NETDEVSIM_PATH}/devices/${DEV}/net/)
0486 }
0487 
0488 cleanup()
0489 {
0490         pre_cleanup
0491         netdevsim_port_destroy
0492         netdevsim_dev_destroy
0493 }
0494 
0495 trap cleanup EXIT
0496 
0497 setup_prepare
0498 
0499 tests_run
0500 
0501 exit $EXIT_STATUS