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