1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# This test sends traffic from H1 to H2. Either on ingress of $swp1, or on 5# egress of $swp2, the traffic is acted upon by a pedit action. An ingress 6# filter installed on $h2 verifies that the packet looks like expected. 7# 8# +----------------------+ +----------------------+ 9# | H1 | | H2 | 10# | + $h1 | | $h2 + | 11# | | 192.0.2.1/28 | | 192.0.2.2/28 | | 12# +----|-----------------+ +----------------|-----+ 13# | | 14# +----|----------------------------------------------------------------|-----+ 15# | SW | | | 16# | +-|----------------------------------------------------------------|-+ | 17# | | + $swp1 BR $swp2 + | | 18# | +--------------------------------------------------------------------+ | 19# +---------------------------------------------------------------------------+ 20 21ALL_TESTS=" 22 ping_ipv4 23 ping_ipv6 24 test_ip_dsfield 25 test_ip_dscp 26 test_ip_ecn 27 test_ip_dscp_ecn 28 test_ip6_dsfield 29 test_ip6_dscp 30 test_ip6_ecn 31" 32 33NUM_NETIFS=4 34source lib.sh 35source tc_common.sh 36 37: ${HIT_TIMEOUT:=2000} # ms 38 39h1_create() 40{ 41 simple_if_init $h1 192.0.2.1/28 2001:db8:1::1/64 42} 43 44h1_destroy() 45{ 46 simple_if_fini $h1 192.0.2.1/28 2001:db8:1::1/64 47} 48 49h2_create() 50{ 51 simple_if_init $h2 192.0.2.2/28 2001:db8:1::2/64 52 tc qdisc add dev $h2 clsact 53} 54 55h2_destroy() 56{ 57 tc qdisc del dev $h2 clsact 58 simple_if_fini $h2 192.0.2.2/28 2001:db8:1::2/64 59} 60 61switch_create() 62{ 63 ip link add name br1 up type bridge vlan_filtering 1 64 ip link set dev $swp1 master br1 65 ip link set dev $swp1 up 66 ip link set dev $swp2 master br1 67 ip link set dev $swp2 up 68 69 tc qdisc add dev $swp1 clsact 70 tc qdisc add dev $swp2 clsact 71} 72 73switch_destroy() 74{ 75 tc qdisc del dev $swp2 clsact 76 tc qdisc del dev $swp1 clsact 77 78 ip link set dev $swp2 nomaster 79 ip link set dev $swp1 nomaster 80 ip link del dev br1 81} 82 83setup_prepare() 84{ 85 h1=${NETIFS[p1]} 86 swp1=${NETIFS[p2]} 87 88 swp2=${NETIFS[p3]} 89 h2=${NETIFS[p4]} 90 91 h2mac=$(mac_get $h2) 92 93 vrf_prepare 94 h1_create 95 h2_create 96 switch_create 97} 98 99cleanup() 100{ 101 pre_cleanup 102 103 switch_destroy 104 h2_destroy 105 h1_destroy 106 vrf_cleanup 107} 108 109ping_ipv4() 110{ 111 ping_test $h1 192.0.2.2 112} 113 114ping_ipv6() 115{ 116 ping6_test $h1 2001:db8:1::2 117} 118 119do_test_pedit_dsfield_common() 120{ 121 local pedit_locus=$1; shift 122 local pedit_action=$1; shift 123 local mz_flags=$1; shift 124 125 RET=0 126 127 # TOS 125: DSCP 31, ECN 1. Used for testing that the relevant part is 128 # overwritten when zero is selected. 129 $MZ $mz_flags $h1 -c 10 -d 20msec -p 100 \ 130 -a own -b $h2mac -q -t tcp tos=0x7d,sp=54321,dp=12345 131 132 local pkts 133 pkts=$(busywait "$TC_HIT_TIMEOUT" until_counter_is ">= 10" \ 134 tc_rule_handle_stats_get "dev $h2 ingress" 101) 135 check_err $? "Expected to get 10 packets on test probe, but got $pkts." 136 137 pkts=$(tc_rule_handle_stats_get "$pedit_locus" 101) 138 ((pkts >= 10)) 139 check_err $? "Expected to get 10 packets on pedit rule, but got $pkts." 140 141 log_test "$pedit_locus pedit $pedit_action" 142} 143 144do_test_pedit_dsfield() 145{ 146 local pedit_locus=$1; shift 147 local pedit_action=$1; shift 148 local match_prot=$1; shift 149 local match_flower=$1; shift 150 local mz_flags=$1; shift 151 local saddr=$1; shift 152 local daddr=$1; shift 153 154 tc filter add $pedit_locus handle 101 pref 1 \ 155 flower action pedit ex munge $pedit_action 156 tc filter add dev $h2 ingress handle 101 pref 1 prot $match_prot \ 157 flower skip_hw $match_flower action pass 158 159 do_test_pedit_dsfield_common "$pedit_locus" "$pedit_action" "$mz_flags" 160 161 tc filter del dev $h2 ingress pref 1 162 tc filter del $pedit_locus pref 1 163} 164 165do_test_ip_dsfield() 166{ 167 local locus=$1; shift 168 local dsfield 169 170 for dsfield in 0 1 2 3 128 252 253 254 255; do 171 do_test_pedit_dsfield "$locus" \ 172 "ip dsfield set $dsfield" \ 173 ip "ip_tos $dsfield" \ 174 "-A 192.0.2.1 -B 192.0.2.2" 175 done 176} 177 178test_ip_dsfield() 179{ 180 do_test_ip_dsfield "dev $swp1 ingress" 181 do_test_ip_dsfield "dev $swp2 egress" 182} 183 184do_test_ip_dscp() 185{ 186 local locus=$1; shift 187 local dscp 188 189 for dscp in 0 1 2 3 32 61 62 63; do 190 do_test_pedit_dsfield "$locus" \ 191 "ip dsfield set $((dscp << 2)) retain 0xfc" \ 192 ip "ip_tos $(((dscp << 2) | 1))" \ 193 "-A 192.0.2.1 -B 192.0.2.2" 194 done 195} 196 197test_ip_dscp() 198{ 199 do_test_ip_dscp "dev $swp1 ingress" 200 do_test_ip_dscp "dev $swp2 egress" 201} 202 203do_test_ip_ecn() 204{ 205 local locus=$1; shift 206 local ecn 207 208 for ecn in 0 1 2 3; do 209 do_test_pedit_dsfield "$locus" \ 210 "ip dsfield set $ecn retain 0x03" \ 211 ip "ip_tos $((124 | $ecn))" \ 212 "-A 192.0.2.1 -B 192.0.2.2" 213 done 214} 215 216test_ip_ecn() 217{ 218 do_test_ip_ecn "dev $swp1 ingress" 219 do_test_ip_ecn "dev $swp2 egress" 220} 221 222do_test_ip_dscp_ecn() 223{ 224 local locus=$1; shift 225 226 tc filter add $locus handle 101 pref 1 \ 227 flower action pedit ex munge ip dsfield set 124 retain 0xfc \ 228 action pedit ex munge ip dsfield set 1 retain 0x03 229 tc filter add dev $h2 ingress handle 101 pref 1 prot ip \ 230 flower skip_hw ip_tos 125 action pass 231 232 do_test_pedit_dsfield_common "$locus" "set DSCP + set ECN" \ 233 "-A 192.0.2.1 -B 192.0.2.2" 234 235 tc filter del dev $h2 ingress pref 1 236 tc filter del $locus pref 1 237} 238 239test_ip_dscp_ecn() 240{ 241 do_test_ip_dscp_ecn "dev $swp1 ingress" 242 do_test_ip_dscp_ecn "dev $swp2 egress" 243} 244 245do_test_ip6_dsfield() 246{ 247 local locus=$1; shift 248 local dsfield 249 250 for dsfield in 0 1 2 3 128 252 253 254 255; do 251 do_test_pedit_dsfield "$locus" \ 252 "ip6 traffic_class set $dsfield" \ 253 ipv6 "ip_tos $dsfield" \ 254 "-6 -A 2001:db8:1::1 -B 2001:db8:1::2" 255 done 256} 257 258test_ip6_dsfield() 259{ 260 do_test_ip6_dsfield "dev $swp1 ingress" 261 do_test_ip6_dsfield "dev $swp2 egress" 262} 263 264do_test_ip6_dscp() 265{ 266 local locus=$1; shift 267 local dscp 268 269 for dscp in 0 1 2 3 32 61 62 63; do 270 do_test_pedit_dsfield "$locus" \ 271 "ip6 traffic_class set $((dscp << 2)) retain 0xfc" \ 272 ipv6 "ip_tos $(((dscp << 2) | 1))" \ 273 "-6 -A 2001:db8:1::1 -B 2001:db8:1::2" 274 done 275} 276 277test_ip6_dscp() 278{ 279 do_test_ip6_dscp "dev $swp1 ingress" 280 do_test_ip6_dscp "dev $swp2 egress" 281} 282 283do_test_ip6_ecn() 284{ 285 local locus=$1; shift 286 local ecn 287 288 for ecn in 0 1 2 3; do 289 do_test_pedit_dsfield "$locus" \ 290 "ip6 traffic_class set $ecn retain 0x3" \ 291 ipv6 "ip_tos $((124 | $ecn))" \ 292 "-6 -A 2001:db8:1::1 -B 2001:db8:1::2" 293 done 294} 295 296test_ip6_ecn() 297{ 298 do_test_ip6_ecn "dev $swp1 ingress" 299 do_test_ip6_ecn "dev $swp2 egress" 300} 301 302trap cleanup EXIT 303 304setup_prepare 305setup_wait 306 307tests_run 308 309exit $EXIT_STATUS 310