xref: /linux/tools/testing/selftests/net/forwarding/router.sh (revision 6439a0e64c355d2e375bd094f365d56ce81faba3)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# +--------------------+                     +----------------------+
5# | H1                 |                     |                   H2 |
6# |                    |                     |                      |
7# |              $h1 + |                     | + $h2                |
8# |     192.0.2.2/24 | |                     | | 198.51.100.2/24    |
9# | 2001:db8:1::2/64 | |                     | | 2001:db8:2::2/64   |
10# |                  | |                     | |                    |
11# +------------------|-+                     +-|--------------------+
12#                    |                         |
13# +------------------|-------------------------|--------------------+
14# | SW               |                         |                    |
15# |                  |                         |                    |
16# |             $rp1 +                         + $rp2               |
17# |     192.0.2.1/24                             198.51.100.1/24    |
18# | 2001:db8:1::1/64                             2001:db8:2::1/64   |
19# |                                                                 |
20# +-----------------------------------------------------------------+
21#
22#shellcheck disable=SC2034 # SC doesn't see our uses of global variables
23
24ALL_TESTS="
25	ping_ipv4
26	ping_ipv6
27	sip_in_class_e
28	mc_mac_mismatch
29	ipv4_sip_equal_dip
30	ipv6_sip_equal_dip
31	ipv4_dip_link_local
32	ipv4_sip_link_local
33"
34
35NUM_NETIFS=4
36source lib.sh
37source tc_common.sh
38
39require_command $MCD
40require_command $MC_CLI
41table_name=selftests
42
43h1_create()
44{
45	vrf_create "vrf-h1"
46	ip link set dev $h1 master vrf-h1
47
48	ip link set dev vrf-h1 up
49	ip link set dev $h1 up
50
51	ip address add 192.0.2.2/24 dev $h1
52	ip address add 2001:db8:1::2/64 dev $h1
53
54	ip route add 198.51.100.0/24 vrf vrf-h1 nexthop via 192.0.2.1
55	ip route add 2001:db8:2::/64 vrf vrf-h1 nexthop via 2001:db8:1::1
56}
57
58h1_destroy()
59{
60	ip route del 2001:db8:2::/64 vrf vrf-h1
61	ip route del 198.51.100.0/24 vrf vrf-h1
62
63	ip address del 2001:db8:1::2/64 dev $h1
64	ip address del 192.0.2.2/24 dev $h1
65
66	ip link set dev $h1 down
67	vrf_destroy "vrf-h1"
68}
69
70h2_create()
71{
72	vrf_create "vrf-h2"
73	ip link set dev $h2 master vrf-h2
74
75	ip link set dev vrf-h2 up
76	ip link set dev $h2 up
77
78	ip address add 198.51.100.2/24 dev $h2
79	ip address add 2001:db8:2::2/64 dev $h2
80
81	ip route add 192.0.2.0/24 vrf vrf-h2 nexthop via 198.51.100.1
82	ip route add 2001:db8:1::/64 vrf vrf-h2 nexthop via 2001:db8:2::1
83}
84
85h2_destroy()
86{
87	ip route del 2001:db8:1::/64 vrf vrf-h2
88	ip route del 192.0.2.0/24 vrf vrf-h2
89
90	ip address del 2001:db8:2::2/64 dev $h2
91	ip address del 198.51.100.2/24 dev $h2
92
93	ip link set dev $h2 down
94	vrf_destroy "vrf-h2"
95}
96
97router_create()
98{
99	ip link set dev $rp1 up
100	ip link set dev $rp2 up
101
102	tc qdisc add dev $rp2 clsact
103
104	ip address add 192.0.2.1/24 dev $rp1
105	ip address add 2001:db8:1::1/64 dev $rp1
106
107	ip address add 198.51.100.1/24 dev $rp2
108	ip address add 2001:db8:2::1/64 dev $rp2
109}
110
111router_destroy()
112{
113	ip address del 2001:db8:2::1/64 dev $rp2
114	ip address del 198.51.100.1/24 dev $rp2
115
116	ip address del 2001:db8:1::1/64 dev $rp1
117	ip address del 192.0.2.1/24 dev $rp1
118
119	tc qdisc del dev $rp2 clsact
120
121	ip link set dev $rp2 down
122	ip link set dev $rp1 down
123}
124
125start_mcd()
126{
127	SMCROUTEDIR="$(mktemp -d)"
128
129	for ((i = 1; i <= $NUM_NETIFS; ++i)); do
130		echo "phyint ${NETIFS[p$i]} enable" >> \
131			$SMCROUTEDIR/$table_name.conf
132	done
133
134	$MCD -N -I $table_name -f $SMCROUTEDIR/$table_name.conf \
135		-P $SMCROUTEDIR/$table_name.pid
136}
137
138kill_mcd()
139{
140	pkill $MCD
141	rm -rf $SMCROUTEDIR
142}
143
144setup_prepare()
145{
146	h1=${NETIFS[p1]}
147	rp1=${NETIFS[p2]}
148
149	rp2=${NETIFS[p3]}
150	h2=${NETIFS[p4]}
151
152	rp1mac=$(mac_get $rp1)
153
154	start_mcd
155
156	vrf_prepare
157
158	h1_create
159	h2_create
160
161	router_create
162
163	forwarding_enable
164}
165
166cleanup()
167{
168	pre_cleanup
169
170	forwarding_restore
171
172	router_destroy
173
174	h2_destroy
175	h1_destroy
176
177	vrf_cleanup
178
179	kill_mcd
180}
181
182ping_ipv4()
183{
184	ping_test $h1 198.51.100.2
185}
186
187ping_ipv6()
188{
189	ping6_test $h1 2001:db8:2::2
190}
191
192sip_in_class_e()
193{
194	RET=0
195
196	# Disable rpfilter to prevent packets to be dropped because of it.
197	sysctl_set net.ipv4.conf.all.rp_filter 0
198	sysctl_set net.ipv4.conf.$rp1.rp_filter 0
199
200	tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
201		flower src_ip 240.0.0.1 ip_proto udp action pass
202
203	$MZ $h1 -t udp "sp=54321,dp=12345" -c 5 -d 1msec \
204		-A 240.0.0.1 -b $rp1mac -B 198.51.100.2 -q
205
206	tc_check_packets "dev $rp2 egress" 101 5
207	check_err $? "Packets were dropped"
208
209	log_test "Source IP in class E"
210
211	tc filter del dev $rp2 egress protocol ip pref 1 handle 101 flower
212	sysctl_restore net.ipv4.conf.$rp1.rp_filter
213	sysctl_restore net.ipv4.conf.all.rp_filter
214}
215
216create_mcast_sg()
217{
218	local if_name=$1; shift
219	local s_addr=$1; shift
220	local mcast=$1; shift
221	local dest_ifs=${@}
222
223	$MC_CLI -I $table_name add $if_name $s_addr $mcast $dest_ifs
224}
225
226delete_mcast_sg()
227{
228	local if_name=$1; shift
229	local s_addr=$1; shift
230	local mcast=$1; shift
231	local dest_ifs=${@}
232
233	$MC_CLI -I $table_name remove $if_name $s_addr $mcast $dest_ifs
234}
235
236__mc_mac_mismatch()
237{
238	local desc=$1; shift
239	local proto=$1; shift
240	local sip=$1; shift
241	local dip=$1; shift
242	local flags=${1:-""}; shift
243	local dmac=01:02:03:04:05:06
244
245	RET=0
246
247	tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
248		flower dst_ip $dip action pass
249
250	create_mcast_sg $rp1 $sip $dip $rp2
251
252	$MZ $flags $h1 -t udp "sp=54321,dp=12345" -c 5 -d 1msec -b $dmac \
253		-B $dip -q
254
255	tc_check_packets "dev $rp2 egress" 101 5
256	check_err $? "Packets were dropped"
257
258	log_test "Multicast MAC mismatch: $desc"
259
260	delete_mcast_sg $rp1 $sip $dip $rp2
261	tc filter del dev $rp2 egress protocol $proto pref 1 handle 101 flower
262}
263
264mc_mac_mismatch()
265{
266	__mc_mac_mismatch "IPv4" "ip" 192.0.2.2 225.1.2.3
267	__mc_mac_mismatch "IPv6" "ipv6" 2001:db8:1::2 ff0e::3 "-6"
268}
269
270ipv4_sip_equal_dip()
271{
272	RET=0
273
274	# Disable rpfilter to prevent packets to be dropped because of it.
275	sysctl_set net.ipv4.conf.all.rp_filter 0
276	sysctl_set net.ipv4.conf.$rp1.rp_filter 0
277
278	tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
279		flower src_ip 198.51.100.2  action pass
280
281	$MZ $h1 -t udp "sp=54321,dp=12345" -c 5 -d 1msec \
282		-A 198.51.100.2 -b $rp1mac -B 198.51.100.2 -q
283
284	tc_check_packets "dev $rp2 egress" 101 5
285	check_err $? "Packets were dropped"
286
287	log_test "Source IP is equal to destination IP: IPv4"
288
289	tc filter del dev $rp2 egress protocol ip pref 1 handle 101 flower
290	sysctl_restore net.ipv4.conf.$rp1.rp_filter
291	sysctl_restore net.ipv4.conf.all.rp_filter
292}
293
294ipv6_sip_equal_dip()
295{
296	RET=0
297
298	tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \
299		flower src_ip 2001:db8:2::2 action pass
300
301	$MZ -6 $h1 -t udp "sp=54321,dp=12345" -c 5 -d 1msec \
302		-A 2001:db8:2::2 -b $rp1mac -B 2001:db8:2::2 -q
303
304	tc_check_packets "dev $rp2 egress" 101 5
305	check_err $? "Packets were dropped"
306
307	log_test "Source IP is equal to destination IP: IPv6"
308
309	tc filter del dev $rp2 egress protocol ipv6 pref 1 handle 101 flower
310}
311
312ipv4_dip_link_local()
313{
314	local dip=169.254.1.1
315
316	RET=0
317
318	tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
319		flower dst_ip $dip action pass
320
321	ip neigh add 169.254.1.1 lladdr 00:11:22:33:44:55 dev $rp2
322	ip route add 169.254.1.0/24 dev $rp2
323
324	$MZ $h1 -t udp "sp=54321,dp=12345" -c 5 -d 1msec -b $rp1mac -B $dip -q
325
326	tc_check_packets "dev $rp2 egress" 101 5
327	check_err $? "Packets were dropped"
328
329	log_test "IPv4 destination IP is link-local"
330
331	ip route del 169.254.1.0/24 dev $rp2
332	ip neigh del 169.254.1.1 lladdr 00:11:22:33:44:55 dev $rp2
333	tc filter del dev $rp2 egress protocol ip pref 1 handle 101 flower
334}
335
336ipv4_sip_link_local()
337{
338	local sip=169.254.1.1
339
340	RET=0
341
342	# Disable rpfilter to prevent packets to be dropped because of it.
343	sysctl_set net.ipv4.conf.all.rp_filter 0
344	sysctl_set net.ipv4.conf."$rp1".rp_filter 0
345
346	tc filter add dev "$rp2" egress protocol ip pref 1 handle 101 \
347		flower src_ip "$sip" action pass
348
349	$MZ "$h1" -t udp "sp=54321,dp=12345" -c 5 -d 1msec -b "$rp1mac" \
350		-A "$sip" -B 198.51.100.2 -q
351
352	tc_check_packets "dev $rp2 egress" 101 5
353	check_err $? "Packets were dropped"
354
355	log_test "IPv4 source IP is link-local"
356
357	tc filter del dev "$rp2" egress protocol ip pref 1 handle 101 flower
358	sysctl_restore net.ipv4.conf."$rp1".rp_filter
359	sysctl_restore net.ipv4.conf.all.rp_filter
360}
361
362trap cleanup EXIT
363
364setup_prepare
365setup_wait
366
367tests_run
368
369exit $EXIT_STATUS
370