diff options
Diffstat (limited to 'tools/testing/selftests/drivers')
6 files changed, 1116 insertions, 5 deletions
diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap.sh new file mode 100755 index 000000000000..89b55e946eed --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap.sh @@ -0,0 +1,129 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test generic devlink-trap functionality over mlxsw. These tests are not +# specific to a single trap, but do not check the devlink-trap common +# infrastructure either. + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + dev_del_test +" +NUM_NETIFS=4 +source $lib_dir/tc_common.sh +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +h1_create() +{ + simple_if_init $h1 +} + +h1_destroy() +{ + simple_if_fini $h1 +} + +h2_create() +{ + simple_if_init $h2 +} + +h2_destroy() +{ + simple_if_fini $h2 +} + +switch_create() +{ + ip link add dev br0 type bridge vlan_filtering 1 mcast_snooping 0 + + ip link set dev $swp1 master br0 + ip link set dev $swp2 master br0 + + ip link set dev br0 up + ip link set dev $swp1 up + ip link set dev $swp2 up +} + +switch_destroy() +{ + ip link set dev $swp2 down + ip link set dev $swp1 down + + ip link del dev br0 +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + swp2=${NETIFS[p3]} + h2=${NETIFS[p4]} + + vrf_prepare + + h1_create + h2_create + + switch_create +} + +cleanup() +{ + pre_cleanup + + switch_destroy + + h2_destroy + h1_destroy + + vrf_cleanup +} + +dev_del_test() +{ + local trap_name="source_mac_is_multicast" + local smac=01:02:03:04:05:06 + local num_iter=5 + local mz_pid + local i + + $MZ $h1 -c 0 -p 100 -a $smac -b bcast -t ip -q & + mz_pid=$! + + # The purpose of this test is to make sure we correctly dismantle a + # port while packets are trapped from it. This is done by reloading the + # the driver while the 'ingress_smac_mc_drop' trap is triggered. + RET=0 + + for i in $(seq 1 $num_iter); do + log_info "Iteration $i / $num_iter" + + devlink_trap_action_set $trap_name "trap" + sleep 1 + + devlink_reload + # Allow netdevices to be re-created following the reload + sleep 20 + + cleanup + setup_prepare + setup_wait + done + + log_test "Device delete" + + kill $mz_pid && wait $mz_pid &> /dev/null +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh new file mode 100755 index 000000000000..5dcdfa20fc6c --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh @@ -0,0 +1,484 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test devlink-trap L2 drops functionality over mlxsw. Each registered L2 drop +# packet trap is tested to make sure it is triggered under the right +# conditions. + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + source_mac_is_multicast_test + vlan_tag_mismatch_test + ingress_vlan_filter_test + ingress_stp_filter_test + port_list_is_empty_test + port_loopback_filter_test +" +NUM_NETIFS=4 +source $lib_dir/tc_common.sh +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +h1_create() +{ + simple_if_init $h1 +} + +h1_destroy() +{ + simple_if_fini $h1 +} + +h2_create() +{ + simple_if_init $h2 +} + +h2_destroy() +{ + simple_if_fini $h2 +} + +switch_create() +{ + ip link add dev br0 type bridge vlan_filtering 1 mcast_snooping 0 + + ip link set dev $swp1 master br0 + ip link set dev $swp2 master br0 + + ip link set dev br0 up + ip link set dev $swp1 up + ip link set dev $swp2 up + + tc qdisc add dev $swp2 clsact +} + +switch_destroy() +{ + tc qdisc del dev $swp2 clsact + + ip link set dev $swp2 down + ip link set dev $swp1 down + + ip link del dev br0 +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + swp2=${NETIFS[p3]} + h2=${NETIFS[p4]} + + vrf_prepare + + h1_create + h2_create + + switch_create +} + +cleanup() +{ + pre_cleanup + + switch_destroy + + h2_destroy + h1_destroy + + vrf_cleanup +} + +l2_drops_test() +{ + local trap_name=$1; shift + local group_name=$1; shift + + # This is the common part of all the tests. It checks that stats are + # initially idle, then non-idle after changing the trap action and + # finally idle again. It also makes sure the packets are dropped and + # never forwarded. + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle with initial drop action" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with initial drop action" + + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_fail $? "Trap stats idle after setting action to trap" + devlink_trap_group_stats_idle_test $group_name + check_fail $? "Trap group stats idle after setting action to trap" + + devlink_trap_action_set $trap_name "drop" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle after setting action to drop" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle after setting action to drop" + + tc_check_packets "dev $swp2 egress" 101 0 + check_err $? "Packets were not dropped" +} + +l2_drops_cleanup() +{ + local mz_pid=$1; shift + + kill $mz_pid && wait $mz_pid &> /dev/null + tc filter del dev $swp2 egress protocol ip pref 1 handle 101 flower +} + +source_mac_is_multicast_test() +{ + local trap_name="source_mac_is_multicast" + local smac=01:02:03:04:05:06 + local group_name="l2_drops" + local mz_pid + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower src_mac $smac action drop + + $MZ $h1 -c 0 -p 100 -a $smac -b bcast -t ip -d 1msec -q & + mz_pid=$! + + RET=0 + + l2_drops_test $trap_name $group_name + + log_test "Source MAC is multicast" + + l2_drops_cleanup $mz_pid +} + +__vlan_tag_mismatch_test() +{ + local trap_name="vlan_tag_mismatch" + local dmac=de:ad:be:ef:13:37 + local group_name="l2_drops" + local opt=$1; shift + local mz_pid + + # Remove PVID flag. This should prevent untagged and prio-tagged + # packets from entering the bridge. + bridge vlan add vid 1 dev $swp1 untagged master + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower dst_mac $dmac action drop + + $MZ $h1 "$opt" -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & + mz_pid=$! + + l2_drops_test $trap_name $group_name + + # Add PVID and make sure packets are no longer dropped. + bridge vlan add vid 1 dev $swp1 pvid untagged master + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle when packets should not be dropped" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with when packets should not be dropped" + + tc_check_packets "dev $swp2 egress" 101 0 + check_fail $? "Packets not forwarded when should" + + devlink_trap_action_set $trap_name "drop" + + l2_drops_cleanup $mz_pid +} + +vlan_tag_mismatch_untagged_test() +{ + RET=0 + + __vlan_tag_mismatch_test + + log_test "VLAN tag mismatch - untagged packets" +} + +vlan_tag_mismatch_vid_0_test() +{ + RET=0 + + __vlan_tag_mismatch_test "-Q 0" + + log_test "VLAN tag mismatch - prio-tagged packets" +} + +vlan_tag_mismatch_test() +{ + vlan_tag_mismatch_untagged_test + vlan_tag_mismatch_vid_0_test +} + +ingress_vlan_filter_test() +{ + local trap_name="ingress_vlan_filter" + local dmac=de:ad:be:ef:13:37 + local group_name="l2_drops" + local mz_pid + local vid=10 + + bridge vlan add vid $vid dev $swp2 master + # During initialization the firmware enables all the VLAN filters and + # the driver does not turn them off since the traffic will be discarded + # by the STP filter whose default is DISCARD state. Add the VID on the + # ingress bridge port and then remove it to make sure it is not member + # in the VLAN. + bridge vlan add vid $vid dev $swp1 master + bridge vlan del vid $vid dev $swp1 master + + RET=0 + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower dst_mac $dmac action drop + + $MZ $h1 -Q $vid -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & + mz_pid=$! + + l2_drops_test $trap_name $group_name + + # Add the VLAN on the bridge port and make sure packets are no longer + # dropped. + bridge vlan add vid $vid dev $swp1 master + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle when packets should not be dropped" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with when packets should not be dropped" + + tc_check_packets "dev $swp2 egress" 101 0 + check_fail $? "Packets not forwarded when should" + + devlink_trap_action_set $trap_name "drop" + + log_test "Ingress VLAN filter" + + l2_drops_cleanup $mz_pid + + bridge vlan del vid $vid dev $swp1 master + bridge vlan del vid $vid dev $swp2 master +} + +__ingress_stp_filter_test() +{ + local trap_name="ingress_spanning_tree_filter" + local dmac=de:ad:be:ef:13:37 + local group_name="l2_drops" + local state=$1; shift + local mz_pid + local vid=20 + + bridge vlan add vid $vid dev $swp2 master + bridge vlan add vid $vid dev $swp1 master + ip link set dev $swp1 type bridge_slave state $state + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower dst_mac $dmac action drop + + $MZ $h1 -Q $vid -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & + mz_pid=$! + + l2_drops_test $trap_name $group_name + + # Change STP state to forwarding and make sure packets are no longer + # dropped. + ip link set dev $swp1 type bridge_slave state 3 + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle when packets should not be dropped" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with when packets should not be dropped" + + tc_check_packets "dev $swp2 egress" 101 0 + check_fail $? "Packets not forwarded when should" + + devlink_trap_action_set $trap_name "drop" + + l2_drops_cleanup $mz_pid + + bridge vlan del vid $vid dev $swp1 master + bridge vlan del vid $vid dev $swp2 master +} + +ingress_stp_filter_listening_test() +{ + local state=$1; shift + + RET=0 + + __ingress_stp_filter_test $state + + log_test "Ingress STP filter - listening state" +} + +ingress_stp_filter_learning_test() +{ + local state=$1; shift + + RET=0 + + __ingress_stp_filter_test $state + + log_test "Ingress STP filter - learning state" +} + +ingress_stp_filter_test() +{ + ingress_stp_filter_listening_test 1 + ingress_stp_filter_learning_test 2 +} + +port_list_is_empty_uc_test() +{ + local trap_name="port_list_is_empty" + local dmac=de:ad:be:ef:13:37 + local group_name="l2_drops" + local mz_pid + + # Disable unicast flooding on both ports, so that packets cannot egress + # any port. + ip link set dev $swp1 type bridge_slave flood off + ip link set dev $swp2 type bridge_slave flood off + + RET=0 + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower dst_mac $dmac action drop + + $MZ $h1 -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & + mz_pid=$! + + l2_drops_test $trap_name $group_name + + # Allow packets to be flooded to one port. + ip link set dev $swp2 type bridge_slave flood on + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle when packets should not be dropped" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with when packets should not be dropped" + + tc_check_packets "dev $swp2 egress" 101 0 + check_fail $? "Packets not forwarded when should" + + devlink_trap_action_set $trap_name "drop" + + log_test "Port list is empty - unicast" + + l2_drops_cleanup $mz_pid + + ip link set dev $swp1 type bridge_slave flood on +} + +port_list_is_empty_mc_test() +{ + local trap_name="port_list_is_empty" + local dmac=01:00:5e:00:00:01 + local group_name="l2_drops" + local dip=239.0.0.1 + local mz_pid + + # Disable multicast flooding on both ports, so that packets cannot + # egress any port. We also need to flush IP addresses from the bridge + # in order to prevent packets from being flooded to the router port. + ip link set dev $swp1 type bridge_slave mcast_flood off + ip link set dev $swp2 type bridge_slave mcast_flood off + ip address flush dev br0 + + RET=0 + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower dst_mac $dmac action drop + + $MZ $h1 -c 0 -p 100 -a own -b $dmac -t ip -B $dip -d 1msec -q & + mz_pid=$! + + l2_drops_test $trap_name $group_name + + # Allow packets to be flooded to one port. + ip link set dev $swp2 type bridge_slave mcast_flood on + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle when packets should not be dropped" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with when packets should not be dropped" + + tc_check_packets "dev $swp2 egress" 101 0 + check_fail $? "Packets not forwarded when should" + + devlink_trap_action_set $trap_name "drop" + + log_test "Port list is empty - multicast" + + l2_drops_cleanup $mz_pid + + ip link set dev $swp1 type bridge_slave mcast_flood on +} + +port_list_is_empty_test() +{ + port_list_is_empty_uc_test + port_list_is_empty_mc_test +} + +port_loopback_filter_uc_test() +{ + local trap_name="port_loopback_filter" + local dmac=de:ad:be:ef:13:37 + local group_name="l2_drops" + local mz_pid + + # Make sure packets can only egress the input port. + ip link set dev $swp2 type bridge_slave flood off + + RET=0 + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower dst_mac $dmac action drop + + $MZ $h1 -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & + mz_pid=$! + + l2_drops_test $trap_name $group_name + + # Allow packets to be flooded. + ip link set dev $swp2 type bridge_slave flood on + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle when packets should not be dropped" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with when packets should not be dropped" + + tc_check_packets "dev $swp2 egress" 101 0 + check_fail $? "Packets not forwarded when should" + + devlink_trap_action_set $trap_name "drop" + + log_test "Port loopback filter - unicast" + + l2_drops_cleanup $mz_pid +} + +port_loopback_filter_test() +{ + port_loopback_filter_uc_test +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh index 40f16f2a3afd..5cbff8038f84 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh @@ -36,8 +36,6 @@ source $lib_dir/lib.sh h1_create() { - local dscp; - simple_if_init $h1 192.0.2.1/28 tc qdisc add dev $h1 clsact dscp_capture_install $h1 10 @@ -67,6 +65,7 @@ h2_destroy() dscp_map() { local base=$1; shift + local prio for prio in {0..7}; do echo app=$prio,5,$((base + prio)) @@ -138,6 +137,7 @@ dscp_ping_test() local prio=$1; shift local dev_10=$1; shift local dev_20=$1; shift + local key local dscp_10=$(((prio + 10) << 2)) local dscp_20=$(((prio + 20) << 2)) @@ -175,6 +175,8 @@ dscp_ping_test() test_dscp() { + local prio + for prio in {0..7}; do dscp_ping_test v$h1 192.0.2.1 192.0.2.2 $prio $h1 $h2 done diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh index 9faf02e32627..c745ce3befee 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh @@ -31,6 +31,7 @@ ALL_TESTS=" ping_ipv4 test_update test_no_update + test_dscp_leftover " lib_dir=$(dirname $0)/../../../net/forwarding @@ -50,10 +51,13 @@ reprioritize() echo ${reprio[$in]} } -h1_create() +zero() { - local dscp; + echo 0 +} +h1_create() +{ simple_if_init $h1 192.0.2.1/28 tc qdisc add dev $h1 clsact dscp_capture_install $h1 0 @@ -87,6 +91,7 @@ h2_destroy() dscp_map() { local base=$1; shift + local prio for prio in {0..7}; do echo app=$prio,5,$((base + prio)) @@ -156,6 +161,7 @@ dscp_ping_test() local reprio=$1; shift local dev1=$1; shift local dev2=$1; shift + local i local prio2=$($reprio $prio) # ICMP Request egress prio local prio3=$($reprio $prio2) # ICMP Response egress prio @@ -205,6 +211,7 @@ __test_update() { local update=$1; shift local reprio=$1; shift + local prio sysctl_restore net.ipv4.ip_forward_update_priority sysctl_set net.ipv4.ip_forward_update_priority $update @@ -224,6 +231,19 @@ test_no_update() __test_update 0 echo } +# Test that when the last APP rule is removed, the prio->DSCP map is properly +# set to zeroes, and that the last APP rule does not stay active in the ASIC. +test_dscp_leftover() +{ + lldptool -T -i $swp2 -V APP -d $(dscp_map 0) >/dev/null + lldpad_app_wait_del + + __test_update 0 zero + + lldptool -T -i $swp2 -V APP $(dscp_map 0) >/dev/null + lldpad_app_wait_set $swp2 +} + trap cleanup EXIT setup_prepare diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh index 9d8baf5d14b3..115837355eaf 100755 --- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh +++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh @@ -3,7 +3,7 @@ lib_dir=$(dirname $0)/../../../net/forwarding -ALL_TESTS="fw_flash_test" +ALL_TESTS="fw_flash_test params_test regions_test" NUM_NETIFS=0 source $lib_dir/lib.sh @@ -30,6 +30,118 @@ fw_flash_test() log_test "fw flash test" } +param_get() +{ + local name=$1 + + cmd_jq "devlink dev param show $DL_HANDLE name $name -j" \ + '.[][][].values[] | select(.cmode == "driverinit").value' +} + +param_set() +{ + local name=$1 + local value=$2 + + devlink dev param set $DL_HANDLE name $name cmode driverinit value $value +} + +check_value() +{ + local name=$1 + local phase_name=$2 + local expected_param_value=$3 + local expected_debugfs_value=$4 + local value + + value=$(param_get $name) + check_err $? "Failed to get $name param value" + [ "$value" == "$expected_param_value" ] + check_err $? "Unexpected $phase_name $name param value" + value=$(<$DEBUGFS_DIR/$name) + check_err $? "Failed to get $name debugfs value" + [ "$value" == "$expected_debugfs_value" ] + check_err $? "Unexpected $phase_name $name debugfs value" +} + +params_test() +{ + RET=0 + + local max_macs + local test1 + + check_value max_macs initial 32 32 + check_value test1 initial true Y + + param_set max_macs 16 + check_err $? "Failed to set max_macs param value" + param_set test1 false + check_err $? "Failed to set test1 param value" + + check_value max_macs post-set 16 32 + check_value test1 post-set false Y + + devlink dev reload $DL_HANDLE + + check_value max_macs post-reload 16 16 + check_value test1 post-reload false N + + log_test "params test" +} + +check_region_size() +{ + local name=$1 + local size + + size=$(devlink region show $DL_HANDLE/$name -j | jq -e -r '.[][].size') + check_err $? "Failed to get $name region size" + [ $size -eq 32768 ] + check_err $? "Invalid $name region size" +} + +check_region_snapshot_count() +{ + local name=$1 + local phase_name=$2 + local expected_count=$3 + local count + + count=$(devlink region show $DL_HANDLE/$name -j | jq -e -r '.[][].snapshot | length') + [ $count -eq $expected_count ] + check_err $? "Unexpected $phase_name snapshot count" +} + +regions_test() +{ + RET=0 + + local count + + check_region_size dummy + check_region_snapshot_count dummy initial 0 + + echo ""> $DEBUGFS_DIR/take_snapshot + check_err $? "Failed to take first dummy region snapshot" + check_region_snapshot_count dummy post-first-snapshot 1 + + echo ""> $DEBUGFS_DIR/take_snapshot + check_err $? "Failed to take second dummy region snapshot" + check_region_snapshot_count dummy post-second-snapshot 2 + + echo ""> $DEBUGFS_DIR/take_snapshot + check_err $? "Failed to take third dummy region snapshot" + check_region_snapshot_count dummy post-third-snapshot 3 + + devlink region del $DL_HANDLE/dummy snapshot 1 + check_err $? "Failed to delete first dummy region snapshot" + + check_region_snapshot_count dummy post-first-delete 2 + + log_test "regions test" +} + setup_prepare() { modprobe netdevsim diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink_trap.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink_trap.sh new file mode 100755 index 000000000000..f101ab9441e2 --- /dev/null +++ b/tools/testing/selftests/drivers/net/netdevsim/devlink_trap.sh @@ -0,0 +1,364 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# This test is for checking devlink-trap functionality. It makes use of +# netdevsim which implements the required callbacks. + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + init_test + trap_action_test + trap_metadata_test + bad_trap_test + bad_trap_action_test + trap_stats_test + trap_group_action_test + bad_trap_group_test + trap_group_stats_test + port_del_test + dev_del_test +" +NETDEVSIM_PATH=/sys/bus/netdevsim/ +DEV_ADDR=1337 +DEV=netdevsim${DEV_ADDR} +DEVLINK_DEV=netdevsim/${DEV} +SLEEP_TIME=1 +NETDEV="" +NUM_NETIFS=0 +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +require_command udevadm + +modprobe netdevsim &> /dev/null +if [ ! -d "$NETDEVSIM_PATH" ]; then + echo "SKIP: No netdevsim support" + exit 1 +fi + +if [ -d "${NETDEVSIM_PATH}/devices/netdevsim${DEV_ADDR}" ]; then + echo "SKIP: Device netdevsim${DEV_ADDR} already exists" + exit 1 +fi + +init_test() +{ + RET=0 + + test $(devlink_traps_num_get) -ne 0 + check_err $? "No traps were registered" + + log_test "Initialization" +} + +trap_action_test() +{ + local orig_action + local trap_name + local action + + RET=0 + + for trap_name in $(devlink_traps_get); do + # The action of non-drop traps cannot be changed. + if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then + devlink_trap_action_set $trap_name "trap" + action=$(devlink_trap_action_get $trap_name) + if [ $action != "trap" ]; then + check_err 1 "Trap $trap_name did not change action to trap" + fi + + devlink_trap_action_set $trap_name "drop" + action=$(devlink_trap_action_get $trap_name) + if [ $action != "drop" ]; then + check_err 1 "Trap $trap_name did not change action to drop" + fi + else + orig_action=$(devlink_trap_action_get $trap_name) + + devlink_trap_action_set $trap_name "trap" + action=$(devlink_trap_action_get $trap_name) + if [ $action != $orig_action ]; then + check_err 1 "Trap $trap_name changed action when should not" + fi + + devlink_trap_action_set $trap_name "drop" + action=$(devlink_trap_action_get $trap_name) + if [ $action != $orig_action ]; then + check_err 1 "Trap $trap_name changed action when should not" + fi + fi + done + + log_test "Trap action" +} + +trap_metadata_test() +{ + local trap_name + + RET=0 + + for trap_name in $(devlink_traps_get); do + devlink_trap_metadata_test $trap_name "input_port" + check_err $? "Input port not reported as metadata of trap $trap_name" + done + + log_test "Trap metadata" +} + +bad_trap_test() +{ + RET=0 + + devlink_trap_action_set "made_up_trap" "drop" + check_fail $? "Did not get an error for non-existing trap" + + log_test "Non-existing trap" +} + +bad_trap_action_test() +{ + local traps_arr + local trap_name + + RET=0 + + # Pick first trap. + traps_arr=($(devlink_traps_get)) + trap_name=${traps_arr[0]} + + devlink_trap_action_set $trap_name "made_up_action" + check_fail $? "Did not get an error for non-existing trap action" + + log_test "Non-existing trap action" +} + +trap_stats_test() +{ + local trap_name + + RET=0 + + for trap_name in $(devlink_traps_get); do + devlink_trap_stats_idle_test $trap_name + check_err $? "Stats of trap $trap_name not idle when netdev down" + + ip link set dev $NETDEV up + + if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then + devlink_trap_action_set $trap_name "trap" + devlink_trap_stats_idle_test $trap_name + check_fail $? "Stats of trap $trap_name idle when action is trap" + + devlink_trap_action_set $trap_name "drop" + devlink_trap_stats_idle_test $trap_name + check_err $? "Stats of trap $trap_name not idle when action is drop" + else + devlink_trap_stats_idle_test $trap_name + check_fail $? "Stats of non-drop trap $trap_name idle when should not" + fi + + ip link set dev $NETDEV down + done + + log_test "Trap statistics" +} + +trap_group_action_test() +{ + local curr_group group_name + local trap_name + local trap_type + local action + + RET=0 + + for group_name in $(devlink_trap_groups_get); do + devlink_trap_group_action_set $group_name "trap" + + for trap_name in $(devlink_traps_get); do + curr_group=$(devlink_trap_group_get $trap_name) + if [ $curr_group != $group_name ]; then + continue + fi + + trap_type=$(devlink_trap_type_get $trap_name) + if [ $trap_type != "drop" ]; then + continue + fi + + action=$(devlink_trap_action_get $trap_name) + if [ $action != "trap" ]; then + check_err 1 "Trap $trap_name did not change action to trap" + fi + done + + devlink_trap_group_action_set $group_name "drop" + + for trap_name in $(devlink_traps_get); do + curr_group=$(devlink_trap_group_get $trap_name) + if [ $curr_group != $group_name ]; then + continue + fi + + trap_type=$(devlink_trap_type_get $trap_name) + if [ $trap_type != "drop" ]; then + continue + fi + + action=$(devlink_trap_action_get $trap_name) + if [ $action != "drop" ]; then + check_err 1 "Trap $trap_name did not change action to drop" + fi + done + done + + log_test "Trap group action" +} + +bad_trap_group_test() +{ + RET=0 + + devlink_trap_group_action_set "made_up_trap_group" "drop" + check_fail $? "Did not get an error for non-existing trap group" + + log_test "Non-existing trap group" +} + +trap_group_stats_test() +{ + local group_name + + RET=0 + + for group_name in $(devlink_trap_groups_get); do + devlink_trap_group_stats_idle_test $group_name + check_err $? "Stats of trap group $group_name not idle when netdev down" + + ip link set dev $NETDEV up + + devlink_trap_group_action_set $group_name "trap" + devlink_trap_group_stats_idle_test $group_name + check_fail $? "Stats of trap group $group_name idle when action is trap" + + devlink_trap_group_action_set $group_name "drop" + ip link set dev $NETDEV down + done + + log_test "Trap group statistics" +} + +port_del_test() +{ + local group_name + local i + + # The test never fails. It is meant to exercise different code paths + # and make sure we properly dismantle a port while packets are + # in-flight. + RET=0 + + devlink_traps_enable_all + + for i in $(seq 1 10); do + ip link set dev $NETDEV up + + sleep $SLEEP_TIME + + netdevsim_port_destroy + netdevsim_port_create + udevadm settle + done + + devlink_traps_disable_all + + log_test "Port delete" +} + +dev_del_test() +{ + local group_name + local i + + # The test never fails. It is meant to exercise different code paths + # and make sure we properly unregister traps while packets are + # in-flight. + RET=0 + + devlink_traps_enable_all + + for i in $(seq 1 10); do + ip link set dev $NETDEV up + + sleep $SLEEP_TIME + + cleanup + setup_prepare + done + + devlink_traps_disable_all + + log_test "Device delete" +} + +netdevsim_dev_create() +{ + echo "$DEV_ADDR 0" > ${NETDEVSIM_PATH}/new_device +} + +netdevsim_dev_destroy() +{ + echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device +} + +netdevsim_port_create() +{ + echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/new_port +} + +netdevsim_port_destroy() +{ + echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/del_port +} + +setup_prepare() +{ + local netdev + + netdevsim_dev_create + + if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}" ]; then + echo "Failed to create netdevsim device" + exit 1 + fi + + netdevsim_port_create + + if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}/net/" ]; then + echo "Failed to create netdevsim port" + exit 1 + fi + + # Wait for udev to rename newly created netdev. + udevadm settle + + NETDEV=$(ls ${NETDEVSIM_PATH}/devices/${DEV}/net/) +} + +cleanup() +{ + pre_cleanup + netdevsim_port_destroy + netdevsim_dev_destroy +} + +trap cleanup EXIT + +setup_prepare + +tests_run + +exit $EXIT_STATUS |