Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | #!/bin/bash # SPDX-License-Identifier: GPL-2.0 # Test for DSCP prioritization in the router. # # With ip_forward_update_priority disabled, the packets are expected to keep # their DSCP (which in this test uses only values 0..7) intact as they are # forwarded by the switch. That is verified at $h2. ICMP responses are formed # with the same DSCP as the requests, and likewise pass through the switch # intact, which is verified at $h1. # # With ip_forward_update_priority enabled, router reprioritizes the packets # according to the table in reprioritize(). Thus, say, DSCP 7 maps to priority # 4, which on egress maps back to DSCP 4. The response packet then gets # reprioritized to 6, getting DSCP 6 on egress. # # +----------------------+ +----------------------+ # | H1 | | H2 | # | + $h1 | | $h2 + | # | | 192.0.2.1/28 | | 192.0.2.18/28 | | # +----|-----------------+ +----------------|-----+ # | | # +----|----------------------------------------------------------------|-----+ # | SW | | | # | + $swp1 $swp2 + | # | 192.0.2.2/28 192.0.2.17/28 | # | APP=0,5,0 .. 7,5,7 APP=0,5,0 .. 7,5,7 | # +---------------------------------------------------------------------------+ ALL_TESTS=" ping_ipv4 test_update test_no_update test_pedit_norewrite test_dscp_leftover " lib_dir=$(dirname $0)/../../../net/forwarding NUM_NETIFS=4 source $lib_dir/lib.sh reprioritize() { local in=$1; shift # This is based on rt_tos2priority in include/net/route.h. Assuming 1:1 # mapping between priorities and TOS, it yields a new priority for a # packet with ingress priority of $in. local -a reprio=(0 0 2 2 6 6 4 4) echo ${reprio[$in]} } zero() { echo 0 } three() { echo 3 } h1_create() { simple_if_init $h1 192.0.2.1/28 tc qdisc add dev $h1 clsact dscp_capture_install $h1 0 ip route add vrf v$h1 192.0.2.16/28 via 192.0.2.2 } h1_destroy() { ip route del vrf v$h1 192.0.2.16/28 via 192.0.2.2 dscp_capture_uninstall $h1 0 tc qdisc del dev $h1 clsact simple_if_fini $h1 192.0.2.1/28 } h2_create() { simple_if_init $h2 192.0.2.18/28 tc qdisc add dev $h2 clsact dscp_capture_install $h2 0 ip route add vrf v$h2 192.0.2.0/28 via 192.0.2.17 } h2_destroy() { ip route del vrf v$h2 192.0.2.0/28 via 192.0.2.17 dscp_capture_uninstall $h2 0 tc qdisc del dev $h2 clsact simple_if_fini $h2 192.0.2.18/28 } dscp_map() { local base=$1; shift local prio for prio in {0..7}; do echo app=$prio,5,$((base + prio)) done } switch_create() { simple_if_init $swp1 192.0.2.2/28 __simple_if_init $swp2 v$swp1 192.0.2.17/28 tc qdisc add dev $swp1 clsact tc qdisc add dev $swp2 clsact lldptool -T -i $swp1 -V APP $(dscp_map 0) >/dev/null lldptool -T -i $swp2 -V APP $(dscp_map 0) >/dev/null lldpad_app_wait_set $swp1 lldpad_app_wait_set $swp2 } switch_destroy() { lldptool -T -i $swp2 -V APP -d $(dscp_map 0) >/dev/null lldptool -T -i $swp1 -V APP -d $(dscp_map 0) >/dev/null lldpad_app_wait_del tc qdisc del dev $swp2 clsact tc qdisc del dev $swp1 clsact __simple_if_fini $swp2 192.0.2.17/28 simple_if_fini $swp1 192.0.2.2/28 } setup_prepare() { h1=${NETIFS[p1]} swp1=${NETIFS[p2]} swp2=${NETIFS[p3]} h2=${NETIFS[p4]} vrf_prepare sysctl_set net.ipv4.ip_forward_update_priority 1 h1_create h2_create switch_create } cleanup() { pre_cleanup switch_destroy h2_destroy h1_destroy sysctl_restore net.ipv4.ip_forward_update_priority vrf_cleanup } ping_ipv4() { ping_test $h1 192.0.2.18 } dscp_ping_test() { local vrf_name=$1; shift local sip=$1; shift local dip=$1; shift local prio=$1; shift local reprio=$1; shift local dev1=$1; shift local dev2=$1; shift local i local prio2=$($reprio $prio) # ICMP Request egress prio local prio3=$($reprio $prio2) # ICMP Response egress prio local dscp=$((prio << 2)) # ICMP Request ingress DSCP local dscp2=$((prio2 << 2)) # ICMP Request egress DSCP local dscp3=$((prio3 << 2)) # ICMP Response egress DSCP RET=0 eval "local -A dev1_t0s=($(dscp_fetch_stats $dev1 0))" eval "local -A dev2_t0s=($(dscp_fetch_stats $dev2 0))" local ping_timeout=$((PING_TIMEOUT * 5)) ip vrf exec $vrf_name \ ${PING} -Q $dscp ${sip:+-I $sip} $dip \ -c 10 -i 0.5 -w $ping_timeout &> /dev/null eval "local -A dev1_t1s=($(dscp_fetch_stats $dev1 0))" eval "local -A dev2_t1s=($(dscp_fetch_stats $dev2 0))" for i in {0..7}; do local dscpi=$((i << 2)) local expect2=0 local expect3=0 if ((i == prio2)); then expect2=10 fi if ((i == prio3)); then expect3=10 fi local delta=$((dev2_t1s[$i] - dev2_t0s[$i])) ((expect2 == delta)) check_err $? "DSCP $dscpi@$dev2: Expected to capture $expect2 packets, got $delta." delta=$((dev1_t1s[$i] - dev1_t0s[$i])) ((expect3 == delta)) check_err $? "DSCP $dscpi@$dev1: Expected to capture $expect3 packets, got $delta." done log_test "DSCP rewrite: $dscp-(prio $prio2)-$dscp2-(prio $prio3)-$dscp3" } __test_update() { local update=$1; shift local reprio=$1; shift local prio sysctl_restore net.ipv4.ip_forward_update_priority sysctl_set net.ipv4.ip_forward_update_priority $update for prio in {0..7}; do dscp_ping_test v$h1 192.0.2.1 192.0.2.18 $prio $reprio $h1 $h2 done } test_update() { echo "Test net.ipv4.ip_forward_update_priority=1" __test_update 1 reprioritize } test_no_update() { echo "Test net.ipv4.ip_forward_update_priority=0" __test_update 0 echo } # Test that when DSCP is updated in pedit, the DSCP rewrite is turned off. test_pedit_norewrite() { echo "Test no DSCP rewrite after DSCP is updated by pedit" tc filter add dev $swp1 ingress handle 101 pref 1 prot ip flower \ action pedit ex munge ip dsfield set $((3 << 2)) retain 0xfc \ action skbedit priority 3 __test_update 0 three tc filter del dev $swp1 ingress pref 1 } # Test that when the last APP rule is removed, the prio->DSCP map is properly # set to zeroes, and that the last APP rule does not stay active in the ASIC. test_dscp_leftover() { echo "Test that last removed DSCP rule is deconfigured correctly" lldptool -T -i $swp2 -V APP -d $(dscp_map 0) >/dev/null lldpad_app_wait_del __test_update 0 zero lldptool -T -i $swp2 -V APP $(dscp_map 0) >/dev/null lldpad_app_wait_set $swp2 } trap cleanup EXIT setup_prepare setup_wait tests_run exit $EXIT_STATUS |