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