| #!/bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # Copyright 2022 NXP |
| |
| # The script is mostly generic, with the exception of the |
| # ethtool per-TC counter names ("rx_green_prio_${tc}") |
| |
| WAIT_TIME=1 |
| NUM_NETIFS=4 |
| STABLE_MAC_ADDRS=yes |
| NETIF_CREATE=no |
| lib_dir=$(dirname $0)/../../../net/forwarding |
| source $lib_dir/tc_common.sh |
| source $lib_dir/lib.sh |
| |
| require_command dcb |
| |
| h1=${NETIFS[p1]} |
| swp1=${NETIFS[p2]} |
| swp2=${NETIFS[p3]} |
| h2=${NETIFS[p4]} |
| |
| H1_IPV4="192.0.2.1" |
| H2_IPV4="192.0.2.2" |
| H1_IPV6="2001:db8:1::1" |
| H2_IPV6="2001:db8:1::2" |
| |
| h1_create() |
| { |
| simple_if_init $h1 $H1_IPV4/24 $H1_IPV6/64 |
| } |
| |
| h1_destroy() |
| { |
| simple_if_fini $h1 $H1_IPV4/24 $H1_IPV6/64 |
| } |
| |
| h2_create() |
| { |
| simple_if_init $h2 $H2_IPV4/24 $H2_IPV6/64 |
| } |
| |
| h2_destroy() |
| { |
| simple_if_fini $h2 $H2_IPV4/24 $H2_IPV6/64 |
| } |
| |
| h1_vlan_create() |
| { |
| local vid=$1 |
| |
| vlan_create $h1 $vid |
| simple_if_init $h1.$vid $H1_IPV4/24 $H1_IPV6/64 |
| ip link set $h1.$vid type vlan \ |
| egress-qos-map 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 \ |
| ingress-qos-map 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 |
| } |
| |
| h1_vlan_destroy() |
| { |
| local vid=$1 |
| |
| simple_if_fini $h1.$vid $H1_IPV4/24 $H1_IPV6/64 |
| vlan_destroy $h1 $vid |
| } |
| |
| h2_vlan_create() |
| { |
| local vid=$1 |
| |
| vlan_create $h2 $vid |
| simple_if_init $h2.$vid $H2_IPV4/24 $H2_IPV6/64 |
| ip link set $h2.$vid type vlan \ |
| egress-qos-map 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 \ |
| ingress-qos-map 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 |
| } |
| |
| h2_vlan_destroy() |
| { |
| local vid=$1 |
| |
| simple_if_fini $h2.$vid $H2_IPV4/24 $H2_IPV6/64 |
| vlan_destroy $h2 $vid |
| } |
| |
| vlans_prepare() |
| { |
| h1_vlan_create 100 |
| h2_vlan_create 100 |
| |
| tc qdisc add dev ${h1}.100 clsact |
| tc filter add dev ${h1}.100 egress protocol ipv4 \ |
| flower ip_proto icmp action skbedit priority 3 |
| tc filter add dev ${h1}.100 egress protocol ipv6 \ |
| flower ip_proto icmpv6 action skbedit priority 3 |
| } |
| |
| vlans_destroy() |
| { |
| tc qdisc del dev ${h1}.100 clsact |
| |
| h1_vlan_destroy 100 |
| h2_vlan_destroy 100 |
| } |
| |
| switch_create() |
| { |
| ip link set ${swp1} up |
| ip link set ${swp2} up |
| |
| # Ports should trust VLAN PCP even with vlan_filtering=0 |
| ip link add br0 type bridge |
| ip link set ${swp1} master br0 |
| ip link set ${swp2} master br0 |
| ip link set br0 up |
| } |
| |
| switch_destroy() |
| { |
| ip link del br0 |
| } |
| |
| setup_prepare() |
| { |
| vrf_prepare |
| |
| h1_create |
| h2_create |
| switch_create |
| } |
| |
| cleanup() |
| { |
| pre_cleanup |
| |
| h2_destroy |
| h1_destroy |
| switch_destroy |
| |
| vrf_cleanup |
| } |
| |
| dscp_cs_to_tos() |
| { |
| local dscp_cs=$1 |
| |
| # https://datatracker.ietf.org/doc/html/rfc2474 |
| # 4.2.2.1 The Class Selector Codepoints |
| echo $((${dscp_cs} << 5)) |
| } |
| |
| run_test() |
| { |
| local test_name=$1; shift |
| local if_name=$1; shift |
| local tc=$1; shift |
| local tos=$1; shift |
| local counter_name="rx_green_prio_${tc}" |
| local ipv4_before |
| local ipv4_after |
| local ipv6_before |
| local ipv6_after |
| |
| ipv4_before=$(ethtool_stats_get ${swp1} "${counter_name}") |
| ping_do ${if_name} $H2_IPV4 "-Q ${tos}" |
| ipv4_after=$(ethtool_stats_get ${swp1} "${counter_name}") |
| |
| if [ $((${ipv4_after} - ${ipv4_before})) -lt ${PING_COUNT} ]; then |
| RET=1 |
| else |
| RET=0 |
| fi |
| log_test "IPv4 ${test_name}" |
| |
| ipv6_before=$(ethtool_stats_get ${swp1} "${counter_name}") |
| ping_do ${if_name} $H2_IPV6 "-Q ${tos}" |
| ipv6_after=$(ethtool_stats_get ${swp1} "${counter_name}") |
| |
| if [ $((${ipv6_after} - ${ipv6_before})) -lt ${PING_COUNT} ]; then |
| RET=1 |
| else |
| RET=0 |
| fi |
| log_test "IPv6 ${test_name}" |
| } |
| |
| port_default_prio_get() |
| { |
| local if_name=$1 |
| local prio |
| |
| prio="$(dcb -j app show dev ${if_name} default-prio | \ |
| jq '.default_prio[]')" |
| if [ -z "${prio}" ]; then |
| prio=0 |
| fi |
| |
| echo ${prio} |
| } |
| |
| test_port_default() |
| { |
| local orig=$(port_default_prio_get ${swp1}) |
| local dmac=$(mac_get ${h2}) |
| |
| dcb app replace dev ${swp1} default-prio 5 |
| |
| run_test "Port-default QoS classification" ${h1} 5 0 |
| |
| dcb app replace dev ${swp1} default-prio ${orig} |
| } |
| |
| test_vlan_pcp() |
| { |
| vlans_prepare |
| |
| run_test "Trusted VLAN PCP QoS classification" ${h1}.100 3 0 |
| |
| vlans_destroy |
| } |
| |
| test_ip_dscp() |
| { |
| local port_default=$(port_default_prio_get ${swp1}) |
| local tos=$(dscp_cs_to_tos 4) |
| |
| dcb app add dev ${swp1} dscp-prio CS4:4 |
| run_test "Trusted DSCP QoS classification" ${h1} 4 ${tos} |
| dcb app del dev ${swp1} dscp-prio CS4:4 |
| |
| vlans_prepare |
| run_test "Untrusted DSCP QoS classification follows VLAN PCP" \ |
| ${h1}.100 3 ${tos} |
| vlans_destroy |
| |
| run_test "Untrusted DSCP QoS classification follows port default" \ |
| ${h1} ${port_default} ${tos} |
| } |
| |
| trap cleanup EXIT |
| |
| ALL_TESTS=" |
| test_port_default |
| test_vlan_pcp |
| test_ip_dscp |
| " |
| |
| setup_prepare |
| setup_wait |
| |
| tests_run |
| |
| exit $EXIT_STATUS |