act_mirred: use the backlog for nested calls to mirred ingress
[platform/kernel/linux-starfive.git] / tools / testing / selftests / net / forwarding / tc_actions.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3
4 ALL_TESTS="gact_drop_and_ok_test mirred_egress_redirect_test \
5         mirred_egress_mirror_test matchall_mirred_egress_mirror_test \
6         gact_trap_test mirred_egress_to_ingress_test \
7         mirred_egress_to_ingress_tcp_test"
8 NUM_NETIFS=4
9 source tc_common.sh
10 source lib.sh
11
12 tcflags="skip_hw"
13
14 h1_create()
15 {
16         simple_if_init $h1 192.0.2.1/24
17         tc qdisc add dev $h1 clsact
18 }
19
20 h1_destroy()
21 {
22         tc qdisc del dev $h1 clsact
23         simple_if_fini $h1 192.0.2.1/24
24 }
25
26 h2_create()
27 {
28         simple_if_init $h2 192.0.2.2/24
29         tc qdisc add dev $h2 clsact
30 }
31
32 h2_destroy()
33 {
34         tc qdisc del dev $h2 clsact
35         simple_if_fini $h2 192.0.2.2/24
36 }
37
38 switch_create()
39 {
40         simple_if_init $swp1 192.0.2.2/24
41         tc qdisc add dev $swp1 clsact
42
43         simple_if_init $swp2 192.0.2.1/24
44 }
45
46 switch_destroy()
47 {
48         simple_if_fini $swp2 192.0.2.1/24
49
50         tc qdisc del dev $swp1 clsact
51         simple_if_fini $swp1 192.0.2.2/24
52 }
53
54 mirred_egress_test()
55 {
56         local action=$1
57         local protocol=$2
58         local classifier=$3
59         local classifier_args=$4
60
61         RET=0
62
63         tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
64                 dst_ip 192.0.2.2 action drop
65
66         $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
67                 -t ip -q
68
69         tc_check_packets "dev $h2 ingress" 101 1
70         check_fail $? "Matched without redirect rule inserted"
71
72         tc filter add dev $swp1 ingress protocol $protocol pref 1 handle 101 \
73                 $classifier $tcflags $classifier_args \
74                 action mirred egress $action dev $swp2
75
76         $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
77                 -t ip -q
78
79         tc_check_packets "dev $h2 ingress" 101 1
80         check_err $? "Did not match incoming $action packet"
81
82         tc filter del dev $swp1 ingress protocol $protocol pref 1 handle 101 \
83                 $classifier
84         tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
85
86         log_test "mirred egress $classifier $action ($tcflags)"
87 }
88
89 gact_drop_and_ok_test()
90 {
91         RET=0
92
93         tc filter add dev $swp1 ingress protocol ip pref 2 handle 102 flower \
94                 $tcflags dst_ip 192.0.2.2 action drop
95
96         $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
97                 -t ip -q
98
99         tc_check_packets "dev $swp1 ingress" 102 1
100         check_err $? "Packet was not dropped"
101
102         tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \
103                 $tcflags dst_ip 192.0.2.2 action ok
104
105         $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
106                 -t ip -q
107
108         tc_check_packets "dev $swp1 ingress" 101 1
109         check_err $? "Did not see passed packet"
110
111         tc_check_packets "dev $swp1 ingress" 102 2
112         check_fail $? "Packet was dropped and it should not reach here"
113
114         tc filter del dev $swp1 ingress protocol ip pref 2 handle 102 flower
115         tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
116
117         log_test "gact drop and ok ($tcflags)"
118 }
119
120 gact_trap_test()
121 {
122         RET=0
123
124         if [[ "$tcflags" != "skip_sw" ]]; then
125                 return 0;
126         fi
127
128         tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \
129                 skip_hw dst_ip 192.0.2.2 action drop
130         tc filter add dev $swp1 ingress protocol ip pref 3 handle 103 flower \
131                 $tcflags dst_ip 192.0.2.2 action mirred egress redirect \
132                 dev $swp2
133
134         $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
135                 -t ip -q
136
137         tc_check_packets "dev $swp1 ingress" 101 1
138         check_fail $? "Saw packet without trap rule inserted"
139
140         tc filter add dev $swp1 ingress protocol ip pref 2 handle 102 flower \
141                 $tcflags dst_ip 192.0.2.2 action trap
142
143         $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
144                 -t ip -q
145
146         tc_check_packets "dev $swp1 ingress" 102 1
147         check_err $? "Packet was not trapped"
148
149         tc_check_packets "dev $swp1 ingress" 101 1
150         check_err $? "Did not see trapped packet"
151
152         tc filter del dev $swp1 ingress protocol ip pref 3 handle 103 flower
153         tc filter del dev $swp1 ingress protocol ip pref 2 handle 102 flower
154         tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
155
156         log_test "trap ($tcflags)"
157 }
158
159 mirred_egress_to_ingress_test()
160 {
161         RET=0
162
163         tc filter add dev $h1 protocol ip pref 100 handle 100 egress flower \
164                 ip_proto icmp src_ip 192.0.2.1 dst_ip 192.0.2.2 type 8 action \
165                         ct commit nat src addr 192.0.2.2 pipe \
166                         ct clear pipe \
167                         ct commit nat dst addr 192.0.2.1 pipe \
168                         mirred ingress redirect dev $h1
169
170         tc filter add dev $swp1 protocol ip pref 11 handle 111 ingress flower \
171                 ip_proto icmp src_ip 192.0.2.1 dst_ip 192.0.2.2 type 8 action drop
172         tc filter add dev $swp1 protocol ip pref 12 handle 112 ingress flower \
173                 ip_proto icmp src_ip 192.0.2.1 dst_ip 192.0.2.2 type 0 action pass
174
175         $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
176                 -t icmp "ping,id=42,seq=10" -q
177
178         tc_check_packets "dev $h1 egress" 100 1
179         check_err $? "didn't mirror first packet"
180
181         tc_check_packets "dev $swp1 ingress" 111 1
182         check_fail $? "didn't redirect first packet"
183         tc_check_packets "dev $swp1 ingress" 112 1
184         check_err $? "didn't receive reply to first packet"
185
186         ping 192.0.2.2 -I$h1 -c1 -w1 -q 1>/dev/null 2>&1
187
188         tc_check_packets "dev $h1 egress" 100 2
189         check_err $? "didn't mirror second packet"
190         tc_check_packets "dev $swp1 ingress" 111 1
191         check_fail $? "didn't redirect second packet"
192         tc_check_packets "dev $swp1 ingress" 112 2
193         check_err $? "didn't receive reply to second packet"
194
195         tc filter del dev $h1 egress protocol ip pref 100 handle 100 flower
196         tc filter del dev $swp1 ingress protocol ip pref 11 handle 111 flower
197         tc filter del dev $swp1 ingress protocol ip pref 12 handle 112 flower
198
199         log_test "mirred_egress_to_ingress ($tcflags)"
200 }
201
202 mirred_egress_to_ingress_tcp_test()
203 {
204         local tmpfile=$(mktemp) tmpfile1=$(mktemp)
205
206         RET=0
207         dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$tmpfile
208         tc filter add dev $h1 protocol ip pref 100 handle 100 egress flower \
209                 $tcflags ip_proto tcp src_ip 192.0.2.1 dst_ip 192.0.2.2 \
210                         action ct commit nat src addr 192.0.2.2 pipe \
211                         action ct clear pipe \
212                         action ct commit nat dst addr 192.0.2.1 pipe \
213                         action ct clear pipe \
214                         action skbedit ptype host pipe \
215                         action mirred ingress redirect dev $h1
216         tc filter add dev $h1 protocol ip pref 101 handle 101 egress flower \
217                 $tcflags ip_proto icmp \
218                         action mirred ingress redirect dev $h1
219         tc filter add dev $h1 protocol ip pref 102 handle 102 ingress flower \
220                 ip_proto icmp \
221                         action drop
222
223         ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $tmpfile1  &
224         local rpid=$!
225         ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$tmpfile
226         wait -n $rpid
227         cmp -s $tmpfile $tmpfile1
228         check_err $? "server output check failed"
229
230         $MZ $h1 -c 10 -p 64 -a $h1mac -b $h1mac -A 192.0.2.1 -B 192.0.2.1 \
231                 -t icmp "ping,id=42,seq=5" -q
232         tc_check_packets "dev $h1 egress" 101 10
233         check_err $? "didn't mirred redirect ICMP"
234         tc_check_packets "dev $h1 ingress" 102 10
235         check_err $? "didn't drop mirred ICMP"
236         local overlimits=$(tc_rule_stats_get ${h1} 101 egress .overlimits)
237         test ${overlimits} = 10
238         check_err $? "wrong overlimits, expected 10 got ${overlimits}"
239
240         tc filter del dev $h1 egress protocol ip pref 100 handle 100 flower
241         tc filter del dev $h1 egress protocol ip pref 101 handle 101 flower
242         tc filter del dev $h1 ingress protocol ip pref 102 handle 102 flower
243
244         rm -f $tmpfile $tmpfile1
245         log_test "mirred_egress_to_ingress_tcp ($tcflags)"
246 }
247
248 setup_prepare()
249 {
250         h1=${NETIFS[p1]}
251         swp1=${NETIFS[p2]}
252
253         swp2=${NETIFS[p3]}
254         h2=${NETIFS[p4]}
255
256         h1mac=$(mac_get $h1)
257         h2mac=$(mac_get $h2)
258
259         swp1origmac=$(mac_get $swp1)
260         swp2origmac=$(mac_get $swp2)
261         ip link set $swp1 address $h2mac
262         ip link set $swp2 address $h1mac
263
264         vrf_prepare
265
266         h1_create
267         h2_create
268         switch_create
269 }
270
271 cleanup()
272 {
273         pre_cleanup
274
275         switch_destroy
276         h2_destroy
277         h1_destroy
278
279         vrf_cleanup
280
281         ip link set $swp2 address $swp2origmac
282         ip link set $swp1 address $swp1origmac
283 }
284
285 mirred_egress_redirect_test()
286 {
287         mirred_egress_test "redirect" "ip" "flower" "dst_ip 192.0.2.2"
288 }
289
290 mirred_egress_mirror_test()
291 {
292         mirred_egress_test "mirror" "ip" "flower" "dst_ip 192.0.2.2"
293 }
294
295 matchall_mirred_egress_mirror_test()
296 {
297         mirred_egress_test "mirror" "all" "matchall" ""
298 }
299
300 trap cleanup EXIT
301
302 setup_prepare
303 setup_wait
304
305 tests_run
306
307 tc_offload_check
308 if [[ $? -ne 0 ]]; then
309         log_info "Could not test offloaded functionality"
310 else
311         tcflags="skip_sw"
312         tests_run
313 fi
314
315 exit $EXIT_STATUS