1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# +-----------------------+                             +----------------------+
5# | H1 (vrf)              |                             | H2 (vrf)             |
6# |    + $h1              |                             |              $h2 +   |
7# |    | 192.0.2.1/28     |                             |     192.0.2.2/28 |   |
8# |    | 2001:db8:1::1/64 |                             | 2001:db8:1::2/64 |   |
9# +----|------------------+                             +------------------|---+
10#      |                                                                   |
11# +----|-------------------------------------------------------------------|---+
12# | SW |                                                                   |   |
13# |  +-|-------------------------------------------------------------------|-+ |
14# |  | + $swp1                       BR                              $swp2 + | |
15# |  +-----------------------------------------------------------------------+ |
16# +----------------------------------------------------------------------------+
17
18ALL_TESTS="
19	test_port_range_ipv4_udp
20	test_port_range_ipv4_tcp
21	test_port_range_ipv6_udp
22	test_port_range_ipv6_tcp
23"
24
25NUM_NETIFS=4
26source lib.sh
27source tc_common.sh
28
29h1_create()
30{
31	simple_if_init $h1 192.0.2.1/28 2001:db8:1::1/64
32}
33
34h1_destroy()
35{
36	simple_if_fini $h1 192.0.2.1/28 2001:db8:1::1/64
37}
38
39h2_create()
40{
41	simple_if_init $h2 192.0.2.2/28 2001:db8:1::2/64
42}
43
44h2_destroy()
45{
46	simple_if_fini $h2 192.0.2.2/28 2001:db8:1::2/64
47}
48
49switch_create()
50{
51	ip link add name br1 type bridge
52	ip link set dev $swp1 master br1
53	ip link set dev $swp1 up
54	ip link set dev $swp2 master br1
55	ip link set dev $swp2 up
56	ip link set dev br1 up
57
58	tc qdisc add dev $swp1 clsact
59	tc qdisc add dev $swp2 clsact
60}
61
62switch_destroy()
63{
64	tc qdisc del dev $swp2 clsact
65	tc qdisc del dev $swp1 clsact
66
67	ip link set dev br1 down
68	ip link set dev $swp2 down
69	ip link set dev $swp2 nomaster
70	ip link set dev $swp1 down
71	ip link set dev $swp1 nomaster
72	ip link del dev br1
73}
74
75__test_port_range()
76{
77	local proto=$1; shift
78	local ip_proto=$1; shift
79	local sip=$1; shift
80	local dip=$1; shift
81	local mode=$1; shift
82	local name=$1; shift
83	local dmac=$(mac_get $h2)
84	local smac=$(mac_get $h1)
85	local sport_min=100
86	local sport_max=200
87	local sport_mid=$((sport_min + (sport_max - sport_min) / 2))
88	local dport_min=300
89	local dport_max=400
90	local dport_mid=$((dport_min + (dport_max - dport_min) / 2))
91
92	RET=0
93
94	tc filter add dev $swp1 ingress protocol $proto handle 101 pref 1 \
95		flower src_ip $sip dst_ip $dip ip_proto $ip_proto \
96		src_port $sport_min-$sport_max \
97		dst_port $dport_min-$dport_max \
98		action pass
99	tc filter add dev $swp2 egress protocol $proto handle 101 pref 1 \
100		flower src_ip $sip dst_ip $dip ip_proto $ip_proto \
101		src_port $sport_min-$sport_max \
102		dst_port $dport_min-$dport_max \
103		action drop
104
105	$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
106		-t $ip_proto "sp=$sport_min,dp=$dport_min"
107	tc_check_packets "dev $swp1 ingress" 101 1
108	check_err $? "Ingress filter not hit with minimum ports"
109	tc_check_packets "dev $swp2 egress" 101 1
110	check_err $? "Egress filter not hit with minimum ports"
111
112	$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
113		-t $ip_proto "sp=$sport_mid,dp=$dport_mid"
114	tc_check_packets "dev $swp1 ingress" 101 2
115	check_err $? "Ingress filter not hit with middle ports"
116	tc_check_packets "dev $swp2 egress" 101 2
117	check_err $? "Egress filter not hit with middle ports"
118
119	$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
120		-t $ip_proto "sp=$sport_max,dp=$dport_max"
121	tc_check_packets "dev $swp1 ingress" 101 3
122	check_err $? "Ingress filter not hit with maximum ports"
123	tc_check_packets "dev $swp2 egress" 101 3
124	check_err $? "Egress filter not hit with maximum ports"
125
126	# Send traffic when both ports are out of range and when only one port
127	# is out of range.
128	$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
129		-t $ip_proto "sp=$((sport_min - 1)),dp=$dport_min"
130	$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
131		-t $ip_proto "sp=$((sport_max + 1)),dp=$dport_min"
132	$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
133		-t $ip_proto "sp=$sport_min,dp=$((dport_min - 1))"
134	$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
135		-t $ip_proto "sp=$sport_min,dp=$((dport_max + 1))"
136	$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
137		-t $ip_proto "sp=$((sport_max + 1)),dp=$((dport_max + 1))"
138	tc_check_packets "dev $swp1 ingress" 101 3
139	check_err $? "Ingress filter was hit when should not"
140	tc_check_packets "dev $swp2 egress" 101 3
141	check_err $? "Egress filter was hit when should not"
142
143	tc filter del dev $swp2 egress protocol $proto pref 1 handle 101 flower
144	tc filter del dev $swp1 ingress protocol $proto pref 1 handle 101 flower
145
146	log_test "Port range matching - $name"
147}
148
149test_port_range_ipv4_udp()
150{
151	local proto=ipv4
152	local ip_proto=udp
153	local sip=192.0.2.1
154	local dip=192.0.2.2
155	local mode="-4"
156	local name="IPv4 UDP"
157
158	__test_port_range $proto $ip_proto $sip $dip $mode "$name"
159}
160
161test_port_range_ipv4_tcp()
162{
163	local proto=ipv4
164	local ip_proto=tcp
165	local sip=192.0.2.1
166	local dip=192.0.2.2
167	local mode="-4"
168	local name="IPv4 TCP"
169
170	__test_port_range $proto $ip_proto $sip $dip $mode "$name"
171}
172
173test_port_range_ipv6_udp()
174{
175	local proto=ipv6
176	local ip_proto=udp
177	local sip=2001:db8:1::1
178	local dip=2001:db8:1::2
179	local mode="-6"
180	local name="IPv6 UDP"
181
182	__test_port_range $proto $ip_proto $sip $dip $mode "$name"
183}
184
185test_port_range_ipv6_tcp()
186{
187	local proto=ipv6
188	local ip_proto=tcp
189	local sip=2001:db8:1::1
190	local dip=2001:db8:1::2
191	local mode="-6"
192	local name="IPv6 TCP"
193
194	__test_port_range $proto $ip_proto $sip $dip $mode "$name"
195}
196
197setup_prepare()
198{
199	h1=${NETIFS[p1]}
200	swp1=${NETIFS[p2]}
201
202	swp2=${NETIFS[p3]}
203	h2=${NETIFS[p4]}
204
205	vrf_prepare
206	h1_create
207	h2_create
208	switch_create
209}
210
211cleanup()
212{
213	pre_cleanup
214
215	switch_destroy
216	h2_destroy
217	h1_destroy
218	vrf_cleanup
219}
220
221trap cleanup EXIT
222
223setup_prepare
224setup_wait
225
226tests_run
227
228exit $EXIT_STATUS
229