1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4ALL_TESTS="unreachable_chain_test gact_goto_chain_test create_destroy_chain \
5	   template_filter_fits"
6NUM_NETIFS=2
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
34unreachable_chain_test()
35{
36	RET=0
37
38	tc filter add dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \
39		flower $tcflags dst_mac $h2mac action drop
40
41	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
42		-t ip -q
43
44	tc_check_packets "dev $h2 ingress" 1101 1
45	check_fail $? "matched on filter in unreachable chain"
46
47	tc filter del dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \
48		flower
49
50	log_test "unreachable chain ($tcflags)"
51}
52
53gact_goto_chain_test()
54{
55	RET=0
56
57	tc filter add dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \
58		flower $tcflags dst_mac $h2mac action drop
59	tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
60		$tcflags dst_mac $h2mac action drop
61	tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
62		$tcflags dst_mac $h2mac action goto chain 1
63
64	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
65		-t ip -q
66
67	tc_check_packets "dev $h2 ingress" 102 1
68	check_fail $? "Matched on a wrong filter"
69
70	tc_check_packets "dev $h2 ingress" 101 1
71	check_err $? "Did not match on correct filter with goto chain action"
72
73	tc_check_packets "dev $h2 ingress" 1101 1
74	check_err $? "Did not match on correct filter in chain 1"
75
76	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
77	tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
78	tc filter del dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \
79		flower
80
81	log_test "gact goto chain ($tcflags)"
82}
83
84create_destroy_chain()
85{
86	RET=0
87
88	tc chain add dev $h2 ingress
89	check_err $? "Failed to create default chain"
90
91	output="$(tc -j chain get dev $h2 ingress)"
92	check_err $? "Failed to get default chain"
93
94	echo $output | jq -e ".[] | select(.chain == 0)" &> /dev/null
95	check_err $? "Unexpected output for default chain"
96
97	tc chain add dev $h2 ingress chain 1
98	check_err $? "Failed to create chain 1"
99
100	output="$(tc -j chain get dev $h2 ingress chain 1)"
101	check_err $? "Failed to get chain 1"
102
103	echo $output | jq -e ".[] | select(.chain == 1)" &> /dev/null
104	check_err $? "Unexpected output for chain 1"
105
106	output="$(tc -j chain show dev $h2 ingress)"
107	check_err $? "Failed to dump chains"
108
109	echo $output | jq -e ".[] | select(.chain == 0)" &> /dev/null
110	check_err $? "Can't find default chain in dump"
111
112	echo $output | jq -e ".[] | select(.chain == 1)" &> /dev/null
113	check_err $? "Can't find chain 1 in dump"
114
115	tc chain del dev $h2 ingress
116	check_err $? "Failed to destroy default chain"
117
118	tc chain del dev $h2 ingress chain 1
119	check_err $? "Failed to destroy chain 1"
120
121	log_test "create destroy chain"
122}
123
124template_filter_fits()
125{
126	RET=0
127
128	tc chain add dev $h2 ingress protocol ip \
129		flower dst_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF &> /dev/null
130	tc chain add dev $h2 ingress chain 1 protocol ip \
131		flower src_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF &> /dev/null
132
133	tc filter add dev $h2 ingress protocol ip pref 1 handle 1101 \
134		flower dst_mac $h2mac action drop
135	check_err $? "Failed to insert filter which fits template"
136
137	tc filter add dev $h2 ingress protocol ip pref 1 handle 1102 \
138		flower src_mac $h2mac action drop &> /dev/null
139	check_fail $? "Incorrectly succeeded to insert filter which does not template"
140
141	tc filter add dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \
142		flower src_mac $h2mac action drop
143	check_err $? "Failed to insert filter which fits template"
144
145	tc filter add dev $h2 ingress chain 1 protocol ip pref 1 handle 1102 \
146		flower dst_mac $h2mac action drop &> /dev/null
147	check_fail $? "Incorrectly succeeded to insert filter which does not template"
148
149	tc filter del dev $h2 ingress chain 1 protocol ip pref 1 handle 1102 \
150		flower &> /dev/null
151	tc filter del dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \
152		flower &> /dev/null
153
154	tc filter del dev $h2 ingress protocol ip pref 1 handle 1102 \
155		flower &> /dev/null
156	tc filter del dev $h2 ingress protocol ip pref 1 handle 1101 \
157		flower &> /dev/null
158
159	tc chain del dev $h2 ingress chain 1
160	tc chain del dev $h2 ingress
161
162	log_test "template filter fits"
163}
164
165setup_prepare()
166{
167	h1=${NETIFS[p1]}
168	h2=${NETIFS[p2]}
169	h1mac=$(mac_get $h1)
170	h2mac=$(mac_get $h2)
171
172	vrf_prepare
173
174	h1_create
175	h2_create
176}
177
178cleanup()
179{
180	pre_cleanup
181
182	h2_destroy
183	h1_destroy
184
185	vrf_cleanup
186}
187
188check_tc_chain_support
189
190trap cleanup EXIT
191
192setup_prepare
193setup_wait
194
195tests_run
196
197tc_offload_check
198if [[ $? -ne 0 ]]; then
199	log_info "Could not test offloaded functionality"
200else
201	tcflags="skip_sw"
202	tests_run
203fi
204
205exit $EXIT_STATUS
206