diff options
Diffstat (limited to 'tools/testing/selftests/drivers/net/mlxsw')
80 files changed, 8353 insertions, 572 deletions
diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh new file mode 100755 index 000000000000..224ca3695c89 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_linecard.sh @@ -0,0 +1,334 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# In addition to the common variables, user might use: +# LC_SLOT - If not set, all probed line cards are going to be tested, +# with an exception of the "activation_16x100G_test". +# It set, only the selected line card is going to be used +# for tests, including "activation_16x100G_test". + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + unprovision_test + provision_test + activation_16x100G_test +" + +NUM_NETIFS=0 + +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +until_lc_state_is() +{ + local state=$1; shift + local current=$("$@") + + echo "$current" + [ "$current" == "$state" ] +} + +until_lc_state_is_not() +{ + ! until_lc_state_is "$@" +} + +lc_state_get() +{ + local lc=$1 + + devlink lc show $DEVLINK_DEV lc $lc -j | jq -e -r ".[][][].state" +} + +lc_wait_until_state_changes() +{ + local lc=$1 + local state=$2 + local timeout=$3 # ms + + busywait "$timeout" until_lc_state_is_not "$state" lc_state_get "$lc" +} + +lc_wait_until_state_becomes() +{ + local lc=$1 + local state=$2 + local timeout=$3 # ms + + busywait "$timeout" until_lc_state_is "$state" lc_state_get "$lc" +} + +until_lc_port_count_is() +{ + local port_count=$1; shift + local current=$("$@") + + echo "$current" + [ $current == $port_count ] +} + +lc_port_count_get() +{ + local lc=$1 + + devlink port -j | jq -e -r ".[][] | select(.lc==$lc) | .port" | wc -l +} + +lc_wait_until_port_count_is() +{ + local lc=$1 + local port_count=$2 + local timeout=$3 # ms + + busywait "$timeout" until_lc_port_count_is "$port_count" lc_port_count_get "$lc" +} + +lc_nested_devlink_dev_get() +{ + local lc=$1 + + devlink lc show $DEVLINK_DEV lc $lc -j | jq -e -r ".[][][].nested_devlink" +} + +PROV_UNPROV_TIMEOUT=8000 # ms +POST_PROV_ACT_TIMEOUT=2000 # ms +PROV_PORTS_INSTANTIATION_TIMEOUT=15000 # ms + +unprovision_one() +{ + local lc=$1 + local state + + state=$(lc_state_get $lc) + check_err $? "Failed to get state of linecard $lc" + if [[ "$state" == "unprovisioned" ]]; then + return + fi + + log_info "Unprovisioning linecard $lc" + + devlink lc set $DEVLINK_DEV lc $lc notype + check_err $? "Failed to trigger linecard $lc unprovisioning" + + state=$(lc_wait_until_state_changes $lc "unprovisioning" \ + $PROV_UNPROV_TIMEOUT) + check_err $? "Failed to unprovision linecard $lc (timeout)" + + [ "$state" == "unprovisioned" ] + check_err $? "Failed to unprovision linecard $lc (state=$state)" +} + +provision_one() +{ + local lc=$1 + local type=$2 + local state + + log_info "Provisioning linecard $lc" + + devlink lc set $DEVLINK_DEV lc $lc type $type + check_err $? "Failed trigger linecard $lc provisioning" + + state=$(lc_wait_until_state_changes $lc "provisioning" \ + $PROV_UNPROV_TIMEOUT) + check_err $? "Failed to provision linecard $lc (timeout)" + + [ "$state" == "provisioned" ] || [ "$state" == "active" ] + check_err $? "Failed to provision linecard $lc (state=$state)" + + provisioned_type=$(devlink lc show $DEVLINK_DEV lc $lc -j | jq -e -r ".[][][].type") + [ "$provisioned_type" == "$type" ] + check_err $? "Wrong provision type returned for linecard $lc (got \"$provisioned_type\", expected \"$type\")" + + # Wait for possible activation to make sure the state + # won't change after return from this function. + state=$(lc_wait_until_state_becomes $lc "active" \ + $POST_PROV_ACT_TIMEOUT) +} + +unprovision_test() +{ + RET=0 + local lc + + lc=$LC_SLOT + unprovision_one $lc + log_test "Unprovision" +} + +LC_16X100G_TYPE="16x100G" +LC_16X100G_PORT_COUNT=16 + +supported_types_check() +{ + local lc=$1 + local supported_types_count + local type_index + local lc_16x100_found=false + + supported_types_count=$(devlink lc show $DEVLINK_DEV lc $lc -j | \ + jq -e -r ".[][][].supported_types | length") + [ $supported_types_count != 0 ] + check_err $? "No supported types found for linecard $lc" + for (( type_index=0; type_index<$supported_types_count; type_index++ )) + do + type=$(devlink lc show $DEVLINK_DEV lc $lc -j | \ + jq -e -r ".[][][].supported_types[$type_index]") + if [[ "$type" == "$LC_16X100G_TYPE" ]]; then + lc_16x100_found=true + break + fi + done + [ $lc_16x100_found = true ] + check_err $? "16X100G not found between supported types of linecard $lc" +} + +ports_check() +{ + local lc=$1 + local expected_port_count=$2 + local port_count + + port_count=$(lc_wait_until_port_count_is $lc $expected_port_count \ + $PROV_PORTS_INSTANTIATION_TIMEOUT) + [ $port_count != 0 ] + check_err $? "No port associated with linecard $lc" + [ $port_count == $expected_port_count ] + check_err $? "Unexpected port count linecard $lc (got $port_count, expected $expected_port_count)" +} + +lc_dev_info_provisioned_check() +{ + local lc=$1 + local nested_devlink_dev=$2 + local fixed_hw_revision + local running_ini_version + + fixed_hw_revision=$(devlink dev info $nested_devlink_dev -j | \ + jq -e -r '.[][].versions.fixed."hw.revision"') + check_err $? "Failed to get linecard $lc fixed.hw.revision" + log_info "Linecard $lc fixed.hw.revision: \"$fixed_hw_revision\"" + running_ini_version=$(devlink dev info $nested_devlink_dev -j | \ + jq -e -r '.[][].versions.running."ini.version"') + check_err $? "Failed to get linecard $lc running.ini.version" + log_info "Linecard $lc running.ini.version: \"$running_ini_version\"" +} + +provision_test() +{ + RET=0 + local lc + local type + local state + local nested_devlink_dev + + lc=$LC_SLOT + supported_types_check $lc + state=$(lc_state_get $lc) + check_err $? "Failed to get state of linecard $lc" + if [[ "$state" != "unprovisioned" ]]; then + unprovision_one $lc + fi + provision_one $lc $LC_16X100G_TYPE + ports_check $lc $LC_16X100G_PORT_COUNT + + nested_devlink_dev=$(lc_nested_devlink_dev_get $lc) + check_err $? "Failed to get nested devlink handle of linecard $lc" + lc_dev_info_provisioned_check $lc $nested_devlink_dev + + log_test "Provision" +} + +ACTIVATION_TIMEOUT=20000 # ms + +interface_check() +{ + ip link set $h1 up + ip link set $h2 up + ifaces_upped=true + setup_wait +} + +lc_dev_info_active_check() +{ + local lc=$1 + local nested_devlink_dev=$2 + local fixed_device_fw_psid + local running_device_fw + + fixed_device_fw_psid=$(devlink dev info $nested_devlink_dev -j | \ + jq -e -r ".[][].versions.fixed" | \ + jq -e -r '."fw.psid"') + check_err $? "Failed to get linecard $lc fixed fw PSID" + log_info "Linecard $lc fixed.fw.psid: \"$fixed_device_fw_psid\"" + + running_device_fw=$(devlink dev info $nested_devlink_dev -j | \ + jq -e -r ".[][].versions.running.fw") + check_err $? "Failed to get linecard $lc running.fw.version" + log_info "Linecard $lc running.fw: \"$running_device_fw\"" +} + +activation_16x100G_test() +{ + RET=0 + local lc + local type + local state + local nested_devlink_dev + + lc=$LC_SLOT + type=$LC_16X100G_TYPE + + unprovision_one $lc + provision_one $lc $type + state=$(lc_wait_until_state_becomes $lc "active" \ + $ACTIVATION_TIMEOUT) + check_err $? "Failed to get linecard $lc activated (timeout)" + + interface_check + + nested_devlink_dev=$(lc_nested_devlink_dev_get $lc) + check_err $? "Failed to get nested devlink handle of linecard $lc" + lc_dev_info_active_check $lc $nested_devlink_dev + + log_test "Activation 16x100G" +} + +setup_prepare() +{ + local lc_num=$(devlink lc show -j | jq -e -r ".[][\"$DEVLINK_DEV\"] |length") + if [[ $? -ne 0 ]] || [[ $lc_num -eq 0 ]]; then + echo "SKIP: No linecard support found" + exit $ksft_skip + fi + + if [ -z "$LC_SLOT" ]; then + echo "SKIP: \"LC_SLOT\" variable not provided" + exit $ksft_skip + fi + + # Interfaces are not present during the script start, + # that's why we define NUM_NETIFS here so dummy + # implicit veth pairs are not created. + NUM_NETIFS=2 + h1=${NETIFS[p1]} + h2=${NETIFS[p2]} + ifaces_upped=false +} + +cleanup() +{ + if [ "$ifaces_upped" = true ] ; then + ip link set $h1 down + ip link set $h2 down + fi +} + +trap cleanup EXIT + +setup_prepare + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_control.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_control.sh index a37273473c1b..64153bbf95df 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_control.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_control.sh @@ -83,10 +83,12 @@ ALL_TESTS=" ptp_general_test flow_action_sample_test flow_action_trap_test + eapol_test " NUM_NETIFS=4 source $lib_dir/lib.sh source $lib_dir/devlink_lib.sh +source mlxsw_lib.sh h1_create() { @@ -626,8 +628,7 @@ ipv6_redirect_test() ptp_event_test() { - # PTP is only supported on Spectrum-1, for now. - [[ "$DEVLINK_VIDDID" != "15b3:cb84" ]] && return + mlxsw_only_on_spectrum 1 || return # PTP Sync (0) devlink_trap_stats_test "PTP Time-Critical Event Message" "ptp_event" \ @@ -638,8 +639,7 @@ ptp_event_test() ptp_general_test() { - # PTP is only supported on Spectrum-1, for now. - [[ "$DEVLINK_VIDDID" != "15b3:cb84" ]] && return + mlxsw_only_on_spectrum 1 || return # PTP Announce (b) devlink_trap_stats_test "PTP General Message" "ptp_general" \ @@ -678,6 +678,27 @@ flow_action_trap_test() tc qdisc del dev $rp1 clsact } +eapol_payload_get() +{ + local source_mac=$1; shift + local p + + p=$(: + )"01:80:C2:00:00:03:"$( : ETH daddr + )"$source_mac:"$( : ETH saddr + )"88:8E:"$( : ETH type + ) + echo $p +} + +eapol_test() +{ + local h1mac=$(mac_get $h1) + + devlink_trap_stats_test "EAPOL" "eapol" $MZ $h1 -c 1 \ + $(eapol_payload_get $h1mac) -p 100 -q +} + trap cleanup EXIT setup_prepare 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 index a4c2812e9807..8d4b2c6265b3 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh @@ -14,6 +14,7 @@ ALL_TESTS=" ingress_stp_filter_test port_list_is_empty_test port_loopback_filter_test + locked_port_test " NUM_NETIFS=4 source $lib_dir/tc_common.sh @@ -420,6 +421,110 @@ port_loopback_filter_test() port_loopback_filter_uc_test } +locked_port_miss_test() +{ + local trap_name="locked_port" + local smac=00:11:22:33:44:55 + + bridge link set dev $swp1 learning off + bridge link set dev $swp1 locked on + + RET=0 + + devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ + -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q + check_fail $? "Trap stats increased before setting action to \"trap\"" + + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ + -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q + check_err $? "Trap stats did not increase when should" + + devlink_trap_action_set $trap_name "drop" + + devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ + -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q + check_fail $? "Trap stats increased after setting action to \"drop\"" + + devlink_trap_action_set $trap_name "trap" + + bridge fdb replace $smac dev $swp1 master static vlan 1 + + devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ + -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q + check_fail $? "Trap stats increased after adding an FDB entry" + + bridge fdb del $smac dev $swp1 master static vlan 1 + bridge link set dev $swp1 locked off + + devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ + -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q + check_fail $? "Trap stats increased after unlocking port" + + log_test "Locked port - FDB miss" + + devlink_trap_action_set $trap_name "drop" + bridge link set dev $swp1 learning on +} + +locked_port_mismatch_test() +{ + local trap_name="locked_port" + local smac=00:11:22:33:44:55 + + bridge link set dev $swp1 learning off + bridge link set dev $swp1 locked on + + RET=0 + + bridge fdb replace $smac dev $swp2 master static vlan 1 + + devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ + -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q + check_fail $? "Trap stats increased before setting action to \"trap\"" + + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ + -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q + check_err $? "Trap stats did not increase when should" + + devlink_trap_action_set $trap_name "drop" + + devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ + -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q + check_fail $? "Trap stats increased after setting action to \"drop\"" + + devlink_trap_action_set $trap_name "trap" + bridge link set dev $swp1 locked off + + devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ + -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q + check_fail $? "Trap stats increased after unlocking port" + + bridge link set dev $swp1 locked on + bridge fdb replace $smac dev $swp1 master static vlan 1 + + devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ + -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q + check_fail $? "Trap stats increased after replacing an FDB entry" + + bridge fdb del $smac dev $swp1 master static vlan 1 + devlink_trap_action_set $trap_name "drop" + + log_test "Locked port - FDB mismatch" + + bridge link set dev $swp1 locked off + bridge link set dev $swp1 learning on +} + +locked_port_test() +{ + locked_port_miss_test + locked_port_mismatch_test +} + trap cleanup EXIT setup_prepare diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_drops.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_drops.sh index f5abb1ebd392..160891dcb4bc 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_drops.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_drops.sh @@ -52,6 +52,7 @@ ALL_TESTS=" blackhole_route_test irif_disabled_test erif_disabled_test + blackhole_nexthop_test " NUM_NETIFS=4 @@ -108,6 +109,9 @@ router_destroy() __addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64 tc qdisc del dev $rp2 clsact + + ip link set dev $rp2 down + ip link set dev $rp1 down } setup_prepare() @@ -647,6 +651,41 @@ erif_disabled_test() devlink_trap_action_set $trap_name "drop" } +__blackhole_nexthop_test() +{ + local flags=$1; shift + local subnet=$1; shift + local proto=$1; shift + local dip=$1; shift + local trap_name="blackhole_nexthop" + local mz_pid + + RET=0 + + ip -$flags nexthop add id 1 blackhole + ip -$flags route add $subnet nhid 1 + tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \ + flower skip_hw dst_ip $dip ip_proto udp action drop + + # Generate packets to the blackhole nexthop + $MZ $h1 -$flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \ + -B $dip -d 1msec -q & + mz_pid=$! + + devlink_trap_drop_test $trap_name $rp2 101 + log_test "Blackhole nexthop: IPv$flags" + + devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101 + ip -$flags route del $subnet + ip -$flags nexthop del id 1 +} + +blackhole_nexthop_test() +{ + __blackhole_nexthop_test "4" "198.51.100.0/30" "ip" $h2_ipv4 + __blackhole_nexthop_test "6" "2001:db8:2::/120" "ipv6" $h2_ipv6 +} + trap cleanup EXIT setup_prepare diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_exceptions.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_exceptions.sh index 1fedfc9da434..190c1b6b5365 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_exceptions.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_exceptions.sh @@ -111,6 +111,9 @@ router_destroy() __addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64 tc qdisc del dev $rp2 clsact + + ip link set dev $rp2 down + ip link set dev $rp1 down } setup_prepare() @@ -446,6 +449,35 @@ __invalid_nexthop_test() log_test "Unresolved neigh: nexthop does not exist: $desc" } +__invalid_nexthop_bucket_test() +{ + local desc=$1; shift + local dip=$1; shift + local via_add=$1; shift + local trap_name="unresolved_neigh" + + RET=0 + + # Check that route to nexthop that does not exist triggers + # unresolved_neigh + ip nexthop add id 1 via $via_add dev $rp2 + ip nexthop add id 10 group 1 type resilient buckets 32 + ip route add $dip nhid 10 + + t0_packets=$(devlink_trap_rx_packets_get $trap_name) + ping_do $h1 $dip + t1_packets=$(devlink_trap_rx_packets_get $trap_name) + + if [[ $t0_packets -eq $t1_packets ]]; then + check_err 1 "Trap counter did not increase" + fi + + ip route del $dip nhid 10 + ip nexthop del id 10 + ip nexthop del id 1 + log_test "Unresolved neigh: nexthop bucket does not exist: $desc" +} + unresolved_neigh_test() { __host_miss_test "IPv4" 198.51.100.1 @@ -453,6 +485,8 @@ unresolved_neigh_test() __invalid_nexthop_test "IPv4" 198.51.100.1 198.51.100.3 24 198.51.100.4 __invalid_nexthop_test "IPv6" 2001:db8:2::1 2001:db8:2::3 64 \ 2001:db8:2::4 + __invalid_nexthop_bucket_test "IPv4" 198.51.100.1 198.51.100.4 + __invalid_nexthop_bucket_test "IPv6" 2001:db8:2::1 2001:db8:2::4 } vrf_without_routes_create() diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_policer.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_policer.sh index 47edf099a17e..0bd5ffc218ac 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_policer.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_policer.sh @@ -207,7 +207,7 @@ __rate_test() RET=0 - devlink trap policer set $DEVLINK_DEV policer $id rate 1000 burst 16 + devlink trap policer set $DEVLINK_DEV policer $id rate 1000 burst 512 devlink trap group set $DEVLINK_DEV group l3_drops policer $id # Send packets at highest possible rate and make sure they are dropped @@ -220,8 +220,8 @@ __rate_test() rate=$(trap_rate_get) pct=$((100 * (rate - 1000) / 1000)) - ((-5 <= pct && pct <= 5)) - check_err $? "Expected rate 1000 pps, got $rate pps, which is $pct% off. Required accuracy is +-5%" + ((-10 <= pct && pct <= 10)) + check_err $? "Expected rate 1000 pps, got $rate pps, which is $pct% off. Required accuracy is +-10%" log_info "Expected rate 1000 pps, measured rate $rate pps" drop_rate=$(policer_drop_rate_get $id) @@ -272,13 +272,17 @@ __rate_test() rate_test() { - local id + local last_policer=$(devlink -j -p trap policer show | + jq '[.[]["'$DEVLINK_DEV'"][].policer] | max') - for id in $(devlink_trap_policer_ids_get); do - echo - log_info "Running rate test for policer $id" - __rate_test $id - done + log_info "Running rate test for policer 1" + __rate_test 1 + + log_info "Running rate test for policer $((last_policer / 2))" + __rate_test $((last_policer / 2)) + + log_info "Running rate test for policer $last_policer" + __rate_test $last_policer } __burst_test() @@ -288,35 +292,12 @@ __burst_test() RET=0 - devlink trap policer set $DEVLINK_DEV policer $id rate 1000 burst 32 + devlink trap policer set $DEVLINK_DEV policer $id rate 1000 burst 512 devlink trap group set $DEVLINK_DEV group l3_drops policer $id - # Send a burst of 64 packets and make sure that about 32 are received - # and the rest are dropped by the policer - log_info "=== Tx burst size: 64, Policer burst size: 32 pps ===" - - t0_rx=$(devlink_trap_rx_packets_get blackhole_route) - t0_drop=$(devlink_trap_policer_rx_dropped_get $id) - - start_traffic $h1 192.0.2.1 198.51.100.100 $rp1_mac -c 64 - - t1_rx=$(devlink_trap_rx_packets_get blackhole_route) - t1_drop=$(devlink_trap_policer_rx_dropped_get $id) - - rx=$((t1_rx - t0_rx)) - pct=$((100 * (rx - 32) / 32)) - ((-20 <= pct && pct <= 20)) - check_err $? "Expected burst size of 32 packets, got $rx packets, which is $pct% off. Required accuracy is +-20%" - log_info "Expected burst size of 32 packets, measured burst size of $rx packets" - - drop=$((t1_drop - t0_drop)) - (( drop > 0 )) - check_err $? "Expected non-zero policer drops, got 0" - log_info "Measured policer drops of $drop packets" - # Send a burst of 16 packets and make sure that 16 are received # and that none are dropped by the policer - log_info "=== Tx burst size: 16, Policer burst size: 32 pps ===" + log_info "=== Tx burst size: 16, Policer burst size: 512 ===" t0_rx=$(devlink_trap_rx_packets_get blackhole_route) t0_drop=$(devlink_trap_policer_rx_dropped_get $id) @@ -365,13 +346,17 @@ __burst_test() burst_test() { - local id + local last_policer=$(devlink -j -p trap policer show | + jq '[.[]["'$DEVLINK_DEV'"][].policer] | max') + + log_info "Running burst test for policer 1" + __burst_test 1 + + log_info "Running burst test for policer $((last_policer / 2))" + __burst_test $((last_policer / 2)) - for id in $(devlink_trap_policer_ids_get); do - echo - log_info "Running burst size test for policer $id" - __burst_test $id - done + log_info "Running burst test for policer $last_policer" + __burst_test $last_policer } trap cleanup EXIT diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_ipip.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_ipip.sh index 8817851da7a9..e9a82cae8c9a 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_ipip.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_ipip.sh @@ -13,7 +13,7 @@ # | # +-------------------|-----+ # | SW1 | | -# | $swp1 + | +# | $swp1 + | # | 192.0.2.2/28 | # | | # | + g1a (gre) | @@ -27,8 +27,8 @@ # | # +--|----------------------+ # | | VRF2 | -# | + $rp2 | -# | 198.51.100.2/28 | +# | + $rp2 | +# | 198.51.100.2/28 | # +-------------------------+ lib_dir=$(dirname $0)/../../../net/forwarding @@ -116,12 +116,16 @@ cleanup() forwarding_restore } -ecn_payload_get() +ipip_payload_get() { + local flags=$1; shift + local key=$1; shift + p=$(: - )"0"$( : GRE flags + )"$flags"$( : GRE flags )"0:00:"$( : Reserved + version )"08:00:"$( : ETH protocol type + )"$key"$( : Key )"4"$( : IP version )"5:"$( : IHL )"00:"$( : IP TOS @@ -137,6 +141,11 @@ ecn_payload_get() echo $p } +ecn_payload_get() +{ + echo $(ipip_payload_get "0") +} + ecn_decap_test() { local trap_name="decap_error" @@ -171,31 +180,6 @@ ecn_decap_test() tc filter del dev $swp1 egress protocol ip pref 1 handle 101 flower } -ipip_payload_get() -{ - local flags=$1; shift - local key=$1; shift - - p=$(: - )"$flags"$( : GRE flags - )"0:00:"$( : Reserved + version - )"08:00:"$( : ETH protocol type - )"$key"$( : Key - )"4"$( : IP version - )"5:"$( : IHL - )"00:"$( : IP TOS - )"00:14:"$( : IP total length - )"00:00:"$( : IP identification - )"20:00:"$( : IP flags + frag off - )"30:"$( : IP TTL - )"01:"$( : IP proto - )"E7:E6:"$( : IP header csum - )"C0:00:01:01:"$( : IP saddr : 192.0.1.1 - )"C0:00:02:01:"$( : IP daddr : 192.0.2.1 - ) - echo $p -} - no_matching_tunnel_test() { local trap_name="decap_error" @@ -239,7 +223,8 @@ decap_error_test() no_matching_tunnel_test "Decap error: Source IP check failed" \ 192.0.2.68 "0" no_matching_tunnel_test \ - "Decap error: Key exists but was not expected" $sip "2" ":E9:" + "Decap error: Key exists but was not expected" $sip "2" \ + "00:00:00:E9:" # Destroy the tunnel and create new one with key __addr_add_del g1 del 192.0.2.65/32 @@ -251,7 +236,8 @@ decap_error_test() no_matching_tunnel_test \ "Decap error: Key does not exist but was expected" $sip "0" no_matching_tunnel_test \ - "Decap error: Packet has a wrong key field" $sip "2" "E8:" + "Decap error: Packet has a wrong key field" $sip "2" \ + "00:00:00:E8:" } trap cleanup EXIT diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_ipip6.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_ipip6.sh new file mode 100755 index 000000000000..878125041fc3 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_ipip6.sh @@ -0,0 +1,250 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test devlink-trap tunnel exceptions functionality over mlxsw. +# Check all exception traps to make sure they are triggered under the right +# conditions. + +# +-------------------------+ +# | H1 | +# | $h1 + | +# | 2001:db8:1::1/64 | | +# +-------------------|-----+ +# | +# +-------------------|-----+ +# | SW1 | | +# | $swp1 + | +# | 2001:db8:1::2/64 | +# | | +# | + g1 (ip6gre) | +# | loc=2001:db8:3::1 | +# | rem=2001:db8:3::2 | +# | tos=inherit | +# | | +# | + $rp1 | +# | | 2001:db8:10::1/64 | +# +--|----------------------+ +# | +# +--|----------------------+ +# | | VRF2 | +# | + $rp2 | +# | 2001:db8:10::2/64 | +# +-------------------------+ + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + decap_error_test +" + +NUM_NETIFS=4 +source $lib_dir/lib.sh +source $lib_dir/tc_common.sh +source $lib_dir/devlink_lib.sh + +h1_create() +{ + simple_if_init $h1 2001:db8:1::1/64 +} + +h1_destroy() +{ + simple_if_fini $h1 2001:db8:1::1/64 +} + +vrf2_create() +{ + simple_if_init $rp2 2001:db8:10::2/64 +} + +vrf2_destroy() +{ + simple_if_fini $rp2 2001:db8:10::2/64 +} + +switch_create() +{ + ip link set dev $swp1 up + __addr_add_del $swp1 add 2001:db8:1::2/64 + tc qdisc add dev $swp1 clsact + + tunnel_create g1 ip6gre 2001:db8:3::1 2001:db8:3::2 tos inherit \ + ttl inherit + ip link set dev g1 up + __addr_add_del g1 add 2001:db8:3::1/128 + + ip link set dev $rp1 up + __addr_add_del $rp1 add 2001:db8:10::1/64 +} + +switch_destroy() +{ + __addr_add_del $rp1 del 2001:db8:10::1/64 + ip link set dev $rp1 down + + __addr_add_del g1 del 2001:db8:3::1/128 + ip link set dev g1 down + tunnel_destroy g1 + + tc qdisc del dev $swp1 clsact + __addr_add_del $swp1 del 2001:db8:1::2/64 + ip link set dev $swp1 down +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + rp1=${NETIFS[p3]} + rp2=${NETIFS[p4]} + + forwarding_enable + vrf_prepare + h1_create + switch_create + vrf2_create +} + +cleanup() +{ + pre_cleanup + + vrf2_destroy + switch_destroy + h1_destroy + vrf_cleanup + forwarding_restore +} + +ipip_payload_get() +{ + local saddr="20:01:0d:b8:00:02:00:00:00:00:00:00:00:00:00:01" + local daddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01" + local flags=$1; shift + local key=$1; shift + + p=$(: + )"$flags"$( : GRE flags + )"0:00:"$( : Reserved + version + )"86:dd:"$( : ETH protocol type + )"$key"$( : Key + )"6"$( : IP version + )"0:0"$( : Traffic class + )"0:00:00:"$( : Flow label + )"00:00:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr + )"$daddr:"$( : IP daddr + ) + echo $p +} + +ecn_payload_get() +{ + echo $(ipip_payload_get "0") +} + +ecn_decap_test() +{ + local trap_name="decap_error" + local desc=$1; shift + local ecn_desc=$1; shift + local outer_tos=$1; shift + local mz_pid + + RET=0 + + tc filter add dev $swp1 egress protocol ipv6 pref 1 handle 101 \ + flower src_ip 2001:db8:2::1 dst_ip 2001:db8:1::1 skip_sw \ + action pass + + rp1_mac=$(mac_get $rp1) + rp2_mac=$(mac_get $rp2) + payload=$(ecn_payload_get) + + ip vrf exec v$rp2 $MZ -6 $rp2 -c 0 -d 1msec -a $rp2_mac -b $rp1_mac \ + -A 2001:db8:3::2 -B 2001:db8:3::1 -t ip \ + tos=$outer_tos,next=47,p=$payload -q & + mz_pid=$! + + devlink_trap_exception_test $trap_name + + tc_check_packets "dev $swp1 egress" 101 0 + check_err $? "Packets were not dropped" + + log_test "$desc: Inner ECN is not ECT and outer is $ecn_desc" + + kill $mz_pid && wait $mz_pid &> /dev/null + tc filter del dev $swp1 egress protocol ipv6 pref 1 handle 101 flower +} + +no_matching_tunnel_test() +{ + local trap_name="decap_error" + local desc=$1; shift + local sip=$1; shift + local mz_pid + + RET=0 + + tc filter add dev $swp1 egress protocol ipv6 pref 1 handle 101 \ + flower src_ip 2001:db8:2::1 dst_ip 2001:db8:1::1 action pass + + rp1_mac=$(mac_get $rp1) + rp2_mac=$(mac_get $rp2) + payload=$(ipip_payload_get "$@") + + ip vrf exec v$rp2 $MZ -6 $rp2 -c 0 -d 1msec -a $rp2_mac -b $rp1_mac \ + -A $sip -B 2001:db8:3::1 -t ip next=47,p=$payload -q & + mz_pid=$! + + devlink_trap_exception_test $trap_name + + tc_check_packets "dev $swp1 egress" 101 0 + check_err $? "Packets were not dropped" + + log_test "$desc" + + kill $mz_pid && wait $mz_pid &> /dev/null + tc filter del dev $swp1 egress protocol ipv6 pref 1 handle 101 flower +} + +decap_error_test() +{ + # Correct source IP - the remote address + local sip=2001:db8:3::2 + + ecn_decap_test "Decap error" "ECT(1)" 01 + ecn_decap_test "Decap error" "ECT(0)" 02 + ecn_decap_test "Decap error" "CE" 03 + + no_matching_tunnel_test "Decap error: Source IP check failed" \ + 2001:db8:4::2 "0" + no_matching_tunnel_test \ + "Decap error: Key exists but was not expected" $sip "2" \ + "00:00:00:E9:" + + # Destroy the tunnel and create new one with key + __addr_add_del g1 del 2001:db8:3::1/128 + tunnel_destroy g1 + + tunnel_create g1 ip6gre 2001:db8:3::1 2001:db8:3::2 tos inherit \ + ttl inherit key 233 + __addr_add_del g1 add 2001:db8:3::1/128 + + no_matching_tunnel_test \ + "Decap error: Key does not exist but was expected" $sip "0" + no_matching_tunnel_test \ + "Decap error: Packet has a wrong key field" $sip "2" \ + "00:00:00:E8:" +} + +trap cleanup EXIT + +setup_prepare +setup_wait +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_vxlan.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_vxlan.sh index 10e0f3dbc930..5f6eb965cfd1 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_vxlan.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_vxlan.sh @@ -217,9 +217,11 @@ short_payload_get() dest_mac=$(mac_get $h1) p=$(: )"08:"$( : VXLAN flags - )"01:00:00:"$( : VXLAN reserved + )"00:00:00:"$( : VXLAN reserved )"00:03:e8:"$( : VXLAN VNI : 1000 )"00:"$( : VXLAN reserved + )"$dest_mac:"$( : ETH daddr + )"00:00:00:00:00:00:"$( : ETH saddr ) echo $p } @@ -263,7 +265,8 @@ decap_error_test() corrupted_packet_test "Decap error: Reserved bits in use" \ "reserved_bits_payload_get" - corrupted_packet_test "Decap error: No L2 header" "short_payload_get" + corrupted_packet_test "Decap error: Too short inner packet" \ + "short_payload_get" } mc_smac_payload_get() diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_vxlan_ipv6.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_vxlan_ipv6.sh new file mode 100755 index 000000000000..f6c16cbb6cf7 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_vxlan_ipv6.sh @@ -0,0 +1,342 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test devlink-trap tunnel drops and exceptions functionality over mlxsw. +# Check all traps to make sure they are triggered under the right +# conditions. + +# +------------------------+ +# | H1 (vrf) | +# | + $h1 | +# | | 2001:db8:1::1/64 | +# +----|-------------------+ +# | +# +----|----------------------------------------------------------------------+ +# | SW | | +# | +--|--------------------------------------------------------------------+ | +# | | + $swp1 BR1 (802.1d) | | +# | | | | +# | | + vx1 (vxlan) | | +# | | local 2001:db8:3::1 | | +# | | id 1000 dstport $VXPORT | | +# | +-----------------------------------------------------------------------+ | +# | | +# | + $rp1 | +# | | 2001:db8:3::1/64 | +# +----|----------------------------------------------------------------------+ +# | +# +----|--------------------------------------------------------+ +# | | VRF2 | +# | + $rp2 | +# | 2001:db8:3::2/64 | +# | | +# +-------------------------------------------------------------+ + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + decap_error_test + overlay_smac_is_mc_test +" + +NUM_NETIFS=4 +source $lib_dir/lib.sh +source $lib_dir/tc_common.sh +source $lib_dir/devlink_lib.sh + +: ${VXPORT:=4789} +export VXPORT + +h1_create() +{ + simple_if_init $h1 2001:db8:1::1/64 +} + +h1_destroy() +{ + simple_if_fini $h1 2001:db8:1::1/64 +} + +switch_create() +{ + ip link add name br1 type bridge vlan_filtering 0 mcast_snooping 0 + # Make sure the bridge uses the MAC address of the local port and not + # that of the VxLAN's device. + ip link set dev br1 address $(mac_get $swp1) + ip link set dev br1 up + + tc qdisc add dev $swp1 clsact + ip link set dev $swp1 master br1 + ip link set dev $swp1 up + + ip link add name vx1 type vxlan id 1000 local 2001:db8:3::1 \ + dstport "$VXPORT" nolearning udp6zerocsumrx udp6zerocsumtx \ + tos inherit ttl 100 + ip link set dev vx1 master br1 + ip link set dev vx1 up + + ip link set dev $rp1 up + ip address add dev $rp1 2001:db8:3::1/64 +} + +switch_destroy() +{ + ip address del dev $rp1 2001:db8:3::1/64 + ip link set dev $rp1 down + + ip link set dev vx1 down + ip link set dev vx1 nomaster + ip link del dev vx1 + + ip link set dev $swp1 down + ip link set dev $swp1 nomaster + tc qdisc del dev $swp1 clsact + + ip link set dev br1 down + ip link del dev br1 +} + +vrf2_create() +{ + simple_if_init $rp2 2001:db8:3::2/64 +} + +vrf2_destroy() +{ + simple_if_fini $rp2 2001:db8:3::2/64 +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + rp1=${NETIFS[p3]} + rp2=${NETIFS[p4]} + + vrf_prepare + forwarding_enable + h1_create + switch_create + vrf2_create +} + +cleanup() +{ + pre_cleanup + + vrf2_destroy + switch_destroy + h1_destroy + forwarding_restore + vrf_cleanup +} + +ecn_payload_get() +{ + local dest_mac=$(mac_get $h1) + local saddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:03" + local daddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01" + p=$(: + )"08:"$( : VXLAN flags + )"00:00:00:"$( : VXLAN reserved + )"00:03:e8:"$( : VXLAN VNI : 1000 + )"00:"$( : VXLAN reserved + )"$dest_mac:"$( : ETH daddr + )"00:00:00:00:00:00:"$( : ETH saddr + )"86:dd:"$( : ETH type + )"6"$( : IP version + )"0:0"$( : Traffic class + )"0:00:00:"$( : Flow label + )"00:08:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr + )"$daddr:"$( : IP daddr + )"80:"$( : ICMPv6.type + )"00:"$( : ICMPv6.code + )"00:"$( : ICMPv6.checksum + ) + echo $p +} + +ecn_decap_test() +{ + local trap_name="decap_error" + local desc=$1; shift + local ecn_desc=$1; shift + local outer_tos=$1; shift + local mz_pid + + RET=0 + + tc filter add dev $swp1 egress protocol ipv6 pref 1 handle 101 \ + flower src_ip 2001:db8:1::3 dst_ip 2001:db8:1::1 action pass + + rp1_mac=$(mac_get $rp1) + payload=$(ecn_payload_get) + + ip vrf exec v$rp2 $MZ -6 $rp2 -c 0 -d 1msec -b $rp1_mac \ + -B 2001:db8:3::1 -t udp \ + sp=12345,dp=$VXPORT,tos=$outer_tos,p=$payload -q & + mz_pid=$! + + devlink_trap_exception_test $trap_name + + tc_check_packets "dev $swp1 egress" 101 0 + check_err $? "Packets were not dropped" + + log_test "$desc: Inner ECN is not ECT and outer is $ecn_desc" + + kill $mz_pid && wait $mz_pid &> /dev/null + tc filter del dev $swp1 egress protocol ipv6 pref 1 handle 101 flower +} + +reserved_bits_payload_get() +{ + local dest_mac=$(mac_get $h1) + local saddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:03" + local daddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01" + p=$(: + )"08:"$( : VXLAN flags + )"01:00:00:"$( : VXLAN reserved + )"00:03:e8:"$( : VXLAN VNI : 1000 + )"00:"$( : VXLAN reserved + )"$dest_mac:"$( : ETH daddr + )"00:00:00:00:00:00:"$( : ETH saddr + )"86:dd:"$( : ETH type + )"6"$( : IP version + )"0:0"$( : Traffic class + )"0:00:00:"$( : Flow label + )"00:08:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr + )"$daddr:"$( : IP daddr + )"80:"$( : ICMPv6.type + )"00:"$( : ICMPv6.code + )"00:"$( : ICMPv6.checksum + ) + echo $p +} + +short_payload_get() +{ + dest_mac=$(mac_get $h1) + p=$(: + )"08:"$( : VXLAN flags + )"00:00:00:"$( : VXLAN reserved + )"00:03:e8:"$( : VXLAN VNI : 1000 + )"00:"$( : VXLAN reserved + )"$dest_mac:"$( : ETH daddr + )"00:00:00:00:00:00:"$( : ETH saddr + ) + echo $p +} + +corrupted_packet_test() +{ + local trap_name="decap_error" + local desc=$1; shift + local payload_get=$1; shift + local mz_pid + + RET=0 + + # In case of too short packet, there is no any inner packet, + # so the matching will always succeed + tc filter add dev $swp1 egress protocol ipv6 pref 1 handle 101 \ + flower skip_hw src_ip 2001:db8:3::1 dst_ip 2001:db8:1::1 \ + action pass + + rp1_mac=$(mac_get $rp1) + payload=$($payload_get) + ip vrf exec v$rp2 $MZ -6 $rp2 -c 0 -d 1msec -b $rp1_mac \ + -B 2001:db8:3::1 -t udp sp=12345,dp=$VXPORT,p=$payload -q & + mz_pid=$! + + devlink_trap_exception_test $trap_name + + tc_check_packets "dev $swp1 egress" 101 0 + check_err $? "Packets were not dropped" + + log_test "$desc" + + kill $mz_pid && wait $mz_pid &> /dev/null + tc filter del dev $swp1 egress protocol ipv6 pref 1 handle 101 flower +} + +decap_error_test() +{ + ecn_decap_test "Decap error" "ECT(1)" 01 + ecn_decap_test "Decap error" "ECT(0)" 02 + ecn_decap_test "Decap error" "CE" 03 + + corrupted_packet_test "Decap error: Reserved bits in use" \ + "reserved_bits_payload_get" + corrupted_packet_test "Decap error: Too short inner packet" \ + "short_payload_get" +} + +mc_smac_payload_get() +{ + local dest_mac=$(mac_get $h1) + local source_mac="01:02:03:04:05:06" + local saddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:03" + local daddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01" + p=$(: + )"08:"$( : VXLAN flags + )"00:00:00:"$( : VXLAN reserved + )"00:03:e8:"$( : VXLAN VNI : 1000 + )"00:"$( : VXLAN reserved + )"$dest_mac:"$( : ETH daddr + )"$source_mac:"$( : ETH saddr + )"86:dd:"$( : ETH type + )"6"$( : IP version + )"0:0"$( : Traffic class + )"0:00:00:"$( : Flow label + )"00:08:"$( : Payload length + )"3a:"$( : Next header + )"04:"$( : Hop limit + )"$saddr:"$( : IP saddr + )"$daddr:"$( : IP daddr + )"80:"$( : ICMPv6.type + )"00:"$( : ICMPv6.code + )"00:"$( : ICMPv6.checksum + ) + echo $p +} + +overlay_smac_is_mc_test() +{ + local trap_name="overlay_smac_is_mc" + local mz_pid + + RET=0 + + # The matching will be checked on devlink_trap_drop_test() + # and the filter will be removed on devlink_trap_drop_cleanup() + tc filter add dev $swp1 egress protocol ipv6 pref 1 handle 101 \ + flower src_mac 01:02:03:04:05:06 action pass + + rp1_mac=$(mac_get $rp1) + payload=$(mc_smac_payload_get) + + ip vrf exec v$rp2 $MZ -6 $rp2 -c 0 -d 1msec -b $rp1_mac \ + -B 2001:db8:3::1 -t udp sp=12345,dp=$VXPORT,p=$payload -q & + mz_pid=$! + + devlink_trap_drop_test $trap_name $swp1 101 + + log_test "Overlay source MAC is multicast" + + devlink_trap_drop_cleanup $mz_pid $swp1 "ipv6" 1 101 +} + +trap cleanup EXIT + +setup_prepare +setup_wait +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/egress_vid_classification.sh b/tools/testing/selftests/drivers/net/mlxsw/egress_vid_classification.sh new file mode 100755 index 000000000000..a5c2aec52898 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/egress_vid_classification.sh @@ -0,0 +1,272 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# Test VLAN classification after routing and verify that the order of +# configuration does not impact switch behavior. Verify that {RIF, Port}->VID +# mapping is added correctly for existing {Port, VID}->FID mapping and that +# {RIF, Port}->VID mapping is added correctly for new {Port, VID}->FID mapping. + +# +-------------------+ +--------------------+ +# | H1 | | H2 | +# | | | | +# | $h1.10 + | | + $h2.10 | +# | 192.0.2.1/28 | | | | 192.0.2.3/28 | +# | | | | | | +# | $h1 + | | + $h2 | +# +----------------|--+ +--|-----------------+ +# | | +# +----------------|-------------------------|-----------------+ +# | SW $swp1 + + $swp2 | +# | | | | +# | +--------------|-------------------------|---------------+ | +# | | $swp1.10 + + $swp2.10 | | +# | | | | +# | | br0 | | +# | | 192.0.2.2/28 | | +# | +--------------------------------------------------------+ | +# | | +# | $swp3.20 + | +# | 192.0.2.17/28 | | +# | | | +# | $swp3 + | +# +---------------|--------------------------------------------+ +# | +# +---------------|--+ +# | $h3 + | +# | | | +# | $h3.20 + | +# | 192.0.2.18/28 | +# | | +# | H3 | +# +------------------+ + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + port_vid_map_rif + rif_port_vid_map +" + +NUM_NETIFS=6 +source $lib_dir/lib.sh +source $lib_dir/tc_common.sh +source $lib_dir/devlink_lib.sh + +h1_create() +{ + simple_if_init $h1 + vlan_create $h1 10 v$h1 192.0.2.1/28 + + ip route add 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2 +} + +h1_destroy() +{ + ip route del 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2 + + vlan_destroy $h1 10 + simple_if_fini $h1 +} + +h2_create() +{ + simple_if_init $h2 + vlan_create $h2 10 v$h2 192.0.2.3/28 +} + +h2_destroy() +{ + vlan_destroy $h2 10 + simple_if_fini $h2 +} + +h3_create() +{ + simple_if_init $h3 + vlan_create $h3 20 v$h3 192.0.2.18/28 + + ip route add 192.0.2.0/28 vrf v$h3 nexthop via 192.0.2.17 +} + +h3_destroy() +{ + ip route del 192.0.2.0/28 vrf v$h3 nexthop via 192.0.2.17 + + vlan_destroy $h3 20 + simple_if_fini $h3 +} + +switch_create() +{ + ip link set dev $swp1 up + tc qdisc add dev $swp1 clsact + + ip link add dev br0 type bridge mcast_snooping 0 + + # By default, a link-local address is generated when netdevice becomes + # up. Adding an address to the bridge will cause creating a RIF for it. + # Prevent generating link-local address to be able to control when the + # RIF is added. + sysctl_set net.ipv6.conf.br0.addr_gen_mode 1 + ip link set dev br0 up + + ip link set dev $swp2 up + vlan_create $swp2 10 + ip link set dev $swp2.10 master br0 + + ip link set dev $swp3 up + vlan_create $swp3 20 "" 192.0.2.17/28 + + # Replace neighbor to avoid 1 packet which is forwarded in software due + # to "unresolved neigh". + ip neigh replace dev $swp3.20 192.0.2.18 lladdr $(mac_get $h3.20) +} + +switch_destroy() +{ + vlan_destroy $swp3 20 + ip link set dev $swp3 down + + ip link set dev $swp2.10 nomaster + vlan_destroy $swp2 10 + ip link set dev $swp2 down + + ip link set dev br0 down + sysctl_restore net.ipv6.conf.br0.addr_gen_mode + ip link del dev br0 + + tc qdisc del dev $swp1 clsact + ip link set dev $swp1 down +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + swp2=${NETIFS[p3]} + h2=${NETIFS[p4]} + + swp3=${NETIFS[p5]} + h3=${NETIFS[p6]} + + vrf_prepare + forwarding_enable + + h1_create + h2_create + h3_create + + switch_create +} + +cleanup() +{ + pre_cleanup + + switch_destroy + + h3_destroy + h2_destroy + h1_destroy + + forwarding_restore + vrf_cleanup +} + +bridge_rif_add() +{ + rifs_occ_t0=$(devlink_resource_occ_get rifs) + __addr_add_del br0 add 192.0.2.2/28 + rifs_occ_t1=$(devlink_resource_occ_get rifs) + + expected_rifs=$((rifs_occ_t0 + 1)) + + [[ $expected_rifs -eq $rifs_occ_t1 ]] + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + sleep 1 +} + +bridge_rif_del() +{ + __addr_add_del br0 del 192.0.2.2/28 +} + +port_vid_map_rif() +{ + RET=0 + + # First add {port, VID}->FID for swp1.10, then add a RIF and verify that + # packets get the correct VID after routing. + vlan_create $swp1 10 + ip link set dev $swp1.10 master br0 + bridge_rif_add + + # Replace neighbor to avoid 1 packet which is forwarded in software due + # to "unresolved neigh". + ip neigh replace dev br0 192.0.2.1 lladdr $(mac_get $h1.10) + + # The hardware matches on the first ethertype which is not VLAN, + # so the protocol should be IP. + tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \ + flower skip_sw dst_ip 192.0.2.1 action pass + + ping_do $h1.10 192.0.2.18 + check_err $? "Ping failed" + + tc_check_at_least_x_packets "dev $swp1 egress" 101 10 + check_err $? "Packets were not routed in hardware" + + log_test "Add RIF for existing {port, VID}->FID mapping" + + tc filter del dev $swp1 egress + + bridge_rif_del + ip link set dev $swp1.10 nomaster + vlan_destroy $swp1 10 +} + +rif_port_vid_map() +{ + RET=0 + + # First add an address to the bridge, which will create a RIF on top of + # it, then add a new {port, VID}->FID mapping and verify that packets + # get the correct VID after routing. + bridge_rif_add + vlan_create $swp1 10 + ip link set dev $swp1.10 master br0 + + # Replace neighbor to avoid 1 packet which is forwarded in software due + # to "unresolved neigh". + ip neigh replace dev br0 192.0.2.1 lladdr $(mac_get $h1.10) + + # The hardware matches on the first ethertype which is not VLAN, + # so the protocol should be IP. + tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \ + flower skip_sw dst_ip 192.0.2.1 action pass + + ping_do $h1.10 192.0.2.18 + check_err $? "Ping failed" + + tc_check_at_least_x_packets "dev $swp1 egress" 101 10 + check_err $? "Packets were not routed in hardware" + + log_test "Add {port, VID}->FID mapping for FID with a RIF" + + tc filter del dev $swp1 egress + + ip link set dev $swp1.10 nomaster + vlan_destroy $swp1 10 + bridge_rif_del +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/ethtool_lanes.sh b/tools/testing/selftests/drivers/net/mlxsw/ethtool_lanes.sh new file mode 100755 index 000000000000..91891b9418d7 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/ethtool_lanes.sh @@ -0,0 +1,187 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + autoneg + autoneg_force_mode +" + +NUM_NETIFS=2 +: ${TIMEOUT:=30000} # ms +source $lib_dir/lib.sh +source $lib_dir/ethtool_lib.sh + +setup_prepare() +{ + swp1=${NETIFS[p1]} + swp2=${NETIFS[p2]} + + ip link set dev $swp1 up + ip link set dev $swp2 up + + busywait "$TIMEOUT" wait_for_port_up ethtool $swp2 + check_err $? "ports did not come up" + + local lanes_exist=$(ethtool $swp1 | grep 'Lanes:') + if [[ -z $lanes_exist ]]; then + log_test "SKIP: driver does not support lanes setting" + exit 1 + fi + + ip link set dev $swp2 down + ip link set dev $swp1 down +} + +check_lanes() +{ + local dev=$1; shift + local lanes=$1; shift + local max_speed=$1; shift + local chosen_lanes + + chosen_lanes=$(ethtool $dev | grep 'Lanes:') + chosen_lanes=${chosen_lanes#*"Lanes: "} + + ((chosen_lanes == lanes)) + check_err $? "swp1 advertise $max_speed and $lanes, devs sync to $chosen_lanes" +} + +check_unsupported_lanes() +{ + local dev=$1; shift + local max_speed=$1; shift + local max_lanes=$1; shift + local autoneg=$1; shift + local autoneg_str="" + + local unsupported_lanes=$((max_lanes *= 2)) + + if [[ $autoneg -eq 0 ]]; then + autoneg_str="autoneg off" + fi + + ethtool -s $swp1 speed $max_speed lanes $unsupported_lanes $autoneg_str &> /dev/null + check_fail $? "Unsuccessful $unsupported_lanes lanes setting was expected" +} + +max_speed_and_lanes_get() +{ + local dev=$1; shift + local arr=("$@") + local max_lanes + local max_speed + local -a lanes_arr + local -a speeds_arr + local -a max_values + + for ((i=0; i<${#arr[@]}; i+=2)); do + speeds_arr+=("${arr[$i]}") + lanes_arr+=("${arr[i+1]}") + done + + max_values+=($(get_max "${speeds_arr[@]}")) + max_values+=($(get_max "${lanes_arr[@]}")) + + echo ${max_values[@]} +} + +search_linkmode() +{ + local speed=$1; shift + local lanes=$1; shift + local arr=("$@") + + for ((i=0; i<${#arr[@]}; i+=2)); do + if [[ $speed -eq ${arr[$i]} && $lanes -eq ${arr[i+1]} ]]; then + return 1 + fi + done + return 0 +} + +autoneg() +{ + RET=0 + + local lanes + local max_speed + local max_lanes + + local -a linkmodes_params=($(dev_linkmodes_params_get $swp1 1)) + local -a max_values=($(max_speed_and_lanes_get $swp1 "${linkmodes_params[@]}")) + max_speed=${max_values[0]} + max_lanes=${max_values[1]} + + lanes=$max_lanes + + while [[ $lanes -ge 1 ]]; do + search_linkmode $max_speed $lanes "${linkmodes_params[@]}" + if [[ $? -eq 1 ]]; then + ethtool_set $swp1 speed $max_speed lanes $lanes + ip link set dev $swp1 up + ip link set dev $swp2 up + busywait "$TIMEOUT" wait_for_port_up ethtool $swp2 + check_err $? "ports did not come up" + + check_lanes $swp1 $lanes $max_speed + log_test "$lanes lanes is autonegotiated" + fi + let $((lanes /= 2)) + done + + check_unsupported_lanes $swp1 $max_speed $max_lanes 1 + log_test "Lanes number larger than max width is not set" + + ip link set dev $swp2 down + ip link set dev $swp1 down +} + +autoneg_force_mode() +{ + RET=0 + + local lanes + local max_speed + local max_lanes + + local -a linkmodes_params=($(dev_linkmodes_params_get $swp1 1)) + local -a max_values=($(max_speed_and_lanes_get $swp1 "${linkmodes_params[@]}")) + max_speed=${max_values[0]} + max_lanes=${max_values[1]} + + lanes=$max_lanes + + while [[ $lanes -ge 1 ]]; do + search_linkmode $max_speed $lanes "${linkmodes_params[@]}" + if [[ $? -eq 1 ]]; then + ethtool_set $swp1 speed $max_speed lanes $lanes autoneg off + ethtool_set $swp2 speed $max_speed lanes $lanes autoneg off + ip link set dev $swp1 up + ip link set dev $swp2 up + busywait "$TIMEOUT" wait_for_port_up ethtool $swp2 + check_err $? "ports did not come up" + + check_lanes $swp1 $lanes $max_speed + log_test "Autoneg off, $lanes lanes detected during force mode" + fi + let $((lanes /= 2)) + done + + check_unsupported_lanes $swp1 $max_speed $max_lanes 0 + log_test "Lanes number larger than max width is not set" + + ip link set dev $swp2 down + ip link set dev $swp1 down + + ethtool -s $swp2 autoneg on + ethtool -s $swp1 autoneg on +} + +check_ethtool_lanes_support +setup_prepare + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/extack.sh b/tools/testing/selftests/drivers/net/mlxsw/extack.sh index 7a0a99c1d22f..6fd422d38fe8 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/extack.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/extack.sh @@ -35,7 +35,9 @@ netdev_pre_up_test() { RET=0 - ip link add name br1 up type bridge vlan_filtering 0 mcast_snooping 0 + ip link add name br1 type bridge vlan_filtering 0 mcast_snooping 0 + ip link set dev br1 addrgenmode none + ip link set dev br1 up ip link add name vx1 up type vxlan id 1000 \ local 192.0.2.17 remote 192.0.2.18 \ dstport 4789 nolearning noudpcsum tos inherit ttl 100 @@ -46,7 +48,9 @@ netdev_pre_up_test() ip link set dev $swp1 master br1 check_err $? - ip link add name br2 up type bridge vlan_filtering 0 mcast_snooping 0 + ip link add name br2 type bridge vlan_filtering 0 mcast_snooping 0 + ip link set dev br2 addrgenmode none + ip link set dev br2 up ip link add name vx2 up type vxlan id 2000 \ local 192.0.2.17 remote 192.0.2.18 \ dstport 4789 nolearning noudpcsum tos inherit ttl 100 @@ -81,7 +85,9 @@ vxlan_vlan_add_test() { RET=0 - ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 0 + ip link add name br1 type bridge vlan_filtering 1 mcast_snooping 0 + ip link set dev br1 addrgenmode none + ip link set dev br1 up # Unsupported configuration: mlxsw demands VXLAN with "noudpcsum". ip link add name vx1 up type vxlan id 1000 \ @@ -117,7 +123,9 @@ vxlan_bridge_create_test() dstport 4789 tos inherit ttl 100 # Test with VLAN-aware bridge. - ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 0 + ip link add name br1 type bridge vlan_filtering 1 mcast_snooping 0 + ip link set dev br1 addrgenmode none + ip link set dev br1 up ip link set dev vx1 master br1 @@ -142,8 +150,12 @@ bridge_create_test() { RET=0 - ip link add name br1 up type bridge vlan_filtering 1 - ip link add name br2 up type bridge vlan_filtering 1 + ip link add name br1 type bridge vlan_filtering 1 + ip link set dev br1 addrgenmode none + ip link set dev br1 up + ip link add name br2 type bridge vlan_filtering 1 + ip link set dev br2 addrgenmode none + ip link set dev br2 up ip link set dev $swp1 master br1 check_err $? diff --git a/tools/testing/selftests/drivers/net/mlxsw/fib.sh b/tools/testing/selftests/drivers/net/mlxsw/fib.sh index eab79b9e58cd..dcbf32b99bb6 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/fib.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/fib.sh @@ -225,6 +225,16 @@ ipv6_local_replace() ip -n $ns link del dev dummy1 } +fib_notify_on_flag_change_set() +{ + local notify=$1; shift + + ip netns exec testns1 sysctl -qw net.ipv4.fib_notify_on_flag_change=$notify + ip netns exec testns1 sysctl -qw net.ipv6.fib_notify_on_flag_change=$notify + + log_info "Set fib_notify_on_flag_change to $notify" +} + setup_prepare() { ip netns add testns1 @@ -251,6 +261,10 @@ trap cleanup EXIT setup_prepare +fib_notify_on_flag_change_set 1 +tests_run + +fib_notify_on_flag_change_set 0 tests_run exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/hw_stats_l3.sh b/tools/testing/selftests/drivers/net/mlxsw/hw_stats_l3.sh new file mode 100755 index 000000000000..941ba4c485c9 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/hw_stats_l3.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + l3_monitor_test +" +NUM_NETIFS=0 +source $lib_dir/lib.sh + +swp=$NETIF_NO_CABLE + +cleanup() +{ + pre_cleanup +} + +l3_monitor_test() +{ + hw_stats_monitor_test $swp l3 \ + "ip addr add dev $swp 192.0.2.1/28" \ + "ip addr del dev $swp 192.0.2.1/28" +} + +trap cleanup EXIT + +setup_wait +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/ingress_rif_conf_1d.sh b/tools/testing/selftests/drivers/net/mlxsw/ingress_rif_conf_1d.sh new file mode 100755 index 000000000000..7d7f862c809c --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/ingress_rif_conf_1d.sh @@ -0,0 +1,263 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# Test routing over bridge and verify that the order of configuration does not +# impact switch behavior. Verify that RIF is added correctly for existing +# mappings and that new mappings use the correct RIF. + +# +-------------------+ +--------------------+ +# | H1 | | H2 | +# | | | | +# | $h1.10 + | | + $h2.10 | +# | 192.0.2.1/28 | | | | 192.0.2.3/28 | +# | | | | | | +# | $h1 + | | + $h2 | +# +----------------|--+ +--|-----------------+ +# | | +# +----------------|-------------------------|-----------------+ +# | SW $swp1 + + $swp2 | +# | | | | +# | +--------------|-------------------------|---------------+ | +# | | $swp1.10 + + $swp2.10 | | +# | | | | +# | | br0 | | +# | | 192.0.2.2/28 | | +# | +--------------------------------------------------------+ | +# | | +# | $swp3.10 + | +# | 192.0.2.17/28 | | +# | | | +# | $swp3 + | +# +---------------|--------------------------------------------+ +# | +# +---------------|--+ +# | $h3 + | +# | | | +# | $h3.10 + | +# | 192.0.2.18/28 | +# | | +# | H3 | +# +------------------+ + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + port_vid_map_rif + rif_port_vid_map +" + +NUM_NETIFS=6 +source $lib_dir/lib.sh +source $lib_dir/tc_common.sh +source $lib_dir/devlink_lib.sh + +h1_create() +{ + simple_if_init $h1 + vlan_create $h1 10 v$h1 192.0.2.1/28 + + ip route add 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2 +} + +h1_destroy() +{ + ip route del 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2 + + vlan_destroy $h1 10 + simple_if_fini $h1 +} + +h2_create() +{ + simple_if_init $h2 + vlan_create $h2 10 v$h2 192.0.2.3/28 +} + +h2_destroy() +{ + vlan_destroy $h2 10 + simple_if_fini $h2 +} + +h3_create() +{ + simple_if_init $h3 + vlan_create $h3 10 v$h3 192.0.2.18/28 + + ip route add 192.0.2.0/28 vrf v$h3 nexthop via 192.0.2.17 +} + +h3_destroy() +{ + ip route del 192.0.2.0/28 vrf v$h3 nexthop via 192.0.2.17 + + vlan_destroy $h3 10 + simple_if_fini $h3 +} + +switch_create() +{ + ip link set dev $swp1 up + + ip link add dev br0 type bridge mcast_snooping 0 + + # By default, a link-local address is generated when netdevice becomes + # up. Adding an address to the bridge will cause creating a RIF for it. + # Prevent generating link-local address to be able to control when the + # RIF is added. + sysctl_set net.ipv6.conf.br0.addr_gen_mode 1 + ip link set dev br0 up + + ip link set dev $swp2 up + vlan_create $swp2 10 + ip link set dev $swp2.10 master br0 + + ip link set dev $swp3 up + vlan_create $swp3 10 "" 192.0.2.17/28 + tc qdisc add dev $swp3 clsact + + # Replace neighbor to avoid 1 packet which is forwarded in software due + # to "unresolved neigh". + ip neigh replace dev $swp3.10 192.0.2.18 lladdr $(mac_get $h3.10) +} + +switch_destroy() +{ + tc qdisc del dev $swp3 clsact + vlan_destroy $swp3 10 + ip link set dev $swp3 down + + ip link set dev $swp2.10 nomaster + vlan_destroy $swp2 10 + ip link set dev $swp2 down + + ip link set dev br0 down + sysctl_restore net.ipv6.conf.br0.addr_gen_mode + ip link del dev br0 + + ip link set dev $swp1 down +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + swp2=${NETIFS[p3]} + h2=${NETIFS[p4]} + + swp3=${NETIFS[p5]} + h3=${NETIFS[p6]} + + vrf_prepare + forwarding_enable + + h1_create + h2_create + h3_create + + switch_create +} + +cleanup() +{ + pre_cleanup + + switch_destroy + + h3_destroy + h2_destroy + h1_destroy + + forwarding_restore + vrf_cleanup +} + +bridge_rif_add() +{ + rifs_occ_t0=$(devlink_resource_occ_get rifs) + __addr_add_del br0 add 192.0.2.2/28 + rifs_occ_t1=$(devlink_resource_occ_get rifs) + + expected_rifs=$((rifs_occ_t0 + 1)) + + [[ $expected_rifs -eq $rifs_occ_t1 ]] + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + sleep 1 +} + +bridge_rif_del() +{ + __addr_add_del br0 del 192.0.2.2/28 +} + +port_vid_map_rif() +{ + RET=0 + + # First add {port, VID}->FID for $swp1.10, then add a RIF and verify + # that packets can be routed via the existing mapping. + vlan_create $swp1 10 + ip link set dev $swp1.10 master br0 + bridge_rif_add + + # The hardware matches on the first ethertype which is not VLAN, + # so the protocol should be IP. + tc filter add dev $swp3 egress protocol ip pref 1 handle 101 \ + flower skip_sw dst_ip 192.0.2.18 action pass + + ping_do $h1.10 192.0.2.18 + check_err $? "Ping failed" + + tc_check_at_least_x_packets "dev $swp3 egress" 101 10 + check_err $? "Packets were not routed in hardware" + + log_test "Add RIF for existing {port, VID}->FID mapping" + + tc filter del dev $swp3 egress + + bridge_rif_del + ip link set dev $swp1.10 nomaster + vlan_destroy $swp1 10 +} + +rif_port_vid_map() +{ + RET=0 + + # First add an address to the bridge, which will create a RIF on top of + # it, then add a new {port, VID}->FID mapping and verify that packets + # can be routed via the new mapping. + bridge_rif_add + vlan_create $swp1 10 + ip link set dev $swp1.10 master br0 + + # The hardware matches on the first ethertype which is not VLAN, + # so the protocol should be IP. + tc filter add dev $swp3 egress protocol ip pref 1 handle 101 \ + flower skip_sw dst_ip 192.0.2.18 action pass + + ping_do $h1.10 192.0.2.18 + check_err $? "Ping failed" + + tc_check_at_least_x_packets "dev $swp3 egress" 101 10 + check_err $? "Packets were not routed in hardware" + + log_test "Add {port, VID}->FID mapping for FID with a RIF" + + tc filter del dev $swp3 egress + + ip link set dev $swp1.10 nomaster + vlan_destroy $swp1 10 + bridge_rif_del +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/ingress_rif_conf_1q.sh b/tools/testing/selftests/drivers/net/mlxsw/ingress_rif_conf_1q.sh new file mode 100755 index 000000000000..577293bab88b --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/ingress_rif_conf_1q.sh @@ -0,0 +1,264 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# Test routing over bridge and verify that the order of configuration does not +# impact switch behavior. Verify that RIF is added correctly for existing +# mapping and that packets can be routed via port which is added after the FID +# already has a RIF. + +# +-------------------+ +--------------------+ +# | H1 | | H2 | +# | | | | +# | $h1.10 + | | + $h2.10 | +# | 192.0.2.1/28 | | | | 192.0.2.3/28 | +# | | | | | | +# | $h1 + | | + $h2 | +# +----------------|--+ +--|-----------------+ +# | | +# +----------------|-------------------------|-----------------+ +# | SW | | | +# | +--------------|-------------------------|---------------+ | +# | | $swp1 + + $swp2 | | +# | | | | +# | | br0 | | +# | +--------------------------------------------------------+ | +# | | | +# | br0.10 | +# | 192.0.2.2/28 | +# | | +# | | +# | $swp3 + | +# | 192.0.2.17/28 | | +# +----------------|-------------------------------------------+ +# | +# +----------------|--+ +# | $h3 + | +# | 192.0.2.18/28 | +# | | +# | H3 | +# +-------------------+ + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + vid_map_rif + rif_vid_map +" + +NUM_NETIFS=6 +source $lib_dir/lib.sh +source $lib_dir/tc_common.sh +source $lib_dir/devlink_lib.sh + +h1_create() +{ + simple_if_init $h1 + vlan_create $h1 10 v$h1 192.0.2.1/28 + + ip route add 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2 +} + +h1_destroy() +{ + ip route del 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2 + + vlan_destroy $h1 10 + simple_if_fini $h1 +} + +h2_create() +{ + simple_if_init $h2 + vlan_create $h2 10 v$h2 192.0.2.3/28 +} + +h2_destroy() +{ + vlan_destroy $h2 10 + simple_if_fini $h2 +} + +h3_create() +{ + simple_if_init $h3 192.0.2.18/28 + ip route add 192.0.2.0/28 vrf v$h3 nexthop via 192.0.2.17 +} + +h3_destroy() +{ + ip route del 192.0.2.0/28 vrf v$h3 nexthop via 192.0.2.17 + simple_if_fini $h3 192.0.2.18/28 +} + +switch_create() +{ + ip link set dev $swp1 up + + ip link add dev br0 type bridge vlan_filtering 1 mcast_snooping 0 + + # By default, a link-local address is generated when netdevice becomes + # up. Adding an address to the bridge will cause creating a RIF for it. + # Prevent generating link-local address to be able to control when the + # RIF is added. + sysctl_set net.ipv6.conf.br0.addr_gen_mode 1 + ip link set dev br0 up + + ip link set dev $swp2 up + ip link set dev $swp2 master br0 + bridge vlan add vid 10 dev $swp2 + + ip link set dev $swp3 up + __addr_add_del $swp3 add 192.0.2.17/28 + tc qdisc add dev $swp3 clsact + + # Replace neighbor to avoid 1 packet which is forwarded in software due + # to "unresolved neigh". + ip neigh replace dev $swp3 192.0.2.18 lladdr $(mac_get $h3) +} + +switch_destroy() +{ + tc qdisc del dev $swp3 clsact + __addr_add_del $swp3 del 192.0.2.17/28 + ip link set dev $swp3 down + + bridge vlan del vid 10 dev $swp2 + ip link set dev $swp2 nomaster + ip link set dev $swp2 down + + ip link set dev br0 down + sysctl_restore net.ipv6.conf.br0.addr_gen_mode + ip link del dev br0 + + ip link set dev $swp1 down +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + swp2=${NETIFS[p3]} + h2=${NETIFS[p4]} + + swp3=${NETIFS[p5]} + h3=${NETIFS[p6]} + + vrf_prepare + forwarding_enable + + h1_create + h2_create + h3_create + + switch_create +} + +cleanup() +{ + pre_cleanup + + switch_destroy + + h3_destroy + h2_destroy + h1_destroy + + forwarding_restore + vrf_cleanup +} + +bridge_rif_add() +{ + rifs_occ_t0=$(devlink_resource_occ_get rifs) + vlan_create br0 10 "" 192.0.2.2/28 + rifs_occ_t1=$(devlink_resource_occ_get rifs) + + expected_rifs=$((rifs_occ_t0 + 1)) + + [[ $expected_rifs -eq $rifs_occ_t1 ]] + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + sleep 1 +} + +bridge_rif_del() +{ + vlan_destroy br0 10 +} + +vid_map_rif() +{ + RET=0 + + # First add VID->FID for vlan 10, then add a RIF and verify that + # packets can be routed via the existing mapping. + bridge vlan add vid 10 dev br0 self + ip link set dev $swp1 master br0 + bridge vlan add vid 10 dev $swp1 + + bridge_rif_add + + tc filter add dev $swp3 egress protocol ip pref 1 handle 101 \ + flower skip_sw dst_ip 192.0.2.18 action pass + + ping_do $h1.10 192.0.2.18 + check_err $? "Ping failed" + + tc_check_at_least_x_packets "dev $swp3 egress" 101 10 + check_err $? "Packets were not routed in hardware" + + log_test "Add RIF for existing VID->FID mapping" + + tc filter del dev $swp3 egress + + bridge_rif_del + + bridge vlan del vid 10 dev $swp1 + ip link set dev $swp1 nomaster + bridge vlan del vid 10 dev br0 self +} + +rif_vid_map() +{ + RET=0 + + # Using 802.1Q, there is only one VID->FID map for each VID. That means + # that we cannot really check adding a new map for existing FID with a + # RIF. Verify that packets can be routed via port which is added after + # the FID already has a RIF, although in practice there is no new + # mapping in the hardware. + bridge vlan add vid 10 dev br0 self + bridge_rif_add + + ip link set dev $swp1 master br0 + bridge vlan add vid 10 dev $swp1 + + tc filter add dev $swp3 egress protocol ip pref 1 handle 101 \ + flower skip_sw dst_ip 192.0.2.18 action pass + + ping_do $h1.10 192.0.2.18 + check_err $? "Ping failed" + + tc_check_at_least_x_packets "dev $swp3 egress" 101 10 + check_err $? "Packets were not routed in hardware" + + log_test "Add port to VID->FID mapping for FID with a RIF" + + tc filter del dev $swp3 egress + + bridge vlan del vid 10 dev $swp1 + ip link set dev $swp1 nomaster + + bridge_rif_del + bridge vlan del vid 10 dev br0 self +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/ingress_rif_conf_vxlan.sh b/tools/testing/selftests/drivers/net/mlxsw/ingress_rif_conf_vxlan.sh new file mode 100755 index 000000000000..90450216a10d --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/ingress_rif_conf_vxlan.sh @@ -0,0 +1,311 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# Test routing after VXLAN decapsulation and verify that the order of +# configuration does not impact switch behavior. Verify that RIF is added +# correctly for existing mapping and that new mapping uses the correct RIF. + +# +---------------------------+ +# | H1 | +# | + $h1 | +# | | 192.0.2.1/28 | +# +----|----------------------+ +# | +# +----|----------------------------------------------------------------------+ +# | SW | | +# | +--|--------------------------------------------------------------------+ | +# | | + $swp1 br1 | | +# | | vid 10 pvid untagged | | +# | | | | +# | | | | +# | | + vx4001 | | +# | | local 192.0.2.17 | | +# | | remote 192.0.2.18 | | +# | | id 104001 | | +# | | dstport $VXPORT | | +# | | vid 4001 pvid untagged | | +# | | | | +# | +----------------------------------+------------------------------------+ | +# | | | +# | +----------------------------------|------------------------------------+ | +# | | | | | +# | | +-------------------------------+---------------------------------+ | | +# | | | | | | +# | | + vlan10 vlan4001 + | | +# | | 192.0.2.2/28 | | +# | | | | +# | | vrf-green | | +# | +-----------------------------------------------------------------------+ | +# | | +# | + $rp1 +lo | +# | | 198.51.100.1/24 192.0.2.17/32 | +# +----|----------------------------------------------------------------------+ +# | +# +----|--------------------------------------------------------+ +# | | v$rp2 | +# | + $rp2 | +# | 198.51.100.2/24 | +# | | +# +-------------------------------------------------------------+ + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + vni_fid_map_rif + rif_vni_fid_map +" + +NUM_NETIFS=4 +source $lib_dir/lib.sh +source $lib_dir/tc_common.sh +source $lib_dir/devlink_lib.sh + +: ${VXPORT:=4789} +export VXPORT + +h1_create() +{ + simple_if_init $h1 192.0.2.1/28 +} + +h1_destroy() +{ + simple_if_fini $h1 192.0.2.1/28 +} + +switch_create() +{ + ip link add name br1 type bridge vlan_filtering 1 vlan_default_pvid 0 \ + mcast_snooping 0 + # Make sure the bridge uses the MAC address of the local port and not + # that of the VxLAN's device. + ip link set dev br1 address $(mac_get $swp1) + ip link set dev br1 up + + ip link set dev $rp1 up + ip address add dev $rp1 198.51.100.1/24 + + ip link set dev $swp1 master br1 + ip link set dev $swp1 up + bridge vlan add vid 10 dev $swp1 pvid untagged + + tc qdisc add dev $swp1 clsact + + ip link add name vx4001 type vxlan id 104001 \ + local 192.0.2.17 dstport $VXPORT \ + nolearning noudpcsum tos inherit ttl 100 + ip link set dev vx4001 up + + ip link set dev vx4001 master br1 + + ip address add 192.0.2.17/32 dev lo + + # Create SVIs. + vrf_create "vrf-green" + ip link set dev vrf-green up + + ip link add link br1 name vlan10 up master vrf-green type vlan id 10 + + # Replace neighbor to avoid 1 packet which is forwarded in software due + # to "unresolved neigh". + ip neigh replace dev vlan10 192.0.2.1 lladdr $(mac_get $h1) + + ip address add 192.0.2.2/28 dev vlan10 + + bridge vlan add vid 10 dev br1 self + bridge vlan add vid 4001 dev br1 self + + sysctl_set net.ipv4.conf.all.rp_filter 0 +} + +switch_destroy() +{ + sysctl_restore net.ipv4.conf.all.rp_filter + + bridge vlan del vid 4001 dev br1 self + bridge vlan del vid 10 dev br1 self + + ip link del dev vlan10 + + vrf_destroy "vrf-green" + + ip address del 192.0.2.17/32 dev lo + + tc qdisc del dev $swp1 clsact + + bridge vlan del vid 10 dev $swp1 + ip link set dev $swp1 down + ip link set dev $swp1 nomaster + + ip link set dev vx4001 nomaster + + ip link set dev vx4001 down + ip link del dev vx4001 + + ip address del dev $rp1 198.51.100.1/24 + ip link set dev $rp1 down + + ip link set dev br1 down + ip link del dev br1 +} + +vrp2_create() +{ + simple_if_init $rp2 198.51.100.2/24 + + ip route add 192.0.2.17/32 vrf v$rp2 nexthop via 198.51.100.1 +} + +vrp2_destroy() +{ + ip route del 192.0.2.17/32 vrf v$rp2 nexthop via 198.51.100.1 + + simple_if_fini $rp2 198.51.100.2/24 +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + rp1=${NETIFS[p3]} + rp2=${NETIFS[p4]} + + vrf_prepare + forwarding_enable + + h1_create + switch_create + + vrp2_create +} + +cleanup() +{ + pre_cleanup + + vrp2_destroy + + switch_destroy + h1_destroy + + forwarding_restore + vrf_cleanup +} + +payload_get() +{ + local dest_mac=$(mac_get vlan4001) + local src_mac=$(mac_get $rp1) + + p=$(: + )"08:"$( : VXLAN flags + )"00:00:00:"$( : VXLAN reserved + )"01:96:41:"$( : VXLAN VNI : 104001 + )"00:"$( : VXLAN reserved + )"$dest_mac:"$( : ETH daddr + )"$src_mac:"$( : ETH saddr + )"08:00:"$( : ETH type + )"45:"$( : IP version + IHL + )"00:"$( : IP TOS + )"00:54:"$( : IP total length + )"3f:49:"$( : IP identification + )"00:00:"$( : IP flags + frag off + )"3f:"$( : IP TTL + )"01:"$( : IP proto + )"50:21:"$( : IP header csum + )"c6:33:64:0a:"$( : IP saddr: 198.51.100.10 + )"c0:00:02:01:"$( : IP daddr: 192.0.2.1 + ) + echo $p +} + +vlan_rif_add() +{ + rifs_occ_t0=$(devlink_resource_occ_get rifs) + + ip link add link br1 name vlan4001 up master vrf-green \ + type vlan id 4001 + + rifs_occ_t1=$(devlink_resource_occ_get rifs) + expected_rifs=$((rifs_occ_t0 + 1)) + + [[ $expected_rifs -eq $rifs_occ_t1 ]] + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" +} + +vlan_rif_del() +{ + ip link del dev vlan4001 +} + +vni_fid_map_rif() +{ + local rp1_mac=$(mac_get $rp1) + + RET=0 + + # First add VNI->FID mapping to the FID of VLAN 4001 + bridge vlan add vid 4001 dev vx4001 pvid untagged + + # Add a RIF to the FID with VNI->FID mapping + vlan_rif_add + + tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \ + flower skip_sw dst_ip 192.0.2.1 action pass + + payload=$(payload_get) + ip vrf exec v$rp2 $MZ $rp2 -c 10 -d 1msec -b $rp1_mac \ + -B 192.0.2.17 -A 192.0.2.18 \ + -t udp sp=12345,dp=$VXPORT,p=$payload -q + + tc_check_at_least_x_packets "dev $swp1 egress" 101 10 + check_err $? "Packets were not routed in hardware" + + log_test "Add RIF for existing VNI->FID mapping" + + tc filter del dev $swp1 egress + + bridge vlan del vid 4001 dev vx4001 pvid untagged + vlan_rif_del +} + +rif_vni_fid_map() +{ + local rp1_mac=$(mac_get $rp1) + + RET=0 + + # First add a RIF to the FID of VLAN 4001 + vlan_rif_add + + # Add VNI->FID mapping to FID with a RIF + bridge vlan add vid 4001 dev vx4001 pvid untagged + + tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \ + flower skip_sw dst_ip 192.0.2.1 action pass + + payload=$(payload_get) + ip vrf exec v$rp2 $MZ $rp2 -c 10 -d 1msec -b $rp1_mac \ + -B 192.0.2.17 -A 192.0.2.18 \ + -t udp sp=12345,dp=$VXPORT,p=$payload -q + + tc_check_at_least_x_packets "dev $swp1 egress" 101 10 + check_err $? "Packets were not routed in hardware" + + log_test "Add VNI->FID mapping for FID with a RIF" + + tc filter del dev $swp1 egress + + bridge vlan del vid 4001 dev vx4001 pvid untagged + vlan_rif_del +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh index 6f3a70df63bc..e5589e2fca85 100644 --- a/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh @@ -120,12 +120,13 @@ __mirror_gre_test() sleep 5 for ((i = 0; i < count; ++i)); do + local sip=$(mirror_gre_ipv6_addr 1 $i)::1 local dip=$(mirror_gre_ipv6_addr 1 $i)::2 local htun=h3-gt6-$i local message icmp6_capture_install $htun - mirror_test v$h1 "" $dip $htun 100 10 + mirror_test v$h1 $sip $dip $htun 100 10 icmp6_capture_uninstall $htun done } @@ -164,6 +165,7 @@ mirror_gre_setup_prepare() simple_if_init $h3 ip link add name br1 type bridge vlan_filtering 1 + ip link set dev br1 addrgenmode none ip link set dev br1 up ip link set dev $swp1 master br1 diff --git a/tools/testing/selftests/drivers/net/mlxsw/mlxsw_lib.sh b/tools/testing/selftests/drivers/net/mlxsw/mlxsw_lib.sh index cbe50f260a40..6369927e9c37 100644 --- a/tools/testing/selftests/drivers/net/mlxsw/mlxsw_lib.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/mlxsw_lib.sh @@ -11,3 +11,67 @@ if [[ ! -v MLXSW_CHIP ]]; then exit 1 fi fi + +MLXSW_SPECTRUM_REV=$(case $MLXSW_CHIP in + mlxsw_spectrum) + echo 1 ;; + mlxsw_spectrum*) + echo ${MLXSW_CHIP#mlxsw_spectrum} ;; + *) + echo "Couldn't determine Spectrum chip revision." \ + > /dev/stderr ;; + esac) + +mlxsw_on_spectrum() +{ + local rev=$1; shift + local op="==" + local rev2=${rev%+} + + if [[ $rev2 != $rev ]]; then + op=">=" + fi + + ((MLXSW_SPECTRUM_REV $op rev2)) +} + +__mlxsw_only_on_spectrum() +{ + local rev=$1; shift + local caller=$1; shift + local src=$1; shift + + if ! mlxsw_on_spectrum "$rev"; then + log_test_skip $src:$caller "(Spectrum-$rev only)" + return 1 + fi +} + +mlxsw_only_on_spectrum() +{ + local caller=${FUNCNAME[1]} + local src=${BASH_SOURCE[1]} + local rev + + for rev in "$@"; do + if __mlxsw_only_on_spectrum "$rev" "$caller" "$src"; then + return 0 + fi + done + + return 1 +} + +mlxsw_max_descriptors_get() +{ + local spectrum_rev=$MLXSW_SPECTRUM_REV + + case $spectrum_rev in + 1) echo 81920 ;; + 2) echo 136960 ;; + 3) echo 204800 ;; + 4) echo 220000 ;; + *) echo "Unknown max descriptors for chip revision." > /dev/stderr + return 1 ;; + esac +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/one_armed_router.sh b/tools/testing/selftests/drivers/net/mlxsw/one_armed_router.sh index f02d83e94576..fca0e1e642c6 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/one_armed_router.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/one_armed_router.sh @@ -83,7 +83,8 @@ h2_destroy() switch_create() { - ip link add name br0 type bridge mcast_snooping 0 + ip link add name br0 address $(mac_get $swp1) \ + type bridge mcast_snooping 0 ip link set dev br0 up ip link set dev $swp1 master br0 diff --git a/tools/testing/selftests/drivers/net/mlxsw/pci_reset.sh b/tools/testing/selftests/drivers/net/mlxsw/pci_reset.sh new file mode 100755 index 000000000000..fe0343b95e6c --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/pci_reset.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test that PCI reset works correctly by verifying that only the expected reset +# methods are supported and that after issuing the reset the ifindex of the +# port changes. + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + pci_reset_test +" +NUM_NETIFS=1 +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +pci_reset_test() +{ + RET=0 + + local bus=$(echo $DEVLINK_DEV | cut -d '/' -f 1) + local bdf=$(echo $DEVLINK_DEV | cut -d '/' -f 2) + + if [ $bus != "pci" ]; then + check_err 1 "devlink device is not a PCI device" + log_test "pci reset" + return + fi + + if [ ! -f /sys/bus/pci/devices/$bdf/reset_method ]; then + check_err 1 "reset is not supported" + log_test "pci reset" + return + fi + + [[ $(cat /sys/bus/pci/devices/$bdf/reset_method) == "bus" ]] + check_err $? "only \"bus\" reset method should be supported" + + local ifindex_pre=$(ip -j link show dev $swp1 | jq '.[]["ifindex"]') + + echo 1 > /sys/bus/pci/devices/$bdf/reset + check_err $? "reset failed" + + # Wait for udev to rename newly created netdev. + udevadm settle + + local ifindex_post=$(ip -j link show dev $swp1 | jq '.[]["ifindex"]') + + [[ $ifindex_pre != $ifindex_post ]] + check_err $? "reset not performed" + + log_test "pci reset" +} + +swp1=${NETIFS[p1]} +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/port_range_occ.sh b/tools/testing/selftests/drivers/net/mlxsw/port_range_occ.sh new file mode 100755 index 000000000000..b1f0781f6b25 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/port_range_occ.sh @@ -0,0 +1,111 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test that filters that match on the same port range, but with different +# combination of IPv4/IPv6 and TCP/UDP all use the same port range register by +# observing port range registers' occupancy via devlink-resource. + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + port_range_occ_test +" +NUM_NETIFS=2 +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +h1_create() +{ + simple_if_init $h1 +} + +h1_destroy() +{ + simple_if_fini $h1 +} + +switch_create() +{ + simple_if_init $swp1 + tc qdisc add dev $swp1 clsact +} + +switch_destroy() +{ + tc qdisc del dev $swp1 clsact + simple_if_fini $swp1 +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + vrf_prepare + + h1_create + switch_create +} + +cleanup() +{ + pre_cleanup + + switch_destroy + h1_destroy + + vrf_cleanup +} + +port_range_occ_get() +{ + devlink_resource_occ_get port_range_registers +} + +port_range_occ_test() +{ + RET=0 + + local occ=$(port_range_occ_get) + + # Two port range registers are used, for source and destination port + # ranges. + tc filter add dev $swp1 ingress pref 1 handle 101 proto ip \ + flower skip_sw ip_proto udp src_port 1-100 dst_port 1-100 \ + action pass + (( occ + 2 == $(port_range_occ_get) )) + check_err $? "Got occupancy $(port_range_occ_get), expected $((occ + 2))" + + tc filter add dev $swp1 ingress pref 1 handle 102 proto ip \ + flower skip_sw ip_proto tcp src_port 1-100 dst_port 1-100 \ + action pass + tc filter add dev $swp1 ingress pref 2 handle 103 proto ipv6 \ + flower skip_sw ip_proto udp src_port 1-100 dst_port 1-100 \ + action pass + tc filter add dev $swp1 ingress pref 2 handle 104 proto ipv6 \ + flower skip_sw ip_proto tcp src_port 1-100 dst_port 1-100 \ + action pass + (( occ + 2 == $(port_range_occ_get) )) + check_err $? "Got occupancy $(port_range_occ_get), expected $((occ + 2))" + + tc filter del dev $swp1 ingress pref 2 handle 104 flower + tc filter del dev $swp1 ingress pref 2 handle 103 flower + tc filter del dev $swp1 ingress pref 1 handle 102 flower + (( occ + 2 == $(port_range_occ_get) )) + check_err $? "Got occupancy $(port_range_occ_get), expected $((occ + 2))" + + tc filter del dev $swp1 ingress pref 1 handle 101 flower + (( occ == $(port_range_occ_get) )) + check_err $? "Got occupancy $(port_range_occ_get), expected $occ" + + log_test "port range occupancy" +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/port_range_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/port_range_scale.sh new file mode 100644 index 000000000000..2a70840ff14b --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/port_range_scale.sh @@ -0,0 +1,95 @@ +# SPDX-License-Identifier: GPL-2.0 + +PORT_RANGE_NUM_NETIFS=2 + +port_range_h1_create() +{ + simple_if_init $h1 +} + +port_range_h1_destroy() +{ + simple_if_fini $h1 +} + +port_range_switch_create() +{ + simple_if_init $swp1 + tc qdisc add dev $swp1 clsact +} + +port_range_switch_destroy() +{ + tc qdisc del dev $swp1 clsact + simple_if_fini $swp1 +} + +port_range_rules_create() +{ + local count=$1; shift + local should_fail=$1; shift + local batch_file="$(mktemp)" + + for ((i = 0; i < count; ++i)); do + cat >> $batch_file <<-EOF + filter add dev $swp1 ingress \ + prot ipv4 \ + pref 1000 \ + flower skip_sw \ + ip_proto udp dst_port 1-$((100 + i)) \ + action pass + EOF + done + + tc -b $batch_file + check_err_fail $should_fail $? "Rule insertion" + + rm -f $batch_file +} + +__port_range_test() +{ + local count=$1; shift + local should_fail=$1; shift + + port_range_rules_create $count $should_fail + + offload_count=$(tc -j filter show dev $swp1 ingress | + jq "[.[] | select(.options.in_hw == true)] | length") + ((offload_count == count)) + check_err_fail $should_fail $? "port range offload count" +} + +port_range_test() +{ + local count=$1; shift + local should_fail=$1; shift + + if ! tc_offload_check $PORT_RANGE_NUM_NETIFS; then + check_err 1 "Could not test offloaded functionality" + return + fi + + __port_range_test $count $should_fail +} + +port_range_setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + vrf_prepare + + port_range_h1_create + port_range_switch_create +} + +port_range_cleanup() +{ + pre_cleanup + + port_range_switch_destroy + port_range_h1_destroy + + vrf_cleanup +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/port_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/port_scale.sh new file mode 100644 index 000000000000..1e9a4aff76a2 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/port_scale.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# Test for physical ports resource. The test splits each splittable port +# to its width and checks that eventually the number of physical ports equals +# the maximum number of physical ports. + +PORT_NUM_NETIFS=0 + +declare -a unsplit + +port_setup_prepare() +{ + : +} + +port_cleanup() +{ + pre_cleanup + + for port in "${unsplit[@]}"; do + devlink port unsplit $port + check_err $? "Did not unsplit $netdev" + done + unsplit=() +} + +split_all_ports() +{ + local should_fail=$1; shift + + # Loop over the splittable netdevs and create tuples of netdev along + # with its width. For example: + # '$netdev1 $count1 $netdev2 $count2...', when: + # $netdev1-2 are splittable netdevs in the device, and + # $count1-2 are the netdevs width respectively. + while read netdev count <<<$( + devlink -j port show | + jq -r '.[][] | select(.splittable==true) | "\(.netdev) \(.lanes)"' + ) + [[ ! -z $netdev ]] + do + devlink port split $netdev count $count + check_err $? "Did not split $netdev into $count" + unsplit+=( "${netdev}s0" ) + done +} + +port_test() +{ + local max_ports=$1; shift + local should_fail=$1; shift + + split_all_ports $should_fail + + occ=$(devlink -j resource show $DEVLINK_DEV \ + | jq '.[][][] | select(.name=="physical_ports") |.["occ"]') + + [[ $occ -eq $max_ports ]] + check_err_fail $should_fail $? "Attempt to create $max_ports ports (actual result $occ)" + +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/q_in_q_veto.sh b/tools/testing/selftests/drivers/net/mlxsw/q_in_q_veto.sh new file mode 100755 index 000000000000..00d55b0e98c1 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/q_in_q_veto.sh @@ -0,0 +1,304 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + create_8021ad_vlan_upper_on_top_front_panel_port + create_8021ad_vlan_upper_on_top_bridge_port + create_8021ad_vlan_upper_on_top_lag + create_8021ad_vlan_upper_on_top_bridge + create_8021ad_vlan_upper_on_top_8021ad_bridge + create_vlan_upper_on_top_8021ad_bridge + create_vlan_upper_on_top_front_panel_enslaved_to_8021ad_bridge + create_vlan_upper_on_top_lag_enslaved_to_8021ad_bridge + enslave_front_panel_with_vlan_upper_to_8021ad_bridge + enslave_lag_with_vlan_upper_to_8021ad_bridge + add_ip_address_to_8021ad_bridge + switch_bridge_protocol_from_8021q_to_8021ad +" +NUM_NETIFS=2 +source $lib_dir/lib.sh + +setup_prepare() +{ + swp1=${NETIFS[p1]} + swp2=${NETIFS[p2]} + + ip link set dev $swp1 up + ip link set dev $swp2 up + + sleep 10 +} + +cleanup() +{ + pre_cleanup + + ip link set dev $swp2 down + ip link set dev $swp1 down +} + +create_vlan_upper_on_top_of_bridge() +{ + RET=0 + + local bridge_proto=$1; shift + local netdev_proto=$1; shift + + ip link add dev br0 type bridge vlan_filtering 1 \ + vlan_protocol $bridge_proto vlan_default_pvid 0 mcast_snooping 0 + ip link set dev br0 addrgenmode none + + ip link set dev br0 up + ip link set dev $swp1 master br0 + + ip link add name br0.100 link br0 type vlan \ + protocol $netdev_proto id 100 2>/dev/null + check_fail $? "$netdev_proto vlan upper creation on top of an $bridge_proto bridge not rejected" + + ip link add name br0.100 link br0 type vlan \ + protocol $netdev_proto id 100 2>&1 >/dev/null \ + | grep -q mlxsw_spectrum + check_err $? "$netdev_proto vlan upper creation on top of an $bridge_proto bridge rejected without extack" + + log_test "create $netdev_proto vlan upper on top $bridge_proto bridge" + + ip link del dev br0 +} + +create_8021ad_vlan_upper_on_top_front_panel_port() +{ + RET=0 + + ip link add name $swp1.100 link $swp1 type vlan \ + protocol 802.1ad id 100 2>/dev/null + check_fail $? "802.1ad vlan upper creation on top of a front panel not rejected" + + ip link add name $swp1.100 link $swp1 type vlan \ + protocol 802.1ad id 100 2>&1 >/dev/null \ + | grep -q mlxsw_spectrum + check_err $? "802.1ad vlan upper creation on top of a front panel rejected without extack" + + log_test "create 802.1ad vlan upper on top of a front panel" +} + +create_8021ad_vlan_upper_on_top_bridge_port() +{ + RET=0 + + ip link add dev br0 type bridge vlan_filtering 1 \ + vlan_default_pvid 0 mcast_snooping 0 + ip link set dev br0 addrgenmode none + + ip link set dev $swp1 master br0 + ip link set dev br0 up + + ip link add name $swp1.100 link $swp1 type vlan \ + protocol 802.1ad id 100 2>/dev/null + check_fail $? "802.1ad vlan upper creation on top of a bridge port not rejected" + + ip link add name $swp1.100 link $swp1 type vlan \ + protocol 802.1ad id 100 2>&1 >/dev/null \ + | grep -q mlxsw_spectrum + check_err $? "802.1ad vlan upper creation on top of a bridge port rejected without extack" + + log_test "create 802.1ad vlan upper on top of a bridge port" + + ip link del dev br0 +} + +create_8021ad_vlan_upper_on_top_lag() +{ + RET=0 + + ip link add name bond1 type bond mode 802.3ad + ip link set dev $swp1 down + ip link set dev $swp1 master bond1 + + ip link add name bond1.100 link bond1 type vlan \ + protocol 802.1ad id 100 2>/dev/null + check_fail $? "802.1ad vlan upper creation on top of a lag not rejected" + + ip link add name bond1.100 link bond1 type vlan \ + protocol 802.1ad id 100 2>&1 >/dev/null \ + | grep -q mlxsw_spectrum + check_err $? "802.1ad vlan upper creation on top of a lag rejected without extack" + + log_test "create 802.1ad vlan upper on top of a lag" + + ip link del dev bond1 +} + +create_8021ad_vlan_upper_on_top_bridge() +{ + RET=0 + + create_vlan_upper_on_top_of_bridge "802.1q" "802.1ad" +} + +create_8021ad_vlan_upper_on_top_8021ad_bridge() +{ + RET=0 + + create_vlan_upper_on_top_of_bridge "802.1ad" "802.1ad" +} + +create_vlan_upper_on_top_8021ad_bridge() +{ + RET=0 + + create_vlan_upper_on_top_of_bridge "802.1ad" "802.1q" +} + +create_vlan_upper_on_top_front_panel_enslaved_to_8021ad_bridge() +{ + RET=0 + + ip link add dev br0 type bridge vlan_filtering 1 \ + vlan_protocol 802.1ad vlan_default_pvid 0 mcast_snooping 0 + ip link set dev br0 addrgenmode none + ip link set dev br0 up + + ip link set dev $swp1 master br0 + + ip link add name $swp1.100 link $swp1 type vlan id 100 2>/dev/null + check_fail $? "vlan upper creation on top of front panel enslaved to 802.1ad bridge not rejected" + + ip link add name $swp1.100 link $swp1 type vlan id 100 2>&1 >/dev/null \ + | grep -q mlxsw_spectrum + check_err $? "vlan upper creation on top of front panel enslaved to 802.1ad bridge rejected without extack" + + log_test "create vlan upper on top of front panel enslaved to 802.1ad bridge" + + ip link del dev br0 +} + +create_vlan_upper_on_top_lag_enslaved_to_8021ad_bridge() +{ + RET=0 + + ip link add dev br0 type bridge vlan_filtering 1 \ + vlan_protocol 802.1ad vlan_default_pvid 0 mcast_snooping 0 + ip link set dev br0 addrgenmode none + ip link set dev br0 up + + ip link add name bond1 type bond mode 802.3ad + ip link set dev $swp1 down + ip link set dev $swp1 master bond1 + ip link set dev bond1 master br0 + + ip link add name bond1.100 link bond1 type vlan id 100 2>/dev/null + check_fail $? "vlan upper creation on top of lag enslaved to 802.1ad bridge not rejected" + + ip link add name bond1.100 link bond1 type vlan id 100 2>&1 >/dev/null \ + | grep -q mlxsw_spectrum + check_err $? "vlan upper creation on top of lag enslaved to 802.1ad bridge rejected without extack" + + log_test "create vlan upper on top of lag enslaved to 802.1ad bridge" + + ip link del dev bond1 + ip link del dev br0 +} + +enslave_front_panel_with_vlan_upper_to_8021ad_bridge() +{ + RET=0 + + ip link add dev br0 type bridge vlan_filtering 1 \ + vlan_protocol 802.1ad vlan_default_pvid 0 mcast_snooping 0 + ip link set dev br0 addrgenmode none + ip link set dev br0 up + + ip link add name $swp1.100 link $swp1 type vlan id 100 + + ip link set dev $swp1 master br0 2>/dev/null + check_fail $? "front panel with vlan upper enslavemnt to 802.1ad bridge not rejected" + + ip link set dev $swp1 master br0 2>&1 >/dev/null | grep -q mlxsw_spectrum + check_err $? "front panel with vlan upper enslavemnt to 802.1ad bridge rejected without extack" + + log_test "enslave front panel with vlan upper to 802.1ad bridge" + + ip link del dev $swp1.100 + ip link del dev br0 +} + +enslave_lag_with_vlan_upper_to_8021ad_bridge() +{ + RET=0 + + ip link add dev br0 type bridge vlan_filtering 1 \ + vlan_protocol 802.1ad vlan_default_pvid 0 mcast_snooping 0 + ip link set dev br0 addrgenmode none + ip link set dev br0 up + + ip link add name bond1 type bond mode 802.3ad + ip link set dev $swp1 down + ip link set dev $swp1 master bond1 + ip link add name bond1.100 link bond1 type vlan id 100 + + ip link set dev bond1 master br0 2>/dev/null + check_fail $? "lag with vlan upper enslavemnt to 802.1ad bridge not rejected" + + ip link set dev bond1 master br0 2>&1 >/dev/null \ + | grep -q mlxsw_spectrum + check_err $? "lag with vlan upper enslavemnt to 802.1ad bridge rejected without extack" + + log_test "enslave lag with vlan upper to 802.1ad bridge" + + ip link del dev bond1 + ip link del dev br0 +} + + +add_ip_address_to_8021ad_bridge() +{ + RET=0 + + ip link add dev br0 type bridge vlan_filtering 1 \ + vlan_protocol 802.1ad vlan_default_pvid 0 mcast_snooping 0 + ip link set dev br0 addrgenmode none + + ip link set dev br0 up + ip link set dev $swp1 master br0 + + ip addr add dev br0 192.0.2.17/28 2>/dev/null + check_fail $? "IP address addition to 802.1ad bridge not rejected" + + ip addr add dev br0 192.0.2.17/28 2>&1 >/dev/null | grep -q mlxsw_spectrum + check_err $? "IP address addition to 802.1ad bridge rejected without extack" + + log_test "IP address addition to 802.1ad bridge" + + ip link del dev br0 +} + +switch_bridge_protocol_from_8021q_to_8021ad() +{ + RET=0 + + ip link add dev br0 type bridge vlan_filtering 1 \ + vlan_protocol 802.1ad vlan_default_pvid 0 mcast_snooping 0 + ip link set dev br0 addrgenmode none + + ip link set dev br0 up + ip link set dev $swp1 master br0 + + ip link set dev br0 type bridge vlan_protocol 802.1q 2>/dev/null + check_fail $? "switching bridge protocol from 802.1q to 802.1ad not rejected" + + log_test "switch bridge protocol" + + ip link del dev br0 +} + + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_defprio.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_defprio.sh index 71066bc4b886..5492fa5550d7 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/qos_defprio.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_defprio.sh @@ -5,18 +5,18 @@ # prioritized according to the default priority specified at the port. # rx_octets_prio_* counters are used to verify the prioritization. # -# +-----------------------+ -# | H1 | -# | + $h1 | -# | | 192.0.2.1/28 | -# +----|------------------+ +# +----------------------------------+ +# | H1 | +# | + $h1 | +# | | 192.0.2.1/28 | +# +----|-----------------------------+ # | -# +----|------------------+ -# | SW | | -# | + $swp1 | -# | 192.0.2.2/28 | -# | APP=<prio>,1,0 | -# +-----------------------+ +# +----|-----------------------------+ +# | SW | | +# | + $swp1 | +# | 192.0.2.2/28 | +# | dcb app default-prio <prio> | +# +----------------------------------+ ALL_TESTS=" ping_ipv4 @@ -29,42 +29,6 @@ NUM_NETIFS=2 : ${HIT_TIMEOUT:=1000} # ms source $lib_dir/lib.sh -declare -a APP - -defprio_install() -{ - local dev=$1; shift - local prio=$1; shift - local app="app=$prio,1,0" - - lldptool -T -i $dev -V APP $app >/dev/null - lldpad_app_wait_set $dev - APP[$prio]=$app -} - -defprio_uninstall() -{ - local dev=$1; shift - local prio=$1; shift - local app=${APP[$prio]} - - lldptool -T -i $dev -V APP -d $app >/dev/null - lldpad_app_wait_del - unset APP[$prio] -} - -defprio_flush() -{ - local dev=$1; shift - local prio - - if ((${#APP[@]})); then - lldptool -T -i $dev -V APP -d ${APP[@]} >/dev/null - fi - lldpad_app_wait_del - APP=() -} - h1_create() { simple_if_init $h1 192.0.2.1/28 @@ -83,7 +47,7 @@ switch_create() switch_destroy() { - defprio_flush $swp1 + dcb app flush dev $swp1 default-prio ip addr del dev $swp1 192.0.2.2/28 ip link set dev $swp1 down } @@ -124,7 +88,7 @@ __test_defprio() RET=0 - defprio_install $swp1 $prio_install + dcb app add dev $swp1 default-prio $prio_install local t0=$(ethtool_stats_get $swp1 rx_frames_prio_$prio_observe) mausezahn -q $h1 -d 100m -c 10 -t arp reply @@ -134,7 +98,7 @@ __test_defprio() check_err $? "Default priority $prio_install/$prio_observe: Expected to capture 10 packets, got $((t1 - t0))." log_test "Default priority $prio_install/$prio_observe" - defprio_uninstall $swp1 $prio_install + dcb app del dev $swp1 default-prio $prio_install } test_defprio() @@ -145,7 +109,7 @@ test_defprio() __test_defprio $prio $prio done - defprio_install $swp1 3 + dcb app add dev $swp1 default-prio 3 __test_defprio 0 3 __test_defprio 1 3 __test_defprio 2 3 @@ -153,7 +117,7 @@ test_defprio() __test_defprio 5 5 __test_defprio 6 6 __test_defprio 7 7 - defprio_uninstall $swp1 3 + dcb app del dev $swp1 default-prio 3 } trap cleanup EXIT 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 5cbff8038f84..914c63d6318a 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh @@ -20,7 +20,7 @@ # | SW | | | # | +-|----------------------------------------------------------------|-+ | # | | + $swp1 BR $swp2 + | | -# | | APP=0,5,10 .. 7,5,17 APP=0,5,20 .. 7,5,27 | | +# | | dcb dscp-prio 10:0...17:7 dcb dscp-prio 20:0...27:7 | | # | +--------------------------------------------------------------------+ | # +---------------------------------------------------------------------------+ @@ -62,38 +62,28 @@ h2_destroy() simple_if_fini $h2 192.0.2.2/28 } -dscp_map() -{ - local base=$1; shift - local prio - - for prio in {0..7}; do - echo app=$prio,5,$((base + prio)) - done -} - switch_create() { ip link add name br1 type bridge vlan_filtering 1 + ip link set dev br1 addrgenmode none ip link set dev br1 up ip link set dev $swp1 master br1 ip link set dev $swp1 up ip link set dev $swp2 master br1 ip link set dev $swp2 up - lldptool -T -i $swp1 -V APP $(dscp_map 10) >/dev/null - lldptool -T -i $swp2 -V APP $(dscp_map 20) >/dev/null - lldpad_app_wait_set $swp1 - lldpad_app_wait_set $swp2 + dcb app add dev $swp1 dscp-prio 10:0 11:1 12:2 13:3 14:4 15:5 16:6 17:7 + dcb app add dev $swp2 dscp-prio 20:0 21:1 22:2 23:3 24:4 25:5 26:6 27:7 } switch_destroy() { - lldptool -T -i $swp2 -V APP -d $(dscp_map 20) >/dev/null - lldptool -T -i $swp1 -V APP -d $(dscp_map 10) >/dev/null - lldpad_app_wait_del + dcb app del dev $swp2 dscp-prio 20:0 21:1 22:2 23:3 24:4 25:5 26:6 27:7 + dcb app del dev $swp1 dscp-prio 10:0 11:1 12:2 13:3 14:4 15:5 16:6 17:7 + ip link set dev $swp2 down ip link set dev $swp2 nomaster + ip link set dev $swp1 down ip link set dev $swp1 nomaster ip link del dev br1 } 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 4cb2aa65278a..f6c23f84423e 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh @@ -94,16 +94,6 @@ h2_destroy() simple_if_fini $h2 192.0.2.18/28 } -dscp_map() -{ - local base=$1; shift - local prio - - for prio in {0..7}; do - echo app=$prio,5,$((base + prio)) - done -} - switch_create() { simple_if_init $swp1 192.0.2.2/28 @@ -112,17 +102,14 @@ switch_create() tc qdisc add dev $swp1 clsact tc qdisc add dev $swp2 clsact - lldptool -T -i $swp1 -V APP $(dscp_map 0) >/dev/null - lldptool -T -i $swp2 -V APP $(dscp_map 0) >/dev/null - lldpad_app_wait_set $swp1 - lldpad_app_wait_set $swp2 + dcb app add dev $swp1 dscp-prio 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 + dcb app add dev $swp2 dscp-prio 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 } switch_destroy() { - lldptool -T -i $swp2 -V APP -d $(dscp_map 0) >/dev/null - lldptool -T -i $swp1 -V APP -d $(dscp_map 0) >/dev/null - lldpad_app_wait_del + dcb app del dev $swp2 dscp-prio 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 + dcb app del dev $swp1 dscp-prio 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 tc qdisc del dev $swp2 clsact tc qdisc del dev $swp1 clsact @@ -265,13 +252,11 @@ test_dscp_leftover() { echo "Test that last removed DSCP rule is deconfigured correctly" - lldptool -T -i $swp2 -V APP -d $(dscp_map 0) >/dev/null - lldpad_app_wait_del + dcb app del dev $swp2 dscp-prio 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 __test_update 0 zero - lldptool -T -i $swp2 -V APP $(dscp_map 0) >/dev/null - lldpad_app_wait_set $swp2 + dcb app add dev $swp2 dscp-prio 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 } trap cleanup EXIT diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_ets_strict.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_ets_strict.sh index 6d1790b5de7a..fee74f215cec 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/qos_ets_strict.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_ets_strict.sh @@ -130,34 +130,48 @@ switch_create() ip link set dev $swp3 up mtu_set $swp3 10000 - ethtool -s $swp3 speed 1000 autoneg off + tc qdisc replace dev $swp3 root handle 101: tbf rate 1gbit \ + burst 128K limit 1G vlan_create $swp1 111 vlan_create $swp2 222 vlan_create $swp3 111 vlan_create $swp3 222 - ip link add name br111 up type bridge vlan_filtering 0 + ip link add name br111 type bridge vlan_filtering 0 + ip link set dev br111 addrgenmode none + ip link set dev br111 up ip link set dev $swp1.111 master br111 ip link set dev $swp3.111 master br111 - ip link add name br222 up type bridge vlan_filtering 0 + ip link add name br222 type bridge vlan_filtering 0 + ip link set dev br222 addrgenmode none + ip link set dev br222 up ip link set dev $swp2.222 master br222 ip link set dev $swp3.222 master br222 # Make sure that ingress quotas are smaller than egress so that there is # room for both streams of traffic to be admitted to shared buffer. + devlink_pool_size_thtype_save 0 devlink_pool_size_thtype_set 0 dynamic 10000000 + devlink_pool_size_thtype_save 4 devlink_pool_size_thtype_set 4 dynamic 10000000 + devlink_port_pool_th_save $swp1 0 devlink_port_pool_th_set $swp1 0 6 + devlink_tc_bind_pool_th_save $swp1 1 ingress devlink_tc_bind_pool_th_set $swp1 1 ingress 0 6 + devlink_port_pool_th_save $swp2 0 devlink_port_pool_th_set $swp2 0 6 + devlink_tc_bind_pool_th_save $swp2 2 ingress devlink_tc_bind_pool_th_set $swp2 2 ingress 0 6 + devlink_tc_bind_pool_th_save $swp3 1 egress devlink_tc_bind_pool_th_set $swp3 1 egress 4 7 + devlink_tc_bind_pool_th_save $swp3 2 egress devlink_tc_bind_pool_th_set $swp3 2 egress 4 7 + devlink_port_pool_th_save $swp3 4 devlink_port_pool_th_set $swp3 4 7 } @@ -184,7 +198,7 @@ switch_destroy() vlan_destroy $swp2 222 vlan_destroy $swp1 111 - ethtool -s $swp3 autoneg on + tc qdisc del dev $swp3 root handle 101: mtu_restore $swp3 ip link set dev $swp3 down lldptool -T -i $swp3 -V ETS-CFG up2tc=0:0,1:0,2:0,3:0,4:0,5:0,6:0,7:0 diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_headroom.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_headroom.sh new file mode 100755 index 000000000000..88162b4027c0 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_headroom.sh @@ -0,0 +1,379 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +ALL_TESTS=" + test_defaults + test_dcb_ets + test_mtu + test_pfc + test_int_buf + test_tc_priomap + test_tc_mtu + test_tc_sizes + test_tc_int_buf +" + +lib_dir=$(dirname $0)/../../../net/forwarding + +NUM_NETIFS=0 +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +swp=$NETIF_NO_CABLE + +cleanup() +{ + pre_cleanup +} + +get_prio_pg() +{ + # Produces a string of numbers "<B0> <B1> ... <B7> ", where BX is number + # of buffer that priority X is mapped to. + dcb -j buffer show dev $swp | + jq -r '[.prio_buffer | .[] | tostring + " "] | add' +} + +get_prio_pfc() +{ + # Produces a string of numbers "<P0> <P1> ... <P7> ", where PX denotes + # whether priority X has PFC enabled (the value is 1) or disabled (0). + dcb -j pfc show dev $swp | + jq -r '[.prio_pfc | .[] | if . then "1 " else "0 " end] | add' +} + +get_prio_tc() +{ + # Produces a string of numbers "<T0> <T1> ... <T7> ", where TC is number + # of TC that priority X is mapped to. + dcb -j ets show dev $swp | + jq -r '[.prio_tc | .[] | tostring + " "] | add' +} + +get_buf_size() +{ + local idx=$1; shift + + dcb -j buffer show dev $swp | jq ".buffer_size[$idx]" +} + +get_tot_size() +{ + dcb -j buffer show dev $swp | jq '.total_size' +} + +check_prio_pg() +{ + local expect=$1; shift + + local current=$(get_prio_pg) + test "$current" = "$expect" + check_err $? "prio2buffer is '$current', expected '$expect'" +} + +check_prio_pfc() +{ + local expect=$1; shift + + local current=$(get_prio_pfc) + test "$current" = "$expect" + check_err $? "prio PFC is '$current', expected '$expect'" +} + +check_prio_tc() +{ + local expect=$1; shift + + local current=$(get_prio_tc) + test "$current" = "$expect" + check_err $? "prio_tc is '$current', expected '$expect'" +} + +__check_buf_size() +{ + local idx=$1; shift + local expr=$1; shift + local what=$1; shift + + local current=$(get_buf_size $idx) + ((current $expr)) + check_err $? "${what}buffer $idx size is '$current', expected '$expr'" + echo $current +} + +check_buf_size() +{ + __check_buf_size "$@" > /dev/null +} + +test_defaults() +{ + RET=0 + + check_prio_pg "0 0 0 0 0 0 0 0 " + check_prio_tc "0 0 0 0 0 0 0 0 " + check_prio_pfc "0 0 0 0 0 0 0 0 " + + log_test "Default headroom configuration" +} + +test_dcb_ets() +{ + RET=0 + + dcb ets set dev $swp prio-tc 0:0 1:2 2:4 3:6 4:1 5:3 6:5 7:7 + + check_prio_pg "0 2 4 6 1 3 5 7 " + check_prio_tc "0 2 4 6 1 3 5 7 " + check_prio_pfc "0 0 0 0 0 0 0 0 " + + dcb ets set dev $swp prio-tc all:0 + + check_prio_pg "0 0 0 0 0 0 0 0 " + check_prio_tc "0 0 0 0 0 0 0 0 " + + dcb buffer set dev $swp prio-buffer 0:1 1:3 2:5 3:7 4:0 5:2 6:4 7:6 2>/dev/null + check_fail $? "prio2buffer accepted in DCB mode" + + log_test "Configuring headroom through ETS" +} + +test_mtu() +{ + local what=$1; shift + local buf0size_2 + local buf0size + + RET=0 + buf0size=$(__check_buf_size 0 "> 0") + + mtu_set $swp 3000 + buf0size_2=$(__check_buf_size 0 "> $buf0size" "MTU 3000: ") + mtu_restore $swp + + mtu_set $swp 6000 + check_buf_size 0 "> $buf0size_2" "MTU 6000: " + mtu_restore $swp + + check_buf_size 0 "== $buf0size" + + log_test "${what}MTU impacts buffer size" +} + +test_tc_mtu() +{ + # In TC mode, MTU still impacts the threshold below which a buffer is + # not permitted to go. + + tc qdisc replace dev $swp root handle 1: bfifo limit 1.5M + test_mtu "TC: " + tc qdisc delete dev $swp root +} + +test_pfc() +{ + RET=0 + + dcb ets set dev $swp prio-tc all:0 5:1 6:2 7:3 + + local buf0size=$(get_buf_size 0) + local buf1size=$(get_buf_size 1) + local buf2size=$(get_buf_size 2) + local buf3size=$(get_buf_size 3) + check_buf_size 0 "> 0" + check_buf_size 1 "> 0" + check_buf_size 2 "> 0" + check_buf_size 3 "> 0" + check_buf_size 4 "== 0" + check_buf_size 5 "== 0" + check_buf_size 6 "== 0" + check_buf_size 7 "== 0" + + log_test "Buffer size sans PFC" + + RET=0 + + dcb pfc set dev $swp prio-pfc all:off 5:on 6:on 7:on delay 0 + + check_prio_pg "0 0 0 0 0 1 2 3 " + check_prio_pfc "0 0 0 0 0 1 1 1 " + check_buf_size 0 "== $buf0size" + check_buf_size 1 "> $buf1size" + check_buf_size 2 "> $buf2size" + check_buf_size 3 "> $buf3size" + + local buf1size=$(get_buf_size 1) + check_buf_size 2 "== $buf1size" + check_buf_size 3 "== $buf1size" + + log_test "PFC: Cable length 0" + + RET=0 + + dcb pfc set dev $swp delay 1000 + + check_buf_size 0 "== $buf0size" + check_buf_size 1 "> $buf1size" + check_buf_size 2 "> $buf1size" + check_buf_size 3 "> $buf1size" + + log_test "PFC: Cable length 1000" + + RET=0 + + dcb pfc set dev $swp prio-pfc all:off delay 0 + dcb ets set dev $swp prio-tc all:0 + + check_prio_pg "0 0 0 0 0 0 0 0 " + check_prio_tc "0 0 0 0 0 0 0 0 " + check_buf_size 0 "> 0" + check_buf_size 1 "== 0" + check_buf_size 2 "== 0" + check_buf_size 3 "== 0" + check_buf_size 4 "== 0" + check_buf_size 5 "== 0" + check_buf_size 6 "== 0" + check_buf_size 7 "== 0" + + log_test "PFC: Restore defaults" +} + +test_tc_priomap() +{ + RET=0 + + dcb ets set dev $swp prio-tc 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 + check_prio_pg "0 1 2 3 4 5 6 7 " + + tc qdisc replace dev $swp root handle 1: bfifo limit 1.5M + check_prio_pg "0 0 0 0 0 0 0 0 " + + dcb buffer set dev $swp prio-buffer 0:1 1:3 2:5 3:7 4:0 5:2 6:4 7:6 + check_prio_pg "1 3 5 7 0 2 4 6 " + + tc qdisc delete dev $swp root + check_prio_pg "0 1 2 3 4 5 6 7 " + + # Clean up. + tc qdisc replace dev $swp root handle 1: bfifo limit 1.5M + dcb buffer set dev $swp prio-buffer all:0 + tc qdisc delete dev $swp root + dcb ets set dev $swp prio-tc all:0 + + log_test "TC: priomap" +} + +test_tc_sizes() +{ + local cell_size=$(devlink_cell_size_get) + local size=$((cell_size * 1000)) + + RET=0 + + dcb buffer set dev $swp buffer-size all:0 0:$size 2>/dev/null + check_fail $? "buffer_size should fail before qdisc is added" + + tc qdisc replace dev $swp root handle 1: bfifo limit 1.5M + + dcb buffer set dev $swp buffer-size all:0 0:$size + check_err $? "buffer_size should pass after qdisc is added" + check_buf_size 0 "== $size" "set size: " + + mtu_set $swp 6000 + check_buf_size 0 "== $size" "set MTU: " + mtu_restore $swp + + dcb buffer set dev $swp buffer-size all:0 + + # After replacing the qdisc for the same kind, buffer_size still has to + # work. + tc qdisc replace dev $swp root handle 1: bfifo limit 1M + + dcb buffer set dev $swp buffer-size all:0 0:$size + check_buf_size 0 "== $size" "post replace, set size: " + + dcb buffer set dev $swp buffer-size all:0 + + # Likewise after replacing for a different kind. + tc qdisc replace dev $swp root handle 2: prio bands 8 + + dcb buffer set dev $swp buffer-size all:0 0:$size + check_buf_size 0 "== $size" "post replace different kind, set size: " + + tc qdisc delete dev $swp root + + dcb buffer set dev $swp buffer-size all:0 0:$size 2>/dev/null + check_fail $? "buffer_size should fail after qdisc is deleted" + + log_test "TC: buffer size" +} + +test_int_buf() +{ + local what=$1; shift + + RET=0 + + local buf0size=$(get_buf_size 0) + local tot_size=$(get_tot_size) + + # Size of internal buffer and buffer 9. + local dsize=$((tot_size - buf0size)) + + tc qdisc add dev $swp clsact + tc filter add dev $swp egress matchall skip_sw action mirred egress mirror dev $swp + + local buf0size_2=$(get_buf_size 0) + local tot_size_2=$(get_tot_size) + local dsize_2=$((tot_size_2 - buf0size_2)) + + # Egress SPAN should have added to the "invisible" buffer configuration. + ((dsize_2 > dsize)) + check_err $? "Invisible buffers account for '$dsize_2', expected '> $dsize'" + + mtu_set $swp 3000 + + local buf0size_3=$(get_buf_size 0) + local tot_size_3=$(get_tot_size) + local dsize_3=$((tot_size_3 - buf0size_3)) + + # MTU change might change buffer 0, which will show at total, but the + # hidden buffers should stay the same size. + ((dsize_3 == dsize_2)) + check_err $? "MTU change: Invisible buffers account for '$dsize_3', expected '== $dsize_2'" + + mtu_restore $swp + tc qdisc del dev $swp clsact + + # After SPAN removal, hidden buffers should be back to the original sizes. + local buf0size_4=$(get_buf_size 0) + local tot_size_4=$(get_tot_size) + local dsize_4=$((tot_size_4 - buf0size_4)) + ((dsize_4 == dsize)) + check_err $? "SPAN removed: Invisible buffers account for '$dsize_4', expected '== $dsize'" + + log_test "${what}internal buffer size" +} + +test_tc_int_buf() +{ + local cell_size=$(devlink_cell_size_get) + local size=$((cell_size * 1000)) + + tc qdisc replace dev $swp root handle 1: bfifo limit 1.5M + test_int_buf "TC: " + + dcb buffer set dev $swp buffer-size all:0 0:$size + test_int_buf "TC+buffsize: " + + dcb buffer set dev $swp buffer-size all:0 + tc qdisc delete dev $swp root +} + +bail_on_lldpad "configure DCB" "configure Qdiscs" + +trap cleanup EXIT +setup_wait +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_lib.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_lib.sh index faa51012cdac..5ad092b9bf10 100644 --- a/tools/testing/selftests/drivers/net/mlxsw/qos_lib.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_lib.sh @@ -54,31 +54,3 @@ measure_rate() echo $ir $er return $ret } - -bail_on_lldpad() -{ - if systemctl is-active --quiet lldpad; then - - cat >/dev/stderr <<-EOF - WARNING: lldpad is running - - lldpad will likely configure DCB, and this test will - configure Qdiscs. mlxsw does not support both at the - same time, one of them is arbitrarily going to overwrite - the other. That will cause spurious failures (or, - unlikely, passes) of this test. - EOF - - if [[ -z $ALLOW_LLDPAD ]]; then - cat >/dev/stderr <<-EOF - - If you want to run the test anyway, please set - an environment variable ALLOW_LLDPAD to a - non-empty string. - EOF - exit 1 - else - return - fi - fi -} diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_max_descriptors.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_max_descriptors.sh new file mode 100755 index 000000000000..5ac4f795e333 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_max_descriptors.sh @@ -0,0 +1,282 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# This test sends many small packets (size is less than cell size) through the +# switch. A shaper is used in $swp2, so the traffic is limited there. Packets +# are queued till they will be sent. +# +# The idea is to verify that the switch can handle at least 85% of maximum +# supported descrpitors by hardware. Then, we verify that the driver configures +# firmware to allow infinite size of egress descriptor pool, and does not use a +# lower limitation. Increase the size of the relevant pools such that the pool's +# size does not limit the traffic. + +# +-----------------------+ +# | H1 | +# | + $h1.111 | +# | | 192.0.2.33/28 | +# | | | +# | + $h1 | +# +---|-------------------+ +# | +# +---|-----------------------------+ +# | + $swp1 | +# | | iPOOL1 | +# | | | +# | +-|------------------------+ | +# | | + $swp1.111 | | +# | | | | +# | | BR1 | | +# | | | | +# | | + $swp2.111 | | +# | +-|------------------------+ | +# | | | +# | + $swp2 | +# | | ePOOL6 | +# | | 1mbit | +# +---+-----------------------------+ +# | +# +---|-------------------+ +# | + $h2 H2 | +# | | | +# | + $h2.111 | +# | 192.0.2.34/28 | +# +-----------------------+ +# + +ALL_TESTS=" + ping_ipv4 + max_descriptors +" + +lib_dir=$(dirname $0)/../../../net/forwarding + +NUM_NETIFS=4 +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh +source mlxsw_lib.sh + +MAX_POOL_SIZE=$(devlink_pool_size_get) +SHAPER_RATE=1mbit + +# The current TBF qdisc interface does not allow us to configure the shaper to +# flat zero. The ASIC shaper is guaranteed to work with a granularity of +# 200Mbps. On Spectrum-2, writing a value close to zero instead of zero works +# well, but the performance on Spectrum-1 is unpredictable. Thus, do not run the +# test on Spectrum-1. +mlxsw_only_on_spectrum 2+ || exit + +h1_create() +{ + simple_if_init $h1 + + vlan_create $h1 111 v$h1 192.0.2.33/28 + ip link set dev $h1.111 type vlan egress-qos-map 0:1 +} + +h1_destroy() +{ + vlan_destroy $h1 111 + + simple_if_fini $h1 +} + +h2_create() +{ + simple_if_init $h2 + + vlan_create $h2 111 v$h2 192.0.2.34/28 +} + +h2_destroy() +{ + vlan_destroy $h2 111 + + simple_if_fini $h2 +} + +switch_create() +{ + # pools + # ----- + + devlink_pool_size_thtype_save 1 + devlink_pool_size_thtype_save 6 + + devlink_port_pool_th_save $swp1 1 + devlink_port_pool_th_save $swp2 6 + + devlink_tc_bind_pool_th_save $swp1 1 ingress + devlink_tc_bind_pool_th_save $swp2 1 egress + + devlink_pool_size_thtype_set 1 dynamic $MAX_POOL_SIZE + devlink_pool_size_thtype_set 6 static $MAX_POOL_SIZE + + # $swp1 + # ----- + + ip link set dev $swp1 up + vlan_create $swp1 111 + ip link set dev $swp1.111 type vlan ingress-qos-map 0:0 1:1 + + devlink_port_pool_th_set $swp1 1 16 + devlink_tc_bind_pool_th_set $swp1 1 ingress 1 16 + + tc qdisc replace dev $swp1 root handle 1: \ + ets bands 8 strict 8 priomap 7 6 + dcb buffer set dev $swp1 prio-buffer all:0 1:1 + + # $swp2 + # ----- + + ip link set dev $swp2 up + vlan_create $swp2 111 + ip link set dev $swp2.111 type vlan egress-qos-map 0:0 1:1 + + devlink_port_pool_th_set $swp2 6 $MAX_POOL_SIZE + devlink_tc_bind_pool_th_set $swp2 1 egress 6 $MAX_POOL_SIZE + + tc qdisc replace dev $swp2 root handle 1: tbf rate $SHAPER_RATE \ + burst 128K limit 500M + tc qdisc replace dev $swp2 parent 1:1 handle 11: \ + ets bands 8 strict 8 priomap 7 6 + + # bridge + # ------ + + ip link add name br1 type bridge vlan_filtering 0 + ip link set dev $swp1.111 master br1 + ip link set dev br1 up + + ip link set dev $swp2.111 master br1 +} + +switch_destroy() +{ + # Do this first so that we can reset the limits to values that are only + # valid for the original static / dynamic setting. + devlink_pool_size_thtype_restore 6 + devlink_pool_size_thtype_restore 1 + + # bridge + # ------ + + ip link set dev $swp2.111 nomaster + + ip link set dev br1 down + ip link set dev $swp1.111 nomaster + ip link del dev br1 + + # $swp2 + # ----- + + tc qdisc del dev $swp2 parent 1:1 handle 11: + tc qdisc del dev $swp2 root + + devlink_tc_bind_pool_th_restore $swp2 1 egress + devlink_port_pool_th_restore $swp2 6 + + vlan_destroy $swp2 111 + ip link set dev $swp2 down + + # $swp1 + # ----- + + dcb buffer set dev $swp1 prio-buffer all:0 + tc qdisc del dev $swp1 root + + devlink_tc_bind_pool_th_restore $swp1 1 ingress + devlink_port_pool_th_restore $swp1 1 + + vlan_destroy $swp1 111 + ip link set dev $swp1 down +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + swp2=${NETIFS[p3]} + h2=${NETIFS[p4]} + + h2mac=$(mac_get $h2) + + vrf_prepare + + h1_create + h2_create + switch_create +} + +cleanup() +{ + pre_cleanup + + switch_destroy + h2_destroy + h1_destroy + + vrf_cleanup +} + +ping_ipv4() +{ + ping_test $h1 192.0.2.34 " h1->h2" +} + +percentage_used() +{ + local num_packets=$1; shift + local max_packets=$1; shift + + bc <<< " + scale=2 + 100 * $num_packets / $max_packets + " +} + +max_descriptors() +{ + local cell_size=$(devlink_cell_size_get) + local exp_perc_used=85 + local max_descriptors + local pktsize=30 + + RET=0 + + max_descriptors=$(mlxsw_max_descriptors_get) || exit 1 + + local d0=$(ethtool_stats_get $swp2 tc_no_buffer_discard_uc_tc_1) + + log_info "Send many small packets, packet size = $pktsize bytes" + start_traffic_pktsize $pktsize $h1.111 192.0.2.33 192.0.2.34 $h2mac + + # Sleep to wait for congestion. + sleep 5 + + local d1=$(ethtool_stats_get $swp2 tc_no_buffer_discard_uc_tc_1) + ((d1 == d0)) + check_err $? "Drops seen on egress port: $d0 -> $d1 ($((d1 - d0)))" + + # Check how many packets the switch can handle, the limitation is + # maximum descriptors. + local pkts_bytes=$(ethtool_stats_get $swp2 tc_transmit_queue_tc_1) + local pkts_num=$((pkts_bytes / cell_size)) + local perc_used=$(percentage_used $pkts_num $max_descriptors) + + check_err $(bc <<< "$perc_used < $exp_perc_used") \ + "Expected > $exp_perc_used% of descriptors, handle $perc_used%" + + stop_traffic + sleep 1 + + log_test "Maximum descriptors usage. The percentage used is $perc_used%" +} + +trap cleanup EXIT +setup_prepare +setup_wait +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_mc_aware.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_mc_aware.sh index b025daea062d..6d892de43fa8 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/qos_mc_aware.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_mc_aware.sh @@ -129,28 +129,36 @@ switch_create() vlan_create $swp2 111 vlan_create $swp3 111 - ethtool -s $swp3 speed 1000 autoneg off - tc qdisc replace dev $swp3 root handle 3: \ - prio bands 8 priomap 7 7 7 7 7 7 7 7 + tc qdisc replace dev $swp3 root handle 3: tbf rate 1gbit \ + burst 128K limit 1G + tc qdisc replace dev $swp3 parent 3:3 handle 33: \ + prio bands 8 priomap 7 7 7 7 7 7 7 7 ip link add name br1 type bridge vlan_filtering 0 + ip link set dev br1 addrgenmode none ip link set dev br1 up ip link set dev $swp1 master br1 ip link set dev $swp3 master br1 ip link add name br111 type bridge vlan_filtering 0 + ip link set dev br111 addrgenmode none ip link set dev br111 up ip link set dev $swp2.111 master br111 ip link set dev $swp3.111 master br111 # Make sure that ingress quotas are smaller than egress so that there is # room for both streams of traffic to be admitted to shared buffer. + devlink_port_pool_th_save $swp1 0 devlink_port_pool_th_set $swp1 0 5 + devlink_tc_bind_pool_th_save $swp1 0 ingress devlink_tc_bind_pool_th_set $swp1 0 ingress 0 5 + devlink_port_pool_th_save $swp2 0 devlink_port_pool_th_set $swp2 0 5 + devlink_tc_bind_pool_th_save $swp2 1 ingress devlink_tc_bind_pool_th_set $swp2 1 ingress 0 5 + devlink_port_pool_th_save $swp3 4 devlink_port_pool_th_set $swp3 4 12 } @@ -167,8 +175,8 @@ switch_destroy() ip link del dev br111 ip link del dev br1 + tc qdisc del dev $swp3 parent 3:3 handle 33: tc qdisc del dev $swp3 root handle 3: - ethtool -s $swp3 autoneg on vlan_destroy $swp3 111 vlan_destroy $swp2 111 diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh new file mode 100755 index 000000000000..0f0f4f05807c --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh @@ -0,0 +1,417 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# This test injects a 10-MB burst of traffic with VLAN tag and 802.1p priority +# of 1. This stream is consistently prioritized as priority 1, is put to PG +# buffer 1, and scheduled at TC 1. +# +# - the stream first ingresses through $swp1, where it is forwarded to $swp3 +# +# - then it ingresses through $swp4. Here it is put to a lossless buffer and put +# to a small pool ("PFC pool"). The traffic is forwarded to $swp2, which is +# shaped, and thus the PFC pool eventually fills, therefore the headroom +# fills, and $swp3 is paused. +# +# - since $swp3 now can't send traffic, the traffic ingressing $swp1 is kept at +# a pool ("overflow pool"). The overflow pool needs to be large enough to +# contain the whole burst. +# +# - eventually the PFC pool gets some traffic out, headroom therefore gets some +# traffic to the pool, and $swp3 is unpaused again. This way the traffic is +# gradually forwarded from the overflow pool, through the PFC pool, out of +# $swp2, and eventually to $h2. +# +# - if PFC works, all lossless flow packets that ingress through $swp1 should +# also be seen ingressing $h2. If it doesn't, there will be drops due to +# discrepancy between the speeds of $swp1 and $h2. +# +# - it should all play out relatively quickly, so that SLL and HLL will not +# cause drops. +# +# +-----------------------+ +# | H1 | +# | + $h1.111 | +# | | 192.0.2.33/28 | +# | | | +# | + $h1 | +# +---|-------------------+ +--------------------+ +# | | | +# +---|----------------------|--------------------|---------------------------+ +# | + $swp1 $swp3 + + $swp4 | +# | | iPOOL1 iPOOL0 | | iPOOL2 | +# | | ePOOL4 ePOOL5 | | ePOOL4 | +# | | PFC:enabled=1 | | PFC:enabled=1 | +# | +-|----------------------|-+ +-|------------------------+ | +# | | + $swp1.111 $swp3.111 + | | + $swp4.111 | | +# | | | | | | +# | | BR1 | | BR2 | | +# | | | | | | +# | | | | + $swp2.111 | | +# | +--------------------------+ +---------|----------------+ | +# | | | +# | iPOOL0: 500KB dynamic | | +# | iPOOL1: 10MB static | | +# | iPOOL2: 1MB static + $swp2 | +# | ePOOL4: 500KB dynamic | iPOOL0 | +# | ePOOL5: 10MB static | ePOOL6 | +# | ePOOL6: "infinite" static | 200Mbps shaper | +# +-------------------------------------------------------|-------------------+ +# | +# +---|-------------------+ +# | + $h2 H2 | +# | | | +# | + $h2.111 | +# | 192.0.2.34/28 | +# +-----------------------+ +# +# iPOOL0+ePOOL4 is a helper pool for control traffic etc. +# iPOOL1+ePOOL5 are overflow pools. +# iPOOL2+ePOOL6 are PFC pools. + +ALL_TESTS=" + ping_ipv4 + test_qos_pfc +" + +lib_dir=$(dirname $0)/../../../net/forwarding + +NUM_NETIFS=6 +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +_1KB=1000 +_100KB=$((100 * _1KB)) +_500KB=$((500 * _1KB)) +_1MB=$((1000 * _1KB)) +_10MB=$((10 * _1MB)) + +h1_create() +{ + simple_if_init $h1 + mtu_set $h1 10000 + + vlan_create $h1 111 v$h1 192.0.2.33/28 +} + +h1_destroy() +{ + vlan_destroy $h1 111 + + mtu_restore $h1 + simple_if_fini $h1 +} + +h2_create() +{ + simple_if_init $h2 + mtu_set $h2 10000 + + vlan_create $h2 111 v$h2 192.0.2.34/28 +} + +h2_destroy() +{ + vlan_destroy $h2 111 + + mtu_restore $h2 + simple_if_fini $h2 +} + +switch_create() +{ + local lanes_swp4 + local pg1_size + + # pools + # ----- + + devlink_pool_size_thtype_save 0 + devlink_pool_size_thtype_save 4 + devlink_pool_size_thtype_save 1 + devlink_pool_size_thtype_save 5 + devlink_pool_size_thtype_save 2 + devlink_pool_size_thtype_save 6 + + devlink_port_pool_th_save $swp1 1 + devlink_port_pool_th_save $swp2 6 + devlink_port_pool_th_save $swp3 5 + devlink_port_pool_th_save $swp4 2 + + devlink_tc_bind_pool_th_save $swp1 1 ingress + devlink_tc_bind_pool_th_save $swp2 1 egress + devlink_tc_bind_pool_th_save $swp3 1 egress + devlink_tc_bind_pool_th_save $swp4 1 ingress + + # Control traffic pools. Just reduce the size. Keep them dynamic so that + # we don't need to change all the uninteresting quotas. + devlink_pool_size_thtype_set 0 dynamic $_500KB + devlink_pool_size_thtype_set 4 dynamic $_500KB + + # Overflow pools. + devlink_pool_size_thtype_set 1 static $_10MB + devlink_pool_size_thtype_set 5 static $_10MB + + # PFC pools. As per the writ, the size of egress PFC pool should be + # infinice, but actually it just needs to be large enough to not matter + # in practice, so reuse the 10MB limit. + devlink_pool_size_thtype_set 2 static $_1MB + devlink_pool_size_thtype_set 6 static $_10MB + + # $swp1 + # ----- + + ip link set dev $swp1 up + mtu_set $swp1 10000 + vlan_create $swp1 111 + ip link set dev $swp1.111 type vlan ingress-qos-map 0:0 1:1 + + devlink_port_pool_th_set $swp1 1 $_10MB + devlink_tc_bind_pool_th_set $swp1 1 ingress 1 $_10MB + + # Configure qdisc so that we can configure PG and therefore pool + # assignment. + tc qdisc replace dev $swp1 root handle 1: \ + ets bands 8 strict 8 priomap 7 6 + dcb buffer set dev $swp1 prio-buffer all:0 1:1 + + # $swp2 + # ----- + + ip link set dev $swp2 up + mtu_set $swp2 10000 + vlan_create $swp2 111 + ip link set dev $swp2.111 type vlan egress-qos-map 0:0 1:1 + + devlink_port_pool_th_set $swp2 6 $_10MB + devlink_tc_bind_pool_th_set $swp2 1 egress 6 $_10MB + + # prio 0->TC0 (band 7), 1->TC1 (band 6). TC1 is shaped. + tc qdisc replace dev $swp2 root handle 1: \ + ets bands 8 strict 8 priomap 7 6 + tc qdisc replace dev $swp2 parent 1:7 handle 17: \ + tbf rate 200Mbit burst 131072 limit 1M + + # $swp3 + # ----- + + ip link set dev $swp3 up + mtu_set $swp3 10000 + vlan_create $swp3 111 + ip link set dev $swp3.111 type vlan egress-qos-map 0:0 1:1 + + devlink_port_pool_th_set $swp3 5 $_10MB + devlink_tc_bind_pool_th_set $swp3 1 egress 5 $_10MB + + # prio 0->TC0 (band 7), 1->TC1 (band 6) + tc qdisc replace dev $swp3 root handle 1: \ + ets bands 8 strict 8 priomap 7 6 + + # Need to enable PFC so that PAUSE takes effect. Therefore need to put + # the lossless prio into a buffer of its own. Don't bother with buffer + # sizes though, there is not going to be any pressure in the "backward" + # direction. + dcb buffer set dev $swp3 prio-buffer all:0 1:1 + dcb pfc set dev $swp3 prio-pfc all:off 1:on + + # $swp4 + # ----- + + ip link set dev $swp4 up + mtu_set $swp4 10000 + vlan_create $swp4 111 + ip link set dev $swp4.111 type vlan ingress-qos-map 0:0 1:1 + + devlink_port_pool_th_set $swp4 2 $_1MB + devlink_tc_bind_pool_th_set $swp4 1 ingress 2 $_1MB + + # Configure qdisc so that we can hand-tune headroom. + tc qdisc replace dev $swp4 root handle 1: \ + ets bands 8 strict 8 priomap 7 6 + dcb buffer set dev $swp4 prio-buffer all:0 1:1 + dcb pfc set dev $swp4 prio-pfc all:off 1:on + # PG0 will get autoconfigured to Xoff, give PG1 arbitrarily 100K, which + # is (-2*MTU) about 80K of delay provision. + pg1_size=$_100KB + + setup_wait_dev_with_timeout $swp4 + + lanes_swp4=$(ethtool $swp4 | grep 'Lanes:') + lanes_swp4=${lanes_swp4#*"Lanes: "} + + # 8-lane ports use two buffers among which the configured buffer + # is split, so double the size to get twice (20K + 80K). + if [[ $lanes_swp4 -eq 8 ]]; then + pg1_size=$((pg1_size * 2)) + fi + + dcb buffer set dev $swp4 buffer-size all:0 1:$pg1_size + + # bridges + # ------- + + ip link add name br1 type bridge vlan_filtering 0 + ip link set dev $swp1.111 master br1 + ip link set dev $swp3.111 master br1 + ip link set dev br1 up + + ip link add name br2 type bridge vlan_filtering 0 + ip link set dev $swp2.111 master br2 + ip link set dev $swp4.111 master br2 + ip link set dev br2 up +} + +switch_destroy() +{ + # Do this first so that we can reset the limits to values that are only + # valid for the original static / dynamic setting. + devlink_pool_size_thtype_restore 6 + devlink_pool_size_thtype_restore 5 + devlink_pool_size_thtype_restore 4 + devlink_pool_size_thtype_restore 2 + devlink_pool_size_thtype_restore 1 + devlink_pool_size_thtype_restore 0 + + # bridges + # ------- + + ip link set dev br2 down + ip link set dev $swp4.111 nomaster + ip link set dev $swp2.111 nomaster + ip link del dev br2 + + ip link set dev br1 down + ip link set dev $swp3.111 nomaster + ip link set dev $swp1.111 nomaster + ip link del dev br1 + + # $swp4 + # ----- + + dcb buffer set dev $swp4 buffer-size all:0 + dcb pfc set dev $swp4 prio-pfc all:off + dcb buffer set dev $swp4 prio-buffer all:0 + tc qdisc del dev $swp4 root + + devlink_tc_bind_pool_th_restore $swp4 1 ingress + devlink_port_pool_th_restore $swp4 2 + + vlan_destroy $swp4 111 + mtu_restore $swp4 + ip link set dev $swp4 down + + # $swp3 + # ----- + + dcb pfc set dev $swp3 prio-pfc all:off + dcb buffer set dev $swp3 prio-buffer all:0 + tc qdisc del dev $swp3 root + + devlink_tc_bind_pool_th_restore $swp3 1 egress + devlink_port_pool_th_restore $swp3 5 + + vlan_destroy $swp3 111 + mtu_restore $swp3 + ip link set dev $swp3 down + + # $swp2 + # ----- + + tc qdisc del dev $swp2 parent 1:7 + tc qdisc del dev $swp2 root + + devlink_tc_bind_pool_th_restore $swp2 1 egress + devlink_port_pool_th_restore $swp2 6 + + vlan_destroy $swp2 111 + mtu_restore $swp2 + ip link set dev $swp2 down + + # $swp1 + # ----- + + dcb buffer set dev $swp1 prio-buffer all:0 + tc qdisc del dev $swp1 root + + devlink_tc_bind_pool_th_restore $swp1 1 ingress + devlink_port_pool_th_restore $swp1 1 + + vlan_destroy $swp1 111 + mtu_restore $swp1 + ip link set dev $swp1 down +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + swp2=${NETIFS[p3]} + h2=${NETIFS[p4]} + + swp3=${NETIFS[p5]} + swp4=${NETIFS[p6]} + + h2mac=$(mac_get $h2) + + vrf_prepare + + h1_create + h2_create + switch_create +} + +cleanup() +{ + pre_cleanup + + switch_destroy + h2_destroy + h1_destroy + + vrf_cleanup +} + +ping_ipv4() +{ + ping_test $h1 192.0.2.34 +} + +test_qos_pfc() +{ + RET=0 + + # 10M pool, each packet is 8K of payload + headers + local pkts=$((_10MB / 8050)) + local size=$((pkts * 8050)) + local in0=$(ethtool_stats_get $swp1 rx_octets_prio_1) + local out0=$(ethtool_stats_get $swp2 tx_octets_prio_1) + + $MZ $h1 -p 8000 -Q 1:111 -A 192.0.2.33 -B 192.0.2.34 \ + -a own -b $h2mac -c $pkts -t udp -q + sleep 2 + + local in1=$(ethtool_stats_get $swp1 rx_octets_prio_1) + local out1=$(ethtool_stats_get $swp2 tx_octets_prio_1) + + local din=$((in1 - in0)) + local dout=$((out1 - out0)) + + local pct_in=$((din * 100 / size)) + + ((pct_in > 95 && pct_in < 105)) + check_err $? "Relative ingress out of expected bounds, $pct_in% should be 100%" + + ((dout == din)) + check_err $? "$((din - dout)) bytes out of $din ingressed got lost" + + log_test "PFC" +} + +bail_on_lldpad "configure DCB" "configure Qdiscs" + +trap cleanup EXIT +setup_prepare +setup_wait +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/rif_bridge.sh b/tools/testing/selftests/drivers/net/mlxsw/rif_bridge.sh new file mode 100755 index 000000000000..b79542a4dcc7 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/rif_bridge.sh @@ -0,0 +1,183 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + bridge_rif_add + bridge_rif_nomaster + bridge_rif_remaster + bridge_rif_nomaster_addr + bridge_rif_nomaster_port + bridge_rif_remaster_port +" + +NUM_NETIFS=2 +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +setup_prepare() +{ + swp1=${NETIFS[p1]} + swp2=${NETIFS[p2]} + + team_create lag1 lacp + ip link set dev lag1 addrgenmode none + ip link set dev lag1 address $(mac_get $swp1) + + team_create lag2 lacp + ip link set dev lag2 addrgenmode none + ip link set dev lag2 address $(mac_get $swp2) + + ip link add name br1 type bridge vlan_filtering 1 + ip link set dev br1 addrgenmode none + ip link set dev br1 address $(mac_get lag1) + ip link set dev br1 up + + ip link set dev lag1 master br1 + + ip link set dev $swp1 master lag1 + ip link set dev $swp1 up + + ip link set dev $swp2 master lag2 + ip link set dev $swp2 up +} + +cleanup() +{ + pre_cleanup + + ip link set dev $swp2 nomaster + ip link set dev $swp2 down + + ip link set dev $swp1 nomaster + ip link set dev $swp1 down + + ip link del dev lag2 + ip link set dev lag1 nomaster + ip link del dev lag1 + + ip link del dev br1 +} + +bridge_rif_add() +{ + RET=0 + + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + __addr_add_del br1 add 192.0.2.2/28 + sleep 1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0 + 1)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + log_test "Add RIF for bridge on address addition" +} + +bridge_rif_nomaster() +{ + RET=0 + + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + ip link set dev lag1 nomaster + sleep 1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0 - 1)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + log_test "Drop RIF for bridge on LAG deslavement" +} + +bridge_rif_remaster() +{ + RET=0 + + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + ip link set dev lag1 master br1 + sleep 1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0 + 1)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + log_test "Add RIF for bridge on LAG reenslavement" +} + +bridge_rif_nomaster_addr() +{ + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + + # Adding an address while the LAG is enslaved shouldn't generate a RIF. + __addr_add_del lag1 add 192.0.2.65/28 + sleep 1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "After adding IP: Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + # Removing the LAG from the bridge should drop RIF for the bridge (as + # tested in bridge_rif_lag_nomaster), but since the LAG now has an + # address, it should gain a RIF. + ip link set dev lag1 nomaster + sleep 1 + local rifs_occ_t2=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0)) + + ((expected_rifs == rifs_occ_t2)) + check_err $? "After deslaving: Expected $expected_rifs RIFs, $rifs_occ_t2 are used" + + log_test "Add RIF for LAG on deslavement from bridge" + + __addr_add_del lag1 del 192.0.2.65/28 + ip link set dev lag1 master br1 + sleep 1 +} + +bridge_rif_nomaster_port() +{ + RET=0 + + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + ip link set dev $swp1 nomaster + sleep 1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0 - 1)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + log_test "Drop RIF for bridge on deslavement of port from LAG" +} + +bridge_rif_remaster_port() +{ + RET=0 + + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + ip link set dev $swp1 down + ip link set dev $swp1 master lag1 + ip link set dev $swp1 up + setup_wait_dev $swp1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0 + 1)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + log_test "Add RIF for bridge on reenslavement of port to LAG" +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/rif_counter_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/rif_counter_scale.sh new file mode 100644 index 000000000000..a43a9926e690 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/rif_counter_scale.sh @@ -0,0 +1,107 @@ +# SPDX-License-Identifier: GPL-2.0 + +RIF_COUNTER_NUM_NETIFS=2 + +rif_counter_addr4() +{ + local i=$1; shift + local p=$1; shift + + printf 192.0.%d.%d $((i / 64)) $(((4 * i % 256) + p)) +} + +rif_counter_addr4pfx() +{ + rif_counter_addr4 $@ + printf /30 +} + +rif_counter_h1_create() +{ + simple_if_init $h1 +} + +rif_counter_h1_destroy() +{ + simple_if_fini $h1 +} + +rif_counter_h2_create() +{ + simple_if_init $h2 +} + +rif_counter_h2_destroy() +{ + simple_if_fini $h2 +} + +rif_counter_setup_prepare() +{ + h1=${NETIFS[p1]} + h2=${NETIFS[p2]} + + vrf_prepare + + rif_counter_h1_create + rif_counter_h2_create +} + +rif_counter_cleanup() +{ + local count=$1; shift + + pre_cleanup + + for ((i = 1; i <= count; i++)); do + vlan_destroy $h2 $i + done + + rif_counter_h2_destroy + rif_counter_h1_destroy + + vrf_cleanup + + if [[ -v RIF_COUNTER_BATCH_FILE ]]; then + rm -f $RIF_COUNTER_BATCH_FILE + fi +} + + +rif_counter_test() +{ + local count=$1; shift + local should_fail=$1; shift + + RIF_COUNTER_BATCH_FILE="$(mktemp)" + + for ((i = 1; i <= count; i++)); do + vlan_create $h2 $i v$h2 $(rif_counter_addr4pfx $i 2) + done + for ((i = 1; i <= count; i++)); do + cat >> $RIF_COUNTER_BATCH_FILE <<-EOF + stats set dev $h2.$i l3_stats on + EOF + done + + ip -b $RIF_COUNTER_BATCH_FILE + check_err_fail $should_fail $? "RIF counter enablement" +} + +rif_counter_traffic_test() +{ + local count=$1; shift + local i; + + for ((i = count; i > 0; i /= 2)); do + $MZ $h1 -Q $i -c 1 -d 20msec -p 100 -a own -b $(mac_get $h2) \ + -A $(rif_counter_addr4 $i 1) \ + -B $(rif_counter_addr4 $i 2) \ + -q -t udp sp=54321,dp=12345 + done + for ((i = count; i > 0; i /= 2)); do + busywait "$TC_HIT_TIMEOUT" until_counter_is "== 1" \ + hw_stats_get l3_stats $h2.$i rx packets > /dev/null + check_err $? "Traffic not seen at RIF $h2.$i" + done +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/rif_lag.sh b/tools/testing/selftests/drivers/net/mlxsw/rif_lag.sh new file mode 100755 index 000000000000..e28f978104f3 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/rif_lag.sh @@ -0,0 +1,136 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + lag_rif_add + lag_rif_nomaster + lag_rif_remaster + lag_rif_nomaster_addr +" + +NUM_NETIFS=2 +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +setup_prepare() +{ + swp1=${NETIFS[p1]} + swp2=${NETIFS[p2]} + + team_create lag1 lacp + ip link set dev lag1 addrgenmode none + ip link set dev lag1 address $(mac_get $swp1) + + team_create lag2 lacp + ip link set dev lag2 addrgenmode none + ip link set dev lag2 address $(mac_get $swp2) + + ip link set dev $swp1 master lag1 + ip link set dev $swp1 up + + ip link set dev $swp2 master lag2 + ip link set dev $swp2 up +} + +cleanup() +{ + pre_cleanup + + ip link set dev $swp2 nomaster + ip link set dev $swp2 down + + ip link set dev $swp1 nomaster + ip link set dev $swp1 down + + ip link del dev lag2 + ip link del dev lag1 +} + +lag_rif_add() +{ + RET=0 + + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + __addr_add_del lag1 add 192.0.2.2/28 + sleep 1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0 + 1)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + log_test "Add RIF for LAG on address addition" +} + +lag_rif_nomaster() +{ + RET=0 + + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + ip link set dev $swp1 nomaster + sleep 1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0 - 1)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + log_test "Drop RIF for LAG on port deslavement" +} + +lag_rif_remaster() +{ + RET=0 + + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + ip link set dev $swp1 down + ip link set dev $swp1 master lag1 + ip link set dev $swp1 up + setup_wait_dev $swp1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0 + 1)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + log_test "Add RIF for LAG on port reenslavement" +} + +lag_rif_nomaster_addr() +{ + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + + # Adding an address while the port is LAG'd shouldn't generate a RIF. + __addr_add_del $swp1 add 192.0.2.65/28 + sleep 1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "After adding IP: Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + # Removing the port from LAG should drop RIF for the LAG (as tested in + # lag_rif_nomaster), but since the port now has an address, it should + # gain a RIF. + ip link set dev $swp1 nomaster + sleep 1 + local rifs_occ_t2=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0)) + + ((expected_rifs == rifs_occ_t2)) + check_err $? "After deslaving: Expected $expected_rifs RIFs, $rifs_occ_t2 are used" + + __addr_add_del $swp1 del 192.0.2.65/28 + log_test "Add RIF for port on deslavement from LAG" +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/rif_lag_vlan.sh b/tools/testing/selftests/drivers/net/mlxsw/rif_lag_vlan.sh new file mode 100755 index 000000000000..6318cfa6434c --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/rif_lag_vlan.sh @@ -0,0 +1,146 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + lag_rif_add + lag_rif_nomaster + lag_rif_remaster + lag_rif_nomaster_addr +" + +NUM_NETIFS=2 +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +setup_prepare() +{ + swp1=${NETIFS[p1]} + swp2=${NETIFS[p2]} + + team_create lag1 lacp + ip link set dev lag1 addrgenmode none + ip link set dev lag1 address $(mac_get $swp1) + + team_create lag2 lacp + ip link set dev lag2 addrgenmode none + ip link set dev lag2 address $(mac_get $swp2) + + ip link set dev $swp1 master lag1 + ip link set dev $swp1 up + + ip link set dev $swp2 master lag2 + ip link set dev $swp2 up + + vlan_create lag1 100 + ip link set dev lag1.100 addrgenmode none + + vlan_create lag1 200 + ip link set dev lag1.200 addrgenmode none +} + +cleanup() +{ + pre_cleanup + + ip link del dev lag1.200 + ip link del dev lag1.100 + + ip link set dev $swp2 nomaster + ip link set dev $swp2 down + + ip link set dev $swp1 nomaster + ip link set dev $swp1 down + + ip link del dev lag2 + ip link del dev lag1 +} + +lag_rif_add() +{ + RET=0 + + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + __addr_add_del lag1.100 add 192.0.2.2/28 + __addr_add_del lag1.200 add 192.0.2.18/28 + sleep 1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0 + 2)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + log_test "Add RIFs for LAG VLANs on address addition" +} + +lag_rif_nomaster() +{ + RET=0 + + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + ip link set dev $swp1 nomaster + sleep 1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0 - 2)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + log_test "Drop RIFs for LAG VLANs on port deslavement" +} + +lag_rif_remaster() +{ + RET=0 + + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + ip link set dev $swp1 down + ip link set dev $swp1 master lag1 + ip link set dev $swp1 up + setup_wait_dev $swp1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0 + 2)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + log_test "Add RIFs for LAG VLANs on port reenslavement" +} + +lag_rif_nomaster_addr() +{ + local rifs_occ_t0=$(devlink_resource_occ_get rifs) + + # Adding an address while the port is LAG'd shouldn't generate a RIF. + __addr_add_del $swp1 add 192.0.2.65/28 + sleep 1 + local rifs_occ_t1=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0)) + + ((expected_rifs == rifs_occ_t1)) + check_err $? "After adding IP: Expected $expected_rifs RIFs, $rifs_occ_t1 are used" + + # Removing the port from LAG should drop two RIFs for the LAG VLANs (as + # tested in lag_rif_nomaster), but since the port now has an address, it + # should gain a RIF. + ip link set dev $swp1 nomaster + sleep 1 + local rifs_occ_t2=$(devlink_resource_occ_get rifs) + local expected_rifs=$((rifs_occ_t0 - 1)) + + ((expected_rifs == rifs_occ_t2)) + check_err $? "After deslaving: Expected $expected_rifs RIFs, $rifs_occ_t2 are used" + + __addr_add_del $swp1 del 192.0.2.65/28 + log_test "Add RIF for port on deslavement from LAG" +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/rif_mac_profile_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/rif_mac_profile_scale.sh new file mode 100644 index 000000000000..71e7681f15f6 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/rif_mac_profile_scale.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# Test for RIF MAC profiles resource. The test adds VLAN netdevices according to +# the maximum number of RIF MAC profiles, sets each of them with a random +# MAC address, and checks that eventually the number of occupied RIF MAC +# profiles equals the maximum number of RIF MAC profiles. + + +RIF_MAC_PROFILE_NUM_NETIFS=2 + +rif_mac_profiles_create() +{ + local count=$1; shift + local should_fail=$1; shift + local batch_file="$(mktemp)" + + for ((i = 1; i <= count; i++)); do + vlan=$(( i*10 )) + m=$(( i*11 )) + + cat >> $batch_file <<-EOF + link add link $h1 name $h1.$vlan \ + address 00:$m:$m:$m:$m:$m type vlan id $vlan + address add 192.0.$m.1/24 dev $h1.$vlan + EOF + done + + ip -b $batch_file &> /dev/null + check_err_fail $should_fail $? "RIF creation" + + rm -f $batch_file +} + +rif_mac_profile_test() +{ + local count=$1; shift + local should_fail=$1; shift + + rif_mac_profiles_create $count $should_fail + + occ=$(devlink -j resource show $DEVLINK_DEV \ + | jq '.[][][] | select(.name=="rif_mac_profiles") |.["occ"]') + + [[ $occ -eq $count ]] + check_err_fail $should_fail $? "Attempt to use $count profiles (actual result $occ)" +} + +rif_mac_profile_setup_prepare() +{ + h1=${NETIFS[p1]} + h2=${NETIFS[p2]} + + # Disable IPv6 on the two interfaces to avoid IPv6 link-local addresses + # being generated and RIFs being created. + sysctl_set net.ipv6.conf.$h1.disable_ipv6 1 + sysctl_set net.ipv6.conf.$h2.disable_ipv6 1 + + ip link set $h1 up + ip link set $h2 up +} + +rif_mac_profile_cleanup() +{ + pre_cleanup + + ip link set $h2 down + ip link set $h1 down + + sysctl_restore net.ipv6.conf.$h2.disable_ipv6 + sysctl_restore net.ipv6.conf.$h1.disable_ipv6 +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/rif_mac_profiles.sh b/tools/testing/selftests/drivers/net/mlxsw/rif_mac_profiles.sh new file mode 100755 index 000000000000..c18340cee55d --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/rif_mac_profiles.sh @@ -0,0 +1,213 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + mac_profile_test +" +NUM_NETIFS=4 +source $lib_dir/lib.sh +source $lib_dir/tc_common.sh +source $lib_dir/devlink_lib.sh + +h1_create() +{ + simple_if_init $h1 192.0.2.1/24 + ip route add 198.51.100.0/24 vrf v$h1 nexthop via 192.0.2.2 + + tc qdisc add dev $h1 ingress +} + +h1_destroy() +{ + tc qdisc del dev $h1 ingress + + ip route del 198.51.100.0/24 vrf v$h1 + simple_if_fini $h1 192.0.2.1/24 +} + +h2_create() +{ + simple_if_init $h2 198.51.100.1/24 + ip route add 192.0.2.0/24 vrf v$h2 nexthop via 198.51.100.2 + + tc qdisc add dev $h2 ingress +} + +h2_destroy() +{ + tc qdisc del dev $h2 ingress + + ip route del 192.0.2.0/24 vrf v$h2 + simple_if_fini $h2 198.51.100.1/24 +} + +router_create() +{ + ip link set dev $rp1 up + ip link set dev $rp2 up + + tc qdisc add dev $rp1 clsact + tc qdisc add dev $rp2 clsact + ip address add 192.0.2.2/24 dev $rp1 + ip address add 198.51.100.2/24 dev $rp2 +} + +router_destroy() +{ + ip address del 198.51.100.2/24 dev $rp2 + ip address del 192.0.2.2/24 dev $rp1 + tc qdisc del dev $rp2 clsact + tc qdisc del dev $rp1 clsact + + ip link set dev $rp2 down + ip link set dev $rp1 down +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + rp1=${NETIFS[p2]} + + rp2=${NETIFS[p3]} + h2=${NETIFS[p4]} + + vrf_prepare + + h1_create + h2_create + + router_create + + forwarding_enable +} + +cleanup() +{ + pre_cleanup + + forwarding_restore + + router_destroy + + h2_destroy + h1_destroy + + vrf_cleanup +} + +h1_to_h2() +{ + local test_name=$@; shift + local smac=$(mac_get $rp2) + + RET=0 + + # Replace neighbour to avoid first packet being forwarded in software + ip neigh replace dev $rp2 198.51.100.1 lladdr $(mac_get $h2) + + # Add a filter to ensure that packets are forwarded in hardware. Cannot + # match on source MAC because it is not set in eACL after routing + tc filter add dev $rp2 egress proto ip pref 1 handle 101 \ + flower skip_sw ip_proto udp src_port 12345 dst_port 54321 \ + action pass + + # Add a filter to ensure that packets are received with the correct + # source MAC + tc filter add dev $h2 ingress proto ip pref 1 handle 101 \ + flower skip_sw src_mac $smac ip_proto udp src_port 12345 \ + dst_port 54321 action pass + + $MZ $h1 -a own -b $(mac_get $rp1) -t udp "sp=12345,dp=54321" \ + -A 192.0.2.1 -B 198.51.100.1 -c 10 -p 100 -d 1msec -q + + tc_check_packets "dev $rp2 egress" 101 10 + check_err $? "packets not forwarded in hardware" + + tc_check_packets "dev $h2 ingress" 101 10 + check_err $? "packets not forwarded with correct source mac" + + log_test "h1->h2: $test_name" + + tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower + tc filter del dev $rp2 egress protocol ip pref 1 handle 101 flower + ip neigh del dev $rp2 198.51.100.1 lladdr $(mac_get $h2) +} + +h2_to_h1() +{ + local test_name=$@; shift + local rp1_mac=$(mac_get $rp1) + + RET=0 + + ip neigh replace dev $rp1 192.0.2.1 lladdr $(mac_get $h1) + + tc filter add dev $rp1 egress proto ip pref 1 handle 101 \ + flower skip_sw ip_proto udp src_port 54321 dst_port 12345 \ + action pass + + tc filter add dev $h1 ingress proto ip pref 1 handle 101 \ + flower skip_sw src_mac $rp1_mac ip_proto udp src_port 54321 \ + dst_port 12345 action pass + + $MZ $h2 -a own -b $(mac_get $rp2) -t udp "sp=54321,dp=12345" \ + -A 198.51.100.1 -B 192.0.2.1 -c 10 -p 100 -d 1msec -q + + tc_check_packets "dev $rp1 egress" 101 10 + check_err $? "packets not forwarded in hardware" + + tc_check_packets "dev $h1 ingress" 101 10 + check_err $? "packets not forwarded with correct source mac" + + log_test "h2->h1: $test_name" + + tc filter del dev $h1 ingress protocol ip pref 1 handle 101 flower + tc filter del dev $rp1 egress protocol ip pref 1 handle 101 flower + ip neigh del dev $rp1 192.0.2.1 lladdr $(mac_get $h1) +} + +smac_test() +{ + local test_name=$@; shift + + # Test that packets forwarded to $h2 via $rp2 are forwarded with the + # current source MAC of $rp2 + h1_to_h2 $test_name + + # Test that packets forwarded to $h1 via $rp1 are forwarded with the + # current source MAC of $rp1. This MAC is never changed during the test, + # but given the shared nature of MAC profile, the point is to see that + # changes to the MAC of $rp2 do not affect that of $rp1 + h2_to_h1 $test_name +} + +mac_profile_test() +{ + local rp2_mac=$(mac_get $rp2) + + # Test behavior when the RIF backing $rp2 is transitioned to use + # a new MAC profile + ip link set dev $rp2 addr 00:11:22:33:44:55 + smac_test "new mac profile" + + # Test behavior when the MAC profile used by the RIF is edited + ip link set dev $rp2 address 00:22:22:22:22:22 + smac_test "edit mac profile" + + # Restore original MAC + ip link set dev $rp2 addr $rp2_mac +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +mac_profiles=$(devlink_resource_size_get rif_mac_profiles) +if [[ $mac_profiles -ne 1 ]]; then + tests_run +fi + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/rif_mac_profiles_occ.sh b/tools/testing/selftests/drivers/net/mlxsw/rif_mac_profiles_occ.sh new file mode 100755 index 000000000000..026a126f584d --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/rif_mac_profiles_occ.sh @@ -0,0 +1,147 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + rif_mac_profile_edit_test +" +NUM_NETIFS=2 +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +setup_prepare() +{ + h1=${NETIFS[p1]} + h2=${NETIFS[p2]} + + # Disable IPv6 on the two interfaces to avoid IPv6 link-local addresses + # being generated and RIFs being created + sysctl_set net.ipv6.conf.$h1.disable_ipv6 1 + sysctl_set net.ipv6.conf.$h2.disable_ipv6 1 + + ip link set $h1 up + ip link set $h2 up +} + +cleanup() +{ + pre_cleanup + + ip link set $h2 down + ip link set $h1 down + + sysctl_restore net.ipv6.conf.$h2.disable_ipv6 + sysctl_restore net.ipv6.conf.$h1.disable_ipv6 + + # Reload in order to clean all the RIFs and RIF MAC profiles created + devlink_reload +} + +create_max_rif_mac_profiles() +{ + local count=$1; shift + local batch_file="$(mktemp)" + + for ((i = 1; i <= count; i++)); do + vlan=$(( i*10 )) + m=$(( i*11 )) + + cat >> $batch_file <<-EOF + link add link $h1 name $h1.$vlan \ + address 00:$m:$m:$m:$m:$m type vlan id $vlan + address add 192.0.$m.1/24 dev $h1.$vlan + EOF + done + + ip -b $batch_file &> /dev/null + rm -f $batch_file +} + +rif_mac_profile_replacement_test() +{ + local h1_10_mac=$(mac_get $h1.10) + + RET=0 + + ip link set $h1.10 address 00:12:34:56:78:99 + check_err $? + + log_test "RIF MAC profile replacement" + + ip link set $h1.10 address $h1_10_mac +} + +rif_mac_profile_consolidation_test() +{ + local count=$1; shift + local h1_20_mac + + RET=0 + + if [[ $count -eq 1 ]]; then + return + fi + + h1_20_mac=$(mac_get $h1.20) + + # Set the MAC of $h1.20 to that of $h1.10 and confirm that they are + # using the same MAC profile. + ip link set $h1.20 address 00:11:11:11:11:11 + check_err $? + + occ=$(devlink -j resource show $DEVLINK_DEV \ + | jq '.[][][] | select(.name=="rif_mac_profiles") |.["occ"]') + + [[ $occ -eq $((count - 1)) ]] + check_err $? "MAC profile occupancy did not decrease" + + log_test "RIF MAC profile consolidation" + + ip link set $h1.20 address $h1_20_mac +} + +rif_mac_profile_shared_replacement_test() +{ + local count=$1; shift + local i=$((count + 1)) + local vlan=$(( i*10 )) + local m=11 + + RET=0 + + # Create a VLAN netdevice that has the same MAC as the first one. + ip link add link $h1 name $h1.$vlan address 00:$m:$m:$m:$m:$m \ + type vlan id $vlan + ip address add 192.0.$m.1/24 dev $h1.$vlan + + # MAC replacement should fail because all the MAC profiles are in use + # and the profile is shared between multiple RIFs + m=$(( i*11 )) + ip link set $h1.$vlan address 00:$m:$m:$m:$m:$m &> /dev/null + check_fail $? + + log_test "RIF MAC profile shared replacement" + + ip link del dev $h1.$vlan +} + +rif_mac_profile_edit_test() +{ + local count=$(devlink_resource_size_get rif_mac_profiles) + + create_max_rif_mac_profiles $count + + rif_mac_profile_replacement_test + rif_mac_profile_consolidation_test $count + rif_mac_profile_shared_replacement_test $count +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/router_bridge_lag.sh b/tools/testing/selftests/drivers/net/mlxsw/router_bridge_lag.sh new file mode 100755 index 000000000000..6ce317cfaf9b --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/router_bridge_lag.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# Test enslavement to LAG with a clean slate. +# See $lib_dir/router_bridge_lag.sh for further details. + +ALL_TESTS=" + config_devlink_reload + config_enslave_h1 + config_enslave_h2 + config_enslave_h3 + config_enslave_h4 + config_enslave_swp1 + config_enslave_swp2 + config_enslave_swp3 + config_enslave_swp4 + config_wait + ping_ipv4 + ping_ipv6 +" + +config_devlink_reload() +{ + log_info "Devlink reload" + devlink_reload +} + +config_enslave_h1() +{ + config_enslave $h1 lag1 +} + +config_enslave_h2() +{ + config_enslave $h2 lag4 +} + +config_enslave_h3() +{ + config_enslave $h3 lag4 +} + +config_enslave_h4() +{ + config_enslave $h4 lag1 +} + +lib_dir=$(dirname $0)/../../../net/forwarding +EXTRA_SOURCE="source $lib_dir/devlink_lib.sh" +source $lib_dir/router_bridge_lag.sh diff --git a/tools/testing/selftests/drivers/net/mlxsw/router_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/router_scale.sh index e93878d42596..683759d29199 100644 --- a/tools/testing/selftests/drivers/net/mlxsw/router_scale.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/router_scale.sh @@ -68,7 +68,7 @@ wait_for_routes() local t0=$1; shift local route_count=$1; shift - local t1=$(ip route | grep -o 'offload' | wc -l) + local t1=$(ip route | grep 'offload' | grep -v 'offload_failed' | wc -l) local delta=$((t1 - t0)) echo $delta [[ $delta -ge $route_count ]] diff --git a/tools/testing/selftests/drivers/net/mlxsw/rtnetlink.sh b/tools/testing/selftests/drivers/net/mlxsw/rtnetlink.sh index f4031002d5e9..893a693ad805 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/rtnetlink.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/rtnetlink.sh @@ -10,18 +10,16 @@ lib_dir=$(dirname $0)/../../../net/forwarding ALL_TESTS=" - rif_set_addr_test rif_vrf_set_addr_test - rif_inherit_bridge_addr_test rif_non_inherit_bridge_addr_test vlan_interface_deletion_test bridge_deletion_test bridge_vlan_flags_test vlan_1_test - lag_bridge_upper_test duplicate_vlans_test vlan_rif_refcount_test subport_rif_refcount_test + subport_rif_lag_join_test vlan_dev_deletion_test lag_unlink_slaves_test lag_dev_deletion_test @@ -29,6 +27,13 @@ ALL_TESTS=" bridge_extern_learn_test neigh_offload_test nexthop_offload_test + nexthop_obj_invalid_test + nexthop_obj_offload_test + nexthop_obj_group_offload_test + nexthop_obj_bucket_offload_test + nexthop_obj_blackhole_offload_test + nexthop_obj_route_offload_test + bridge_locked_port_test devlink_reload_test " NUM_NETIFS=2 @@ -53,55 +58,6 @@ cleanup() ip link set dev $swp1 down } -rif_set_addr_test() -{ - local swp1_mac=$(mac_get $swp1) - local swp2_mac=$(mac_get $swp2) - - RET=0 - - # $swp1 and $swp2 likely got their IPv6 local addresses already, but - # here we need to test the transition to RIF. - ip addr flush dev $swp1 - ip addr flush dev $swp2 - sleep .1 - - ip addr add dev $swp1 192.0.2.1/28 - check_err $? - - ip link set dev $swp1 addr 00:11:22:33:44:55 - check_err $? - - # IP address enablement should be rejected if the MAC address prefix - # doesn't match other RIFs. - ip addr add dev $swp2 192.0.2.2/28 &>/dev/null - check_fail $? "IP address addition passed for a device with a wrong MAC" - ip addr add dev $swp2 192.0.2.2/28 2>&1 >/dev/null \ - | grep -q mlxsw_spectrum - check_err $? "no extack for IP address addition" - - ip link set dev $swp2 addr 00:11:22:33:44:66 - check_err $? - ip addr add dev $swp2 192.0.2.2/28 &>/dev/null - check_err $? - - # Change of MAC address of a RIF should be forbidden if the new MAC - # doesn't share the prefix with other MAC addresses. - ip link set dev $swp2 addr 00:11:22:33:00:66 &>/dev/null - check_fail $? "change of MAC address passed for a wrong MAC" - ip link set dev $swp2 addr 00:11:22:33:00:66 2>&1 >/dev/null \ - | grep -q mlxsw_spectrum - check_err $? "no extack for MAC address change" - - log_test "RIF - bad MAC change" - - ip addr del dev $swp2 192.0.2.2/28 - ip addr del dev $swp1 192.0.2.1/28 - - ip link set dev $swp2 addr $swp2_mac - ip link set dev $swp1 addr $swp1_mac -} - rif_vrf_set_addr_test() { # Test that it is possible to set an IP address on a VRF upper despite @@ -121,45 +77,6 @@ rif_vrf_set_addr_test() ip link del dev vrf-test } -rif_inherit_bridge_addr_test() -{ - RET=0 - - # Create first RIF - ip addr add dev $swp1 192.0.2.1/28 - check_err $? - - # Create a FID RIF - ip link add name br1 up type bridge vlan_filtering 0 - ip link set dev $swp2 master br1 - ip addr add dev br1 192.0.2.17/28 - check_err $? - - # Prepare a device with a low MAC address - ip link add name d up type dummy - ip link set dev d addr 00:11:22:33:44:55 - - # Attach the device to br1. That prompts bridge address change, which - # should be vetoed, thus preventing the attachment. - ip link set dev d master br1 &>/dev/null - check_fail $? "Device with low MAC was permitted to attach a bridge with RIF" - ip link set dev d master br1 2>&1 >/dev/null \ - | grep -q mlxsw_spectrum - check_err $? "no extack for bridge attach rejection" - - ip link set dev $swp2 addr 00:11:22:33:44:55 &>/dev/null - check_fail $? "Changing swp2's MAC address permitted" - ip link set dev $swp2 addr 00:11:22:33:44:55 2>&1 >/dev/null \ - | grep -q mlxsw_spectrum - check_err $? "no extack for bridge port MAC address change rejection" - - log_test "RIF - attach port with bad MAC to bridge" - - ip link del dev d - ip link del dev br1 - ip addr del dev $swp1 192.0.2.1/28 -} - rif_non_inherit_bridge_addr_test() { local swp2_mac=$(mac_get $swp2) @@ -293,33 +210,6 @@ vlan_1_test() ip link del dev $swp1.1 } -lag_bridge_upper_test() -{ - # Test that ports cannot be enslaved to LAG devices that have uppers - # and that failure is handled gracefully. See commit b3529af6bb0d - # ("spectrum: Reference count VLAN entries") for more details - RET=0 - - ip link add name bond1 type bond mode 802.3ad - - ip link add name br0 type bridge vlan_filtering 1 - ip link set dev bond1 master br0 - - ip link set dev $swp1 down - ip link set dev $swp1 master bond1 &> /dev/null - check_fail $? "managed to enslave port to lag when should not" - - # This might generate a trace, if we did not handle the failure - # correctly - ip -6 address add 2001:db8:1::1/64 dev $swp1 - ip -6 address del 2001:db8:1::1/64 dev $swp1 - - log_test "lag with bridge upper" - - ip link del dev br0 - ip link del dev bond1 -} - duplicate_vlans_test() { # Test that on a given port a VLAN is only used once. Either as VLAN @@ -435,6 +325,48 @@ subport_rif_refcount_test() ip link del dev bond1 } +subport_rif_lag_join_test() +{ + # Test that the reference count of a RIF configured for a LAG is + # incremented / decremented when ports join / leave the LAG. We use the + # offload indication on routes configured on the RIF to understand if + # it was created / destroyed + RET=0 + + ip link add name bond1 type bond mode 802.3ad + ip link set dev $swp1 down + ip link set dev $swp2 down + ip link set dev $swp1 master bond1 + ip link set dev $swp2 master bond1 + + ip link set dev bond1 up + ip -6 address add 2001:db8:1::1/64 dev bond1 + + busywait "$TIMEOUT" wait_for_offload \ + ip -6 route get fibmatch 2001:db8:1::2 dev bond1 + check_err $? "subport rif was not created on lag device" + + ip link set dev $swp1 nomaster + busywait "$TIMEOUT" wait_for_offload \ + ip -6 route get fibmatch 2001:db8:1::2 dev bond1 + check_err $? "subport rif of lag device was destroyed after removing one port" + + ip link set dev $swp1 master bond1 + ip link set dev $swp2 nomaster + busywait "$TIMEOUT" wait_for_offload \ + ip -6 route get fibmatch 2001:db8:1::2 dev bond1 + check_err $? "subport rif of lag device was destroyed after re-adding a port and removing another" + + ip link set dev $swp1 nomaster + busywait "$TIMEOUT" not wait_for_offload \ + ip -6 route get fibmatch 2001:db8:1::2 dev bond1 + check_err $? "subport rif of lag device was not destroyed when should" + + log_test "subport rif lag join" + + ip link del dev bond1 +} + vlan_dev_deletion_test() { # Test that VLAN devices are correctly deleted / unlinked when enslaved @@ -550,9 +482,6 @@ vlan_interface_uppers_test() ip link set dev $swp1 master br0 ip link add link br0 name br0.10 type vlan id 10 - ip link add link br0.10 name macvlan0 \ - type macvlan mode private &> /dev/null - check_fail $? "managed to create a macvlan when should not" ip -6 address add 2001:db8:1::1/64 dev br0.10 ip link add link br0.10 name macvlan0 type macvlan mode private @@ -674,6 +603,320 @@ nexthop_offload_test() sysctl_restore net.ipv6.conf.$swp2.keep_addr_on_down } +nexthop_obj_invalid_test() +{ + # Test that invalid nexthop object configurations are rejected + RET=0 + + simple_if_init $swp1 192.0.2.1/24 2001:db8:1::1/64 + simple_if_init $swp2 192.0.2.2/24 2001:db8:1::2/64 + setup_wait + + ip nexthop add id 1 via 192.0.2.3 fdb + check_fail $? "managed to configure an FDB nexthop when should not" + + ip nexthop add id 1 encap mpls 200/300 via 192.0.2.3 dev $swp1 + check_fail $? "managed to configure a nexthop with MPLS encap when should not" + + ip nexthop add id 1 dev $swp1 + ip nexthop add id 2 dev $swp1 + ip nexthop add id 3 via 192.0.2.3 dev $swp1 + ip nexthop add id 10 group 1/2 + check_fail $? "managed to configure a nexthop group with device-only nexthops when should not" + + ip nexthop add id 10 group 3 type resilient buckets 7 + check_fail $? "managed to configure a too small resilient nexthop group when should not" + + ip nexthop add id 10 group 3 type resilient buckets 129 + check_fail $? "managed to configure a resilient nexthop group with invalid number of buckets when should not" + + ip nexthop add id 10 group 1/2 type resilient buckets 32 + check_fail $? "managed to configure a resilient nexthop group with device-only nexthops when should not" + + ip nexthop add id 10 group 3 type resilient buckets 32 + check_err $? "failed to configure a valid resilient nexthop group" + ip nexthop replace id 3 dev $swp1 + check_fail $? "managed to populate a nexthop bucket with a device-only nexthop when should not" + + log_test "nexthop objects - invalid configurations" + + ip nexthop del id 10 + ip nexthop del id 3 + ip nexthop del id 2 + ip nexthop del id 1 + + simple_if_fini $swp2 192.0.2.2/24 2001:db8:1::2/64 + simple_if_fini $swp1 192.0.2.1/24 2001:db8:1::1/64 +} + +nexthop_obj_offload_test() +{ + # Test offload indication of nexthop objects + RET=0 + + simple_if_init $swp1 192.0.2.1/24 2001:db8:1::1/64 + simple_if_init $swp2 + setup_wait + + ip nexthop add id 1 via 192.0.2.2 dev $swp1 + ip neigh replace 192.0.2.2 lladdr 00:11:22:33:44:55 nud perm \ + dev $swp1 + + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop show id 1 + check_err $? "nexthop not marked as offloaded when should" + + ip neigh replace 192.0.2.2 nud failed dev $swp1 + busywait "$TIMEOUT" not wait_for_offload \ + ip nexthop show id 1 + check_err $? "nexthop marked as offloaded after setting neigh to failed state" + + ip neigh replace 192.0.2.2 lladdr 00:11:22:33:44:55 nud perm \ + dev $swp1 + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop show id 1 + check_err $? "nexthop not marked as offloaded after neigh replace" + + ip nexthop replace id 1 via 192.0.2.3 dev $swp1 + busywait "$TIMEOUT" not wait_for_offload \ + ip nexthop show id 1 + check_err $? "nexthop marked as offloaded after replacing to use an invalid address" + + ip nexthop replace id 1 via 192.0.2.2 dev $swp1 + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop show id 1 + check_err $? "nexthop not marked as offloaded after replacing to use a valid address" + + log_test "nexthop objects offload indication" + + ip neigh del 192.0.2.2 dev $swp1 + ip nexthop del id 1 + + simple_if_fini $swp2 + simple_if_fini $swp1 192.0.2.1/24 2001:db8:1::1/64 +} + +nexthop_obj_group_offload_test() +{ + # Test offload indication of nexthop group objects + RET=0 + + simple_if_init $swp1 192.0.2.1/24 2001:db8:1::1/64 + simple_if_init $swp2 + setup_wait + + ip nexthop add id 1 via 192.0.2.2 dev $swp1 + ip nexthop add id 2 via 2001:db8:1::2 dev $swp1 + ip nexthop add id 10 group 1/2 + ip neigh replace 192.0.2.2 lladdr 00:11:22:33:44:55 nud perm \ + dev $swp1 + ip neigh replace 192.0.2.3 lladdr 00:11:22:33:44:55 nud perm \ + dev $swp1 + ip neigh replace 2001:db8:1::2 lladdr 00:11:22:33:44:55 nud perm \ + dev $swp1 + + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop show id 1 + check_err $? "IPv4 nexthop not marked as offloaded when should" + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop show id 2 + check_err $? "IPv6 nexthop not marked as offloaded when should" + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop show id 10 + check_err $? "nexthop group not marked as offloaded when should" + + # Invalidate nexthop id 1 + ip neigh replace 192.0.2.2 nud failed dev $swp1 + busywait "$TIMEOUT" not wait_for_offload \ + ip nexthop show id 10 + check_fail $? "nexthop group not marked as offloaded with one valid nexthop" + + # Invalidate nexthop id 2 + ip neigh replace 2001:db8:1::2 nud failed dev $swp1 + busywait "$TIMEOUT" not wait_for_offload \ + ip nexthop show id 10 + check_err $? "nexthop group marked as offloaded when should not" + + # Revalidate nexthop id 1 + ip nexthop replace id 1 via 192.0.2.3 dev $swp1 + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop show id 10 + check_err $? "nexthop group not marked as offloaded after revalidating nexthop" + + log_test "nexthop group objects offload indication" + + ip neigh del 2001:db8:1::2 dev $swp1 + ip neigh del 192.0.2.3 dev $swp1 + ip neigh del 192.0.2.2 dev $swp1 + ip nexthop del id 10 + ip nexthop del id 2 + ip nexthop del id 1 + + simple_if_fini $swp2 + simple_if_fini $swp1 192.0.2.1/24 2001:db8:1::1/64 +} + +nexthop_obj_bucket_offload_test() +{ + # Test offload indication of nexthop buckets + RET=0 + + simple_if_init $swp1 192.0.2.1/24 2001:db8:1::1/64 + simple_if_init $swp2 + setup_wait + + ip nexthop add id 1 via 192.0.2.2 dev $swp1 + ip nexthop add id 2 via 2001:db8:1::2 dev $swp1 + ip nexthop add id 10 group 1/2 type resilient buckets 32 idle_timer 0 + ip neigh replace 192.0.2.2 lladdr 00:11:22:33:44:55 nud perm \ + dev $swp1 + ip neigh replace 192.0.2.3 lladdr 00:11:22:33:44:55 nud perm \ + dev $swp1 + ip neigh replace 2001:db8:1::2 lladdr 00:11:22:33:44:55 nud perm \ + dev $swp1 + + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop bucket show nhid 1 + check_err $? "IPv4 nexthop buckets not marked as offloaded when should" + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop bucket show nhid 2 + check_err $? "IPv6 nexthop buckets not marked as offloaded when should" + + # Invalidate nexthop id 1 + ip neigh replace 192.0.2.2 nud failed dev $swp1 + busywait "$TIMEOUT" wait_for_trap \ + ip nexthop bucket show nhid 1 + check_err $? "IPv4 nexthop buckets not marked with trap when should" + + # Invalidate nexthop id 2 + ip neigh replace 2001:db8:1::2 nud failed dev $swp1 + busywait "$TIMEOUT" wait_for_trap \ + ip nexthop bucket show nhid 2 + check_err $? "IPv6 nexthop buckets not marked with trap when should" + + # Revalidate nexthop id 1 by changing its configuration + ip nexthop replace id 1 via 192.0.2.3 dev $swp1 + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop bucket show nhid 1 + check_err $? "nexthop bucket not marked as offloaded after revalidating nexthop" + + # Revalidate nexthop id 2 by changing its neighbour + ip neigh replace 2001:db8:1::2 lladdr 00:11:22:33:44:55 nud perm \ + dev $swp1 + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop bucket show nhid 2 + check_err $? "nexthop bucket not marked as offloaded after revalidating neighbour" + + log_test "nexthop bucket offload indication" + + ip neigh del 2001:db8:1::2 dev $swp1 + ip neigh del 192.0.2.3 dev $swp1 + ip neigh del 192.0.2.2 dev $swp1 + ip nexthop del id 10 + ip nexthop del id 2 + ip nexthop del id 1 + + simple_if_fini $swp2 + simple_if_fini $swp1 192.0.2.1/24 2001:db8:1::1/64 +} + +nexthop_obj_blackhole_offload_test() +{ + # Test offload indication of blackhole nexthop objects + RET=0 + + ip nexthop add id 1 blackhole + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop show id 1 + check_err $? "Blackhole nexthop not marked as offloaded when should" + + ip nexthop add id 10 group 1 + busywait "$TIMEOUT" wait_for_offload \ + ip nexthop show id 10 + check_err $? "Nexthop group not marked as offloaded when should" + + log_test "blackhole nexthop objects offload indication" + + ip nexthop del id 10 + ip nexthop del id 1 +} + +nexthop_obj_route_offload_test() +{ + # Test offload indication of routes using nexthop objects + RET=0 + + simple_if_init $swp1 192.0.2.1/24 2001:db8:1::1/64 + simple_if_init $swp2 + setup_wait + + ip nexthop add id 1 via 192.0.2.2 dev $swp1 + ip neigh replace 192.0.2.2 lladdr 00:11:22:33:44:55 nud perm \ + dev $swp1 + ip neigh replace 192.0.2.3 lladdr 00:11:22:33:44:55 nud perm \ + dev $swp1 + + ip route replace 198.51.100.0/24 nhid 1 + busywait "$TIMEOUT" wait_for_offload \ + ip route show 198.51.100.0/24 + check_err $? "route not marked as offloaded when using valid nexthop" + + ip nexthop replace id 1 via 192.0.2.3 dev $swp1 + busywait "$TIMEOUT" wait_for_offload \ + ip route show 198.51.100.0/24 + check_err $? "route not marked as offloaded after replacing valid nexthop with a valid one" + + ip nexthop replace id 1 via 192.0.2.4 dev $swp1 + busywait "$TIMEOUT" not wait_for_offload \ + ip route show 198.51.100.0/24 + check_err $? "route marked as offloaded after replacing valid nexthop with an invalid one" + + ip nexthop replace id 1 via 192.0.2.2 dev $swp1 + busywait "$TIMEOUT" wait_for_offload \ + ip route show 198.51.100.0/24 + check_err $? "route not marked as offloaded after replacing invalid nexthop with a valid one" + + log_test "routes using nexthop objects offload indication" + + ip route del 198.51.100.0/24 + ip neigh del 192.0.2.3 dev $swp1 + ip neigh del 192.0.2.2 dev $swp1 + ip nexthop del id 1 + + simple_if_fini $swp2 + simple_if_fini $swp1 192.0.2.1/24 2001:db8:1::1/64 +} + +bridge_locked_port_test() +{ + RET=0 + + ip link add name br1 up type bridge vlan_filtering 0 + + ip link add link $swp1 name $swp1.10 type vlan id 10 + ip link set dev $swp1.10 master br1 + + bridge link set dev $swp1.10 locked on + check_fail $? "managed to set locked flag on a VLAN upper" + + ip link set dev $swp1.10 nomaster + ip link set dev $swp1 master br1 + + bridge link set dev $swp1 locked on + check_fail $? "managed to set locked flag on a bridge port that has a VLAN upper" + + ip link del dev $swp1.10 + bridge link set dev $swp1 locked on + + ip link add link $swp1 name $swp1.10 type vlan id 10 + check_fail $? "managed to configure a VLAN upper on a locked port" + + log_test "bridge locked port" + + ip link del dev $swp1.10 &> /dev/null + ip link del dev br1 +} + devlink_reload_test() { # Test that after executing all the above configuration tests, a diff --git a/tools/testing/selftests/drivers/net/mlxsw/sch_ets.sh b/tools/testing/selftests/drivers/net/mlxsw/sch_ets.sh index 94c37124a840..139175fd03e7 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/sch_ets.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/sch_ets.sh @@ -5,7 +5,6 @@ lib_dir=$(dirname $0)/../../../net/forwarding source $lib_dir/sch_ets_core.sh source $lib_dir/devlink_lib.sh -source qos_lib.sh ALL_TESTS=" ping_ipv4 @@ -15,23 +14,31 @@ ALL_TESTS=" ets_test_dwrr " +PARENT="parent 3:3" + switch_create() { - ets_switch_create - # Create a bottleneck so that the DWRR process can kick in. - ethtool -s $h2 speed 1000 autoneg off - ethtool -s $swp2 speed 1000 autoneg off + tc qdisc replace dev $swp2 root handle 3: tbf rate 1gbit \ + burst 128K limit 1G + + ets_switch_create # Set the ingress quota high and use the three egress TCs to limit the # amount of traffic that is admitted to the shared buffers. This makes # sure that there is always enough traffic of all types to select from # for the DWRR process. + devlink_port_pool_th_save $swp1 0 devlink_port_pool_th_set $swp1 0 12 + devlink_tc_bind_pool_th_save $swp1 0 ingress devlink_tc_bind_pool_th_set $swp1 0 ingress 0 12 + devlink_port_pool_th_save $swp2 4 devlink_port_pool_th_set $swp2 4 12 + devlink_tc_bind_pool_th_save $swp2 7 egress devlink_tc_bind_pool_th_set $swp2 7 egress 4 5 + devlink_tc_bind_pool_th_save $swp2 6 egress devlink_tc_bind_pool_th_set $swp2 6 egress 4 5 + devlink_tc_bind_pool_th_save $swp2 5 egress devlink_tc_bind_pool_th_set $swp2 5 egress 4 5 # Note: sch_ets_core.sh uses VLAN ingress-qos-map to assign packet @@ -49,10 +56,9 @@ switch_destroy() devlink_tc_bind_pool_th_restore $swp1 0 ingress devlink_port_pool_th_restore $swp1 0 - ethtool -s $swp2 autoneg on - ethtool -s $h2 autoneg on - ets_switch_destroy + + tc qdisc del dev $swp2 root handle 3: } # Callback from sch_ets_tests.sh @@ -71,5 +77,5 @@ collect_stats() done } -bail_on_lldpad +bail_on_lldpad "configure DCB" "configure Qdiscs" ets_run diff --git a/tools/testing/selftests/drivers/net/mlxsw/sch_offload.sh b/tools/testing/selftests/drivers/net/mlxsw/sch_offload.sh new file mode 100755 index 000000000000..071a33d10c20 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/sch_offload.sh @@ -0,0 +1,290 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test qdisc offload indication + + +ALL_TESTS=" + test_root + test_port_tbf + test_etsprio + test_etsprio_port_tbf +" +NUM_NETIFS=1 +lib_dir=$(dirname $0)/../../../net/forwarding +source $lib_dir/lib.sh + +check_not_offloaded() +{ + local handle=$1; shift + local h + local offloaded + + h=$(qdisc_stats_get $h1 "$handle" .handle) + [[ $h == '"'$handle'"' ]] + check_err $? "Qdisc with handle $handle does not exist" + + offloaded=$(qdisc_stats_get $h1 "$handle" .offloaded) + [[ $offloaded == true ]] + check_fail $? "Qdisc with handle $handle offloaded, but should not be" +} + +check_all_offloaded() +{ + local handle=$1; shift + + if [[ ! -z $handle ]]; then + local offloaded=$(qdisc_stats_get $h1 "$handle" .offloaded) + [[ $offloaded == true ]] + check_err $? "Qdisc with handle $handle not offloaded" + fi + + local unoffloaded=$(tc q sh dev $h1 invisible | + grep -v offloaded | + sed s/root/parent\ root/ | + cut -d' ' -f 5) + [[ -z $unoffloaded ]] + check_err $? "Qdiscs with following parents not offloaded: $unoffloaded" + + pre_cleanup +} + +with_ets() +{ + local handle=$1; shift + local locus=$1; shift + + tc qdisc add dev $h1 $locus handle $handle \ + ets bands 8 priomap 7 6 5 4 3 2 1 0 + "$@" + tc qdisc del dev $h1 $locus +} + +with_prio() +{ + local handle=$1; shift + local locus=$1; shift + + tc qdisc add dev $h1 $locus handle $handle \ + prio bands 8 priomap 7 6 5 4 3 2 1 0 + "$@" + tc qdisc del dev $h1 $locus +} + +with_red() +{ + local handle=$1; shift + local locus=$1; shift + + tc qdisc add dev $h1 $locus handle $handle \ + red limit 1000000 min 200000 max 300000 probability 0.5 avpkt 1500 + "$@" + tc qdisc del dev $h1 $locus +} + +with_tbf() +{ + local handle=$1; shift + local locus=$1; shift + + tc qdisc add dev $h1 $locus handle $handle \ + tbf rate 400Mbit burst 128K limit 1M + "$@" + tc qdisc del dev $h1 $locus +} + +with_pfifo() +{ + local handle=$1; shift + local locus=$1; shift + + tc qdisc add dev $h1 $locus handle $handle pfifo limit 100K + "$@" + tc qdisc del dev $h1 $locus +} + +with_bfifo() +{ + local handle=$1; shift + local locus=$1; shift + + tc qdisc add dev $h1 $locus handle $handle bfifo limit 100K + "$@" + tc qdisc del dev $h1 $locus +} + +with_drr() +{ + local handle=$1; shift + local locus=$1; shift + + tc qdisc add dev $h1 $locus handle $handle drr + "$@" + tc qdisc del dev $h1 $locus +} + +with_qdiscs() +{ + local handle=$1; shift + local parent=$1; shift + local kind=$1; shift + local next_handle=$((handle * 2)) + local locus; + + if [[ $kind == "--" ]]; then + local cmd=$1; shift + $cmd $(printf %x: $parent) "$@" + else + if ((parent == 0)); then + locus=root + else + locus=$(printf "parent %x:1" $parent) + fi + + with_$kind $(printf %x: $handle) "$locus" \ + with_qdiscs $next_handle $handle "$@" + fi +} + +get_name() +{ + local parent=$1; shift + local name=$(echo "" "${@^^}" | tr ' ' -) + + if ((parent != 0)); then + kind=$(qdisc_stats_get $h1 $parent: .kind) + kind=${kind%\"} + kind=${kind#\"} + name="-${kind^^}$name" + fi + + echo root$name +} + +do_test_offloaded() +{ + local handle=$1; shift + local parent=$1; shift + + RET=0 + with_qdiscs $handle $parent "$@" -- check_all_offloaded + log_test $(get_name $parent "$@")" offloaded" +} + +do_test_nooffload() +{ + local handle=$1; shift + local parent=$1; shift + + local name=$(echo "${@^^}" | tr ' ' -) + local kind + + RET=0 + with_qdiscs $handle $parent "$@" -- check_not_offloaded + log_test $(get_name $parent "$@")" not offloaded" +} + +do_test_combinations() +{ + local handle=$1; shift + local parent=$1; shift + + local cont + local leaf + local fifo + + for cont in "" ets prio; do + for leaf in "" red tbf "red tbf" "tbf red"; do + for fifo in "" pfifo bfifo; do + if [[ -z "$cont$leaf$fifo" ]]; then + continue + fi + do_test_offloaded $handle $parent \ + $cont $leaf $fifo + done + done + done + + for cont in ets prio; do + for leaf in red tbf; do + do_test_nooffload $handle $parent $cont red tbf $leaf + do_test_nooffload $handle $parent $cont tbf red $leaf + done + for leaf in "red red" "tbf tbf"; do + do_test_nooffload $handle $parent $cont $leaf + done + done + + do_test_nooffload $handle $parent drr +} + +test_root() +{ + do_test_combinations 1 0 +} + +test_port_tbf() +{ + with_tbf 1: root \ + do_test_combinations 8 1 +} + +do_test_etsprio() +{ + local parent=$1; shift + local tbfpfx=$1; shift + local cont + + for cont in ets prio; do + RET=0 + with_$cont 8: "$parent" \ + with_red 11: "parent 8:1" \ + with_red 12: "parent 8:2" \ + with_tbf 13: "parent 8:3" \ + with_tbf 14: "parent 8:4" \ + check_all_offloaded + log_test "root$tbfpfx-ETS-{RED,TBF} offloaded" + + RET=0 + with_$cont 8: "$parent" \ + with_red 81: "parent 8:1" \ + with_tbf 811: "parent 81:1" \ + with_tbf 84: "parent 8:4" \ + with_red 841: "parent 84:1" \ + check_all_offloaded + log_test "root$tbfpfx-ETS-{RED-TBF,TBF-RED} offloaded" + + RET=0 + with_$cont 8: "$parent" \ + with_red 81: "parent 8:1" \ + with_tbf 811: "parent 81:1" \ + with_bfifo 8111: "parent 811:1" \ + with_tbf 82: "parent 8:2" \ + with_red 821: "parent 82:1" \ + with_bfifo 8211: "parent 821:1" \ + check_all_offloaded + log_test "root$tbfpfx-ETS-{RED-TBF-bFIFO,TBF-RED-bFIFO} offloaded" + done +} + +test_etsprio() +{ + do_test_etsprio root "" +} + +test_etsprio_port_tbf() +{ + with_tbf 1: root \ + do_test_etsprio "parent 1:1" "-TBF" +} + +cleanup() +{ + tc qdisc del dev $h1 root &>/dev/null +} + +trap cleanup EXIT +h1=${NETIFS[p1]} +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/sch_red_core.sh b/tools/testing/selftests/drivers/net/mlxsw/sch_red_core.sh index 517297a14ecf..299e06a5808c 100644 --- a/tools/testing/selftests/drivers/net/mlxsw/sch_red_core.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/sch_red_core.sh @@ -73,7 +73,7 @@ CHECK_TC="yes" lib_dir=$(dirname $0)/../../../net/forwarding source $lib_dir/lib.sh source $lib_dir/devlink_lib.sh -source qos_lib.sh +source mlxsw_lib.sh ipaddr() { @@ -134,14 +134,16 @@ h2_create() # cause packets to fail to queue up at $swp3 due to shared buffer # quotas, and the test to spuriously fail. # - # Prevent this by setting the speed of $h2 to 1Gbps. + # Prevent this by adding a shaper which limits the traffic in $h2 to + # 1Gbps. - ethtool -s $h2 speed 1000 autoneg off + tc qdisc replace dev $h2 root handle 10: tbf rate 1gbit \ + burst 128K limit 1G } h2_destroy() { - ethtool -s $h2 autoneg on + tc qdisc del dev $h2 root handle 10: tc qdisc del dev $h2 clsact host_destroy $h2 } @@ -149,12 +151,10 @@ h2_destroy() h3_create() { host_create $h3 3 - ethtool -s $h3 speed 1000 autoneg off } h3_destroy() { - ethtool -s $h3 autoneg on host_destroy $h3 } @@ -198,8 +198,9 @@ switch_create() done done - for intf in $swp2 $swp3 $swp4 $swp5; do - ethtool -s $intf speed 1000 autoneg off + for intf in $swp3 $swp4; do + tc qdisc replace dev $intf root handle 1: tbf rate 1gbit \ + burst 128K limit 1G done ip link set dev br1_10 up @@ -208,6 +209,7 @@ switch_create() ip link set dev br2_11 up local size=$(devlink_pool_size_thtype 0 | cut -d' ' -f 1) + devlink_port_pool_th_save $swp3 8 devlink_port_pool_th_set $swp3 8 $size } @@ -218,15 +220,13 @@ switch_destroy() devlink_port_pool_th_restore $swp3 8 - tc qdisc del dev $swp3 root 2>/dev/null - ip link set dev br2_11 down ip link set dev br2_10 down ip link set dev br1_11 down ip link set dev br1_10 down - for intf in $swp5 $swp4 $swp3 $swp2; do - ethtool -s $intf autoneg on + for intf in $swp4 $swp3; do + tc qdisc del dev $intf root handle 1: done for intf in $swp5 $swp3 $swp2 $swp4 $swp1; do @@ -330,6 +330,14 @@ get_nmarked() ethtool_stats_get $swp3 ecn_marked } +get_qdisc_nmarked() +{ + local vlan=$1; shift + + busywait_for_counter 1100 +1 \ + qdisc_stats_get $swp3 $(get_qdisc_handle $vlan) .marked +} + get_qdisc_npackets() { local vlan=$1; shift @@ -383,14 +391,15 @@ build_backlog() check_marking() { + local get_nmarked=$1; shift local vlan=$1; shift local cond=$1; shift local npackets_0=$(get_qdisc_npackets $vlan) - local nmarked_0=$(get_nmarked $vlan) + local nmarked_0=$($get_nmarked $vlan) sleep 5 local npackets_1=$(get_qdisc_npackets $vlan) - local nmarked_1=$(get_nmarked $vlan) + local nmarked_1=$($get_nmarked $vlan) local nmarked_d=$((nmarked_1 - nmarked_0)) local npackets_d=$((npackets_1 - npackets_0)) @@ -403,6 +412,7 @@ check_marking() ecn_test_common() { local name=$1; shift + local get_nmarked=$1; shift local vlan=$1; shift local limit=$1; shift local backlog @@ -415,7 +425,7 @@ ecn_test_common() RET=0 backlog=$(build_backlog $vlan $((2 * limit / 3)) udp) check_err $? "Could not build the requested backlog" - pct=$(check_marking $vlan "== 0") + pct=$(check_marking "$get_nmarked" $vlan "== 0") check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0." log_test "TC $((vlan - 10)): $name backlog < limit" @@ -425,22 +435,23 @@ ecn_test_common() RET=0 backlog=$(build_backlog $vlan $((3 * limit / 2)) tcp tos=0x01) check_err $? "Could not build the requested backlog" - pct=$(check_marking $vlan ">= 95") + pct=$(check_marking "$get_nmarked" $vlan ">= 95") check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected >= 95." log_test "TC $((vlan - 10)): $name backlog > limit" } -do_ecn_test() +__do_ecn_test() { + local get_nmarked=$1; shift local vlan=$1; shift local limit=$1; shift - local name=ECN + local name=${1-ECN}; shift start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) \ $h3_mac tos=0x01 sleep 1 - ecn_test_common "$name" $vlan $limit + ecn_test_common "$name" "$get_nmarked" $vlan $limit # Up there we saw that UDP gets accepted when backlog is below the # limit. Now that it is above, it should all get dropped, and backlog @@ -454,6 +465,23 @@ do_ecn_test() sleep 1 } +do_ecn_test() +{ + local vlan=$1; shift + local limit=$1; shift + + __do_ecn_test get_nmarked "$vlan" "$limit" +} + +do_ecn_test_perband() +{ + local vlan=$1; shift + local limit=$1; shift + + mlxsw_only_on_spectrum 3+ || return + __do_ecn_test get_qdisc_nmarked "$vlan" "$limit" "per-band ECN" +} + do_ecn_nodrop_test() { local vlan=$1; shift @@ -464,7 +492,7 @@ do_ecn_nodrop_test() $h3_mac tos=0x01 sleep 1 - ecn_test_common "$name" $vlan $limit + ecn_test_common "$name" get_nmarked $vlan $limit # Up there we saw that UDP gets accepted when backlog is below the # limit. Now that it is above, in nodrop mode, make sure it goes to @@ -494,7 +522,7 @@ do_red_test() RET=0 backlog=$(build_backlog $vlan $((2 * limit / 3)) tcp tos=0x01) check_err $? "Could not build the requested backlog" - pct=$(check_marking $vlan "== 0") + pct=$(check_marking get_nmarked $vlan "== 0") check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0." log_test "TC $((vlan - 10)): RED backlog < limit" @@ -502,12 +530,12 @@ do_red_test() RET=0 backlog=$(build_backlog $vlan $((3 * limit / 2)) tcp tos=0x01) check_fail $? "Traffic went into backlog instead of being early-dropped" - pct=$(check_marking $vlan "== 0") + pct=$(check_marking get_nmarked $vlan "== 0") check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0." local diff=$((limit - backlog)) pct=$((100 * diff / limit)) - ((0 <= pct && pct <= 5)) - check_err $? "backlog $backlog / $limit expected <= 5% distance" + ((-10 <= pct && pct <= 10)) + check_err $? "backlog $backlog / $limit expected <= 10% distance" log_test "TC $((vlan - 10)): RED backlog > limit" stop_traffic @@ -543,6 +571,55 @@ do_mc_backlog_test() log_test "TC $((vlan - 10)): Qdisc reports MC backlog" } +do_mark_test() +{ + local vlan=$1; shift + local limit=$1; shift + local subtest=$1; shift + local fetch_counter=$1; shift + local should_fail=$1; shift + local base + + mlxsw_only_on_spectrum 2+ || return + + RET=0 + + start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) \ + $h3_mac tos=0x01 + + # Create a bit of a backlog and observe no mirroring due to marks. + qevent_rule_install_$subtest + + build_backlog $vlan $((2 * limit / 3)) tcp tos=0x01 >/dev/null + + base=$($fetch_counter) + count=$(busywait 1100 until_counter_is ">= $((base + 1))" \ + $fetch_counter) + check_fail $? "Spurious packets ($base -> $count) observed without buffer pressure" + + # Above limit, everything should be mirrored, we should see lots of + # packets. + build_backlog $vlan $((3 * limit / 2)) tcp tos=0x01 >/dev/null + busywait_for_counter 1100 +10000 \ + $fetch_counter > /dev/null + check_err_fail "$should_fail" $? "ECN-marked packets $subtest'd" + + # When the rule is uninstalled, there should be no mirroring. + qevent_rule_uninstall_$subtest + busywait_for_counter 1100 +10 \ + $fetch_counter > /dev/null + check_fail $? "Spurious packets observed after uninstall" + + if ((should_fail)); then + log_test "TC $((vlan - 10)): marked packets not $subtest'd" + else + log_test "TC $((vlan - 10)): marked packets $subtest'd" + fi + + stop_traffic + sleep 1 +} + do_drop_test() { local vlan=$1; shift @@ -550,10 +627,10 @@ do_drop_test() local trigger=$1; shift local subtest=$1; shift local fetch_counter=$1; shift - local backlog local base local now - local pct + + mlxsw_only_on_spectrum 2+ || return RET=0 @@ -627,6 +704,22 @@ do_drop_mirror_test() tc filter del dev $h2 ingress pref 1 handle 101 flower } +do_mark_mirror_test() +{ + local vlan=$1; shift + local limit=$1; shift + + tc filter add dev $h2 ingress pref 1 handle 101 prot ip \ + flower skip_sw ip_proto tcp \ + action drop + + do_mark_test "$vlan" "$limit" mirror \ + qevent_counter_fetch_mirror \ + $(: should_fail=)0 + + tc filter del dev $h2 ingress pref 1 handle 101 flower +} + qevent_rule_install_trap() { tc filter add block 10 pref 1234 handle 102 matchall skip_sw \ @@ -654,3 +747,14 @@ do_drop_trap_test() do_drop_test "$vlan" "$limit" "$trap_name" trap \ "qevent_counter_fetch_trap $trap_name" } + +qevent_rule_install_trap_fwd() +{ + tc filter add block 10 pref 1234 handle 102 matchall skip_sw \ + action trap_fwd hw_stats disabled +} + +qevent_rule_uninstall_trap_fwd() +{ + tc filter del block 10 pref 1234 handle 102 matchall +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/sch_red_ets.sh b/tools/testing/selftests/drivers/net/mlxsw/sch_red_ets.sh index 3f007c5f8361..8ecddafa79b3 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/sch_red_ets.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/sch_red_ets.sh @@ -4,11 +4,13 @@ ALL_TESTS=" ping_ipv4 ecn_test + ecn_test_perband ecn_nodrop_test red_test mc_backlog_test red_mirror_test red_trap_test + ecn_mirror_test " : ${QDISC:=ets} source sch_red_core.sh @@ -21,26 +23,58 @@ source sch_red_core.sh BACKLOG1=200000 BACKLOG2=500000 -install_qdisc() +install_root_qdisc() +{ + tc qdisc add dev $swp3 parent 1: handle 10: $QDISC \ + bands 8 priomap 7 6 5 4 3 2 1 0 +} + +install_qdisc_tc0() { local -a args=("$@") - tc qdisc add dev $swp3 root handle 10: $QDISC \ - bands 8 priomap 7 6 5 4 3 2 1 0 tc qdisc add dev $swp3 parent 10:8 handle 108: red \ limit 1000000 min $BACKLOG1 max $((BACKLOG1 + 1)) \ probability 1.0 avpkt 8000 burst 38 "${args[@]}" +} + +install_qdisc_tc1() +{ + local -a args=("$@") + tc qdisc add dev $swp3 parent 10:7 handle 107: red \ limit 1000000 min $BACKLOG2 max $((BACKLOG2 + 1)) \ probability 1.0 avpkt 8000 burst 63 "${args[@]}" +} + +install_qdisc() +{ + install_root_qdisc + install_qdisc_tc0 "$@" + install_qdisc_tc1 "$@" sleep 1 } -uninstall_qdisc() +uninstall_qdisc_tc0() { - tc qdisc del dev $swp3 parent 10:7 tc qdisc del dev $swp3 parent 10:8 - tc qdisc del dev $swp3 root +} + +uninstall_qdisc_tc1() +{ + tc qdisc del dev $swp3 parent 10:7 +} + +uninstall_root_qdisc() +{ + tc qdisc del dev $swp3 parent 1: +} + +uninstall_qdisc() +{ + uninstall_qdisc_tc0 + uninstall_qdisc_tc1 + uninstall_root_qdisc } ecn_test() @@ -53,6 +87,16 @@ ecn_test() uninstall_qdisc } +ecn_test_perband() +{ + install_qdisc ecn + + do_ecn_test_perband 10 $BACKLOG1 + do_ecn_test_perband 11 $BACKLOG2 + + uninstall_qdisc +} + ecn_nodrop_test() { install_qdisc ecn nodrop @@ -67,6 +111,13 @@ red_test() { install_qdisc + # Make sure that we get the non-zero value if there is any. + local cur=$(busywait 1100 until_counter_is "> 0" \ + qdisc_stats_get $swp3 10: .backlog) + (( cur == 0 )) + check_err $? "backlog of $cur observed on non-busy qdisc" + log_test "$QDISC backlog properly cleaned" + do_red_test 10 $BACKLOG1 do_red_test 11 $BACKLOG2 @@ -105,12 +156,21 @@ red_trap_test() uninstall_qdisc } -trap cleanup EXIT +ecn_mirror_test() +{ + install_qdisc ecn qevent mark block 10 + + do_mark_mirror_test 10 $BACKLOG1 + do_mark_mirror_test 11 $BACKLOG2 + uninstall_qdisc +} + +bail_on_lldpad "configure DCB" "configure Qdiscs" + +trap cleanup EXIT setup_prepare setup_wait - -bail_on_lldpad tests_run exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/sch_red_root.sh b/tools/testing/selftests/drivers/net/mlxsw/sch_red_root.sh index ede9c38d3eff..159108d02895 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/sch_red_root.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/sch_red_root.sh @@ -4,6 +4,7 @@ ALL_TESTS=" ping_ipv4 ecn_test + ecn_test_perband ecn_nodrop_test red_test mc_backlog_test @@ -17,7 +18,7 @@ install_qdisc() { local -a args=("$@") - tc qdisc add dev $swp3 root handle 108: red \ + tc qdisc add dev $swp3 parent 1: handle 108: red \ limit 1000000 min $BACKLOG max $((BACKLOG + 1)) \ probability 1.0 avpkt 8000 burst 38 "${args[@]}" sleep 1 @@ -25,7 +26,7 @@ install_qdisc() uninstall_qdisc() { - tc qdisc del dev $swp3 root + tc qdisc del dev $swp3 parent 1: } ecn_test() @@ -35,6 +36,13 @@ ecn_test() uninstall_qdisc } +ecn_test_perband() +{ + install_qdisc ecn + do_ecn_test_perband 10 $BACKLOG + uninstall_qdisc +} + ecn_nodrop_test() { install_qdisc ecn nodrop @@ -65,12 +73,11 @@ red_mirror_test() uninstall_qdisc } -trap cleanup EXIT +bail_on_lldpad "configure DCB" "configure Qdiscs" +trap cleanup EXIT setup_prepare setup_wait - -bail_on_lldpad tests_run exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/sch_tbf_ets.sh b/tools/testing/selftests/drivers/net/mlxsw/sch_tbf_ets.sh index c6ce0b448bf3..ecc3664376b3 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/sch_tbf_ets.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/sch_tbf_ets.sh @@ -1,8 +1,10 @@ #!/bin/bash # SPDX-License-Identifier: GPL-2.0 -source qos_lib.sh -bail_on_lldpad +sch_tbf_pre_hook() +{ + bail_on_lldpad "configure DCB" "configure Qdiscs" +} lib_dir=$(dirname $0)/../../../net/forwarding TCFLAGS=skip_sw diff --git a/tools/testing/selftests/drivers/net/mlxsw/sch_tbf_prio.sh b/tools/testing/selftests/drivers/net/mlxsw/sch_tbf_prio.sh index 8d245f331619..2e0a4efb1703 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/sch_tbf_prio.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/sch_tbf_prio.sh @@ -1,8 +1,10 @@ #!/bin/bash # SPDX-License-Identifier: GPL-2.0 -source qos_lib.sh -bail_on_lldpad +sch_tbf_pre_hook() +{ + bail_on_lldpad "configure DCB" "configure Qdiscs" +} lib_dir=$(dirname $0)/../../../net/forwarding TCFLAGS=skip_sw diff --git a/tools/testing/selftests/drivers/net/mlxsw/sch_tbf_root.sh b/tools/testing/selftests/drivers/net/mlxsw/sch_tbf_root.sh index 013886061f15..6679a338dfc4 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/sch_tbf_root.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/sch_tbf_root.sh @@ -1,8 +1,10 @@ #!/bin/bash # SPDX-License-Identifier: GPL-2.0 -source qos_lib.sh -bail_on_lldpad +sch_tbf_pre_hook() +{ + bail_on_lldpad "configure DCB" "configure Qdiscs" +} lib_dir=$(dirname $0)/../../../net/forwarding TCFLAGS=skip_sw diff --git a/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer.sh b/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer.sh index 7d9e73a43a49..0c47faff9274 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer.sh @@ -98,12 +98,12 @@ sb_occ_etc_check() port_pool_test() { - local exp_max_occ=288 + local exp_max_occ=$(devlink_cell_size_get) local max_occ devlink sb occupancy clearmax $DEVLINK_DEV - $MZ $h1 -c 1 -p 160 -a $h1mac -b $h2mac -A 192.0.1.1 -B 192.0.1.2 \ + $MZ $h1 -c 1 -p 10 -a $h1mac -b $h2mac -A 192.0.1.1 -B 192.0.1.2 \ -t ip -q devlink sb occupancy snapshot $DEVLINK_DEV @@ -126,12 +126,12 @@ port_pool_test() port_tc_ip_test() { - local exp_max_occ=288 + local exp_max_occ=$(devlink_cell_size_get) local max_occ devlink sb occupancy clearmax $DEVLINK_DEV - $MZ $h1 -c 1 -p 160 -a $h1mac -b $h2mac -A 192.0.1.1 -B 192.0.1.2 \ + $MZ $h1 -c 1 -p 10 -a $h1mac -b $h2mac -A 192.0.1.1 -B 192.0.1.2 \ -t ip -q devlink sb occupancy snapshot $DEVLINK_DEV @@ -154,16 +154,12 @@ port_tc_ip_test() port_tc_arp_test() { - local exp_max_occ=96 + local exp_max_occ=$(devlink_cell_size_get) local max_occ - if [[ $MLXSW_CHIP != "mlxsw_spectrum" ]]; then - exp_max_occ=144 - fi - devlink sb occupancy clearmax $DEVLINK_DEV - $MZ $h1 -c 1 -p 160 -a $h1mac -A 192.0.1.1 -t arp -q + $MZ $h1 -c 1 -p 10 -a $h1mac -A 192.0.1.1 -t arp -q devlink sb occupancy snapshot $DEVLINK_DEV diff --git a/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer_configuration.py b/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer_configuration.py index 0d4b9327c9b3..2223337eed0c 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer_configuration.py +++ b/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer_configuration.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # SPDX-License-Identifier: GPL-2.0 import subprocess diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/port_range_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/port_range_scale.sh new file mode 120000 index 000000000000..bd670d9dc4e5 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/port_range_scale.sh @@ -0,0 +1 @@ +../spectrum/port_range_scale.sh
\ No newline at end of file diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/port_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/port_scale.sh new file mode 100644 index 000000000000..0b71dfbbb447 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/port_scale.sh @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 +source ../port_scale.sh + +port_get_target() +{ + local should_fail=$1 + local target + + target=$(devlink_resource_size_get physical_ports) + + if ((! should_fail)); then + echo $target + else + echo $((target + 1)) + fi +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/resource_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/resource_scale.sh index d7cf33a3f18d..a88d8a8c85f2 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/resource_scale.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/resource_scale.sh @@ -7,12 +7,9 @@ NUM_NETIFS=6 source $lib_dir/lib.sh source $lib_dir/tc_common.sh source $lib_dir/devlink_lib.sh +source ../mlxsw_lib.sh -if [[ "$DEVLINK_VIDDID" != "15b3:cf6c" && \ - "$DEVLINK_VIDDID" != "15b3:cf70" ]]; then - echo "SKIP: test is tailored for Mellanox Spectrum-2 and Spectrum-3" - exit 1 -fi +mlxsw_only_on_spectrum 2+ || exit 1 current_test="" @@ -28,8 +25,19 @@ cleanup() trap cleanup EXIT -ALL_TESTS="router tc_flower mirror_gre tc_police" +ALL_TESTS=" + router + tc_flower + mirror_gre + tc_police + port + rif_mac_profile + rif_counter + port_range +" + for current_test in ${TESTS:-$ALL_TESTS}; do + RET_FIN=0 source ${current_test}_scale.sh num_netifs_var=${current_test^^}_NUM_NETIFS @@ -38,18 +46,35 @@ for current_test in ${TESTS:-$ALL_TESTS}; do for should_fail in 0 1; do RET=0 target=$(${current_test}_get_target "$should_fail") + if ((target == 0)); then + log_test_skip "'$current_test' should_fail=$should_fail test" + continue + fi + ${current_test}_setup_prepare setup_wait $num_netifs + # Update target in case occupancy of a certain resource changed + # following the test setup. + target=$(${current_test}_get_target "$should_fail") ${current_test}_test "$target" "$should_fail" - ${current_test}_cleanup - devlink_reload if [[ "$should_fail" -eq 0 ]]; then log_test "'$current_test' $target" + + if ((!RET)); then + tt=${current_test}_traffic_test + if [[ $(type -t $tt) == "function" ]]; then + $tt "$target" + log_test "'$current_test' $target traffic test" + fi + fi else log_test "'$current_test' overflow $target" fi + ${current_test}_cleanup $target + devlink_reload + RET_FIN=$(( RET_FIN || RET )) done done current_test="" -exit "$RET" +exit "$RET_FIN" diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/rif_counter_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/rif_counter_scale.sh new file mode 120000 index 000000000000..1f5752e8ffc0 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/rif_counter_scale.sh @@ -0,0 +1 @@ +../spectrum/rif_counter_scale.sh
\ No newline at end of file diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/rif_mac_profile_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/rif_mac_profile_scale.sh new file mode 100644 index 000000000000..303d7cbe3c45 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/rif_mac_profile_scale.sh @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 +source ../rif_mac_profile_scale.sh + +rif_mac_profile_get_target() +{ + local should_fail=$1 + local target + + target=$(devlink_resource_size_get rif_mac_profiles) + + if ((! should_fail)); then + echo $target + else + echo $((target + 1)) + fi +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh index fb850e0ec837..31252bc8775e 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh @@ -10,7 +10,8 @@ lib_dir=$(dirname $0)/../../../../net/forwarding ALL_TESTS="single_mask_test identical_filters_test two_masks_test \ multiple_masks_test ctcam_edge_cases_test delta_simple_test \ delta_two_masks_one_key_test delta_simple_rehash_test \ - bloom_simple_test bloom_complex_test bloom_delta_test" + bloom_simple_test bloom_complex_test bloom_delta_test \ + max_erp_entries_test max_group_size_test" NUM_NETIFS=2 source $lib_dir/lib.sh source $lib_dir/tc_common.sh @@ -868,7 +869,7 @@ bloom_simple_test() bloom_complex_test() { # Bloom filter index computation is affected from region ID, eRP - # ID and from the region key size. In order to excercise those parts + # ID and from the region key size. In order to exercise those parts # of the Bloom filter code, use a series of regions, each with a # different key size and send packet that should hit all of them. local index @@ -983,6 +984,109 @@ bloom_delta_test() log_test "bloom delta test ($tcflags)" } +max_erp_entries_test() +{ + # The number of eRP entries is limited. Once the maximum number of eRPs + # has been reached, filters cannot be added. This test verifies that + # when this limit is reached, inserstion fails without crashing. + + RET=0 + + local num_masks=32 + local num_regions=15 + local chain_failed + local mask_failed + local ret + + if [[ "$tcflags" != "skip_sw" ]]; then + return 0; + fi + + for ((i=1; i < $num_regions; i++)); do + for ((j=$num_masks; j >= 0; j--)); do + tc filter add dev $h2 ingress chain $i protocol ip \ + pref $i handle $j flower $tcflags \ + dst_ip 192.1.0.0/$j &> /dev/null + ret=$? + + if [ $ret -ne 0 ]; then + chain_failed=$i + mask_failed=$j + break 2 + fi + done + done + + # We expect to exceed the maximum number of eRP entries, so that + # insertion eventually fails. Otherwise, the test should be adjusted to + # add more filters. + check_fail $ret "expected to exceed number of eRP entries" + + for ((; i >= 1; i--)); do + for ((j=0; j <= $num_masks; j++)); do + tc filter del dev $h2 ingress chain $i protocol ip \ + pref $i handle $j flower &> /dev/null + done + done + + log_test "max eRP entries test ($tcflags). " \ + "max chain $chain_failed, mask $mask_failed" +} + +max_group_size_test() +{ + # The number of ACLs in an ACL group is limited. Once the maximum + # number of ACLs has been reached, filters cannot be added. This test + # verifies that when this limit is reached, insertion fails without + # crashing. + + RET=0 + + local num_acls=32 + local max_size + local ret + + if [[ "$tcflags" != "skip_sw" ]]; then + return 0; + fi + + for ((i=1; i < $num_acls; i++)); do + if [[ $(( i % 2 )) == 1 ]]; then + tc filter add dev $h2 ingress pref $i proto ipv4 \ + flower $tcflags dst_ip 198.51.100.1/32 \ + ip_proto tcp tcp_flags 0x01/0x01 \ + action drop &> /dev/null + else + tc filter add dev $h2 ingress pref $i proto ipv6 \ + flower $tcflags dst_ip 2001:db8:1::1/128 \ + action drop &> /dev/null + fi + + ret=$? + [[ $ret -ne 0 ]] && max_size=$((i - 1)) && break + done + + # We expect to exceed the maximum number of ACLs in a group, so that + # insertion eventually fails. Otherwise, the test should be adjusted to + # add more filters. + check_fail $ret "expected to exceed number of ACLs in a group" + + for ((; i >= 1; i--)); do + if [[ $(( i % 2 )) == 1 ]]; then + tc filter del dev $h2 ingress pref $i proto ipv4 \ + flower $tcflags dst_ip 198.51.100.1/32 \ + ip_proto tcp tcp_flags 0x01/0x01 \ + action drop &> /dev/null + else + tc filter del dev $h2 ingress pref $i proto ipv6 \ + flower $tcflags dst_ip 2001:db8:1::1/128 \ + action drop &> /dev/null + fi + done + + log_test "max ACL group size test ($tcflags). max size $max_size" +} + setup_prepare() { h1=${NETIFS[p1]} diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower_scale.sh index efd798a85931..4444bbace1a9 100644 --- a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower_scale.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower_scale.sh @@ -4,17 +4,22 @@ source ../tc_flower_scale.sh tc_flower_get_target() { local should_fail=$1; shift + local max_cnts # The driver associates a counter with each tc filter, which means the # number of supported filters is bounded by the number of available # counters. - # Currently, the driver supports 30K (30,720) flow counters and six of - # these are used for multicast routing. - local target=30714 + max_cnts=$(devlink_resource_size_get counters flow) + + # Remove already allocated counters. + ((max_cnts -= $(devlink_resource_occ_get counters flow))) + + # Each rule uses two counters, for packets and bytes. + ((max_cnts /= 2)) if ((! should_fail)); then - echo $target + echo $max_cnts else - echo $((target + 1)) + echo $((max_cnts + 1)) fi } diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/vxlan_flooding_ipv6.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/vxlan_flooding_ipv6.sh new file mode 100755 index 000000000000..fd23c80eba31 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/vxlan_flooding_ipv6.sh @@ -0,0 +1,339 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test VxLAN flooding. The device stores flood records in a singly linked list +# where each record stores up to four IPv6 addresses of remote VTEPs. The test +# verifies that packets are correctly flooded in various cases such as deletion +# of a record in the middle of the list. +# +# +-----------------------+ +# | H1 (vrf) | +# | + $h1 | +# | | 2001:db8:1::1/64 | +# +----|------------------+ +# | +# +----|----------------------------------------------------------------------+ +# | SW | | +# | +--|--------------------------------------------------------------------+ | +# | | + $swp1 BR0 (802.1d) | | +# | | | | +# | | + vxlan0 (vxlan) | | +# | | local 2001:db8:2::1 | | +# | | remote 2001:db8:2::{2..17} | | +# | | id 10 dstport 4789 | | +# | +-----------------------------------------------------------------------+ | +# | | +# | 2001:db8:2::0/64 via 2001:db8:3::2 | +# | | +# | + $rp1 | +# | | 2001:db8:3::1/64 | +# +----|----------------------------------------------------------------------+ +# | +# +----|--------------------------------------------------------+ +# | | R2 (vrf) | +# | + $rp2 | +# | 2001:db8:3::2/64 | +# | | +# +-------------------------------------------------------------+ + +lib_dir=$(dirname $0)/../../../../net/forwarding + +ALL_TESTS="flooding_test" +NUM_NETIFS=4 +source $lib_dir/tc_common.sh +source $lib_dir/lib.sh + +h1_create() +{ + simple_if_init $h1 2001:db8:1::1/64 +} + +h1_destroy() +{ + simple_if_fini $h1 2001:db8:1::1/64 +} + +switch_create() +{ + # Make sure the bridge uses the MAC address of the local port and + # not that of the VxLAN's device + ip link add dev br0 type bridge mcast_snooping 0 + ip link set dev br0 address $(mac_get $swp1) + + ip link add name vxlan0 type vxlan id 10 nolearning \ + udp6zerocsumrx udp6zerocsumtx ttl 20 tos inherit \ + local 2001:db8:2::1 dstport 4789 + + ip address add 2001:db8:2::1/128 dev lo + + ip link set dev $swp1 master br0 + ip link set dev vxlan0 master br0 + + ip link set dev br0 up + ip link set dev $swp1 up + ip link set dev vxlan0 up +} + +switch_destroy() +{ + ip link set dev vxlan0 down + ip link set dev $swp1 down + ip link set dev br0 down + + ip link set dev vxlan0 nomaster + ip link set dev $swp1 nomaster + + ip address del 2001:db8:2::1/128 dev lo + + ip link del dev vxlan0 + + ip link del dev br0 +} + +router1_create() +{ + # This router is in the default VRF, where the VxLAN device is + # performing the L3 lookup + ip link set dev $rp1 up + ip address add 2001:db8:3::1/64 dev $rp1 + ip route add 2001:db8:2::0/64 via 2001:db8:3::2 +} + +router1_destroy() +{ + ip route del 2001:db8:2::0/64 via 2001:db8:3::2 + ip address del 2001:db8:3::1/64 dev $rp1 + ip link set dev $rp1 down +} + +router2_create() +{ + # This router is not in the default VRF, so use simple_if_init() + simple_if_init $rp2 2001:db8:3::2/64 +} + +router2_destroy() +{ + simple_if_fini $rp2 2001:db8:3::2/64 +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + rp1=${NETIFS[p3]} + rp2=${NETIFS[p4]} + + vrf_prepare + + h1_create + + switch_create + + router1_create + router2_create + + forwarding_enable +} + +cleanup() +{ + pre_cleanup + + forwarding_restore + + router2_destroy + router1_destroy + + switch_destroy + + h1_destroy + + vrf_cleanup +} + +flooding_remotes_add() +{ + local num_remotes=$1 + local lsb + local i + + # Prevent unwanted packets from entering the bridge and interfering + # with the test. + tc qdisc add dev br0 clsact + tc filter add dev br0 egress protocol all pref 1 handle 1 \ + matchall skip_hw action drop + tc qdisc add dev $h1 clsact + tc filter add dev $h1 egress protocol all pref 1 handle 1 \ + flower skip_hw dst_mac de:ad:be:ef:13:37 action pass + tc filter add dev $h1 egress protocol all pref 2 handle 2 \ + matchall skip_hw action drop + + for i in $(eval echo {1..$num_remotes}); do + lsb=$((i + 1)) + + bridge fdb append 00:00:00:00:00:00 dev vxlan0 self \ + dst 2001:db8:2::$lsb + done +} + +flooding_filters_add() +{ + local num_remotes=$1 + local lsb + local i + + tc qdisc add dev $rp2 clsact + + for i in $(eval echo {1..$num_remotes}); do + lsb=$((i + 1)) + + tc filter add dev $rp2 ingress protocol ipv6 pref $i handle $i \ + flower ip_proto udp dst_ip 2001:db8:2::$lsb \ + dst_port 4789 skip_sw action drop + done +} + +flooding_filters_del() +{ + local num_remotes=$1 + local i + + for i in $(eval echo {1..$num_remotes}); do + tc filter del dev $rp2 ingress protocol ipv6 pref $i \ + handle $i flower + done + + tc qdisc del dev $rp2 clsact + + tc filter del dev $h1 egress protocol all pref 2 handle 2 matchall + tc filter del dev $h1 egress protocol all pref 1 handle 1 flower + tc qdisc del dev $h1 clsact + tc filter del dev br0 egress protocol all pref 1 handle 1 matchall + tc qdisc del dev br0 clsact +} + +flooding_check_packets() +{ + local packets=("$@") + local num_remotes=${#packets[@]} + local i + + for i in $(eval echo {1..$num_remotes}); do + tc_check_packets "dev $rp2 ingress" $i ${packets[i - 1]} + check_err $? "remote $i - did not get expected number of packets" + done +} + +flooding_test() +{ + # Use 16 remote VTEPs that will be stored in 4 records. The array + # 'packets' will store how many packets are expected to be received + # by each remote VTEP at each stage of the test + declare -a packets=(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1) + local num_remotes=16 + + RET=0 + + # Add FDB entries for remote VTEPs and corresponding tc filters on the + # ingress of the nexthop router. These filters will count how many + # packets were flooded to each remote VTEP + flooding_remotes_add $num_remotes + flooding_filters_add $num_remotes + + # Send one packet and make sure it is flooded to all the remote VTEPs + $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 1 packet" + + # Delete the third record which corresponds to VTEPs with LSB 10..13 + # and check that packet is flooded correctly when we remove a record + # from the middle of the list + RET=0 + + packets=(2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::10 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::11 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::12 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::13 + + $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 2 packets" + + # Delete the first record and make sure the packet is flooded correctly + RET=0 + + packets=(2 2 2 2 3 3 3 3 1 1 1 1 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::2 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::3 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::4 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::5 + + $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 3 packets" + + # Delete the last record and make sure the packet is flooded correctly + RET=0 + + packets=(2 2 2 2 4 4 4 4 1 1 1 1 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::14 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::15 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::16 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::17 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 4 packets" + + # Delete the last record, one entry at a time and make sure single + # entries are correctly removed + RET=0 + + packets=(2 2 2 2 4 5 5 5 1 1 1 1 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::6 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 5 packets" + + RET=0 + + packets=(2 2 2 2 4 5 6 6 1 1 1 1 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::7 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 6 packets" + + RET=0 + + packets=(2 2 2 2 4 5 6 7 1 1 1 1 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::8 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 7 packets" + + RET=0 + + packets=(2 2 2 2 4 5 6 7 1 1 1 1 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::9 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 8 packets" + + flooding_filters_del $num_remotes +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_lib_spectrum.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_lib_spectrum.sh index 73035e25085d..06a80f40daa4 100644 --- a/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_lib_spectrum.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_lib_spectrum.sh @@ -2,11 +2,9 @@ # SPDX-License-Identifier: GPL-2.0 source "../../../../net/forwarding/devlink_lib.sh" +source ../mlxsw_lib.sh -if [ "$DEVLINK_VIDDID" != "15b3:cb84" ]; then - echo "SKIP: test is tailored for Mellanox Spectrum" - exit 1 -fi +mlxsw_only_on_spectrum 1 || exit 1 # Needed for returning to default declare -A KVD_DEFAULTS diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/port_range_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/port_range_scale.sh new file mode 100644 index 000000000000..d0847e8ea270 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/port_range_scale.sh @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 +source ../port_range_scale.sh + +port_range_get_target() +{ + local should_fail=$1; shift + local target + + target=$(devlink_resource_size_get port_range_registers) + + if ((! should_fail)); then + echo $target + else + echo $((target + 1)) + fi +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/port_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/port_scale.sh new file mode 100644 index 000000000000..0b71dfbbb447 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/port_scale.sh @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 +source ../port_scale.sh + +port_get_target() +{ + local should_fail=$1 + local target + + target=$(devlink_resource_size_get physical_ports) + + if ((! should_fail)); then + echo $target + else + echo $((target + 1)) + fi +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/q_in_vni_veto.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/q_in_vni_veto.sh new file mode 100755 index 000000000000..60753d46a2d4 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/q_in_vni_veto.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +lib_dir=$(dirname $0)/../../../../net/forwarding + +VXPORT=4789 + +ALL_TESTS=" + create_vxlan_on_top_of_8021ad_bridge +" +NUM_NETIFS=2 +source $lib_dir/lib.sh + +setup_prepare() +{ + swp1=${NETIFS[p1]} + swp2=${NETIFS[p2]} + + ip link set dev $swp1 up + ip link set dev $swp2 up +} + +cleanup() +{ + pre_cleanup + + ip link set dev $swp2 down + ip link set dev $swp1 down +} + +create_vxlan_on_top_of_8021ad_bridge() +{ + RET=0 + + ip link add dev br0 type bridge vlan_filtering 1 vlan_protocol 802.1ad \ + vlan_default_pvid 0 mcast_snooping 0 + ip link set dev br0 addrgenmode none + ip link set dev br0 up + + ip link add name vx100 type vxlan id 1000 local 192.0.2.17 dstport \ + "$VXPORT" nolearning noudpcsum tos inherit ttl 100 + ip link set dev vx100 up + + ip link set dev $swp1 master br0 + ip link set dev vx100 master br0 + + bridge vlan add vid 100 dev vx100 pvid untagged 2>/dev/null + check_fail $? "802.1ad bridge with VxLAN in Spectrum-1 not rejected" + + bridge vlan add vid 100 dev vx100 pvid untagged 2>&1 >/dev/null \ + | grep -q mlxsw_spectrum + check_err $? "802.1ad bridge with VxLAN in Spectrum-1 rejected without extack" + + log_test "create VxLAN on top of 802.1ad bridge" + + ip link del dev vx100 + ip link del dev br0 +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh index 43f662401bc3..f981c957f097 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh @@ -22,8 +22,19 @@ cleanup() devlink_sp_read_kvd_defaults trap cleanup EXIT -ALL_TESTS="router tc_flower mirror_gre tc_police" +ALL_TESTS=" + router + tc_flower + mirror_gre + tc_police + port + rif_mac_profile + rif_counter + port_range +" + for current_test in ${TESTS:-$ALL_TESTS}; do + RET_FIN=0 source ${current_test}_scale.sh num_netifs_var=${current_test^^}_NUM_NETIFS @@ -40,18 +51,35 @@ for current_test in ${TESTS:-$ALL_TESTS}; do for should_fail in 0 1; do RET=0 target=$(${current_test}_get_target "$should_fail") + if ((target == 0)); then + log_test_skip "'$current_test' [$profile] should_fail=$should_fail test" + continue + fi ${current_test}_setup_prepare setup_wait $num_netifs + # Update target in case occupancy of a certain resource + # changed following the test setup. + target=$(${current_test}_get_target "$should_fail") ${current_test}_test "$target" "$should_fail" - ${current_test}_cleanup if [[ "$should_fail" -eq 0 ]]; then log_test "'$current_test' [$profile] $target" + + if ((!RET)); then + tt=${current_test}_traffic_test + if [[ $(type -t $tt) == "function" ]] + then + $tt "$target" + log_test "'$current_test' [$profile] $target traffic test" + fi + fi else log_test "'$current_test' [$profile] overflow $target" fi + ${current_test}_cleanup $target + RET_FIN=$(( RET_FIN || RET )) done done done current_test="" -exit "$RET" +exit "$RET_FIN" diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/rif_counter_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/rif_counter_scale.sh new file mode 100644 index 000000000000..d44536276e8a --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/rif_counter_scale.sh @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: GPL-2.0 +source ../rif_counter_scale.sh + +rif_counter_get_target() +{ + local should_fail=$1; shift + local max_cnts + local max_rifs + local target + + max_rifs=$(devlink_resource_size_get rifs) + max_cnts=$(devlink_resource_size_get counters rif) + + # Remove already allocated RIFs. + ((max_rifs -= $(devlink_resource_occ_get rifs))) + + # 10 KVD slots per counter, ingress+egress counters per RIF + ((max_cnts /= 20)) + + # Pointless to run the overflow test if we don't have enough RIFs to + # host all the counters. + if ((max_cnts > max_rifs && should_fail)); then + echo 0 + return + fi + + target=$((max_rifs < max_cnts ? max_rifs : max_cnts)) + + if ((! should_fail)); then + echo $target + else + echo $((target + 1)) + fi +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/rif_mac_profile_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/rif_mac_profile_scale.sh new file mode 100644 index 000000000000..303d7cbe3c45 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/rif_mac_profile_scale.sh @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 +source ../rif_mac_profile_scale.sh + +rif_mac_profile_get_target() +{ + local should_fail=$1 + local target + + target=$(devlink_resource_size_get rif_mac_profiles) + + if ((! should_fail)); then + echo $target + else + echo $((target + 1)) + fi +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/vxlan_flooding_ipv6.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/vxlan_flooding_ipv6.sh new file mode 100755 index 000000000000..d8fd875ad527 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/vxlan_flooding_ipv6.sh @@ -0,0 +1,334 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test VxLAN flooding. The device stores flood records in a singly linked list +# where each record stores up to five IPv6 addresses of remote VTEPs. The test +# verifies that packets are correctly flooded in various cases such as deletion +# of a record in the middle of the list. +# +# +-----------------------+ +# | H1 (vrf) | +# | + $h1 | +# | | 2001:db8:1::1/64 | +# +----|------------------+ +# | +# +----|----------------------------------------------------------------------+ +# | SW | | +# | +--|--------------------------------------------------------------------+ | +# | | + $swp1 BR0 (802.1d) | | +# | | | | +# | | + vxlan0 (vxlan) | | +# | | local 2001:db8:2::1 | | +# | | remote 2001:db8:2::{2..21} | | +# | | id 10 dstport 4789 | | +# | +-----------------------------------------------------------------------+ | +# | | +# | 2001:db8:2::0/64 via 2001:db8:3::2 | +# | | +# | + $rp1 | +# | | 2001:db8:3::1/64 | +# +----|----------------------------------------------------------------------+ +# | +# +----|--------------------------------------------------------+ +# | | R2 (vrf) | +# | + $rp2 | +# | 2001:db8:3::2/64 | +# | | +# +-------------------------------------------------------------+ + +lib_dir=$(dirname $0)/../../../../net/forwarding + +ALL_TESTS="flooding_test" +NUM_NETIFS=4 +source $lib_dir/tc_common.sh +source $lib_dir/lib.sh + +h1_create() +{ + simple_if_init $h1 2001:db8:1::1/64 +} + +h1_destroy() +{ + simple_if_fini $h1 2001:db8:1::1/64 +} + +switch_create() +{ + # Make sure the bridge uses the MAC address of the local port and + # not that of the VxLAN's device + ip link add dev br0 type bridge mcast_snooping 0 + ip link set dev br0 address $(mac_get $swp1) + + ip link add name vxlan0 type vxlan id 10 nolearning \ + udp6zerocsumrx udp6zerocsumtx ttl 20 tos inherit \ + local 2001:db8:2::1 dstport 4789 + + ip address add 2001:db8:2::1/128 dev lo + + ip link set dev $swp1 master br0 + ip link set dev vxlan0 master br0 + + ip link set dev br0 up + ip link set dev $swp1 up + ip link set dev vxlan0 up +} + +switch_destroy() +{ + ip link set dev vxlan0 down + ip link set dev $swp1 down + ip link set dev br0 down + + ip link set dev vxlan0 nomaster + ip link set dev $swp1 nomaster + + ip address del 2001:db8:2::1/128 dev lo + + ip link del dev vxlan0 + + ip link del dev br0 +} + +router1_create() +{ + # This router is in the default VRF, where the VxLAN device is + # performing the L3 lookup + ip link set dev $rp1 up + ip address add 2001:db8:3::1/64 dev $rp1 + ip route add 2001:db8:2::0/64 via 2001:db8:3::2 +} + +router1_destroy() +{ + ip route del 2001:db8:2::0/64 via 2001:db8:3::2 + ip address del 2001:db8:3::1/64 dev $rp1 + ip link set dev $rp1 down +} + +router2_create() +{ + # This router is not in the default VRF, so use simple_if_init() + simple_if_init $rp2 2001:db8:3::2/64 +} + +router2_destroy() +{ + simple_if_fini $rp2 2001:db8:3::2/64 +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + rp1=${NETIFS[p3]} + rp2=${NETIFS[p4]} + + vrf_prepare + + h1_create + + switch_create + + router1_create + router2_create + + forwarding_enable +} + +cleanup() +{ + pre_cleanup + + forwarding_restore + + router2_destroy + router1_destroy + + switch_destroy + + h1_destroy + + vrf_cleanup +} + +flooding_remotes_add() +{ + local num_remotes=$1 + local lsb + local i + + for i in $(eval echo {1..$num_remotes}); do + lsb=$((i + 1)) + + bridge fdb append 00:00:00:00:00:00 dev vxlan0 self \ + dst 2001:db8:2::$lsb + done +} + +flooding_filters_add() +{ + local num_remotes=$1 + local lsb + local i + + tc qdisc add dev $rp2 clsact + + for i in $(eval echo {1..$num_remotes}); do + lsb=$((i + 1)) + + tc filter add dev $rp2 ingress protocol ipv6 pref $i handle $i \ + flower ip_proto udp dst_ip 2001:db8:2::$lsb \ + dst_port 4789 skip_sw action drop + done +} + +flooding_filters_del() +{ + local num_remotes=$1 + local i + + for i in $(eval echo {1..$num_remotes}); do + tc filter del dev $rp2 ingress protocol ipv6 pref $i \ + handle $i flower + done + + tc qdisc del dev $rp2 clsact +} + +flooding_check_packets() +{ + local packets=("$@") + local num_remotes=${#packets[@]} + local i + + for i in $(eval echo {1..$num_remotes}); do + tc_check_packets "dev $rp2 ingress" $i ${packets[i - 1]} + check_err $? "remote $i - did not get expected number of packets" + done +} + +flooding_test() +{ + # Use 20 remote VTEPs that will be stored in 4 records. The array + # 'packets' will store how many packets are expected to be received + # by each remote VTEP at each stage of the test + declare -a packets=(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1) + local num_remotes=20 + + RET=0 + + # Add FDB entries for remote VTEPs and corresponding tc filters on the + # ingress of the nexthop router. These filters will count how many + # packets were flooded to each remote VTEP + flooding_remotes_add $num_remotes + flooding_filters_add $num_remotes + + # Send one packet and make sure it is flooded to all the remote VTEPs + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 1 packet" + + # Delete the third record which corresponds to VTEPs with LSB 12..16 + # and check that packet is flooded correctly when we remove a record + # from the middle of the list + RET=0 + + packets=(2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::12 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::13 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::14 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::15 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::16 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 2 packets" + + # Delete the first record and make sure the packet is flooded correctly + RET=0 + + packets=(2 2 2 2 2 3 3 3 3 3 1 1 1 1 1 3 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::2 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::3 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::4 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::5 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::6 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 3 packets" + + # Delete the last record and make sure the packet is flooded correctly + RET=0 + + packets=(2 2 2 2 2 4 4 4 4 4 1 1 1 1 1 3 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::17 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::18 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::19 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::20 + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::21 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 4 packets" + + # Delete the last record, one entry at a time and make sure single + # entries are correctly removed + RET=0 + + packets=(2 2 2 2 2 4 5 5 5 5 1 1 1 1 1 3 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::7 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 5 packets" + + RET=0 + + packets=(2 2 2 2 2 4 5 6 6 6 1 1 1 1 1 3 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::8 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 6 packets" + + RET=0 + + packets=(2 2 2 2 2 4 5 6 7 7 1 1 1 1 1 3 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::9 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 7 packets" + + RET=0 + + packets=(2 2 2 2 2 4 5 6 7 8 1 1 1 1 1 3 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::10 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 8 packets" + + RET=0 + + packets=(2 2 2 2 2 4 5 6 7 8 1 1 1 1 1 3 3 3 3 3) + bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 2001:db8:2::11 + + $MZ -6 $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1 + flooding_check_packets "${packets[@]}" + log_test "flood after 9 packets" + + flooding_filters_del $num_remotes +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_flower_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_flower_scale.sh index cc0f07e72cf2..d3d9e60d6ddf 100644 --- a/tools/testing/selftests/drivers/net/mlxsw/tc_flower_scale.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/tc_flower_scale.sh @@ -77,6 +77,7 @@ tc_flower_rules_create() filter add dev $h2 ingress \ prot ipv6 \ pref 1000 \ + handle 42$i \ flower $tcflags dst_ip $(tc_flower_addr $i) \ action drop EOF @@ -98,11 +99,7 @@ __tc_flower_test() jq -r '[ .[] | select(.kind == "flower") | .options | .in_hw ]' | jq .[] | wc -l) [[ $((offload_count - 1)) -eq $count ]] - if [[ $should_fail -eq 0 ]]; then - check_err $? "Offload mismatch" - else - check_err_fail $should_fail $? "Offload more than expacted" - fi + check_err_fail $should_fail $? "Attempt to offload $count rules (actual result $((offload_count - 1)))" } tc_flower_test() @@ -125,3 +122,19 @@ tc_flower_test() tcflags="skip_sw" __tc_flower_test $count $should_fail } + +tc_flower_traffic_test() +{ + local count=$1; shift + local i; + + for ((i = count - 1; i > 0; i /= 2)); do + $MZ -6 $h1 -c 1 -d 20msec -p 100 -a own -b $(mac_get $h2) \ + -A $(tc_flower_addr 0) -B $(tc_flower_addr $i) \ + -q -t udp sp=54321,dp=12345 + done + for ((i = count - 1; i > 0; i /= 2)); do + tc_check_packets "dev $h2 ingress" 42$i 1 + check_err $? "Traffic not seen at rule #$i" + done +} diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_police_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_police_scale.sh index 4b96561c462f..86e787895f78 100644 --- a/tools/testing/selftests/drivers/net/mlxsw/tc_police_scale.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/tc_police_scale.sh @@ -24,6 +24,13 @@ tc_police_switch_destroy() simple_if_fini $swp1 } +tc_police_addr() +{ + local num=$1; shift + + printf "2001:db8:1::%x" $num +} + tc_police_rules_create() { local count=$1; shift @@ -34,8 +41,9 @@ tc_police_rules_create() for ((i = 0; i < count; ++i)); do cat >> $TC_POLICE_BATCH_FILE <<-EOF filter add dev $swp1 ingress \ - prot ip \ - flower skip_sw \ + prot ipv6 \ + pref 1000 \ + flower skip_sw dst_ip $(tc_police_addr $i) \ action police rate 10mbit burst 100k \ conform-exceed drop/ok EOF @@ -52,7 +60,8 @@ __tc_police_test() tc_police_rules_create $count $should_fail - offload_count=$(tc filter show dev $swp1 ingress | grep in_hw | wc -l) + offload_count=$(tc -j filter show dev $swp1 ingress | + jq "[.[] | select(.options.in_hw == true)] | length") ((offload_count == count)) check_err_fail $should_fail $? "tc police offload count" } diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh index 553cb9fad508..0441a18f098b 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh @@ -11,6 +11,7 @@ ALL_TESTS=" matchall_mirror_behind_flower_ingress_test matchall_sample_behind_flower_ingress_test matchall_mirror_behind_flower_egress_test + matchall_proto_match_test police_limits_test multi_police_test " @@ -18,6 +19,8 @@ NUM_NETIFS=2 source $lib_dir/tc_common.sh source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh +source mlxsw_lib.sh switch_create() { @@ -166,7 +169,8 @@ matchall_sample_egress_test() RET=0 # It is forbidden in mlxsw driver to have matchall with sample action - # bound on egress + # bound on egress. Spectrum-1 specific restriction + mlxsw_only_on_spectrum 1 || return tc qdisc add dev $swp1 clsact @@ -289,6 +293,22 @@ matchall_mirror_behind_flower_egress_test() matchall_behind_flower_egress_test "mirror" "mirred egress mirror dev $swp2" } +matchall_proto_match_test() +{ + RET=0 + + tc qdisc add dev $swp1 clsact + + tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ + matchall skip_sw \ + action sample group 1 rate 100 + check_fail $? "Incorrect success to add matchall rule with protocol match" + + tc qdisc del dev $swp1 clsact + + log_test "matchall protocol match" +} + police_limits_test() { RET=0 diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_sample.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_sample.sh new file mode 100755 index 000000000000..83a0210e7544 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/tc_sample.sh @@ -0,0 +1,658 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test that packets are sampled when tc-sample is used and that reported +# metadata is correct. Two sets of hosts (with and without LAG) are used, since +# metadata extraction in mlxsw is a bit different when LAG is involved. +# +# +---------------------------------+ +---------------------------------+ +# | H1 (vrf) | | H3 (vrf) | +# | + $h1 | | + $h3_lag | +# | | 192.0.2.1/28 | | | 192.0.2.17/28 | +# | | | | | | +# | | default via 192.0.2.2 | | | default via 192.0.2.18 | +# +----|----------------------------+ +----|----------------------------+ +# | | +# +----|-----------------------------------------|----------------------------+ +# | | 192.0.2.2/28 | 192.0.2.18/28 | +# | + $rp1 + $rp3_lag | +# | | +# | + $rp2 + $rp4_lag | +# | | 198.51.100.2/28 | 198.51.100.18/28 | +# +----|-----------------------------------------|----------------------------+ +# | | +# +----|----------------------------+ +----|----------------------------+ +# | | default via 198.51.100.2 | | | default via 198.51.100.18 | +# | | | | | | +# | | 198.51.100.1/28 | | | 198.51.100.17/28 | +# | + $h2 | | + $h4_lag | +# | H2 (vrf) | | H4 (vrf) | +# +---------------------------------+ +---------------------------------+ + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + tc_sample_rate_test + tc_sample_max_rate_test + tc_sample_conflict_test + tc_sample_group_conflict_test + tc_sample_md_iif_test + tc_sample_md_lag_iif_test + tc_sample_md_oif_test + tc_sample_md_lag_oif_test + tc_sample_md_out_tc_test + tc_sample_md_out_tc_occ_test + tc_sample_md_latency_test + tc_sample_acl_group_conflict_test + tc_sample_acl_rate_test + tc_sample_acl_max_rate_test +" +NUM_NETIFS=8 +CAPTURE_FILE=$(mktemp) +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh +source mlxsw_lib.sh + +# Available at https://github.com/Mellanox/libpsample +require_command psample + +h1_create() +{ + simple_if_init $h1 192.0.2.1/28 + + ip -4 route add default vrf v$h1 nexthop via 192.0.2.2 +} + +h1_destroy() +{ + ip -4 route del default vrf v$h1 nexthop via 192.0.2.2 + + simple_if_fini $h1 192.0.2.1/28 +} + +h2_create() +{ + simple_if_init $h2 198.51.100.1/28 + + ip -4 route add default vrf v$h2 nexthop via 198.51.100.2 +} + +h2_destroy() +{ + ip -4 route del default vrf v$h2 nexthop via 198.51.100.2 + + simple_if_fini $h2 198.51.100.1/28 +} + +h3_create() +{ + ip link set dev $h3 down + ip link add name ${h3}_bond type bond mode 802.3ad + ip link set dev $h3 master ${h3}_bond + + simple_if_init ${h3}_bond 192.0.2.17/28 + + ip -4 route add default vrf v${h3}_bond nexthop via 192.0.2.18 +} + +h3_destroy() +{ + ip -4 route del default vrf v${h3}_bond nexthop via 192.0.2.18 + + simple_if_fini ${h3}_bond 192.0.2.17/28 + + ip link set dev $h3 nomaster + ip link del dev ${h3}_bond +} + +h4_create() +{ + ip link set dev $h4 down + ip link add name ${h4}_bond type bond mode 802.3ad + ip link set dev $h4 master ${h4}_bond + + simple_if_init ${h4}_bond 198.51.100.17/28 + + ip -4 route add default vrf v${h4}_bond nexthop via 198.51.100.18 +} + +h4_destroy() +{ + ip -4 route del default vrf v${h4}_bond nexthop via 198.51.100.18 + + simple_if_fini ${h4}_bond 198.51.100.17/28 + + ip link set dev $h4 nomaster + ip link del dev ${h4}_bond +} + +router_create() +{ + ip link set dev $rp1 up + __addr_add_del $rp1 add 192.0.2.2/28 + tc qdisc add dev $rp1 clsact + + ip link set dev $rp2 up + __addr_add_del $rp2 add 198.51.100.2/28 + tc qdisc add dev $rp2 clsact + + ip link add name ${rp3}_bond type bond mode 802.3ad + ip link set dev $rp3 master ${rp3}_bond + __addr_add_del ${rp3}_bond add 192.0.2.18/28 + tc qdisc add dev $rp3 clsact + ip link set dev ${rp3}_bond up + + ip link add name ${rp4}_bond type bond mode 802.3ad + ip link set dev $rp4 master ${rp4}_bond + __addr_add_del ${rp4}_bond add 198.51.100.18/28 + tc qdisc add dev $rp4 clsact + ip link set dev ${rp4}_bond up +} + +router_destroy() +{ + ip link set dev ${rp4}_bond down + tc qdisc del dev $rp4 clsact + __addr_add_del ${rp4}_bond del 198.51.100.18/28 + ip link set dev $rp4 nomaster + ip link del dev ${rp4}_bond + + ip link set dev ${rp3}_bond down + tc qdisc del dev $rp3 clsact + __addr_add_del ${rp3}_bond del 192.0.2.18/28 + ip link set dev $rp3 nomaster + ip link del dev ${rp3}_bond + + tc qdisc del dev $rp2 clsact + __addr_add_del $rp2 del 198.51.100.2/28 + ip link set dev $rp2 down + + tc qdisc del dev $rp1 clsact + __addr_add_del $rp1 del 192.0.2.2/28 + ip link set dev $rp1 down +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + rp1=${NETIFS[p2]} + rp2=${NETIFS[p3]} + h2=${NETIFS[p4]} + h3=${NETIFS[p5]} + rp3=${NETIFS[p6]} + h4=${NETIFS[p7]} + rp4=${NETIFS[p8]} + + vrf_prepare + + h1_create + h2_create + h3_create + h4_create + router_create +} + +cleanup() +{ + pre_cleanup + + rm -f $CAPTURE_FILE + + router_destroy + h4_destroy + h3_destroy + h2_destroy + h1_destroy + + vrf_cleanup +} + +psample_capture_start() +{ + rm -f $CAPTURE_FILE + + psample &> $CAPTURE_FILE & + + sleep 1 +} + +psample_capture_stop() +{ + { kill %% && wait %%; } 2>/dev/null +} + +__tc_sample_rate_test() +{ + local desc=$1; shift + local dip=$1; shift + local pkts pct + + RET=0 + + tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ + skip_sw action sample rate 32 group 1 + check_err $? "Failed to configure sampling rule" + + psample_capture_start + + ip vrf exec v$h1 $MZ $h1 -c 320000 -d 100usec -p 64 -A 192.0.2.1 \ + -B $dip -t udp dp=52768,sp=42768 -q + + psample_capture_stop + + pkts=$(grep -e "group 1 " $CAPTURE_FILE | wc -l) + pct=$((100 * (pkts - 10000) / 10000)) + (( -25 <= pct && pct <= 25)) + check_err $? "Expected 10000 packets, got $pkts packets, which is $pct% off. Required accuracy is +-25%" + + log_test "tc sample rate ($desc)" + + tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall +} + +tc_sample_rate_test() +{ + __tc_sample_rate_test "forward" 198.51.100.1 + __tc_sample_rate_test "local receive" 192.0.2.2 +} + +tc_sample_max_rate_test() +{ + RET=0 + + tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ + skip_sw action sample rate $((35 * 10 ** 8)) group 1 + check_err $? "Failed to configure sampling rule with max rate" + + tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall + + tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ + skip_sw action sample rate $((35 * 10 ** 8 + 1)) \ + group 1 &> /dev/null + check_fail $? "Managed to configure sampling rate above maximum" + + log_test "tc sample maximum rate" +} + +tc_sample_conflict_test() +{ + RET=0 + + # Test that two sampling rules cannot be configured on the same port, + # even when they share the same parameters. + + tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ + skip_sw action sample rate 1024 group 1 + check_err $? "Failed to configure sampling rule" + + tc filter add dev $rp1 ingress protocol all pref 2 handle 102 matchall \ + skip_sw action sample rate 1024 group 1 &> /dev/null + check_fail $? "Managed to configure second sampling rule" + + # Delete the first rule and make sure the second rule can now be + # configured. + + tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall + + tc filter add dev $rp1 ingress protocol all pref 2 handle 102 matchall \ + skip_sw action sample rate 1024 group 1 + check_err $? "Failed to configure sampling rule after deletion" + + log_test "tc sample conflict test" + + tc filter del dev $rp1 ingress protocol all pref 2 handle 102 matchall +} + +tc_sample_group_conflict_test() +{ + RET=0 + + # Test that two sampling rules cannot be configured on the same port + # with different groups. + + tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ + skip_sw action sample rate 1024 group 1 + check_err $? "Failed to configure sampling rule" + + tc filter add dev $rp1 ingress protocol all pref 2 handle 102 matchall \ + skip_sw action sample rate 1024 group 2 &> /dev/null + check_fail $? "Managed to configure sampling rule with conflicting group" + + log_test "tc sample group conflict test" + + tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall +} + +tc_sample_md_iif_test() +{ + local rp1_ifindex + + RET=0 + + tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ + skip_sw action sample rate 5 group 1 + check_err $? "Failed to configure sampling rule" + + psample_capture_start + + ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ + -B 198.51.100.1 -t udp dp=52768,sp=42768 -q + + psample_capture_stop + + rp1_ifindex=$(ip -j -p link show dev $rp1 | jq '.[]["ifindex"]') + grep -q -e "in-ifindex $rp1_ifindex " $CAPTURE_FILE + check_err $? "Sampled packets do not have expected in-ifindex" + + log_test "tc sample iif" + + tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall +} + +tc_sample_md_lag_iif_test() +{ + local rp3_ifindex + + RET=0 + + tc filter add dev $rp3 ingress protocol all pref 1 handle 101 matchall \ + skip_sw action sample rate 5 group 1 + check_err $? "Failed to configure sampling rule" + + psample_capture_start + + ip vrf exec v${h3}_bond $MZ ${h3}_bond -c 3200 -d 1msec -p 64 \ + -A 192.0.2.17 -B 198.51.100.17 -t udp dp=52768,sp=42768 -q + + psample_capture_stop + + rp3_ifindex=$(ip -j -p link show dev $rp3 | jq '.[]["ifindex"]') + grep -q -e "in-ifindex $rp3_ifindex " $CAPTURE_FILE + check_err $? "Sampled packets do not have expected in-ifindex" + + log_test "tc sample lag iif" + + tc filter del dev $rp3 ingress protocol all pref 1 handle 101 matchall +} + +tc_sample_md_oif_test() +{ + local rp2_ifindex + + RET=0 + + tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ + skip_sw action sample rate 5 group 1 + check_err $? "Failed to configure sampling rule" + + psample_capture_start + + ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ + -B 198.51.100.1 -t udp dp=52768,sp=42768 -q + + psample_capture_stop + + rp2_ifindex=$(ip -j -p link show dev $rp2 | jq '.[]["ifindex"]') + grep -q -e "out-ifindex $rp2_ifindex " $CAPTURE_FILE + check_err $? "Sampled packets do not have expected out-ifindex" + + log_test "tc sample oif" + + tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall +} + +tc_sample_md_lag_oif_test() +{ + local rp4_ifindex + + RET=0 + + tc filter add dev $rp3 ingress protocol all pref 1 handle 101 matchall \ + skip_sw action sample rate 5 group 1 + check_err $? "Failed to configure sampling rule" + + psample_capture_start + + ip vrf exec v${h3}_bond $MZ ${h3}_bond -c 3200 -d 1msec -p 64 \ + -A 192.0.2.17 -B 198.51.100.17 -t udp dp=52768,sp=42768 -q + + psample_capture_stop + + rp4_ifindex=$(ip -j -p link show dev $rp4 | jq '.[]["ifindex"]') + grep -q -e "out-ifindex $rp4_ifindex " $CAPTURE_FILE + check_err $? "Sampled packets do not have expected out-ifindex" + + log_test "tc sample lag oif" + + tc filter del dev $rp3 ingress protocol all pref 1 handle 101 matchall +} + +tc_sample_md_out_tc_test() +{ + RET=0 + + # Output traffic class is not supported on Spectrum-1. + mlxsw_only_on_spectrum 2+ || return + + tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ + skip_sw action sample rate 5 group 1 + check_err $? "Failed to configure sampling rule" + + # By default, all the packets should go to the same traffic class (0). + + psample_capture_start + + ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ + -B 198.51.100.1 -t udp dp=52768,sp=42768 -q + + psample_capture_stop + + grep -q -e "out-tc 0 " $CAPTURE_FILE + check_err $? "Sampled packets do not have expected out-tc (0)" + + # Map all priorities to highest traffic class (7) and check reported + # out-tc. + tc qdisc replace dev $rp2 root handle 1: \ + prio bands 3 priomap 0 0 0 0 0 0 0 0 + + psample_capture_start + + ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ + -B 198.51.100.1 -t udp dp=52768,sp=42768 -q + + psample_capture_stop + + grep -q -e "out-tc 7 " $CAPTURE_FILE + check_err $? "Sampled packets do not have expected out-tc (7)" + + log_test "tc sample out-tc" + + tc qdisc del dev $rp2 root handle 1: + tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall +} + +tc_sample_md_out_tc_occ_test() +{ + local backlog pct occ + + RET=0 + + # Output traffic class occupancy is not supported on Spectrum-1. + mlxsw_only_on_spectrum 2+ || return + + tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ + skip_sw action sample rate 1024 group 1 + check_err $? "Failed to configure sampling rule" + + # Configure a shaper on egress to create congestion. + tc qdisc replace dev $rp2 root handle 1: \ + tbf rate 1Mbit burst 256k limit 1M + + psample_capture_start + + ip vrf exec v$h1 $MZ $h1 -c 0 -d 1usec -p 1400 -A 192.0.2.1 \ + -B 198.51.100.1 -t udp dp=52768,sp=42768 -q & + + # Allow congestion to reach steady state. + sleep 10 + + backlog=$(tc -j -p -s qdisc show dev $rp2 | jq '.[0]["backlog"]') + + # Kill mausezahn. + { kill %% && wait %%; } 2>/dev/null + + psample_capture_stop + + # Record last congestion sample. + occ=$(grep -e "out-tc-occ " $CAPTURE_FILE | tail -n 1 | \ + cut -d ' ' -f 16) + + pct=$((100 * (occ - backlog) / backlog)) + (( -1 <= pct && pct <= 1)) + check_err $? "Recorded a congestion of $backlog bytes, but sampled congestion is $occ bytes, which is $pct% off. Required accuracy is +-5%" + + log_test "tc sample out-tc-occ" + + tc qdisc del dev $rp2 root handle 1: + tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall +} + +tc_sample_md_latency_test() +{ + RET=0 + + # Egress sampling not supported on Spectrum-1. + mlxsw_only_on_spectrum 2+ || return + + tc filter add dev $rp2 egress protocol all pref 1 handle 101 matchall \ + skip_sw action sample rate 5 group 1 + check_err $? "Failed to configure sampling rule" + + psample_capture_start + + ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ + -B 198.51.100.1 -t udp dp=52768,sp=42768 -q + + psample_capture_stop + + grep -q -e "latency " $CAPTURE_FILE + check_err $? "Sampled packets do not have latency attribute" + + log_test "tc sample latency" + + tc filter del dev $rp2 egress protocol all pref 1 handle 101 matchall +} + +tc_sample_acl_group_conflict_test() +{ + RET=0 + + # Test that two flower sampling rules cannot be configured on the same + # port with different groups. + + # Policy-based sampling is not supported on Spectrum-1. + mlxsw_only_on_spectrum 2+ || return + + tc filter add dev $rp1 ingress protocol ip pref 1 handle 101 flower \ + skip_sw action sample rate 1024 group 1 + check_err $? "Failed to configure sampling rule" + + tc filter add dev $rp1 ingress protocol ip pref 2 handle 102 flower \ + skip_sw action sample rate 1024 group 1 + check_err $? "Failed to configure sampling rule with same group" + + tc filter add dev $rp1 ingress protocol ip pref 3 handle 103 flower \ + skip_sw action sample rate 1024 group 2 &> /dev/null + check_fail $? "Managed to configure sampling rule with conflicting group" + + log_test "tc sample (w/ flower) group conflict test" + + tc filter del dev $rp1 ingress protocol ip pref 2 handle 102 flower + tc filter del dev $rp1 ingress protocol ip pref 1 handle 101 flower +} + +__tc_sample_acl_rate_test() +{ + local bind=$1; shift + local port=$1; shift + local pkts pct + + RET=0 + + # Policy-based sampling is not supported on Spectrum-1. + mlxsw_only_on_spectrum 2+ || return + + tc filter add dev $port $bind protocol ip pref 1 handle 101 flower \ + skip_sw dst_ip 198.51.100.1 action sample rate 32 group 1 + check_err $? "Failed to configure sampling rule" + + psample_capture_start + + ip vrf exec v$h1 $MZ $h1 -c 320000 -d 100usec -p 64 -A 192.0.2.1 \ + -B 198.51.100.1 -t udp dp=52768,sp=42768 -q + + psample_capture_stop + + pkts=$(grep -e "group 1 " $CAPTURE_FILE | wc -l) + pct=$((100 * (pkts - 10000) / 10000)) + (( -25 <= pct && pct <= 25)) + check_err $? "Expected 10000 packets, got $pkts packets, which is $pct% off. Required accuracy is +-25%" + + # Setup a filter that should not match any packet and make sure packets + # are not sampled. + tc filter del dev $port $bind protocol ip pref 1 handle 101 flower + + tc filter add dev $port $bind protocol ip pref 1 handle 101 flower \ + skip_sw dst_ip 198.51.100.10 action sample rate 32 group 1 + check_err $? "Failed to configure sampling rule" + + psample_capture_start + + ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ + -B 198.51.100.1 -t udp dp=52768,sp=42768 -q + + psample_capture_stop + + grep -q -e "group 1 " $CAPTURE_FILE + check_fail $? "Sampled packets when should not" + + log_test "tc sample (w/ flower) rate ($bind)" + + tc filter del dev $port $bind protocol ip pref 1 handle 101 flower +} + +tc_sample_acl_rate_test() +{ + __tc_sample_acl_rate_test ingress $rp1 + __tc_sample_acl_rate_test egress $rp2 +} + +tc_sample_acl_max_rate_test() +{ + RET=0 + + # Policy-based sampling is not supported on Spectrum-1. + mlxsw_only_on_spectrum 2+ || return + + tc filter add dev $rp1 ingress protocol ip pref 1 handle 101 flower \ + skip_sw action sample rate $((2 ** 24 - 1)) group 1 + check_err $? "Failed to configure sampling rule with max rate" + + tc filter del dev $rp1 ingress protocol ip pref 1 handle 101 flower + + tc filter add dev $rp1 ingress protocol ip pref 1 handle 101 flower \ + skip_sw action sample rate $((2 ** 24)) \ + group 1 &> /dev/null + check_fail $? "Managed to configure sampling rate above maximum" + + log_test "tc sample (w/ flower) maximum rate" +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/mlxsw/vxlan.sh b/tools/testing/selftests/drivers/net/mlxsw/vxlan.sh index 729a86cc4ede..4687b0a7dffb 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/vxlan.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/vxlan.sh @@ -4,10 +4,35 @@ # Test various aspects of VxLAN offloading which are specific to mlxsw, such # as sanitization of invalid configurations and offload indication. -lib_dir=$(dirname $0)/../../../net/forwarding +: ${ADDR_FAMILY:=ipv4} +export ADDR_FAMILY + +: ${LOCAL_IP_1:=198.51.100.1} +export LOCAL_IP_1 + +: ${LOCAL_IP_2:=198.51.100.2} +export LOCAL_IP_2 + +: ${PREFIX_LEN:=32} +export PREFIX_LEN + +: ${UDPCSUM_FLAFS:=noudpcsum} +export UDPCSUM_FLAFS + +: ${MC_IP:=239.0.0.1} +export MC_IP -ALL_TESTS="sanitization_test offload_indication_test \ - sanitization_vlan_aware_test offload_indication_vlan_aware_test" +: ${IP_FLAG:=""} +export IP_FLAG + +: ${ALL_TESTS:=" + sanitization_test + offload_indication_test + sanitization_vlan_aware_test + offload_indication_vlan_aware_test +"} + +lib_dir=$(dirname $0)/../../../net/forwarding NUM_NETIFS=2 : ${TIMEOUT:=20000} # ms source $lib_dir/lib.sh @@ -63,8 +88,8 @@ sanitization_single_dev_valid_test() ip link add dev br0 type bridge mcast_snooping 0 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 sanitization_single_dev_test_pass @@ -80,8 +105,8 @@ sanitization_single_dev_vlan_aware_test() ip link add dev br0 type bridge mcast_snooping 0 vlan_filtering 1 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 sanitization_single_dev_test_pass @@ -97,8 +122,8 @@ sanitization_single_dev_mcast_enabled_test() ip link add dev br0 type bridge - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 sanitization_single_dev_test_fail @@ -115,9 +140,9 @@ sanitization_single_dev_mcast_group_test() ip link add dev br0 type bridge mcast_snooping 0 ip link add name dummy1 up type dummy - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 \ - dev dummy1 group 239.0.0.1 + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 \ + dev dummy1 group $MC_IP sanitization_single_dev_test_fail @@ -134,7 +159,7 @@ sanitization_single_dev_no_local_ip_test() ip link add dev br0 type bridge mcast_snooping 0 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ ttl 20 tos inherit dstport 4789 sanitization_single_dev_test_fail @@ -145,31 +170,14 @@ sanitization_single_dev_no_local_ip_test() log_test "vxlan device with no local ip" } -sanitization_single_dev_local_ipv6_test() -{ - RET=0 - - ip link add dev br0 type bridge mcast_snooping 0 - - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 2001:db8::1 dstport 4789 - - sanitization_single_dev_test_fail - - ip link del dev vxlan0 - ip link del dev br0 - - log_test "vxlan device with local ipv6 address" -} - -sanitization_single_dev_learning_enabled_test() +sanitization_single_dev_learning_enabled_ipv4_test() { RET=0 ip link add dev br0 type bridge mcast_snooping 0 - ip link add name vxlan0 up type vxlan id 10 learning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 + ip link add name vxlan0 up type vxlan id 10 learning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 sanitization_single_dev_test_pass @@ -186,8 +194,8 @@ sanitization_single_dev_local_interface_test() ip link add dev br0 type bridge mcast_snooping 0 ip link add name dummy1 up type dummy - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 dev dummy1 + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 dev dummy1 sanitization_single_dev_test_fail @@ -204,8 +212,8 @@ sanitization_single_dev_port_range_test() ip link add dev br0 type bridge mcast_snooping 0 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 \ + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 \ srcport 4000 5000 sanitization_single_dev_test_fail @@ -222,8 +230,8 @@ sanitization_single_dev_tos_static_test() ip link add dev br0 type bridge mcast_snooping 0 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos 20 local 198.51.100.1 dstport 4789 + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos 20 local $LOCAL_IP_1 dstport 4789 sanitization_single_dev_test_fail @@ -239,8 +247,8 @@ sanitization_single_dev_ttl_inherit_test() ip link add dev br0 type bridge mcast_snooping 0 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl inherit tos inherit local 198.51.100.1 dstport 4789 + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl inherit tos inherit local $LOCAL_IP_1 dstport 4789 sanitization_single_dev_test_fail @@ -250,14 +258,14 @@ sanitization_single_dev_ttl_inherit_test() log_test "vxlan device with inherit ttl" } -sanitization_single_dev_udp_checksum_test() +sanitization_single_dev_udp_checksum_ipv4_test() { RET=0 ip link add dev br0 type bridge mcast_snooping 0 ip link add name vxlan0 up type vxlan id 10 nolearning udpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 sanitization_single_dev_test_fail @@ -276,13 +284,12 @@ sanitization_single_dev_test() sanitization_single_dev_mcast_enabled_test sanitization_single_dev_mcast_group_test sanitization_single_dev_no_local_ip_test - sanitization_single_dev_local_ipv6_test - sanitization_single_dev_learning_enabled_test + sanitization_single_dev_learning_enabled_"$ADDR_FAMILY"_test sanitization_single_dev_local_interface_test sanitization_single_dev_port_range_test sanitization_single_dev_tos_static_test sanitization_single_dev_ttl_inherit_test - sanitization_single_dev_udp_checksum_test + sanitization_single_dev_udp_checksum_"$ADDR_FAMILY"_test } sanitization_multi_devs_test_pass() @@ -334,10 +341,10 @@ sanitization_multi_devs_valid_test() ip link add dev br0 type bridge mcast_snooping 0 ip link add dev br1 type bridge mcast_snooping 0 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 - ip link add name vxlan1 up type vxlan id 20 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 + ip link add name vxlan1 up type vxlan id 20 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 sanitization_multi_devs_test_pass @@ -356,10 +363,10 @@ sanitization_multi_devs_ttl_test() ip link add dev br0 type bridge mcast_snooping 0 ip link add dev br1 type bridge mcast_snooping 0 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 - ip link add name vxlan1 up type vxlan id 20 nolearning noudpcsum \ - ttl 40 tos inherit local 198.51.100.1 dstport 4789 + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 + ip link add name vxlan1 up type vxlan id 20 nolearning $UDPCSUM_FLAFS \ + ttl 40 tos inherit local $LOCAL_IP_1 dstport 4789 sanitization_multi_devs_test_fail @@ -378,10 +385,10 @@ sanitization_multi_devs_udp_dstport_test() ip link add dev br0 type bridge mcast_snooping 0 ip link add dev br1 type bridge mcast_snooping 0 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 - ip link add name vxlan1 up type vxlan id 20 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 5789 + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 + ip link add name vxlan1 up type vxlan id 20 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 5789 sanitization_multi_devs_test_fail @@ -400,10 +407,10 @@ sanitization_multi_devs_local_ip_test() ip link add dev br0 type bridge mcast_snooping 0 ip link add dev br1 type bridge mcast_snooping 0 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 - ip link add name vxlan1 up type vxlan id 20 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.2 dstport 4789 + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 + ip link add name vxlan1 up type vxlan id 20 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_2 dstport 4789 sanitization_multi_devs_test_fail @@ -437,18 +444,22 @@ offload_indication_setup_create() { # Create a simple setup with two bridges, each with a VxLAN device # and one local port - ip link add name br0 up type bridge mcast_snooping 0 - ip link add name br1 up type bridge mcast_snooping 0 + ip link add name br0 type bridge mcast_snooping 0 + ip link set dev br0 addrgenmode none + ip link set dev br0 up + ip link add name br1 type bridge mcast_snooping 0 + ip link set dev br1 addrgenmode none + ip link set dev br1 up ip link set dev $swp1 master br0 ip link set dev $swp2 master br1 - ip address add 198.51.100.1/32 dev lo + ip address add $LOCAL_IP_1/$PREFIX_LEN dev lo ip link add name vxlan0 up master br0 type vxlan id 10 nolearning \ - noudpcsum ttl 20 tos inherit local 198.51.100.1 dstport 4789 + $UDPCSUM_FLAFS ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 ip link add name vxlan1 up master br1 type vxlan id 20 nolearning \ - noudpcsum ttl 20 tos inherit local 198.51.100.1 dstport 4789 + $UDPCSUM_FLAFS ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 } offload_indication_setup_destroy() @@ -456,7 +467,7 @@ offload_indication_setup_destroy() ip link del dev vxlan1 ip link del dev vxlan0 - ip address del 198.51.100.1/32 dev lo + ip address del $LOCAL_IP_1/$PREFIX_LEN dev lo ip link set dev $swp2 nomaster ip link set dev $swp1 nomaster @@ -469,7 +480,7 @@ offload_indication_fdb_flood_test() { RET=0 - bridge fdb append 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.2 + bridge fdb append 00:00:00:00:00:00 dev vxlan0 self dst $LOCAL_IP_2 busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb 00:00:00:00:00:00 \ bridge fdb show brport vxlan0 @@ -485,7 +496,7 @@ offload_indication_fdb_bridge_test() RET=0 bridge fdb add de:ad:be:ef:13:37 dev vxlan0 self master static \ - dst 198.51.100.2 + dst $LOCAL_IP_2 busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \ de:ad:be:ef:13:37 self bridge fdb show brport vxlan0 @@ -536,7 +547,7 @@ offload_indication_fdb_bridge_test() # marked as offloaded in both drivers RET=0 - bridge fdb add de:ad:be:ef:13:37 dev vxlan0 self dst 198.51.100.2 + bridge fdb add de:ad:be:ef:13:37 dev vxlan0 self dst $LOCAL_IP_2 busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \ de:ad:be:ef:13:37 self bridge fdb show brport vxlan0 check_err $? @@ -560,17 +571,17 @@ offload_indication_decap_route_test() RET=0 busywait "$TIMEOUT" wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? ip link set dev vxlan0 down busywait "$TIMEOUT" wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? ip link set dev vxlan1 down busywait "$TIMEOUT" not wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? log_test "vxlan decap route - vxlan device down" @@ -579,26 +590,26 @@ offload_indication_decap_route_test() ip link set dev vxlan1 up busywait "$TIMEOUT" wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? ip link set dev vxlan0 up busywait "$TIMEOUT" wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? log_test "vxlan decap route - vxlan device up" RET=0 - ip address delete 198.51.100.1/32 dev lo + ip address delete $LOCAL_IP_1/$PREFIX_LEN dev lo busywait "$TIMEOUT" not wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? - ip address add 198.51.100.1/32 dev lo + ip address add $LOCAL_IP_1/$PREFIX_LEN dev lo busywait "$TIMEOUT" wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? log_test "vxlan decap route - add local route" @@ -607,18 +618,18 @@ offload_indication_decap_route_test() ip link set dev $swp1 nomaster busywait "$TIMEOUT" wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? ip link set dev $swp2 nomaster busywait "$TIMEOUT" not wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? ip link set dev $swp1 master br0 ip link set dev $swp2 master br1 busywait "$TIMEOUT" wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? log_test "vxlan decap route - local ports enslavement" @@ -627,44 +638,48 @@ offload_indication_decap_route_test() ip link del dev br0 busywait "$TIMEOUT" wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? ip link del dev br1 busywait "$TIMEOUT" not wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? log_test "vxlan decap route - bridge device deletion" RET=0 - ip link add name br0 up type bridge mcast_snooping 0 - ip link add name br1 up type bridge mcast_snooping 0 + ip link add name br0 type bridge mcast_snooping 0 + ip link set dev br0 addrgenmode none + ip link set dev br0 up + ip link add name br1 type bridge mcast_snooping 0 + ip link set dev br1 addrgenmode none + ip link set dev br1 up ip link set dev $swp1 master br0 ip link set dev $swp2 master br1 ip link set dev vxlan0 master br0 ip link set dev vxlan1 master br1 busywait "$TIMEOUT" wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? ip link del dev vxlan0 busywait "$TIMEOUT" wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? ip link del dev vxlan1 busywait "$TIMEOUT" not wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? log_test "vxlan decap route - vxlan device deletion" ip link add name vxlan0 up master br0 type vxlan id 10 nolearning \ - noudpcsum ttl 20 tos inherit local 198.51.100.1 dstport 4789 + $UDPCSUM_FLAFS ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 ip link add name vxlan1 up master br1 type vxlan id 20 nolearning \ - noudpcsum ttl 20 tos inherit local 198.51.100.1 dstport 4789 + $UDPCSUM_FLAFS ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 } check_fdb_offloaded() @@ -721,10 +736,10 @@ __offload_indication_join_vxlan_first() local mac=00:11:22:33:44:55 local zmac=00:00:00:00:00:00 - bridge fdb append $zmac dev vxlan0 self dst 198.51.100.2 + bridge fdb append $zmac dev vxlan0 self dst $LOCAL_IP_2 ip link set dev vxlan0 master br0 - bridge fdb add dev vxlan0 $mac self master static dst 198.51.100.2 + bridge fdb add dev vxlan0 $mac self master static dst $LOCAL_IP_2 RET=0 check_vxlan_fdb_not_offloaded @@ -773,9 +788,11 @@ __offload_indication_join_vxlan_first() offload_indication_join_vxlan_first() { - ip link add dev br0 up type bridge mcast_snooping 0 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 + ip link add dev br0 type bridge mcast_snooping 0 + ip link set dev br0 addrgenmode none + ip link set dev br0 up + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 __offload_indication_join_vxlan_first @@ -789,7 +806,7 @@ __offload_indication_join_vxlan_last() RET=0 - bridge fdb append $zmac dev vxlan0 self dst 198.51.100.2 + bridge fdb append $zmac dev vxlan0 self dst $LOCAL_IP_2 ip link set dev $swp1 master br0 @@ -808,9 +825,11 @@ __offload_indication_join_vxlan_last() offload_indication_join_vxlan_last() { - ip link add dev br0 up type bridge mcast_snooping 0 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 + ip link add dev br0 type bridge mcast_snooping 0 + ip link set dev br0 addrgenmode none + ip link set dev br0 up + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 __offload_indication_join_vxlan_last @@ -835,12 +854,13 @@ sanitization_vlan_aware_test() RET=0 ip link add dev br0 type bridge mcast_snooping 0 vlan_filtering 1 + ip link set dev br0 addrgenmode none ip link add name vxlan10 up master br0 type vxlan id 10 nolearning \ - noudpcsum ttl 20 tos inherit local 198.51.100.1 dstport 4789 + $UDPCSUM_FLAFS ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 ip link add name vxlan20 up master br0 type vxlan id 20 nolearning \ - noudpcsum ttl 20 tos inherit local 198.51.100.1 dstport 4789 + $UDPCSUM_FLAFS ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 # Test that when each VNI is mapped to a different VLAN we can enslave # a port to the bridge @@ -884,20 +904,20 @@ sanitization_vlan_aware_test() # Use the offload indication of the local route to ensure the VXLAN # configuration was correctly rollbacked. - ip address add 198.51.100.1/32 dev lo + ip address add $LOCAL_IP_1/$PREFIX_LEN dev lo ip link set dev vxlan10 type vxlan ttl 10 ip link set dev $swp1 master br0 &> /dev/null check_fail $? busywait "$TIMEOUT" not wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? log_test "vlan-aware - failed enslavement to bridge due to conflict" ip link set dev vxlan10 type vxlan ttl 20 - ip address del 198.51.100.1/32 dev lo + ip address del $LOCAL_IP_1/$PREFIX_LEN dev lo ip link del dev vxlan20 ip link del dev vxlan10 @@ -908,20 +928,22 @@ offload_indication_vlan_aware_setup_create() { # Create a simple setup with two VxLAN devices and a single VLAN-aware # bridge - ip link add name br0 up type bridge mcast_snooping 0 vlan_filtering 1 \ + ip link add name br0 type bridge mcast_snooping 0 vlan_filtering 1 \ vlan_default_pvid 0 + ip link set dev br0 addrgenmode none + ip link set dev br0 up ip link set dev $swp1 master br0 bridge vlan add vid 10 dev $swp1 bridge vlan add vid 20 dev $swp1 - ip address add 198.51.100.1/32 dev lo + ip address add $LOCAL_IP_1/$PREFIX_LEN dev lo ip link add name vxlan10 up master br0 type vxlan id 10 nolearning \ - noudpcsum ttl 20 tos inherit local 198.51.100.1 dstport 4789 + $UDPCSUM_FLAFS ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 ip link add name vxlan20 up master br0 type vxlan id 20 nolearning \ - noudpcsum ttl 20 tos inherit local 198.51.100.1 dstport 4789 + $UDPCSUM_FLAFS ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 bridge vlan add vid 10 dev vxlan10 pvid untagged bridge vlan add vid 20 dev vxlan20 pvid untagged @@ -935,7 +957,7 @@ offload_indication_vlan_aware_setup_destroy() ip link del dev vxlan20 ip link del dev vxlan10 - ip address del 198.51.100.1/32 dev lo + ip address del $LOCAL_IP_1/$PREFIX_LEN dev lo bridge vlan del vid 20 dev $swp1 bridge vlan del vid 10 dev $swp1 @@ -952,7 +974,7 @@ offload_indication_vlan_aware_fdb_test() log_info "vxlan entry offload indication - vlan-aware" bridge fdb add de:ad:be:ef:13:37 dev vxlan10 self master static \ - dst 198.51.100.2 vlan 10 + dst $LOCAL_IP_2 vlan 10 busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \ de:ad:be:ef:13:37 self bridge fdb show brport vxlan10 @@ -1003,7 +1025,7 @@ offload_indication_vlan_aware_fdb_test() # marked as offloaded in both drivers RET=0 - bridge fdb add de:ad:be:ef:13:37 dev vxlan10 self dst 198.51.100.2 + bridge fdb add de:ad:be:ef:13:37 dev vxlan10 self dst $LOCAL_IP_2 busywait "$TIMEOUT" wait_for_offload grep_bridge_fdb \ de:ad:be:ef:13:37 self bridge fdb show brport vxlan10 check_err $? @@ -1021,7 +1043,7 @@ offload_indication_vlan_aware_decap_route_test() RET=0 busywait "$TIMEOUT" wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? # Toggle PVID flag on one VxLAN device and make sure route is still @@ -1029,7 +1051,7 @@ offload_indication_vlan_aware_decap_route_test() bridge vlan add vid 10 dev vxlan10 untagged busywait "$TIMEOUT" wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? # Toggle PVID flag on second VxLAN device and make sure route is no @@ -1037,14 +1059,15 @@ offload_indication_vlan_aware_decap_route_test() bridge vlan add vid 20 dev vxlan20 untagged busywait "$TIMEOUT" not wait_for_offload \ - ip route show table local 198.51.100.1 + ip $IP_FLAG route show table local $LOCAL_IP_1 check_err $? # Toggle PVID flag back and make sure route is marked as offloaded bridge vlan add vid 10 dev vxlan10 pvid untagged bridge vlan add vid 20 dev vxlan20 pvid untagged - busywait "$TIMEOUT" wait_for_offload ip route show table local 198.51.100.1 + busywait "$TIMEOUT" wait_for_offload ip $IP_FLAG route show table local \ + $LOCAL_IP_1 check_err $? log_test "vxlan decap route - vni map/unmap" @@ -1052,10 +1075,12 @@ offload_indication_vlan_aware_decap_route_test() offload_indication_vlan_aware_join_vxlan_first() { - ip link add dev br0 up type bridge mcast_snooping 0 \ + ip link add dev br0 type bridge mcast_snooping 0 \ vlan_filtering 1 vlan_default_pvid 1 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 + ip link set dev br0 addrgenmode none + ip link set dev br0 up + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 __offload_indication_join_vxlan_first 1 @@ -1065,10 +1090,12 @@ offload_indication_vlan_aware_join_vxlan_first() offload_indication_vlan_aware_join_vxlan_last() { - ip link add dev br0 up type bridge mcast_snooping 0 \ + ip link add dev br0 type bridge mcast_snooping 0 \ vlan_filtering 1 vlan_default_pvid 1 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 + ip link set dev br0 addrgenmode none + ip link set dev br0 up + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 __offload_indication_join_vxlan_last @@ -1083,16 +1110,18 @@ offload_indication_vlan_aware_l3vni_test() RET=0 sysctl_set net.ipv6.conf.default.disable_ipv6 1 - ip link add dev br0 up type bridge mcast_snooping 0 \ + ip link add dev br0 type bridge mcast_snooping 0 \ vlan_filtering 1 vlan_default_pvid 0 - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 + ip link set dev br0 addrgenmode none + ip link set dev br0 up + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 ip link set dev $swp1 master br0 # The test will use the offload indication on the FDB entry to # understand if the tunnel is offloaded or not - bridge fdb append $zmac dev vxlan0 self dst 192.0.2.1 + bridge fdb append $zmac dev vxlan0 self dst $LOCAL_IP_2 ip link set dev vxlan0 master br0 bridge vlan add dev vxlan0 vid 10 pvid untagged diff --git a/tools/testing/selftests/drivers/net/mlxsw/vxlan_fdb_veto.sh b/tools/testing/selftests/drivers/net/mlxsw/vxlan_fdb_veto.sh index 749ba3cfda1d..38148f51877a 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/vxlan_fdb_veto.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/vxlan_fdb_veto.sh @@ -4,6 +4,21 @@ # Test vetoing of FDB entries that mlxsw can not offload. This exercises several # different veto vectors to test various rollback scenarios in the vxlan driver. +: ${LOCAL_IP:=198.51.100.1} +export LOCAL_IP + +: ${REMOTE_IP_1:=198.51.100.2} +export REMOTE_IP_1 + +: ${REMOTE_IP_2:=198.51.100.3} +export REMOTE_IP_2 + +: ${UDPCSUM_FLAFS:=noudpcsum} +export UDPCSUM_FLAFS + +: ${MC_IP:=224.0.0.1} +export MC_IP + lib_dir=$(dirname $0)/../../../net/forwarding ALL_TESTS=" @@ -26,8 +41,8 @@ setup_prepare() ip link set dev $swp1 master br0 ip link set dev $swp2 up - ip link add name vxlan0 up type vxlan id 10 nolearning noudpcsum \ - ttl 20 tos inherit local 198.51.100.1 dstport 4789 + ip link add name vxlan0 up type vxlan id 10 nolearning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP dstport 4789 ip link set dev vxlan0 master br0 } @@ -50,11 +65,11 @@ fdb_create_veto_test() RET=0 bridge fdb add 01:02:03:04:05:06 dev vxlan0 self static \ - dst 198.51.100.2 2>/dev/null + dst $REMOTE_IP_1 2>/dev/null check_fail $? "multicast MAC not rejected" bridge fdb add 01:02:03:04:05:06 dev vxlan0 self static \ - dst 198.51.100.2 2>&1 >/dev/null | grep -q mlxsw_spectrum + dst $REMOTE_IP_1 2>&1 >/dev/null | grep -q mlxsw_spectrum check_err $? "multicast MAC rejected without extack" log_test "vxlan FDB veto - create" @@ -65,15 +80,15 @@ fdb_replace_veto_test() RET=0 bridge fdb add 00:01:02:03:04:05 dev vxlan0 self static \ - dst 198.51.100.2 + dst $REMOTE_IP_1 check_err $? "valid FDB rejected" bridge fdb replace 00:01:02:03:04:05 dev vxlan0 self static \ - dst 198.51.100.2 port 1234 2>/dev/null + dst $REMOTE_IP_1 port 1234 2>/dev/null check_fail $? "FDB with an explicit port not rejected" bridge fdb replace 00:01:02:03:04:05 dev vxlan0 self static \ - dst 198.51.100.2 port 1234 2>&1 >/dev/null \ + dst $REMOTE_IP_1 port 1234 2>&1 >/dev/null \ | grep -q mlxsw_spectrum check_err $? "FDB with an explicit port rejected without extack" @@ -85,15 +100,15 @@ fdb_append_veto_test() RET=0 bridge fdb add 00:00:00:00:00:00 dev vxlan0 self static \ - dst 198.51.100.2 + dst $REMOTE_IP_1 check_err $? "valid FDB rejected" bridge fdb append 00:00:00:00:00:00 dev vxlan0 self static \ - dst 198.51.100.3 port 1234 2>/dev/null + dst $REMOTE_IP_2 port 1234 2>/dev/null check_fail $? "FDB with an explicit port not rejected" bridge fdb append 00:00:00:00:00:00 dev vxlan0 self static \ - dst 198.51.100.3 port 1234 2>&1 >/dev/null \ + dst $REMOTE_IP_2 port 1234 2>&1 >/dev/null \ | grep -q mlxsw_spectrum check_err $? "FDB with an explicit port rejected without extack" @@ -105,11 +120,11 @@ fdb_changelink_veto_test() RET=0 ip link set dev vxlan0 type vxlan \ - group 224.0.0.1 dev lo 2>/dev/null + group $MC_IP dev lo 2>/dev/null check_fail $? "FDB with a multicast IP not rejected" ip link set dev vxlan0 type vxlan \ - group 224.0.0.1 dev lo 2>&1 >/dev/null \ + group $MC_IP dev lo 2>&1 >/dev/null \ | grep -q mlxsw_spectrum check_err $? "FDB with a multicast IP rejected without extack" diff --git a/tools/testing/selftests/drivers/net/mlxsw/vxlan_fdb_veto_ipv6.sh b/tools/testing/selftests/drivers/net/mlxsw/vxlan_fdb_veto_ipv6.sh new file mode 100755 index 000000000000..66c87aab86f6 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/vxlan_fdb_veto_ipv6.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# A wrapper to run VXLAN test for IPv6. + +LOCAL_IP=2001:db8:1::1 +REMOTE_IP_1=2001:db8:2::1 +REMOTE_IP_2=2001:db8:3::1 +UDPCSUM_FLAFS="udp6zerocsumrx udp6zerocsumtx" +MC_IP=FF02::2 + +source vxlan_fdb_veto.sh diff --git a/tools/testing/selftests/drivers/net/mlxsw/vxlan_flooding.sh b/tools/testing/selftests/drivers/net/mlxsw/vxlan_flooding.sh index fedcb7b35af9..af5ea50ed5c0 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/vxlan_flooding.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/vxlan_flooding.sh @@ -172,6 +172,17 @@ flooding_filters_add() local lsb local i + # Prevent unwanted packets from entering the bridge and interfering + # with the test. + tc qdisc add dev br0 clsact + tc filter add dev br0 egress protocol all pref 1 handle 1 \ + matchall skip_hw action drop + tc qdisc add dev $h1 clsact + tc filter add dev $h1 egress protocol all pref 1 handle 1 \ + flower skip_hw dst_mac de:ad:be:ef:13:37 action pass + tc filter add dev $h1 egress protocol all pref 2 handle 2 \ + matchall skip_hw action drop + tc qdisc add dev $rp2 clsact for i in $(eval echo {1..$num_remotes}); do @@ -194,6 +205,12 @@ flooding_filters_del() done tc qdisc del dev $rp2 clsact + + tc filter del dev $h1 egress protocol all pref 2 handle 2 matchall + tc filter del dev $h1 egress protocol all pref 1 handle 1 flower + tc qdisc del dev $h1 clsact + tc filter del dev br0 egress protocol all pref 1 handle 1 matchall + tc qdisc del dev br0 clsact } flooding_check_packets() diff --git a/tools/testing/selftests/drivers/net/mlxsw/vxlan_ipv6.sh b/tools/testing/selftests/drivers/net/mlxsw/vxlan_ipv6.sh new file mode 100755 index 000000000000..f2ea0163ddea --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/vxlan_ipv6.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# A wrapper to run VXLAN test for IPv6. + +ADDR_FAMILY=ipv6 +LOCAL_IP_1=2001:db8:1::1 +LOCAL_IP_2=2001:db8:1::2 +PREFIX_LEN=128 +UDPCSUM_FLAFS="udp6zerocsumrx udp6zerocsumtx" +MC_IP=FF02::2 +IP_FLAG="-6" + +ALL_TESTS=" + sanitization_test + offload_indication_test + sanitization_vlan_aware_test + offload_indication_vlan_aware_test +" + +sanitization_single_dev_learning_enabled_ipv6_test() +{ + RET=0 + + ip link add dev br0 type bridge mcast_snooping 0 + + ip link add name vxlan0 up type vxlan id 10 learning $UDPCSUM_FLAFS \ + ttl 20 tos inherit local $LOCAL_IP_1 dstport 4789 + + sanitization_single_dev_test_fail + + ip link del dev vxlan0 + ip link del dev br0 + + log_test "vxlan device with learning enabled" +} + +sanitization_single_dev_udp_checksum_ipv6_test() +{ + RET=0 + + ip link add dev br0 type bridge mcast_snooping 0 + + ip link add name vxlan0 up type vxlan id 10 nolearning \ + noudp6zerocsumrx udp6zerocsumtx ttl 20 tos inherit \ + local $LOCAL_IP_1 dstport 4789 + + sanitization_single_dev_test_fail + log_test "vxlan device without zero udp checksum at RX" + + ip link del dev vxlan0 + + ip link add name vxlan0 up type vxlan id 10 nolearning \ + udp6zerocsumrx noudp6zerocsumtx ttl 20 tos inherit \ + local $LOCAL_IP_1 dstport 4789 + + sanitization_single_dev_test_fail + log_test "vxlan device without zero udp checksum at TX" + + ip link del dev vxlan0 + ip link del dev br0 + +} + +source vxlan.sh |