# SPDX-License-Identifier: GPL-2.0 # This test sends a stream of traffic from H1 through a switch, to H2. On the # egress port from the switch ($swp2), a shaper is installed. The test verifies # that the rates on the port match the configured shaper. # # In order to test per-class shaping, $swp2 actually contains TBF under PRIO or # ETS, with two different configurations. Traffic is prioritized using 802.1p. # # +-------------------------------------------+ # | H1 | # | + $h1.10 $h1.11 + | # | | 192.0.2.1/28 192.0.2.17/28 | | # | | | | # | \______________ _____________/ | # | \ / | # | + $h1 | # +---------------------|---------------------+ # | # +---------------------|---------------------+ # | SW + $swp1 | # | _______________/ \_______________ | # | / \ | # | +-|--------------+ +--------------|-+ | # | | + $swp1.10 | | $swp1.11 + | | # | | | | | | # | | BR10 | | BR11 | | # | | | | | | # | | + $swp2.10 | | $swp2.11 + | | # | +-|--------------+ +--------------|-+ | # | \_______________ ______________/ | # | \ / | # | + $swp2 | # +---------------------|---------------------+ # | # +---------------------|---------------------+ # | H2 + $h2 | # | ______________/ \______________ | # | / \ | # | | | | # | + $h2.10 $h2.11 + | # | 192.0.2.2/28 192.0.2.18/28 | # +-------------------------------------------+ NUM_NETIFS=4 CHECK_TC="yes" source $lib_dir/lib.sh ipaddr() { local host=$1; shift local vlan=$1; shift echo 192.0.2.$((16 * (vlan - 10) + host)) } host_create() { local dev=$1; shift local host=$1; shift simple_if_init $dev mtu_set $dev 10000 vlan_create $dev 10 v$dev $(ipaddr $host 10)/28 ip link set dev $dev.10 type vlan egress 0:0 vlan_create $dev 11 v$dev $(ipaddr $host 11)/28 ip link set dev $dev.11 type vlan egress 0:1 } host_destroy() { local dev=$1; shift vlan_destroy $dev 11 vlan_destroy $dev 10 mtu_restore $dev simple_if_fini $dev } h1_create() { host_create $h1 1 } h1_destroy() { host_destroy $h1 } h2_create() { host_create $h2 2 tc qdisc add dev $h2 clsact tc filter add dev $h2 ingress pref 1010 prot 802.1q \ flower $TCFLAGS vlan_id 10 action pass tc filter add dev $h2 ingress pref 1011 prot 802.1q \ flower $TCFLAGS vlan_id 11 action pass } h2_destroy() { tc qdisc del dev $h2 clsact host_destroy $h2 } switch_create() { local intf local vlan ip link add dev br10 type bridge ip link add dev br11 type bridge for intf in $swp1 $swp2; do ip link set dev $intf up mtu_set $intf 10000 for vlan in 10 11; do vlan_create $intf $vlan ip link set dev $intf.$vlan master br$vlan ip link set dev $intf.$vlan up done done for vlan in 10 11; do ip link set dev $swp1.$vlan type vlan ingress 0:0 1:1 done ip link set dev br10 up ip link set dev br11 up } switch_destroy() { local intf local vlan # A test may have been interrupted mid-run, with Qdisc installed. Delete # it here. tc qdisc del dev $swp2 root 2>/dev/null ip link set dev br11 down ip link set dev br10 down for intf in $swp2 $swp1; do for vlan in 11 10; do ip link set dev $intf.$vlan down ip link set dev $intf.$vlan nomaster vlan_destroy $intf $vlan done mtu_restore $intf ip link set dev $intf down done ip link del dev br11 ip link del dev br10 } setup_prepare() { h1=${NETIFS[p1]} swp1=${NETIFS[p2]} swp2=${NETIFS[p3]} h2=${NETIFS[p4]} swp3=${NETIFS[p5]} h3=${NETIFS[p6]} swp4=${NETIFS[p7]} swp5=${NETIFS[p8]} h2_mac=$(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.10 $(ipaddr 2 10) " vlan 10" ping_test $h1.11 $(ipaddr 2 11) " vlan 11" } tbf_get_counter() { local vlan=$1; shift tc_rule_stats_get $h2 10$vlan ingress .bytes } do_tbf_test() { local vlan=$1; shift local mbit=$1; shift start_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 2 $vlan) $h2_mac sleep 5 # Wait for the burst to dwindle local t2=$(busywait_for_counter 1000 +1 tbf_get_counter $vlan) sleep 10 local t3=$(tbf_get_counter $vlan) stop_traffic RET=0 # Note: TBF uses 10^6 Mbits, not 2^20 ones. local er=$((mbit * 1000 * 1000)) local nr=$(rate $t2 $t3 10) local nr_pct=$((100 * (nr - er) / er)) ((-5 <= nr_pct && nr_pct <= 5)) check_err $? "Expected rate $(humanize $er), got $(humanize $nr), which is $nr_pct% off. Required accuracy is +-5%." log_test "TC $((vlan - 10)): TBF rate ${mbit}Mbit" }