xref: /freebsd/tests/sys/netinet6/forward6.sh (revision 780f28929782a104eefbc81f031836bf1febb6de)
1#!/usr/bin/env atf-sh
2#-
3# SPDX-License-Identifier: BSD-2-Clause
4#
5# Copyright (c) 2020 Alexander V. Chernikov
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28#
29
30. $(atf_get_srcdir)/../common/vnet.subr
31
32atf_test_case "fwd_ip6_gu_icmp_iface_fast_success" "cleanup"
33fwd_ip6_gu_icmp_iface_fast_success_head() {
34
35	atf_set descr 'Test valid IPv6 global unicast fast-forwarding to interface'
36	atf_set require.user root
37	atf_set require.progs scapy
38}
39
40fwd_ip6_gu_icmp_iface_fast_success_body() {
41
42	ids=65529
43	id=`printf "%x" ${ids}`
44	if [ $$ -gt 65535 ]; then
45		xl=`printf "%x" $(($$ - 65535))`
46		yl="1"
47	else
48		xl=`printf "%x" $$`
49		yl=""
50	fi
51
52	vnet_init
53
54	ip6a="2001:db8:6666:0000:${yl}:${id}:1:${xl}"
55	ip6b="2001:db8:6666:0000:${yl}:${id}:2:${xl}"
56	plen=96
57
58	src_ip="2001:db8:6666:0000:${yl}:${id}:3:${xl}"
59
60	script_name="../common/sender.py"
61
62	epair=$(vnet_mkepair)
63	ifconfig ${epair}a up
64	ifconfig ${epair}a inet6 ${ip6a}/${plen}
65
66	jname="v6t-${id}-${yl}-${xl}"
67	vnet_mkjail ${jname} ${epair}b
68	jexec ${jname} ifconfig ${epair}b up
69	jexec ${jname} ifconfig ${epair}b inet6 ${ip6b}/${plen}
70
71	jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'`
72
73	our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'`
74
75	# wait for DAD to complete
76	while [ `jexec ${jname} ifconfig ${epair}b inet6 | grep -c tentative` != "0" ]; do
77		sleep 0.1
78	done
79	while [ `ifconfig ${epair}a inet6 | grep -c tentative` != "0" ]; do
80		sleep 0.1
81	done
82
83	jexec ${jname} sysctl net.inet6.ip6.forwarding=1
84	# As we're doing router-on-the-stick, turn sending IP redirects off:
85	jexec ${jname} sysctl net.inet6.ip6.redirect=0
86
87	atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \
88		--test_name fwd_ip6_icmp \
89		--smac ${our_mac} --dmac ${jail_mac} \
90		--sip ${src_ip} --dip ${ip6a} \
91		--iface ${epair}a
92
93	# check counters are valid
94	atf_check -o match:'1 packet forwarded' jexec ${jname} netstat -sp ip6
95}
96
97fwd_ip6_gu_icmp_iface_fast_success_cleanup() {
98
99	vnet_cleanup
100}
101
102atf_test_case "fwd_ip6_gu_icmp_gw_gu_fast_success" "cleanup"
103fwd_ip6_gu_icmp_gw_gu_fast_success_head() {
104
105	atf_set descr 'Test valid IPv6 global unicast fast-forwarding to GU gw'
106	atf_set require.user root
107	atf_set require.progs scapy
108}
109
110fwd_ip6_gu_icmp_gw_gu_fast_success_body() {
111
112	ids=65528
113	id=`printf "%x" ${ids}`
114	if [ $$ -gt 65535 ]; then
115		xl=`printf "%x" $(($$ - 65535))`
116		yl="1"
117	else
118		xl=`printf "%x" $$`
119		yl=""
120	fi
121
122	vnet_init
123
124	ip6a="2001:db8:6666:0000:${yl}:${id}:1:${xl}"
125	ip6b="2001:db8:6666:0000:${yl}:${id}:2:${xl}"
126	plen=96
127
128	src_ip="2001:db8:6666:0000:${yl}:${id}:3:${xl}"
129	dst_ip="2001:db8:6666:0000:${yl}:${id}:4:${xl}"
130
131	script_name="../common/sender.py"
132
133	epair=$(vnet_mkepair)
134	ifconfig ${epair}a up
135	ifconfig ${epair}a inet6 ${ip6a}/${plen}
136
137	jname="v6t-${id}-${yl}-${xl}"
138	vnet_mkjail ${jname} ${epair}b
139	jexec ${jname} ifconfig ${epair}b up
140	jexec ${jname} ifconfig ${epair}b inet6 ${ip6b}/${plen}
141
142	jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'`
143
144	our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'`
145
146	# wait for DAD to complete
147	while [ `jexec ${jname} ifconfig ${epair}b inet6 | grep -c tentative` != "0" ]; do
148		sleep 0.1
149	done
150	while [ `ifconfig ${epair}a inet6 | grep -c tentative` != "0" ]; do
151		sleep 0.1
152	done
153
154	# Add static route back to us
155	jexec ${jname} route add -6 -host ${dst_ip} ${ip6a}
156
157	jexec ${jname} sysctl net.inet6.ip6.forwarding=1
158	# As we're doing router-on-the-stick, turn sending IP redirects off:
159	jexec ${jname} sysctl net.inet6.ip6.redirect=0
160
161	atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \
162		--test_name fwd_ip6_icmp \
163		--smac ${our_mac} --dmac ${jail_mac} \
164		--sip ${src_ip} --dip ${dst_ip} \
165		--iface ${epair}a
166
167	# check counters are valid
168	atf_check -o match:'1 packet forwarded' jexec ${jname} netstat -sp ip6
169}
170
171fwd_ip6_gu_icmp_gw_gu_fast_success_cleanup() {
172
173	vnet_cleanup
174}
175
176atf_test_case "fwd_ip6_gu_icmp_gw_ll_fast_success" "cleanup"
177fwd_ip6_gu_icmp_gw_ll_fast_success_head() {
178
179	atf_set descr 'Test valid IPv6 global unicast fast-forwarding to LL gw'
180	atf_set require.user root
181	atf_set require.progs scapy
182}
183
184fwd_ip6_gu_icmp_gw_ll_fast_success_body() {
185
186	ids=65527
187	id=`printf "%x" ${ids}`
188	if [ $$ -gt 65535 ]; then
189		xl=`printf "%x" $(($$ - 65535))`
190		yl="1"
191	else
192		xl=`printf "%x" $$`
193		yl=""
194	fi
195
196	vnet_init
197
198	ip6a="2001:db8:6666:0000:${yl}:${id}:1:${xl}"
199	ip6b="2001:db8:6666:0000:${yl}:${id}:2:${xl}"
200	plen=96
201
202	src_ip="2001:db8:6666:0000:${yl}:${id}:3:${xl}"
203	dst_ip="2001:db8:6666:0000:${yl}:${id}:4:${xl}"
204
205	script_name="../common/sender.py"
206
207	epair=$(vnet_mkepair)
208	ifconfig ${epair}a up
209	ifconfig ${epair}a inet6 ${ip6a}/${plen}
210
211	jname="v6t-${id}-${yl}-${xl}"
212	vnet_mkjail ${jname} ${epair}b
213	jexec ${jname} ifconfig ${epair}b up
214	jexec ${jname} ifconfig ${epair}b inet6 ${ip6b}/${plen}
215
216	jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'`
217
218	our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'`
219	our_ll_ip=`ifconfig ${epair}a inet6 | awk '$1~/inet6/&& $2~/^fe80:/{print$2}' | awk -F% '{print$1}'`
220
221	# wait for DAD to complete
222	while [ `jexec ${jname} ifconfig ${epair}b inet6 | grep -c tentative` != "0" ]; do
223		sleep 0.1
224	done
225	while [ `ifconfig ${epair}a inet6 | grep -c tentative` != "0" ]; do
226		sleep 0.1
227	done
228
229	# Add static route back to us
230	atf_check -s exit:0 -o ignore jexec ${jname} route add -6 -host ${dst_ip} ${our_ll_ip}%${epair}b
231
232	jexec ${jname} sysctl net.inet6.ip6.forwarding=1
233	# As we're doing router-on-the-stick, turn sending IP redirects off:
234	jexec ${jname} sysctl net.inet6.ip6.redirect=0
235
236	atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \
237		--test_name fwd_ip6_icmp \
238		--smac ${our_mac} --dmac ${jail_mac} \
239		--sip ${src_ip} --dip ${dst_ip} \
240		--iface ${epair}a
241
242	# check counters are valid
243	atf_check -o match:'1 packet forwarded' jexec ${jname} netstat -sp ip6
244}
245
246fwd_ip6_gu_icmp_gw_ll_fast_success_cleanup() {
247
248	vnet_cleanup
249}
250
251atf_test_case "fwd_ip6_gu_icmp_iface_slow_success" "cleanup"
252fwd_ip6_gu_icmp_iface_slow_success_head() {
253
254	atf_set descr 'Test valid IPv6 global unicast fast-forwarding to interface'
255	atf_set require.user root
256	atf_set require.progs scapy
257}
258
259fwd_ip6_gu_icmp_iface_slow_success_body() {
260
261	ids=65526
262	id=`printf "%x" ${ids}`
263	if [ $$ -gt 65535 ]; then
264		xl=`printf "%x" $(($$ - 65535))`
265		yl="1"
266	else
267		xl=`printf "%x" $$`
268		yl=""
269	fi
270
271	vnet_init
272
273	ip6a="2001:db8:6666:0000:${yl}:${id}:1:${xl}"
274	ip6b="2001:db8:6666:0000:${yl}:${id}:2:${xl}"
275	plen=96
276
277	src_ip="2001:db8:6666:0000:${yl}:${id}:3:${xl}"
278
279	script_name="../common/sender.py"
280
281	epair=$(vnet_mkepair)
282	ifconfig ${epair}a up
283	ifconfig ${epair}a inet6 ${ip6a}/${plen}
284
285	jname="v6t-${id}-${yl}-${xl}"
286	vnet_mkjail ${jname} ${epair}b
287	jexec ${jname} ifconfig ${epair}b up
288	jexec ${jname} ifconfig ${epair}b inet6 ${ip6b}/${plen}
289
290	jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'`
291
292	our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'`
293
294	# wait for DAD to complete
295	while [ `jexec ${jname} ifconfig ${epair}b inet6 | grep -c tentative` != "0" ]; do
296		sleep 0.1
297	done
298	while [ `ifconfig ${epair}a inet6 | grep -c tentative` != "0" ]; do
299		sleep 0.1
300	done
301
302	jexec ${jname} sysctl net.inet6.ip6.forwarding=1
303	# Do not turn off route redirects to ensure slow path is on
304
305	atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \
306		--test_name fwd_ip6_icmp \
307		--smac ${our_mac} --dmac ${jail_mac} \
308		--sip ${src_ip} --dip ${ip6a} \
309		--iface ${epair}a
310
311	# check counters are valid
312	atf_check -o match:'1 packet forwarded' jexec ${jname} netstat -sp ip6
313}
314
315fwd_ip6_gu_icmp_iface_slow_success_cleanup() {
316
317	vnet_cleanup
318}
319
320atf_test_case "fwd_ip6_gu_icmp_gw_gu_slow_success" "cleanup"
321fwd_ip6_gu_icmp_gw_gu_slow_success_head() {
322
323	atf_set descr 'Test valid IPv6 global unicast fast-forwarding to GU gw'
324	atf_set require.user root
325	atf_set require.progs scapy
326}
327
328fwd_ip6_gu_icmp_gw_gu_slow_success_body() {
329
330	ids=65525
331	id=`printf "%x" ${ids}`
332	if [ $$ -gt 65535 ]; then
333		xl=`printf "%x" $(($$ - 65535))`
334		yl="1"
335	else
336		xl=`printf "%x" $$`
337		yl=""
338	fi
339
340	vnet_init
341
342	ip6a="2001:db8:6666:0000:${yl}:${id}:1:${xl}"
343	ip6b="2001:db8:6666:0000:${yl}:${id}:2:${xl}"
344	plen=96
345
346	src_ip="2001:db8:6666:0000:${yl}:${id}:3:${xl}"
347	dst_ip="2001:db8:6666:0000:${yl}:${id}:4:${xl}"
348
349	script_name="../common/sender.py"
350
351	epair=$(vnet_mkepair)
352	ifconfig ${epair}a up
353	ifconfig ${epair}a inet6 ${ip6a}/${plen}
354
355	jname="v6t-${id}-${yl}-${xl}"
356	vnet_mkjail ${jname} ${epair}b
357	jexec ${jname} ifconfig ${epair}b up
358	jexec ${jname} ifconfig ${epair}b inet6 ${ip6b}/${plen}
359
360	jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'`
361
362	our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'`
363
364	# wait for DAD to complete
365	while [ `jexec ${jname} ifconfig ${epair}b inet6 | grep -c tentative` != "0" ]; do
366		sleep 0.1
367	done
368	while [ `ifconfig ${epair}a inet6 | grep -c tentative` != "0" ]; do
369		sleep 0.1
370	done
371
372	# Add static route back to us
373	jexec ${jname} route add -6 -host ${dst_ip} ${ip6a}
374
375	jexec ${jname} sysctl net.inet6.ip6.forwarding=1
376	# Do not turn off route redirects to ensure slow path is on
377
378	atf_check -s exit:0 \
379		$(atf_get_srcdir)/${script_name} \
380		--test_name fwd_ip6_icmp \
381		--smac ${our_mac} --dmac ${jail_mac} \
382		--sip ${src_ip} --dip ${dst_ip} \
383		--iface ${epair}a
384	jexec ${jname} netstat -sp ip6
385
386	# check counters are valid
387	atf_check -o match:'1 packet forwarded' jexec ${jname} netstat -sp ip6
388}
389
390fwd_ip6_gu_icmp_gw_gu_slow_success_cleanup() {
391
392	vnet_cleanup
393}
394
395atf_test_case "fwd_ip6_gu_icmp_gw_ll_slow_success" "cleanup"
396fwd_ip6_gu_icmp_gw_ll_slow_success_head() {
397
398	atf_set descr 'Test valid IPv6 global unicast fast-forwarding to LL gw'
399	atf_set require.user root
400	atf_set require.progs scapy
401}
402
403fwd_ip6_gu_icmp_gw_ll_slow_success_body() {
404
405	ids=65524
406	id=`printf "%x" ${ids}`
407	if [ $$ -gt 65535 ]; then
408		xl=`printf "%x" $(($$ - 65535))`
409		yl="1"
410	else
411		xl=`printf "%x" $$`
412		yl=""
413	fi
414
415	vnet_init
416
417	ip6a="2001:db8:6666:0000:${yl}:${id}:1:${xl}"
418	ip6b="2001:db8:6666:0000:${yl}:${id}:2:${xl}"
419	plen=96
420
421	src_ip="2001:db8:6666:0000:${yl}:${id}:3:${xl}"
422	dst_ip="2001:db8:6666:0000:${yl}:${id}:4:${xl}"
423
424	script_name="../common/sender.py"
425
426	epair=$(vnet_mkepair)
427	ifconfig ${epair}a up
428	ifconfig ${epair}a inet6 ${ip6a}/${plen}
429
430	jname="v6t-${id}-${yl}-${xl}"
431	vnet_mkjail ${jname} ${epair}b
432	jexec ${jname} ifconfig ${epair}b up
433	jexec ${jname} ifconfig ${epair}b inet6 ${ip6b}/${plen}
434
435	jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'`
436
437	our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'`
438	our_ll_ip=`ifconfig ${epair}a inet6 | awk '$1~/inet6/&& $2~/^fe80:/{print$2}' | awk -F% '{print$1}'`
439
440	# wait for DAD to complete
441	while [ `jexec ${jname} ifconfig ${epair}b inet6 | grep -c tentative` != "0" ]; do
442		sleep 0.1
443	done
444	while [ `ifconfig ${epair}a inet6 | grep -c tentative` != "0" ]; do
445		sleep 0.1
446	done
447
448	# Add static route back to us
449	atf_check -s exit:0 -o ignore jexec ${jname} route add -6 -host ${dst_ip} ${our_ll_ip}%${epair}b
450
451	jexec ${jname} sysctl net.inet6.ip6.forwarding=1
452	# Do not turn off route redirects to ensure slow path is on
453
454	atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \
455		--test_name fwd_ip6_icmp \
456		--smac ${our_mac} --dmac ${jail_mac} \
457		--sip ${src_ip} --dip ${dst_ip} \
458		--iface ${epair}a
459
460	# check counters are valid
461	atf_check -o match:'1 packet forwarded' jexec ${jname} netstat -sp ip6
462}
463
464fwd_ip6_gu_icmp_gw_ll_slow_success_cleanup() {
465
466	vnet_cleanup
467}
468
469atf_test_case "fwd_ip6_blackhole" "cleanup"
470fwd_ip6_blackhole_head() {
471
472	atf_set descr 'Test blackhole routing'
473	atf_set require.user root
474}
475
476fwd_ip6_blackhole_body() {
477	jname="v6t-fwd_ip6_blackhole"
478
479	vnet_init
480
481	epair=$(vnet_mkepair)
482	epair_out=$(vnet_mkepair)
483
484	ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad
485
486	vnet_mkjail ${jname} ${epair}b ${epair_out}b
487	jexec ${jname} ifconfig lo0 inet6 ::1/128 up no_dad
488	jexec ${jname} ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad
489	jexec ${jname} ifconfig ${epair_out}b inet6 2001:db8:1::1/64 up no_dad
490	jexec ${jname} sysctl net.inet6.ip6.forwarding=1
491
492	route -6 add default 2001:db8::1
493
494	atf_check -s exit:2 -o ignore \
495	    ping6 -c 1 -t 1 2001:db8:1::2
496	atf_check -s exit:0 -o match:"0 packets not forwardable" \
497	    jexec ${jname} netstat -s -p ip6
498
499	# Create blackhole route
500	jexec ${jname} route -6 add 2001:db8:1::2 -blackhole
501
502	# Force slow path
503	jexec ${jname} sysctl net.inet6.ip6.redirect=1
504	atf_check -s exit:2 -o ignore \
505	    ping6 -c 1 -t 1 2001:db8:1::2
506	atf_check -s exit:0 -o match:"1 packet not forwardable" \
507	    jexec ${jname} netstat -s -p ip6
508
509	# Now try the fast path
510	jexec ${jname} sysctl net.inet6.ip6.redirect=0
511	atf_check -s exit:2 -o ignore \
512	    ping6 -c 1 -t 1 2001:db8:1::2
513	atf_check -s exit:0 -o match:"2 packets not forwardable" \
514	    jexec ${jname} netstat -s -p ip6
515}
516
517fwd_ip6_blackhole_cleanup() {
518
519	vnet_cleanup
520}
521
522atf_init_test_cases()
523{
524
525	atf_add_test_case "fwd_ip6_gu_icmp_iface_fast_success"
526	atf_add_test_case "fwd_ip6_gu_icmp_gw_gu_fast_success"
527	atf_add_test_case "fwd_ip6_gu_icmp_gw_ll_fast_success"
528	atf_add_test_case "fwd_ip6_gu_icmp_iface_slow_success"
529	atf_add_test_case "fwd_ip6_gu_icmp_gw_gu_slow_success"
530	atf_add_test_case "fwd_ip6_gu_icmp_gw_ll_slow_success"
531	atf_add_test_case "fwd_ip6_blackhole"
532}
533
534# end
535
536