cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

devlink_trap.sh (12676B)


      1#!/bin/bash
      2# SPDX-License-Identifier: GPL-2.0
      3#
      4# This test is for checking devlink-trap functionality. It makes use of
      5# netdevsim which implements the required callbacks.
      6
      7lib_dir=$(dirname $0)/../../../net/forwarding
      8
      9ALL_TESTS="
     10	init_test
     11	trap_action_test
     12	trap_metadata_test
     13	bad_trap_test
     14	bad_trap_action_test
     15	trap_stats_test
     16	trap_group_action_test
     17	bad_trap_group_test
     18	trap_group_stats_test
     19	trap_policer_test
     20	trap_policer_bind_test
     21	port_del_test
     22	dev_del_test
     23"
     24NETDEVSIM_PATH=/sys/bus/netdevsim/
     25DEV_ADDR=1337
     26DEV=netdevsim${DEV_ADDR}
     27DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/
     28SLEEP_TIME=1
     29NETDEV=""
     30NUM_NETIFS=0
     31source $lib_dir/lib.sh
     32
     33DEVLINK_DEV=
     34source $lib_dir/devlink_lib.sh
     35DEVLINK_DEV=netdevsim/${DEV}
     36
     37require_command udevadm
     38
     39modprobe netdevsim &> /dev/null
     40if [ ! -d "$NETDEVSIM_PATH" ]; then
     41	echo "SKIP: No netdevsim support"
     42	exit 1
     43fi
     44
     45if [ -d "${NETDEVSIM_PATH}/devices/netdevsim${DEV_ADDR}" ]; then
     46	echo "SKIP: Device netdevsim${DEV_ADDR} already exists"
     47	exit 1
     48fi
     49
     50init_test()
     51{
     52	RET=0
     53
     54	test $(devlink_traps_num_get) -ne 0
     55	check_err $? "No traps were registered"
     56
     57	log_test "Initialization"
     58}
     59
     60trap_action_test()
     61{
     62	local orig_action
     63	local trap_name
     64	local action
     65
     66	RET=0
     67
     68	for trap_name in $(devlink_traps_get); do
     69		# The action of non-drop traps cannot be changed.
     70		if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then
     71			devlink_trap_action_set $trap_name "trap"
     72			action=$(devlink_trap_action_get $trap_name)
     73			if [ $action != "trap" ]; then
     74				check_err 1 "Trap $trap_name did not change action to trap"
     75			fi
     76
     77			devlink_trap_action_set $trap_name "drop"
     78			action=$(devlink_trap_action_get $trap_name)
     79			if [ $action != "drop" ]; then
     80				check_err 1 "Trap $trap_name did not change action to drop"
     81			fi
     82		else
     83			orig_action=$(devlink_trap_action_get $trap_name)
     84
     85			devlink_trap_action_set $trap_name "trap"
     86			action=$(devlink_trap_action_get $trap_name)
     87			if [ $action != $orig_action ]; then
     88				check_err 1 "Trap $trap_name changed action when should not"
     89			fi
     90
     91			devlink_trap_action_set $trap_name "drop"
     92			action=$(devlink_trap_action_get $trap_name)
     93			if [ $action != $orig_action ]; then
     94				check_err 1 "Trap $trap_name changed action when should not"
     95			fi
     96		fi
     97	done
     98
     99	log_test "Trap action"
    100}
    101
    102trap_metadata_test()
    103{
    104	local trap_name
    105
    106	RET=0
    107
    108	for trap_name in $(devlink_traps_get); do
    109		devlink_trap_metadata_test $trap_name "input_port"
    110		check_err $? "Input port not reported as metadata of trap $trap_name"
    111		if [ $trap_name == "ingress_flow_action_drop" ] ||
    112		   [ $trap_name == "egress_flow_action_drop" ]; then
    113			devlink_trap_metadata_test $trap_name "flow_action_cookie"
    114			check_err $? "Flow action cookie not reported as metadata of trap $trap_name"
    115		fi
    116	done
    117
    118	log_test "Trap metadata"
    119}
    120
    121bad_trap_test()
    122{
    123	RET=0
    124
    125	devlink_trap_action_set "made_up_trap" "drop"
    126	check_fail $? "Did not get an error for non-existing trap"
    127
    128	log_test "Non-existing trap"
    129}
    130
    131bad_trap_action_test()
    132{
    133	local traps_arr
    134	local trap_name
    135
    136	RET=0
    137
    138	# Pick first trap.
    139	traps_arr=($(devlink_traps_get))
    140	trap_name=${traps_arr[0]}
    141
    142	devlink_trap_action_set $trap_name "made_up_action"
    143	check_fail $? "Did not get an error for non-existing trap action"
    144
    145	log_test "Non-existing trap action"
    146}
    147
    148trap_stats_test()
    149{
    150	local trap_name
    151
    152	RET=0
    153
    154	for trap_name in $(devlink_traps_get); do
    155		devlink_trap_stats_idle_test $trap_name
    156		check_err $? "Stats of trap $trap_name not idle when netdev down"
    157
    158		ip link set dev $NETDEV up
    159
    160		if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then
    161			devlink_trap_action_set $trap_name "trap"
    162			devlink_trap_stats_idle_test $trap_name
    163			check_fail $? "Stats of trap $trap_name idle when action is trap"
    164
    165			devlink_trap_action_set $trap_name "drop"
    166			devlink_trap_stats_idle_test $trap_name
    167			check_err $? "Stats of trap $trap_name not idle when action is drop"
    168
    169			echo "y"> $DEBUGFS_DIR/fail_trap_drop_counter_get
    170			devlink -s trap show $DEVLINK_DEV trap $trap_name &> /dev/null
    171			check_fail $? "Managed to read trap (hard dropped) statistics when should not"
    172			echo "n"> $DEBUGFS_DIR/fail_trap_drop_counter_get
    173			devlink -s trap show $DEVLINK_DEV trap $trap_name &> /dev/null
    174			check_err $? "Did not manage to read trap (hard dropped) statistics when should"
    175
    176			devlink_trap_drop_stats_idle_test $trap_name
    177			check_fail $? "Drop stats of trap $trap_name idle when should not"
    178		else
    179			devlink_trap_stats_idle_test $trap_name
    180			check_fail $? "Stats of non-drop trap $trap_name idle when should not"
    181		fi
    182
    183		ip link set dev $NETDEV down
    184	done
    185
    186	log_test "Trap statistics"
    187}
    188
    189trap_group_action_test()
    190{
    191	local curr_group group_name
    192	local trap_name
    193	local trap_type
    194	local action
    195
    196	RET=0
    197
    198	for group_name in $(devlink_trap_groups_get); do
    199		devlink_trap_group_action_set $group_name "trap"
    200
    201		for trap_name in $(devlink_traps_get); do
    202			curr_group=$(devlink_trap_group_get $trap_name)
    203			if [ $curr_group != $group_name ]; then
    204				continue
    205			fi
    206
    207			trap_type=$(devlink_trap_type_get $trap_name)
    208			if [ $trap_type != "drop" ]; then
    209				continue
    210			fi
    211
    212			action=$(devlink_trap_action_get $trap_name)
    213			if [ $action != "trap" ]; then
    214				check_err 1 "Trap $trap_name did not change action to trap"
    215			fi
    216		done
    217
    218		devlink_trap_group_action_set $group_name "drop"
    219
    220		for trap_name in $(devlink_traps_get); do
    221			curr_group=$(devlink_trap_group_get $trap_name)
    222			if [ $curr_group != $group_name ]; then
    223				continue
    224			fi
    225
    226			trap_type=$(devlink_trap_type_get $trap_name)
    227			if [ $trap_type != "drop" ]; then
    228				continue
    229			fi
    230
    231			action=$(devlink_trap_action_get $trap_name)
    232			if [ $action != "drop" ]; then
    233				check_err 1 "Trap $trap_name did not change action to drop"
    234			fi
    235		done
    236	done
    237
    238	log_test "Trap group action"
    239}
    240
    241bad_trap_group_test()
    242{
    243	RET=0
    244
    245	devlink_trap_group_action_set "made_up_trap_group" "drop"
    246	check_fail $? "Did not get an error for non-existing trap group"
    247
    248	log_test "Non-existing trap group"
    249}
    250
    251trap_group_stats_test()
    252{
    253	local group_name
    254
    255	RET=0
    256
    257	for group_name in $(devlink_trap_groups_get); do
    258		devlink_trap_group_stats_idle_test $group_name
    259		check_err $? "Stats of trap group $group_name not idle when netdev down"
    260
    261		ip link set dev $NETDEV up
    262
    263		devlink_trap_group_action_set $group_name "trap"
    264		devlink_trap_group_stats_idle_test $group_name
    265		check_fail $? "Stats of trap group $group_name idle when action is trap"
    266
    267		devlink_trap_group_action_set $group_name "drop"
    268		ip link set dev $NETDEV down
    269	done
    270
    271	log_test "Trap group statistics"
    272}
    273
    274trap_policer_test()
    275{
    276	local packets_t0
    277	local packets_t1
    278
    279	RET=0
    280
    281	if [ $(devlink_trap_policers_num_get) -eq 0 ]; then
    282		check_err 1 "Failed to dump policers"
    283	fi
    284
    285	devlink trap policer set $DEVLINK_DEV policer 1337 &> /dev/null
    286	check_fail $? "Did not get an error for setting a non-existing policer"
    287	devlink trap policer show $DEVLINK_DEV policer 1337 &> /dev/null
    288	check_fail $? "Did not get an error for getting a non-existing policer"
    289
    290	devlink trap policer set $DEVLINK_DEV policer 1 rate 2000 burst 16
    291	check_err $? "Failed to set valid parameters for a valid policer"
    292	if [ $(devlink_trap_policer_rate_get 1) -ne 2000 ]; then
    293		check_err 1 "Policer rate was not changed"
    294	fi
    295	if [ $(devlink_trap_policer_burst_get 1) -ne 16 ]; then
    296		check_err 1 "Policer burst size was not changed"
    297	fi
    298
    299	devlink trap policer set $DEVLINK_DEV policer 1 rate 0 &> /dev/null
    300	check_fail $? "Policer rate was changed to rate lower than limit"
    301	devlink trap policer set $DEVLINK_DEV policer 1 rate 9000 &> /dev/null
    302	check_fail $? "Policer rate was changed to rate higher than limit"
    303	devlink trap policer set $DEVLINK_DEV policer 1 burst 2 &> /dev/null
    304	check_fail $? "Policer burst size was changed to burst size lower than limit"
    305	devlink trap policer set $DEVLINK_DEV policer 1 rate 65537 &> /dev/null
    306	check_fail $? "Policer burst size was changed to burst size higher than limit"
    307	echo "y" > $DEBUGFS_DIR/fail_trap_policer_set
    308	devlink trap policer set $DEVLINK_DEV policer 1 rate 3000 &> /dev/null
    309	check_fail $? "Managed to set policer rate when should not"
    310	echo "n" > $DEBUGFS_DIR/fail_trap_policer_set
    311	if [ $(devlink_trap_policer_rate_get 1) -ne 2000 ]; then
    312		check_err 1 "Policer rate was changed to an invalid value"
    313	fi
    314	if [ $(devlink_trap_policer_burst_get 1) -ne 16 ]; then
    315		check_err 1 "Policer burst size was changed to an invalid value"
    316	fi
    317
    318	packets_t0=$(devlink_trap_policer_rx_dropped_get 1)
    319	sleep .5
    320	packets_t1=$(devlink_trap_policer_rx_dropped_get 1)
    321	if [ ! $packets_t1 -gt $packets_t0 ]; then
    322		check_err 1 "Policer drop counter was not incremented"
    323	fi
    324
    325	echo "y"> $DEBUGFS_DIR/fail_trap_policer_counter_get
    326	devlink -s trap policer show $DEVLINK_DEV policer 1 &> /dev/null
    327	check_fail $? "Managed to read policer drop counter when should not"
    328	echo "n"> $DEBUGFS_DIR/fail_trap_policer_counter_get
    329	devlink -s trap policer show $DEVLINK_DEV policer 1 &> /dev/null
    330	check_err $? "Did not manage to read policer drop counter when should"
    331
    332	log_test "Trap policer"
    333}
    334
    335trap_group_check_policer()
    336{
    337	local group_name=$1; shift
    338
    339	devlink -j -p trap group show $DEVLINK_DEV group $group_name \
    340		| jq -e '.[][][]["policer"]' &> /dev/null
    341}
    342
    343trap_policer_bind_test()
    344{
    345	RET=0
    346
    347	devlink trap group set $DEVLINK_DEV group l2_drops policer 1
    348	check_err $? "Failed to bind a valid policer"
    349	if [ $(devlink_trap_group_policer_get "l2_drops") -ne 1 ]; then
    350		check_err 1 "Bound policer was not changed"
    351	fi
    352
    353	devlink trap group set $DEVLINK_DEV group l2_drops policer 1337 \
    354		&> /dev/null
    355	check_fail $? "Did not get an error for binding a non-existing policer"
    356	if [ $(devlink_trap_group_policer_get "l2_drops") -ne 1 ]; then
    357		check_err 1 "Bound policer was changed when should not"
    358	fi
    359
    360	devlink trap group set $DEVLINK_DEV group l2_drops policer 0
    361	check_err $? "Failed to unbind a policer when using ID 0"
    362	trap_group_check_policer "l2_drops"
    363	check_fail $? "Trap group has a policer after unbinding with ID 0"
    364
    365	devlink trap group set $DEVLINK_DEV group l2_drops policer 1
    366	check_err $? "Failed to bind a valid policer"
    367
    368	devlink trap group set $DEVLINK_DEV group l2_drops nopolicer
    369	check_err $? "Failed to unbind a policer when using 'nopolicer' keyword"
    370	trap_group_check_policer "l2_drops"
    371	check_fail $? "Trap group has a policer after unbinding with 'nopolicer' keyword"
    372
    373	devlink trap group set $DEVLINK_DEV group l2_drops policer 1
    374	check_err $? "Failed to bind a valid policer"
    375
    376	echo "y"> $DEBUGFS_DIR/fail_trap_group_set
    377	devlink trap group set $DEVLINK_DEV group l2_drops policer 2 \
    378		&> /dev/null
    379	check_fail $? "Managed to bind a policer when should not"
    380	echo "n"> $DEBUGFS_DIR/fail_trap_group_set
    381	devlink trap group set $DEVLINK_DEV group l2_drops policer 2
    382	check_err $? "Did not manage to bind a policer when should"
    383
    384	devlink trap group set $DEVLINK_DEV group l2_drops action drop \
    385		policer 1337 &> /dev/null
    386	check_fail $? "Did not get an error for partially modified trap group"
    387
    388	log_test "Trap policer binding"
    389}
    390
    391port_del_test()
    392{
    393	local group_name
    394	local i
    395
    396	# The test never fails. It is meant to exercise different code paths
    397	# and make sure we properly dismantle a port while packets are
    398	# in-flight.
    399	RET=0
    400
    401	devlink_traps_enable_all
    402
    403	for i in $(seq 1 10); do
    404		ip link set dev $NETDEV up
    405
    406		sleep $SLEEP_TIME
    407
    408		netdevsim_port_destroy
    409		netdevsim_port_create
    410		udevadm settle
    411	done
    412
    413	devlink_traps_disable_all
    414
    415	log_test "Port delete"
    416}
    417
    418dev_del_test()
    419{
    420	local group_name
    421	local i
    422
    423	# The test never fails. It is meant to exercise different code paths
    424	# and make sure we properly unregister traps while packets are
    425	# in-flight.
    426	RET=0
    427
    428	devlink_traps_enable_all
    429
    430	for i in $(seq 1 10); do
    431		ip link set dev $NETDEV up
    432
    433		sleep $SLEEP_TIME
    434
    435		cleanup
    436		setup_prepare
    437	done
    438
    439	devlink_traps_disable_all
    440
    441	log_test "Device delete"
    442}
    443
    444netdevsim_dev_create()
    445{
    446	echo "$DEV_ADDR 0" > ${NETDEVSIM_PATH}/new_device
    447}
    448
    449netdevsim_dev_destroy()
    450{
    451	echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device
    452}
    453
    454netdevsim_port_create()
    455{
    456	echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/new_port
    457}
    458
    459netdevsim_port_destroy()
    460{
    461	echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/del_port
    462}
    463
    464setup_prepare()
    465{
    466	local netdev
    467
    468	netdevsim_dev_create
    469
    470	if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}" ]; then
    471		echo "Failed to create netdevsim device"
    472		exit 1
    473	fi
    474
    475	netdevsim_port_create
    476
    477	if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}/net/" ]; then
    478		echo "Failed to create netdevsim port"
    479		exit 1
    480	fi
    481
    482	# Wait for udev to rename newly created netdev.
    483	udevadm settle
    484
    485	NETDEV=$(ls ${NETDEVSIM_PATH}/devices/${DEV}/net/)
    486}
    487
    488cleanup()
    489{
    490	pre_cleanup
    491	netdevsim_port_destroy
    492	netdevsim_dev_destroy
    493}
    494
    495trap cleanup EXIT
    496
    497setup_prepare
    498
    499tests_run
    500
    501exit $EXIT_STATUS