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, but got $pkts." 136 log_test "$pedit_locus pedit $pedit_action" 137} 138 139do_test_pedit_dsfield() 140{ 141 local pedit_locus=$1; shift 142 local pedit_action=$1; shift 143 local match_prot=$1; shift 144 local match_flower=$1; shift 145 local mz_flags=$1; shift 146 local saddr=$1; shift 147 local daddr=$1; shift 148 149 tc filter add $pedit_locus handle 101 pref 1 \ 150 flower action pedit ex munge $pedit_action 151 tc filter add dev $h2 ingress handle 101 pref 1 prot $match_prot \ 152 flower skip_hw $match_flower action pass 153 154 do_test_pedit_dsfield_common "$pedit_locus" "$pedit_action" "$mz_flags" 155 156 tc filter del dev $h2 ingress pref 1 157 tc filter del $pedit_locus pref 1 158} 159 160do_test_ip_dsfield() 161{ 162 local locus=$1; shift 163 local dsfield 164 165 for dsfield in 0 1 2 3 128 252 253 254 255; do 166 do_test_pedit_dsfield "$locus" \ 167 "ip dsfield set $dsfield" \ 168 ip "ip_tos $dsfield" \ 169 "-A 192.0.2.1 -B 192.0.2.2" 170 done 171} 172 173test_ip_dsfield() 174{ 175 do_test_ip_dsfield "dev $swp1 ingress" 176 do_test_ip_dsfield "dev $swp2 egress" 177} 178 179do_test_ip_dscp() 180{ 181 local locus=$1; shift 182 local dscp 183 184 for dscp in 0 1 2 3 32 61 62 63; do 185 do_test_pedit_dsfield "$locus" \ 186 "ip dsfield set $((dscp << 2)) retain 0xfc" \ 187 ip "ip_tos $(((dscp << 2) | 1))" \ 188 "-A 192.0.2.1 -B 192.0.2.2" 189 done 190} 191 192test_ip_dscp() 193{ 194 do_test_ip_dscp "dev $swp1 ingress" 195 do_test_ip_dscp "dev $swp2 egress" 196} 197 198do_test_ip_ecn() 199{ 200 local locus=$1; shift 201 local ecn 202 203 for ecn in 0 1 2 3; do 204 do_test_pedit_dsfield "$locus" \ 205 "ip dsfield set $ecn retain 0x03" \ 206 ip "ip_tos $((124 | $ecn))" \ 207 "-A 192.0.2.1 -B 192.0.2.2" 208 done 209} 210 211test_ip_ecn() 212{ 213 do_test_ip_ecn "dev $swp1 ingress" 214 do_test_ip_ecn "dev $swp2 egress" 215} 216 217do_test_ip_dscp_ecn() 218{ 219 local locus=$1; shift 220 221 tc filter add $locus handle 101 pref 1 \ 222 flower action pedit ex munge ip dsfield set 124 retain 0xfc \ 223 action pedit ex munge ip dsfield set 1 retain 0x03 224 tc filter add dev $h2 ingress handle 101 pref 1 prot ip \ 225 flower skip_hw ip_tos 125 action pass 226 227 do_test_pedit_dsfield_common "$locus" "set DSCP + set ECN" \ 228 "-A 192.0.2.1 -B 192.0.2.2" 229 230 tc filter del dev $h2 ingress pref 1 231 tc filter del $locus pref 1 232} 233 234test_ip_dscp_ecn() 235{ 236 do_test_ip_dscp_ecn "dev $swp1 ingress" 237 do_test_ip_dscp_ecn "dev $swp2 egress" 238} 239 240do_test_ip6_dsfield() 241{ 242 local locus=$1; shift 243 local dsfield 244 245 for dsfield in 0 1 2 3 128 252 253 254 255; do 246 do_test_pedit_dsfield "$locus" \ 247 "ip6 traffic_class set $dsfield" \ 248 ipv6 "ip_tos $dsfield" \ 249 "-6 -A 2001:db8:1::1 -B 2001:db8:1::2" 250 done 251} 252 253test_ip6_dsfield() 254{ 255 do_test_ip6_dsfield "dev $swp1 ingress" 256 do_test_ip6_dsfield "dev $swp2 egress" 257} 258 259do_test_ip6_dscp() 260{ 261 local locus=$1; shift 262 local dscp 263 264 for dscp in 0 1 2 3 32 61 62 63; do 265 do_test_pedit_dsfield "$locus" \ 266 "ip6 traffic_class set $((dscp << 2)) retain 0xfc" \ 267 ipv6 "ip_tos $(((dscp << 2) | 1))" \ 268 "-6 -A 2001:db8:1::1 -B 2001:db8:1::2" 269 done 270} 271 272test_ip6_dscp() 273{ 274 do_test_ip6_dscp "dev $swp1 ingress" 275 do_test_ip6_dscp "dev $swp2 egress" 276} 277 278do_test_ip6_ecn() 279{ 280 local locus=$1; shift 281 local ecn 282 283 for ecn in 0 1 2 3; do 284 do_test_pedit_dsfield "$locus" \ 285 "ip6 traffic_class set $ecn retain 0x3" \ 286 ipv6 "ip_tos $((124 | $ecn))" \ 287 "-6 -A 2001:db8:1::1 -B 2001:db8:1::2" 288 done 289} 290 291test_ip6_ecn() 292{ 293 do_test_ip6_ecn "dev $swp1 ingress" 294 do_test_ip6_ecn "dev $swp2 egress" 295} 296 297trap cleanup EXIT 298 299setup_prepare 300setup_wait 301 302tests_run 303 304exit $EXIT_STATUS 305