1*7d4e91e0SVladimir Oltean#!/bin/bash 2*7d4e91e0SVladimir Oltean# SPDX-License-Identifier: GPL-2.0 3*7d4e91e0SVladimir Oltean# Copyright 2022 NXP 4*7d4e91e0SVladimir Oltean 5*7d4e91e0SVladimir Oltean# The script is mostly generic, with the exception of the 6*7d4e91e0SVladimir Oltean# ethtool per-TC counter names ("rx_green_prio_${tc}") 7*7d4e91e0SVladimir Oltean 8*7d4e91e0SVladimir OlteanWAIT_TIME=1 9*7d4e91e0SVladimir OlteanNUM_NETIFS=4 10*7d4e91e0SVladimir OlteanSTABLE_MAC_ADDRS=yes 11*7d4e91e0SVladimir OlteanNETIF_CREATE=no 12*7d4e91e0SVladimir Olteanlib_dir=$(dirname $0)/../../../net/forwarding 13*7d4e91e0SVladimir Olteansource $lib_dir/tc_common.sh 14*7d4e91e0SVladimir Olteansource $lib_dir/lib.sh 15*7d4e91e0SVladimir Oltean 16*7d4e91e0SVladimir Olteanrequire_command dcb 17*7d4e91e0SVladimir Oltean 18*7d4e91e0SVladimir Olteanh1=${NETIFS[p1]} 19*7d4e91e0SVladimir Olteanswp1=${NETIFS[p2]} 20*7d4e91e0SVladimir Olteanswp2=${NETIFS[p3]} 21*7d4e91e0SVladimir Olteanh2=${NETIFS[p4]} 22*7d4e91e0SVladimir Oltean 23*7d4e91e0SVladimir OlteanH1_IPV4="192.0.2.1" 24*7d4e91e0SVladimir OlteanH2_IPV4="192.0.2.2" 25*7d4e91e0SVladimir OlteanH1_IPV6="2001:db8:1::1" 26*7d4e91e0SVladimir OlteanH2_IPV6="2001:db8:1::2" 27*7d4e91e0SVladimir Oltean 28*7d4e91e0SVladimir Olteanh1_create() 29*7d4e91e0SVladimir Oltean{ 30*7d4e91e0SVladimir Oltean simple_if_init $h1 $H1_IPV4/24 $H1_IPV6/64 31*7d4e91e0SVladimir Oltean} 32*7d4e91e0SVladimir Oltean 33*7d4e91e0SVladimir Olteanh1_destroy() 34*7d4e91e0SVladimir Oltean{ 35*7d4e91e0SVladimir Oltean simple_if_fini $h1 $H1_IPV4/24 $H1_IPV6/64 36*7d4e91e0SVladimir Oltean} 37*7d4e91e0SVladimir Oltean 38*7d4e91e0SVladimir Olteanh2_create() 39*7d4e91e0SVladimir Oltean{ 40*7d4e91e0SVladimir Oltean simple_if_init $h2 $H2_IPV4/24 $H2_IPV6/64 41*7d4e91e0SVladimir Oltean} 42*7d4e91e0SVladimir Oltean 43*7d4e91e0SVladimir Olteanh2_destroy() 44*7d4e91e0SVladimir Oltean{ 45*7d4e91e0SVladimir Oltean simple_if_fini $h2 $H2_IPV4/24 $H2_IPV6/64 46*7d4e91e0SVladimir Oltean} 47*7d4e91e0SVladimir Oltean 48*7d4e91e0SVladimir Olteanh1_vlan_create() 49*7d4e91e0SVladimir Oltean{ 50*7d4e91e0SVladimir Oltean local vid=$1 51*7d4e91e0SVladimir Oltean 52*7d4e91e0SVladimir Oltean vlan_create $h1 $vid 53*7d4e91e0SVladimir Oltean simple_if_init $h1.$vid $H1_IPV4/24 $H1_IPV6/64 54*7d4e91e0SVladimir Oltean ip link set $h1.$vid type vlan \ 55*7d4e91e0SVladimir Oltean egress-qos-map 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 \ 56*7d4e91e0SVladimir Oltean ingress-qos-map 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 57*7d4e91e0SVladimir Oltean} 58*7d4e91e0SVladimir Oltean 59*7d4e91e0SVladimir Olteanh1_vlan_destroy() 60*7d4e91e0SVladimir Oltean{ 61*7d4e91e0SVladimir Oltean local vid=$1 62*7d4e91e0SVladimir Oltean 63*7d4e91e0SVladimir Oltean simple_if_fini $h1.$vid $H1_IPV4/24 $H1_IPV6/64 64*7d4e91e0SVladimir Oltean vlan_destroy $h1 $vid 65*7d4e91e0SVladimir Oltean} 66*7d4e91e0SVladimir Oltean 67*7d4e91e0SVladimir Olteanh2_vlan_create() 68*7d4e91e0SVladimir Oltean{ 69*7d4e91e0SVladimir Oltean local vid=$1 70*7d4e91e0SVladimir Oltean 71*7d4e91e0SVladimir Oltean vlan_create $h2 $vid 72*7d4e91e0SVladimir Oltean simple_if_init $h2.$vid $H2_IPV4/24 $H2_IPV6/64 73*7d4e91e0SVladimir Oltean ip link set $h2.$vid type vlan \ 74*7d4e91e0SVladimir Oltean egress-qos-map 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 \ 75*7d4e91e0SVladimir Oltean ingress-qos-map 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 76*7d4e91e0SVladimir Oltean} 77*7d4e91e0SVladimir Oltean 78*7d4e91e0SVladimir Olteanh2_vlan_destroy() 79*7d4e91e0SVladimir Oltean{ 80*7d4e91e0SVladimir Oltean local vid=$1 81*7d4e91e0SVladimir Oltean 82*7d4e91e0SVladimir Oltean simple_if_fini $h2.$vid $H2_IPV4/24 $H2_IPV6/64 83*7d4e91e0SVladimir Oltean vlan_destroy $h2 $vid 84*7d4e91e0SVladimir Oltean} 85*7d4e91e0SVladimir Oltean 86*7d4e91e0SVladimir Olteanvlans_prepare() 87*7d4e91e0SVladimir Oltean{ 88*7d4e91e0SVladimir Oltean h1_vlan_create 100 89*7d4e91e0SVladimir Oltean h2_vlan_create 100 90*7d4e91e0SVladimir Oltean 91*7d4e91e0SVladimir Oltean tc qdisc add dev ${h1}.100 clsact 92*7d4e91e0SVladimir Oltean tc filter add dev ${h1}.100 egress protocol ipv4 \ 93*7d4e91e0SVladimir Oltean flower ip_proto icmp action skbedit priority 3 94*7d4e91e0SVladimir Oltean tc filter add dev ${h1}.100 egress protocol ipv6 \ 95*7d4e91e0SVladimir Oltean flower ip_proto icmpv6 action skbedit priority 3 96*7d4e91e0SVladimir Oltean} 97*7d4e91e0SVladimir Oltean 98*7d4e91e0SVladimir Olteanvlans_destroy() 99*7d4e91e0SVladimir Oltean{ 100*7d4e91e0SVladimir Oltean tc qdisc del dev ${h1}.100 clsact 101*7d4e91e0SVladimir Oltean 102*7d4e91e0SVladimir Oltean h1_vlan_destroy 100 103*7d4e91e0SVladimir Oltean h2_vlan_destroy 100 104*7d4e91e0SVladimir Oltean} 105*7d4e91e0SVladimir Oltean 106*7d4e91e0SVladimir Olteanswitch_create() 107*7d4e91e0SVladimir Oltean{ 108*7d4e91e0SVladimir Oltean ip link set ${swp1} up 109*7d4e91e0SVladimir Oltean ip link set ${swp2} up 110*7d4e91e0SVladimir Oltean 111*7d4e91e0SVladimir Oltean # Ports should trust VLAN PCP even with vlan_filtering=0 112*7d4e91e0SVladimir Oltean ip link add br0 type bridge 113*7d4e91e0SVladimir Oltean ip link set ${swp1} master br0 114*7d4e91e0SVladimir Oltean ip link set ${swp2} master br0 115*7d4e91e0SVladimir Oltean ip link set br0 up 116*7d4e91e0SVladimir Oltean} 117*7d4e91e0SVladimir Oltean 118*7d4e91e0SVladimir Olteanswitch_destroy() 119*7d4e91e0SVladimir Oltean{ 120*7d4e91e0SVladimir Oltean ip link del br0 121*7d4e91e0SVladimir Oltean} 122*7d4e91e0SVladimir Oltean 123*7d4e91e0SVladimir Olteansetup_prepare() 124*7d4e91e0SVladimir Oltean{ 125*7d4e91e0SVladimir Oltean vrf_prepare 126*7d4e91e0SVladimir Oltean 127*7d4e91e0SVladimir Oltean h1_create 128*7d4e91e0SVladimir Oltean h2_create 129*7d4e91e0SVladimir Oltean switch_create 130*7d4e91e0SVladimir Oltean} 131*7d4e91e0SVladimir Oltean 132*7d4e91e0SVladimir Olteancleanup() 133*7d4e91e0SVladimir Oltean{ 134*7d4e91e0SVladimir Oltean pre_cleanup 135*7d4e91e0SVladimir Oltean 136*7d4e91e0SVladimir Oltean h2_destroy 137*7d4e91e0SVladimir Oltean h1_destroy 138*7d4e91e0SVladimir Oltean switch_destroy 139*7d4e91e0SVladimir Oltean 140*7d4e91e0SVladimir Oltean vrf_cleanup 141*7d4e91e0SVladimir Oltean} 142*7d4e91e0SVladimir Oltean 143*7d4e91e0SVladimir Olteandscp_cs_to_tos() 144*7d4e91e0SVladimir Oltean{ 145*7d4e91e0SVladimir Oltean local dscp_cs=$1 146*7d4e91e0SVladimir Oltean 147*7d4e91e0SVladimir Oltean # https://datatracker.ietf.org/doc/html/rfc2474 148*7d4e91e0SVladimir Oltean # 4.2.2.1 The Class Selector Codepoints 149*7d4e91e0SVladimir Oltean echo $((${dscp_cs} << 5)) 150*7d4e91e0SVladimir Oltean} 151*7d4e91e0SVladimir Oltean 152*7d4e91e0SVladimir Olteanrun_test() 153*7d4e91e0SVladimir Oltean{ 154*7d4e91e0SVladimir Oltean local test_name=$1; shift 155*7d4e91e0SVladimir Oltean local if_name=$1; shift 156*7d4e91e0SVladimir Oltean local tc=$1; shift 157*7d4e91e0SVladimir Oltean local tos=$1; shift 158*7d4e91e0SVladimir Oltean local counter_name="rx_green_prio_${tc}" 159*7d4e91e0SVladimir Oltean local ipv4_before 160*7d4e91e0SVladimir Oltean local ipv4_after 161*7d4e91e0SVladimir Oltean local ipv6_before 162*7d4e91e0SVladimir Oltean local ipv6_after 163*7d4e91e0SVladimir Oltean 164*7d4e91e0SVladimir Oltean ipv4_before=$(ethtool_stats_get ${swp1} "${counter_name}") 165*7d4e91e0SVladimir Oltean ping_do ${if_name} $H2_IPV4 "-Q ${tos}" 166*7d4e91e0SVladimir Oltean ipv4_after=$(ethtool_stats_get ${swp1} "${counter_name}") 167*7d4e91e0SVladimir Oltean 168*7d4e91e0SVladimir Oltean if [ $((${ipv4_after} - ${ipv4_before})) -lt ${PING_COUNT} ]; then 169*7d4e91e0SVladimir Oltean RET=1 170*7d4e91e0SVladimir Oltean else 171*7d4e91e0SVladimir Oltean RET=0 172*7d4e91e0SVladimir Oltean fi 173*7d4e91e0SVladimir Oltean log_test "IPv4 ${test_name}" 174*7d4e91e0SVladimir Oltean 175*7d4e91e0SVladimir Oltean ipv6_before=$(ethtool_stats_get ${swp1} "${counter_name}") 176*7d4e91e0SVladimir Oltean ping_do ${if_name} $H2_IPV6 "-Q ${tos}" 177*7d4e91e0SVladimir Oltean ipv6_after=$(ethtool_stats_get ${swp1} "${counter_name}") 178*7d4e91e0SVladimir Oltean 179*7d4e91e0SVladimir Oltean if [ $((${ipv6_after} - ${ipv6_before})) -lt ${PING_COUNT} ]; then 180*7d4e91e0SVladimir Oltean RET=1 181*7d4e91e0SVladimir Oltean else 182*7d4e91e0SVladimir Oltean RET=0 183*7d4e91e0SVladimir Oltean fi 184*7d4e91e0SVladimir Oltean log_test "IPv6 ${test_name}" 185*7d4e91e0SVladimir Oltean} 186*7d4e91e0SVladimir Oltean 187*7d4e91e0SVladimir Olteanport_default_prio_get() 188*7d4e91e0SVladimir Oltean{ 189*7d4e91e0SVladimir Oltean local if_name=$1 190*7d4e91e0SVladimir Oltean local prio 191*7d4e91e0SVladimir Oltean 192*7d4e91e0SVladimir Oltean prio="$(dcb -j app show dev ${if_name} default-prio | \ 193*7d4e91e0SVladimir Oltean jq '.default_prio[]')" 194*7d4e91e0SVladimir Oltean if [ -z "${prio}" ]; then 195*7d4e91e0SVladimir Oltean prio=0 196*7d4e91e0SVladimir Oltean fi 197*7d4e91e0SVladimir Oltean 198*7d4e91e0SVladimir Oltean echo ${prio} 199*7d4e91e0SVladimir Oltean} 200*7d4e91e0SVladimir Oltean 201*7d4e91e0SVladimir Olteantest_port_default() 202*7d4e91e0SVladimir Oltean{ 203*7d4e91e0SVladimir Oltean local orig=$(port_default_prio_get ${swp1}) 204*7d4e91e0SVladimir Oltean local dmac=$(mac_get ${h2}) 205*7d4e91e0SVladimir Oltean 206*7d4e91e0SVladimir Oltean dcb app replace dev ${swp1} default-prio 5 207*7d4e91e0SVladimir Oltean 208*7d4e91e0SVladimir Oltean run_test "Port-default QoS classification" ${h1} 5 0 209*7d4e91e0SVladimir Oltean 210*7d4e91e0SVladimir Oltean dcb app replace dev ${swp1} default-prio ${orig} 211*7d4e91e0SVladimir Oltean} 212*7d4e91e0SVladimir Oltean 213*7d4e91e0SVladimir Olteantest_vlan_pcp() 214*7d4e91e0SVladimir Oltean{ 215*7d4e91e0SVladimir Oltean vlans_prepare 216*7d4e91e0SVladimir Oltean 217*7d4e91e0SVladimir Oltean run_test "Trusted VLAN PCP QoS classification" ${h1}.100 3 0 218*7d4e91e0SVladimir Oltean 219*7d4e91e0SVladimir Oltean vlans_destroy 220*7d4e91e0SVladimir Oltean} 221*7d4e91e0SVladimir Oltean 222*7d4e91e0SVladimir Olteantest_ip_dscp() 223*7d4e91e0SVladimir Oltean{ 224*7d4e91e0SVladimir Oltean local port_default=$(port_default_prio_get ${swp1}) 225*7d4e91e0SVladimir Oltean local tos=$(dscp_cs_to_tos 4) 226*7d4e91e0SVladimir Oltean 227*7d4e91e0SVladimir Oltean dcb app add dev ${swp1} dscp-prio CS4:4 228*7d4e91e0SVladimir Oltean run_test "Trusted DSCP QoS classification" ${h1} 4 ${tos} 229*7d4e91e0SVladimir Oltean dcb app del dev ${swp1} dscp-prio CS4:4 230*7d4e91e0SVladimir Oltean 231*7d4e91e0SVladimir Oltean vlans_prepare 232*7d4e91e0SVladimir Oltean run_test "Untrusted DSCP QoS classification follows VLAN PCP" \ 233*7d4e91e0SVladimir Oltean ${h1}.100 3 ${tos} 234*7d4e91e0SVladimir Oltean vlans_destroy 235*7d4e91e0SVladimir Oltean 236*7d4e91e0SVladimir Oltean run_test "Untrusted DSCP QoS classification follows port default" \ 237*7d4e91e0SVladimir Oltean ${h1} ${port_default} ${tos} 238*7d4e91e0SVladimir Oltean} 239*7d4e91e0SVladimir Oltean 240*7d4e91e0SVladimir Olteantrap cleanup EXIT 241*7d4e91e0SVladimir Oltean 242*7d4e91e0SVladimir OlteanALL_TESTS=" 243*7d4e91e0SVladimir Oltean test_port_default 244*7d4e91e0SVladimir Oltean test_vlan_pcp 245*7d4e91e0SVladimir Oltean test_ip_dscp 246*7d4e91e0SVladimir Oltean" 247*7d4e91e0SVladimir Oltean 248*7d4e91e0SVladimir Olteansetup_prepare 249*7d4e91e0SVladimir Olteansetup_wait 250*7d4e91e0SVladimir Oltean 251*7d4e91e0SVladimir Olteantests_run 252*7d4e91e0SVladimir Oltean 253*7d4e91e0SVladimir Olteanexit $EXIT_STATUS 254