1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4ALL_TESTS="gact_drop_and_ok_test mirred_egress_redirect_test \
5	mirred_egress_mirror_test gact_trap_test"
6NUM_NETIFS=4
7source tc_common.sh
8source lib.sh
9
10tcflags="skip_hw"
11
12h1_create()
13{
14	simple_if_init $h1 192.0.2.1/24
15}
16
17h1_destroy()
18{
19	simple_if_fini $h1 192.0.2.1/24
20}
21
22h2_create()
23{
24	simple_if_init $h2 192.0.2.2/24
25	tc qdisc add dev $h2 clsact
26}
27
28h2_destroy()
29{
30	tc qdisc del dev $h2 clsact
31	simple_if_fini $h2 192.0.2.2/24
32}
33
34switch_create()
35{
36	simple_if_init $swp1 192.0.2.2/24
37	tc qdisc add dev $swp1 clsact
38
39	simple_if_init $swp2 192.0.2.1/24
40}
41
42switch_destroy()
43{
44	simple_if_fini $swp2 192.0.2.1/24
45
46	tc qdisc del dev $swp1 clsact
47	simple_if_fini $swp1 192.0.2.2/24
48}
49
50mirred_egress_test()
51{
52	local action=$1
53
54	RET=0
55
56	tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
57		$tcflags dst_ip 192.0.2.2 action drop
58
59	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
60		-t ip -q
61
62	tc_check_packets "dev $h2 ingress" 101 1
63	check_fail $? "Matched without redirect rule inserted"
64
65	tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \
66		$tcflags dst_ip 192.0.2.2 action mirred egress $action \
67		dev $swp2
68
69	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
70		-t ip -q
71
72	tc_check_packets "dev $h2 ingress" 101 1
73	check_err $? "Did not match incoming $action packet"
74
75	tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
76	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
77
78	log_test "mirred egress $action ($tcflags)"
79}
80
81gact_drop_and_ok_test()
82{
83	RET=0
84
85	tc filter add dev $swp1 ingress protocol ip pref 2 handle 102 flower \
86		$tcflags dst_ip 192.0.2.2 action drop
87
88	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
89		-t ip -q
90
91	tc_check_packets "dev $swp1 ingress" 102 1
92	check_err $? "Packet was not dropped"
93
94	tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \
95		$tcflags dst_ip 192.0.2.2 action ok
96
97	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
98		-t ip -q
99
100	tc_check_packets "dev $swp1 ingress" 101 1
101	check_err $? "Did not see passed packet"
102
103	tc_check_packets "dev $swp1 ingress" 102 2
104	check_fail $? "Packet was dropped and it should not reach here"
105
106	tc filter del dev $swp1 ingress protocol ip pref 2 handle 102 flower
107	tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
108
109	log_test "gact drop and ok ($tcflags)"
110}
111
112gact_trap_test()
113{
114	RET=0
115
116	if [[ "$tcflags" != "skip_sw" ]]; then
117		return 0;
118	fi
119
120	tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \
121		skip_hw dst_ip 192.0.2.2 action drop
122	tc filter add dev $swp1 ingress protocol ip pref 3 handle 103 flower \
123		$tcflags dst_ip 192.0.2.2 action mirred egress redirect \
124		dev $swp2
125
126	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
127		-t ip -q
128
129	tc_check_packets "dev $swp1 ingress" 101 1
130	check_fail $? "Saw packet without trap rule inserted"
131
132	tc filter add dev $swp1 ingress protocol ip pref 2 handle 102 flower \
133		$tcflags dst_ip 192.0.2.2 action trap
134
135	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
136		-t ip -q
137
138	tc_check_packets "dev $swp1 ingress" 102 1
139	check_err $? "Packet was not trapped"
140
141	tc_check_packets "dev $swp1 ingress" 101 1
142	check_err $? "Did not see trapped packet"
143
144	tc filter del dev $swp1 ingress protocol ip pref 3 handle 103 flower
145	tc filter del dev $swp1 ingress protocol ip pref 2 handle 102 flower
146	tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
147
148	log_test "trap ($tcflags)"
149}
150
151setup_prepare()
152{
153	h1=${NETIFS[p1]}
154	swp1=${NETIFS[p2]}
155
156	swp2=${NETIFS[p3]}
157	h2=${NETIFS[p4]}
158
159	h1mac=$(mac_get $h1)
160	h2mac=$(mac_get $h2)
161
162	swp1origmac=$(mac_get $swp1)
163	swp2origmac=$(mac_get $swp2)
164	ip link set $swp1 address $h2mac
165	ip link set $swp2 address $h1mac
166
167	vrf_prepare
168
169	h1_create
170	h2_create
171	switch_create
172}
173
174cleanup()
175{
176	pre_cleanup
177
178	switch_destroy
179	h2_destroy
180	h1_destroy
181
182	vrf_cleanup
183
184	ip link set $swp2 address $swp2origmac
185	ip link set $swp1 address $swp1origmac
186}
187
188mirred_egress_redirect_test()
189{
190	mirred_egress_test "redirect"
191}
192
193mirred_egress_mirror_test()
194{
195	mirred_egress_test "mirror"
196}
197
198trap cleanup EXIT
199
200setup_prepare
201setup_wait
202
203tests_run
204
205tc_offload_check
206if [[ $? -ne 0 ]]; then
207	log_info "Could not test offloaded functionality"
208else
209	tcflags="skip_sw"
210	tests_run
211fi
212
213exit $EXIT_STATUS
214