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