xref: /freebsd/tools/test/netfibs/reflector.sh (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
1#!/bin/sh
2#-
3# Copyright (c) 2012 Cisco Systems, Inc.
4# All rights reserved.
5#
6# This software was developed by Bjoern Zeeb under contract to
7# Cisco Systems, Inc..
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions
11# are met:
12# 1. Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14# 2. Redistributions in binary form must reproduce the above copyright
15#    notice, this list of conditions and the following disclaimer in the
16#    documentation and/or other materials provided with the distribution.
17#
18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28# SUCH DAMAGE.
29#
30#
31
32# We will use the RFC5180 (and Errata) benchmarking working group prefix
33# 2001:0002::/48 for testing.
34PREFIX="2001:2:"
35
36# Set IFACE to the real interface you want to run the test on.
37: ${IFACE:=lo0}
38
39# Control port we use to exchange messages between nodes to sync. tests, etc.
40: ${CTRLPORT:=6666}
41
42# Get the number of FIBs from the kernel.
43RT_NUMFIBS=`sysctl -n net.fibs`
44
45PEERADDR="2001:2:ff00::1"
46OURADDR="2001:2:ff00::2"
47
48OURLINKLOCAL=""
49PEERLINKLOCAL=""
50
51# By default all commands must succeed.  Individual tests may disable this
52# temporary.
53set -e
54
55# Debug magic.
56case "${DEBUG}" in
5742)	set -x ;;
58esac
59
60
61
62#
63# Helper functions.
64#
65
66# Function to avoid prelist races adding and deleting prefixes too quickly.
67delay()
68{
69
70	# sleep 1 is too long.
71	touch /tmp/foo || true
72	stat /tmp/foo > /dev/null 2>&1 || true
73}
74
75check_rc()
76{
77	local _rc _exp _testno _testname _msg _r
78	_rc=$1
79	_exp=$2
80	_testno=$3
81	_testname="$4"
82	_msg="$5"
83
84	_r="not ok"
85	if test ${_rc} -eq ${_exp}; then
86		_r="ok"
87	fi
88	echo "${_r} ${_testno} ${_testname} # ${_msg} ${_rc}"
89}
90
91print_debug()
92{
93	local _msg
94	_msg="$*"
95
96	case ${DEBUG} in
97	''|0)	;;
98	*)	echo "DEBUG: ${_msg}" >&2 ;;
99	esac
100}
101
102die()
103{
104	local _msg
105	_msg="$*"
106
107	echo "ERROR: ${_msg}" >&2
108	exit 1
109}
110
111#
112# Test functions.
113#
114
115# Setup our side and wait for the peer to tell us that it is ready.
116wait_remote_ready()
117{
118	local _greeting _keyword _fibs _linklocal i
119
120	print_debug "Setting up interface ${IFACE}"
121	ifconfig ${IFACE} inet6 ${OURADDR}/64 -alias > /dev/null 2>&1 || true
122	delay
123	ifconfig ${IFACE} inet6 ${OURADDR}/64 alias up
124	i=0
125	while test ${i} -lt ${RT_NUMFIBS}; do
126		ifconfig ${IFACE} inet6 2001:2:${i}::2/64 -alias \
127		    > /dev/null 2>&1 || true
128		delay
129		i=$((i + 1))
130	done
131	OURLINKLOCAL=`ifconfig ${IFACE} | awk '/inet6 fe80:/ { print $2 }'`
132
133	# Let things settle.
134	print_debug "Waiting 4 seconds for things to settle"
135	sleep 4
136
137	# Wait for the remote to connect and start things.
138	# We tell it the magic keyword, our number of FIBs and our link-local.
139	# It already knows our global address.
140	_greeting=`echo "SETUP ${RT_NUMFIBS} ${OURLINKLOCAL}" | \
141	    nc -6 -l ${CTRLPORT}`
142
143	read _keyword _fibs _linklocal <<EOI
144${_greeting}
145EOI
146	print_debug "_keyword=${_keyword}"
147	print_debug "_fibs=${_fibs}"
148	print_debug "_linklocal=${_linklocal}"
149	case ${_keyword} in
150	SETUP)	;;
151	*)	die "Got invalid keyword in greeting: ${_greeting}"
152		;;
153	esac
154	if test ${_fibs} -ne ${RT_NUMFIBS}; then
155		die "Number of FIBs not matching ours (${RT_NUMFIBS}) in" \
156		    "greeting: ${_greeting}"
157	fi
158	PEERLINKLOCAL=${_linklocal}
159
160	print_debug "Successfully received greeting. Peer at ${PEERLINKLOCAL}"
161}
162
163cleanup()
164{
165
166	print_debug "Removing address from interface ${IFACE}"
167	ifconfig ${IFACE} inet6 ${OURADDR}/64 -alias
168	delay
169}
170
171################################################################################
172#
173testtx_icmp6_connected()
174{
175	local _opts
176
177	_opts=""
178	case ${DEBUG} in
179	''|0)	;;
180	42)	_opts="-d -d" ;;
181	*)	_opts="-d" ;;
182	esac
183	print_debug "./reflect -p ${CTRLPORT} -T TCP6 " \
184	    "-t testtx_icmp6_connected ${_opts}"
185	./reflect -p ${CTRLPORT} -T TCP6 -t testtx_icmp6_connected ${_opts}
186	print_debug "reflect terminated without error."
187}
188
189testtx_tcp6_connected()
190{
191	local _opts
192
193	_opts=""
194	case ${DEBUG} in
195	''|0)	;;
196	42)	_opts="-d -d" ;;
197	*)	_opts="-d" ;;
198	esac
199	print_debug "./reflect -p ${CTRLPORT} -T TCP6 " \
200	    "-t testtx_tcp6_connected ${_opts}"
201	./reflect -p ${CTRLPORT} -T TCP6 -t testtx_tcp6_connected ${_opts}
202	print_debug "reflect terminated without error."
203}
204
205testtx_udp6_connected()
206{
207	local _opts
208
209	_opts=""
210	case ${DEBUG} in
211	''|0)	;;
212	42)	_opts="-d -d" ;;
213	*)	_opts="-d" ;;
214	esac
215	print_debug "./reflect -p ${CTRLPORT} -T UDP6 " \
216	    "-t testtx_udp6_connected ${_opts}"
217	./reflect -p ${CTRLPORT} -T UDP6 -t testtx_udp6_connected ${_opts}
218	print_debug "reflect terminated without error."
219}
220
221################################################################################
222#
223testtx_icmp6_connected_blackhole()
224{
225	local _opts fib
226
227	_opts=""
228	case ${DEBUG} in
229	''|0)	;;
230	42)	_opts="-d -d" ;;
231	*)	_opts="-d" ;;
232	esac
233
234	fib=0
235	while test ${fib} -lt ${RT_NUMFIBS}; do
236		print_debug "./reflect -p ${CTRLPORT} -T TCP6 " \
237		    "-t testtx_icmp6_connected_blackhole${fib} ${_opts}"
238		./reflect -p ${CTRLPORT} -T TCP6 \
239		    -t testtx_icmp6_connected_blackhole${fib} ${_opts}
240		print_debug "reflect terminated without error."
241		fib=$((fib + 1))
242	done
243}
244
245testtx_tcp6_connected_blackhole()
246{
247	local _opts fib
248
249	_opts=""
250	case ${DEBUG} in
251	''|0)	;;
252	42)	_opts="-d -d" ;;
253	*)	_opts="-d" ;;
254	esac
255
256	fib=0
257	while test ${fib} -lt ${RT_NUMFIBS}; do
258		print_debug "./reflect -p ${CTRLPORT} -T TCP6 " \
259		    "-t testtx_tcp6_connected_blackhole${fib} ${_opts}"
260		./reflect -p ${CTRLPORT} -T TCP6 \
261		    -t testtx_tcp6_connected_blackhole${fib} ${_opts}
262		print_debug "reflect terminated without error."
263		fib=$((fib + 1))
264	done
265}
266
267testtx_udp6_connected_blackhole()
268{
269	local _opts fib
270
271	_opts=""
272	case ${DEBUG} in
273	''|0)	;;
274	42)	_opts="-d -d" ;;
275	*)	_opts="-d" ;;
276	esac
277
278	fib=0
279	while test ${fib} -lt ${RT_NUMFIBS}; do
280		print_debug "./reflect -p ${CTRLPORT} -T UDP6 " \
281		    "-t testtx_udp6_connected_blackhole${fib} ${_opts}"
282		./reflect -p ${CTRLPORT} -T UDP6 \
283		    -t testtx_udp6_connected_blackhole${fib} ${_opts}
284		print_debug "reflect terminated without error."
285		fib=$((fib + 1))
286	done
287}
288
289################################################################################
290#
291testtx_ulp6_connected_transfernets()
292{
293	local _opts fib _n _o
294	_n="$1"
295	_o="$2"
296
297	_opts=""
298	case ${DEBUG} in
299	''|0)	;;
300	42)	_opts="-d -d" ;;
301	*)	_opts="-d" ;;
302	esac
303
304	# Setup transfer networks.
305	fib=0
306	while test ${fib} -lt ${RT_NUMFIBS}; do
307		setfib -F${fib} \
308		    ifconfig ${IFACE} inet6 2001:2:${fib}::2/64 alias
309		fib=$((fib + 1))
310	done
311
312	fib=0
313	while test ${fib} -lt ${RT_NUMFIBS}; do
314		print_debug "./reflect -p ${CTRLPORT} -T ${_o} -t ${_n}${fib} ${_opts}"
315		./reflect -p ${CTRLPORT} -T ${_o} -t ${_n}${fib} ${_opts}
316		print_debug "reflect terminated without error."
317		fib=$((fib + 1))
318	done
319
320	# Cleanup transfer networks.
321	fib=0
322	while test ${fib} -lt ${RT_NUMFIBS}; do
323		setfib -F${fib} \
324		    ifconfig ${IFACE} inet6 2001:2:${fib}::2/64 -alias
325		delay
326		fib=$((fib + 1))
327	done
328}
329
330testtx_icmp6_connected_transfernets()
331{
332
333	testtx_ulp6_connected_transfernets \
334	    "testtx_icmp6_connected_transfernets" "TCP6"
335}
336
337testtx_tcp6_connected_transfernets()
338{
339
340	testtx_ulp6_connected_transfernets \
341	    "testtx_tcp6_connected_transfernets" "TCP6"
342}
343
344testtx_udp6_connected_transfernets()
345{
346
347	testtx_ulp6_connected_transfernets \
348	    "testtx_udp6_connected_transfernets" "UDP6"
349}
350
351testtx_icmp6_connected_ifconfig_transfernets()
352{
353
354	testtx_ulp6_connected_transfernets \
355	    "testtx_icmp6_connected_ifconfig_transfernets" "TCP6"
356}
357
358testtx_tcp6_connected_ifconfig_transfernets()
359{
360
361	testtx_ulp6_connected_transfernets \
362	    "testtx_tcp6_connected_ifconfig_transfernets" "TCP6"
363}
364
365testtx_udp6_connected_ifconfig_transfernets()
366{
367
368	testtx_ulp6_connected_transfernets \
369	    "testtx_udp6_connected_ifconfig_transfernets" "UDP6"
370}
371
372################################################################################
373#
374testtx_ulp6_gateway()
375{
376	local _opts _n _o
377	_n="$1"
378	_o="$2"
379
380	ifconfig lo0 inet6 2001:2:ff01::2 -alias > /dev/null 2>&1 || true
381	delay
382	ifconfig lo0 inet6 2001:2:ff01::2 alias
383
384	_opts=""
385	case ${DEBUG} in
386	''|0)	;;
387	42)	_opts="-d -d" ;;
388	*)	_opts="-d" ;;
389	esac
390
391	print_debug "./reflect -p ${CTRLPORT} -T ${_o} " \
392	    "-t ${_n} ${_opts} -A 2001:2:ff01::2"
393	./reflect -p ${CTRLPORT} -T ${_o} \
394	    -t ${_n} ${_opts} -A 2001:2:ff01::2
395	print_debug "reflect terminated without error."
396
397	ifconfig lo0 inet6 2001:2:ff01::2 -alias
398	delay
399}
400
401testtx_icmp6_gateway()
402{
403
404	testtx_ulp6_gateway "testtx_icmp6_gateway" "TCP6"
405}
406
407testtx_tcp6_gateway()
408{
409
410	testtx_ulp6_gateway "testtx_tcp6_gateway" "TCP6"
411}
412
413testtx_udp6_gateway()
414{
415
416	testtx_ulp6_gateway "testtx_udp6_gateway" "UDP6"
417}
418
419################################################################################
420#
421testtx_ulp6_transfernets_gateways()
422{
423	local _opts fib _n _o
424	_n="$1"
425	_o="$2"
426
427	_opts=""
428	case ${DEBUG} in
429	''|0)	;;
430	42)	_opts="-d -d" ;;
431	*)	_opts="-d" ;;
432	esac
433
434	# Setup transfer networks.
435	fib=0
436	while test ${fib} -lt ${RT_NUMFIBS}; do
437		setfib -F${fib} \
438		    ifconfig ${IFACE} inet6 2001:2:${fib}::2/64 alias
439		fib=$((fib + 1))
440	done
441
442	# Setup out listener IP.
443	ifconfig lo0 inet6 2001:2:ff01::2 -alias > /dev/null 2>&1 || true
444	delay
445	ifconfig lo0 inet6 2001:2:ff01::2 alias
446
447	# Reflect requests.
448	print_debug "./reflect -p ${CTRLPORT} -T ${_o} " \
449	    "-t ${_n} ${_opts} -A 2001:2:ff01::2"
450	./reflect -p ${CTRLPORT} -T ${_o} \
451	    -t ${_n} ${_opts} -A 2001:2:ff01::2
452	print_debug "reflect terminated without error."
453
454	# Cleanup transfer networks and listener IP.
455	fib=0
456	while test ${fib} -lt ${RT_NUMFIBS}; do
457		setfib -F${fib} \
458		    ifconfig ${IFACE} inet6 2001:2:${fib}::2/64 -alias
459		delay
460		fib=$((fib + 1))
461	done
462	ifconfig lo0 inet6 2001:2:ff01::2 -alias
463}
464
465testtx_icmp6_transfernets_gateways()
466{
467
468	testtx_ulp6_transfernets_gateways \
469	    "testtx_icmp6_transfernets_gateways" "TCP6"
470}
471
472testtx_tcp6_transfernets_gateways()
473{
474
475	testtx_ulp6_transfernets_gateways \
476	    "testtx_tcp6_transfernets_gateways" "TCP6"
477}
478
479testtx_udp6_transfernets_gateways()
480{
481
482	testtx_ulp6_transfernets_gateways \
483	    "testtx_udp6_transfernets_gateways" "UDP6"
484}
485
486
487################################################################################
488#
489testtx_ulp6_transfernets_gateway()
490{
491	local _opts fib _n _o
492	_n="$1"
493	_o="$2"
494
495	_opts=""
496	case ${DEBUG} in
497	''|0)	;;
498	42)	_opts="-d -d" ;;
499	*)	_opts="-d" ;;
500	esac
501
502	# Setup transfer networks.
503	fib=0
504	while test ${fib} -lt ${RT_NUMFIBS}; do
505		setfib -F${fib} \
506		    ifconfig ${IFACE} inet6 2001:2:${fib}::2/64 alias
507		fib=$((fib + 1))
508	done
509
510	# Setup out listener IP.
511	ifconfig lo0 inet6 2001:2:ff01::2 -alias > /dev/null 2>&1 || true
512	delay
513	ifconfig lo0 inet6 2001:2:ff01::2 alias
514
515	# Reflect requests.
516	fib=0
517	while test ${fib} -lt ${RT_NUMFIBS}; do
518		print_debug "./reflect -p ${CTRLPORT} -T ${_o} " \
519		    "-t ${_n}${fib} ${_opts} -A 2001:2:ff01::2"
520		./reflect -p ${CTRLPORT} -T ${_o} \
521		    -t ${_n}${fib} ${_opts} -A 2001:2:ff01::2
522		print_debug "reflect terminated without error."
523		fib=$((fib + 1))
524	done
525
526	# Cleanup transfer networks and listener IP.
527	fib=0
528	while test ${fib} -lt ${RT_NUMFIBS}; do
529		setfib -F${fib} \
530		    ifconfig ${IFACE} inet6 2001:2:${fib}::2/64 -alias
531		delay
532		fib=$((fib + 1))
533	done
534	ifconfig lo0 inet6 2001:2:ff01::2 -alias
535}
536
537testtx_icmp6_transfernets_gateway()
538{
539
540	testtx_ulp6_transfernets_gateway \
541	    "testtx_icmp6_transfernets_gateway" "TCP6"
542}
543
544testtx_tcp6_transfernets_gateway()
545{
546
547	testtx_ulp6_transfernets_gateway \
548	    "testtx_tcp6_transfernets_gateway" "TCP6"
549}
550
551testtx_udp6_transfernets_gateway()
552{
553
554	testtx_ulp6_transfernets_gateway \
555	    "testtx_udp6_transfernets_gateway" "UDP6"
556}
557
558################################################################################
559#
560# We are receiver, but the FIBs are with us this time.
561#
562#
563
564#       # For IPFW, IFCONFIG
565#       #   For each FIB
566#       #     Send OOB well known to work START, wait for reflect
567#       #     Send probe, wait for reply with FIB# or RST/ICMP6 unreach
568#       #       (in case of ICMP6 use magic like ipfw count and OOB reply)
569#       #     Send OOB well known to work DONE, wait for reflect
570#       #     Compare real with expected results.
571#
572
573textrx_ipfw_setup()
574{
575	local _fib _transfer i _p _o
576	_fib=$1
577	_transfer=$2
578
579	# ICMP6 would need content inspection to distinguish FIB, we can
580	# only differentiate by address.
581	# For the default single-address cases always set to current FIB.
582	ipfw add 100 setfib ${_fib} ipv6-icmp \
583	    from ${PEERADDR} to ${OURADDR} \
584	    via ${IFACE} in > /dev/null 2>&1
585	ipfw add 100 setfib ${_fib} ipv6-icmp \
586	    from ${PEERLINKLOCAL%\%*} to ${OURLINKLOCAL%\%*} \
587	    via ${IFACE} in > /dev/null 2>&1
588
589	# Always also do a setfib for the control port so that OOB
590	# signaling workes even if we remove connected subnets.
591	ipfw add 200 setfib ${_fib} ip6 from ${PEERADDR} to ${OURADDR} \
592	    dst-port ${CTRLPORT} via ${IFACE} in > /dev/null 2>&1
593
594	# Save addresses
595	_p="${PEERADDR}"
596	_o="${OURADDR}"
597
598	i=0
599	while test ${i} -lt ${RT_NUMFIBS}; do
600
601		# If doing multiple transfer networks, replace PEERADDR.
602		case ${_transfer} in
603		1)	PEERADDR=2001:2:${i}::1
604			OURADDR=2001:2:${i}::2
605			;;
606		esac
607
608		if test ${_instances} -gt 1 -o ${_transfer} -eq 1; then
609			ipfw add 400 setfib ${_fib} ipv6-icmp \
610			    from ${PEERADDR} to ${OURADDR} \
611			    icmp6types 128 \
612			    via ${IFACE} in > /dev/null 2>&1
613		fi
614
615		case ${i} in
616		${_fib})
617			ipfw add 400 setfib ${_fib} ip6 \
618			    from ${PEERADDR} to ${OURADDR} \
619			    dst-port $((CTRLPORT + 1000 + i)) \
620			    via ${IFACE} in > /dev/null 2>&1
621			ipfw add 400 setfib ${_fib} ip6 \
622			    from ${PEERLINKLOCAL%\%*} to ${OURLINKLOCAL%\%*} \
623			    dst-port $((CTRLPORT + 1000 + i)) \
624			    via ${IFACE} in > /dev/null 2>&1
625			if test ${_instances} -le 1 -o ${_transfer} -ne 1; then
626				ipfw add 400 setfib ${_fib} ipv6-icmp \
627				    from ${PEERADDR} to ${OURADDR} \
628				    icmp6types 128 \
629				    via ${IFACE} in > /dev/null 2>&1
630			fi
631			;;
632		esac
633
634		i=$((i + 1))
635	done
636
637	# Restore addresses.
638	PEERADDR="${_p}"
639	OURADDR="${_o}"
640
641	case ${DEBUG} in
642	''|0)	;;
643	*)	ipfw show ;;
644	esac
645}
646
647textrx_ifconfig_setup()
648{
649	local _fib
650	_fib=$1
651
652	ifconfig ${IFACE} fib ${_fib} > /dev/null 2>&1
653}
654
655textrx_ipfw_cleanup()
656{
657	local i
658
659	case ${DEBUG} in
660	''|0)	;;
661	*)	ipfw show ;;
662	esac
663
664	ipfw delete 100 > /dev/null 2>&1 || true
665	ipfw delete 200 > /dev/null 2>&1 || true
666	ipfw delete 400 > /dev/null 2>&1 || true
667
668	i=0
669	while test ${i} -lt ${RT_NUMFIBS}; do
670
671		ipfw delete $((1000 + i)) > /dev/null 2>&1 || true
672		i=$((i + 1))
673	done
674}
675
676textrx_ifconfig_cleanup()
677{
678
679	ifconfig ${IFACE} fib 0 > /dev/null 2>&1
680}
681
682textrx_count_setup()
683{
684	local i
685
686	i=0
687	while test ${i} -lt ${RT_NUMFIBS}; do
688
689		# Count ICMP6 echo replies.
690		ipfw add $((500 + i)) count ipv6-icmp from any to any \
691		    icmp6types 129 fib ${i} via ${IFACE} out > /dev/null 2>&1
692		ipfw add $((500 + i)) count tcp from any to any \
693		    fib ${i} via ${IFACE} out > /dev/null 2>&1
694		ipfw add $((500 + i)) count udp from any to any \
695		    fib ${i} via ${IFACE} out > /dev/null 2>&1
696		i=$((i + 1))
697	done
698}
699
700textrx_count_results()
701{
702	local _fib _o i _rstr _c _req _p _opts
703	_fib=$1
704	_o="$2"
705
706	case ${DEBUG} in
707	''|0)	;;
708	*)	ipfw show ;;
709	esac
710
711	_rstr=""
712	i=0
713	while test ${i} -lt ${RT_NUMFIBS}; do
714
715		case "${_o}" in
716		"-i")	_c=`ipfw show $((500 + i)) | awk '/ ipv6-icmp / { print $2 }'` ;;
717		"-u")	_c=`ipfw show $((500 + i)) | awk '/ udp / { print $2 }'` ;;
718		*)	_c=`ipfw show $((500 + i)) | awk '/ tcp / { print $2 }'` ;;
719		esac
720		_rstr="${_rstr}${i} ${_c},"
721
722		ipfw delete $((500 + i)) > /dev/null 2>&1 || true
723		i=$((i + 1))
724	done
725
726	# We do not care about the request.
727	_req=`echo "RESULT ${_rstr}" | nc -V ${_fib} -6 -l ${CTRLPORT}`
728	print_debug "$? -- ${_req} -- RESULT ${_rstr}"
729}
730
731testrx_remove_connected()
732{
733	local _fib _transfer i j _prefix
734	_fib=$1
735	_transfer=$2
736
737	if test ${_transfer} -eq 1; then
738		i=0
739		while test ${i} -lt ${RT_NUMFIBS}; do
740			j=0
741			while test ${j} -lt ${RT_NUMFIBS}; do
742				_prefix="2001:2:${j}::"
743
744				case ${j} in
745				${_fib});;
746				*)	print_debug "setfib -F${i} route delete" \
747					    "-inet6 -net ${_prefix}"
748					setfib -F${i} route delete -inet6 -net \
749					    ${_prefix} > /dev/null 2>&1
750					;;
751				esac
752				j=$((j + 1))
753			done
754			i=$((i + 1))
755		done
756
757	else
758		_prefix=${OURADDR%2}	# Luckily we know the details.
759		i=0
760		while test ${i} -lt ${RT_NUMFIBS}; do
761
762			case ${i} in
763			${_fib});;
764			*)	print_debug "setfib -F${i} route delete" \
765				    "-inet6 -net ${_prefix}"
766				setfib -F${i} route delete -inet6 -net \
767				    ${_prefix} > /dev/null 2>&1
768				;;
769			esac
770
771			i=$((i + 1))
772		done
773	fi
774}
775
776testrx_cleanup_connected()
777{
778	local _fib _transfer i _prefix
779	_fib=$1
780	_transfer=$2
781
782	if test ${_transfer} -eq 1; then
783
784		i=0
785		while test ${i} -lt ${RT_NUMFIBS}; do
786			setfib -F${i} \
787			   ifconfig ${IFACE} inet6 2001:2:${i}::2/64 -alias \
788			    > /dev/null 2>&1
789			delay
790			i=$((i + 1))
791		done
792
793	else
794		# Use the hammer removing the address and adding it again to get
795		# the connected subnet back to all FIBs.  Hard to do otherwise.
796		ifconfig ${IFACE} inet6 ${OURADDR}/64 -alias || true
797		delay
798		ifconfig ${IFACE} inet6 ${OURADDR}/64 alias up
799	fi
800}
801
802testrx_setup_transfer_networks()
803{
804	local i
805
806	i=0
807	while test ${i} -lt ${RT_NUMFIBS}; do
808		ifconfig ${IFACE} inet6 2001:2:${i}::2/64 -alias \
809		    > /dev/null 2>&1 || true
810		delay
811		ifconfig ${IFACE} inet6 2001:2:${i}::2/64 alias
812		i=$((i + 1))
813	done
814}
815
816testrx_run_one()
817{
818	local _fib _txt _opts
819	_fib=$1
820	_txt="$2"
821	_opts="$3"
822
823	case ${USE_SOSETFIB} in
824	0)	print_debug "setfib -F${_fib} ./reflect -p ${CTRLPORT}" \
825		    "-t ${_txt} ${_opts}"
826		setfib -F${_fib} ./reflect -p ${CTRLPORT} -t ${_txt} ${_opts}
827		;;
828	1)	print_debug "./reflect -F${_fib} -p ${CTRLPORT} -t ${_txt}" \
829		    "${_opts}"
830		./reflect -F${_fib} -p ${CTRLPORT} -t ${_txt} ${_opts}
831		;;
832	*)	die "Invalid value for USE_SOSETFIB: ${USE_SOSETFIB}" ;;
833	esac
834	print_debug "reflect '${_txt}' terminated without error."
835}
836
837testrx_run_multiple()
838{
839	local _fib _txt _opts i _jobs _p _w
840	_fib=$1
841	_txt="$2"
842	_opts="$3"
843
844	i=0
845	_jobs=""
846	while test ${i} -lt ${RT_NUMFIBS}; do
847		case ${USE_SOSETFIB} in
848		0)	print_debug "setfib -F${i} ./reflect" \
849			    "-p $((CTRLPORT + 1000 + i))" \
850			    "-t ${_txt} ${_opts} -N -f ${i} &"
851			setfib -F${i} ./reflect -p $((CTRLPORT + 1000 + i)) \
852			    -t ${_txt} ${_opts} -N -f ${i} &
853			;;
854		1)	print_debug "./reflect -F ${i}" \
855			    "-p $((CTRLPORT + 1000 + i))" \
856			    "-t ${_txt} ${_opts} -N -f ${i} &"
857			./reflect -F ${i} -p $((CTRLPORT + 1000 + i)) \
858			    -t ${_txt} ${_opts} -N -f ${i} &
859			;;
860		*)	die "Invalid value for USE_SOSETFIB: ${USE_SOSETFIB}" ;;
861		esac
862		_p=$!
863		_jobs="${_jobs}${_p} "
864		case ${i} in
865		${_fib}) _w=${_p} ;;
866		esac
867		i=$((i + 1))
868	done
869
870	# Start OOB control connection for START/DONE.
871	testrx_run_one ${_fib} "${_txt}" "${_opts}"
872	print_debug "KILL ${_jobs}"
873	for i in ${_jobs}; do
874		kill ${i} || true
875	done
876	#killall reflect || true
877	print_debug "reflects for '${_txt}' terminated without error."
878}
879
880testrx_run_test()
881{
882	local _n _t _fib _o _txt i _f _instance _destructive _transfer
883	_n="$1"
884	_t="$2"
885	_fib=$3
886	_o="$4"
887	_instances=$5
888	_destructive=$6
889	_transfer=$7
890
891	: ${_destructive:=0}
892
893	_opts=""
894	case ${DEBUG} in
895	''|0)	;;
896	42)	_opts="-d -d" ;;
897	*)	_opts="-d" ;;
898	esac
899
900	# Convert netcat options to reflect aguments.
901	case "${_o}" in
902	-i)	_opts="${_opts} -T TCP6" ;;	# Use TCP for START/DONE.
903	-u)	_opts="${_opts} -T UDP6" ;;
904	*)	_opts="${_opts} -T TCP6" ;;
905	esac
906
907	# Combined test case base name.
908	case ${USE_SOSETFIB} in
909	0)	_f="setfib" ;;
910	1)	_f="so_setfib" ;;
911	*)	die "Unexpected value for SO_SETFIB: ${SO_SETFIB}" ;;
912	esac
913
914        _txt="${_n}_${_f}_${_t}_${_fib}_${_instances}_${_destructive}_${_transfer}"
915
916	case ${_transfer} in
917	1)	testrx_setup_transfer_networks ;;
918	esac
919
920	case "${_t}" in
921	ipfw)		textrx_ipfw_setup ${_fib} ${_transfer} ${_instances} ;;
922	ifconfig)	textrx_ifconfig_setup ${_fib} ;;
923	*)		die "Invalid type in ${_txt}" ;;
924	esac
925
926	# Setup unresponsive FIBs.
927	case ${_destructive} in
928	1)	testrx_remove_connected ${_fib} ${_transfer} ;;
929	esac
930
931	# Setup to get result counts.
932	textrx_count_setup
933
934	# Run just one / one per FIB (with incremental ports).
935	#case ${_instances} in
936	#1)	testrx_run_one ${_fib} "${_txt}" "${_opts}" ;;
937	#*)	testrx_run_multiple ${_fib} "${_txt}" "${_opts}" ;;
938	#esac
939	testrx_run_multiple ${_fib} "${_txt}" "${_opts}" ${_transfer}
940
941	# Export result counts.
942	textrx_count_results ${_fib} "${_o}"
943
944	# Cleanup unresponsive  FIBs or multiple prefixes.
945	if test ${_destructive} -eq 1 -o ${_transfer} -eq 1; then
946		testrx_cleanup_connected ${_fib} ${_transfer}
947	fi
948
949	case "${_t}" in
950	ipfw)		textrx_ipfw_cleanup ;;
951	ifconfig)	textrx_ifconfig_cleanup ;;
952	*)		die "Invalid type in ${_txt}" ;;
953	esac
954}
955
956testrx_main()
957{
958	local _n _o s t fib _instances _destructive
959	_n="$1"
960	_o="$2"
961	_instances=$3
962
963	: ${_instances:=1}
964
965	print_debug "${_n}"
966	for _transfer in 1 0; do
967		for _destructive in 0 1; do
968			for t in ipfw ifconfig; do
969
970				print_debug "${_n}_${t}"
971				fib=0
972				while test ${fib} -lt ${RT_NUMFIBS}; do
973
974					print_debug "${_n}_${t}_${fib}" \
975					    "${_instances} ${_destructive}" \
976					    "${_transfer}"
977					testrx_run_test "${_n}" "${t}" ${fib} \
978					   "${_o}" ${_instances} \
979					   ${_destructive} ${_transfer}
980
981					fib=$((fib + 1))
982				done
983			done
984		done
985	done
986}
987
988################################################################################
989#
990# Probe all FIBs with one "active" one a time.
991#
992testrx_icmp6_same_addr_one_fib_a_time()
993{
994
995	testrx_main "testrx_icmp6_same_addr_one_fib_a_time" "-i"
996}
997
998testrx_tcp6_same_addr_one_fib_a_time()
999{
1000
1001	testrx_main "testrx_tcp6_same_addr_one_fib_a_time" ""
1002}
1003
1004testrx_udp6_same_addr_one_fib_a_time()
1005{
1006
1007	testrx_main "testrx_udp6_same_addr_one_fib_a_time" "-u"
1008}
1009
1010################################################################################
1011#
1012# Probe all FIBs with all "active" all time.
1013#
1014testrx_tcp6_same_addr_all_fibs_a_time()
1015{
1016
1017	testrx_main "testrx_tcp6_same_addr_all_fibs_a_time" "" ${RT_NUMFIBS}
1018}
1019
1020testrx_udp6_same_addr_all_fibs_a_time()
1021{
1022
1023	testrx_main "testrx_udp6_same_addr_all_fibs_a_time" "-u" ${RT_NUMFIBS}
1024}
1025
1026
1027################################################################################
1028#
1029# Prereqs.
1030#
1031if test `sysctl -n security.jail.jailed` -eq 0; then
1032	kldload ipfw > /dev/null 2>&1 || kldstat -v | grep -q ipfw
1033fi
1034ipfw -f flush > /dev/null 2>&1 || die "please load ipfw in base system"
1035ipfw add 65000 permit ip from any to any > /dev/null 2>&1
1036killall reflect || true
1037
1038################################################################################
1039#
1040# Run tests.
1041#
1042wait_remote_ready
1043
1044# We are receiver reflecting the input back.
1045for uso in 0 1; do
1046
1047	# Only run ICMP6 tests for the first loop.
1048	test ${uso} -ne 0 || testtx_icmp6_connected
1049	testtx_tcp6_connected
1050	testtx_udp6_connected
1051
1052	test ${uso} -ne 0 || testtx_icmp6_connected_blackhole
1053	testtx_tcp6_connected_blackhole
1054	testtx_udp6_connected_blackhole
1055
1056	test ${uso} -ne 0 || testtx_icmp6_connected_transfernets
1057	testtx_tcp6_connected_transfernets
1058	testtx_udp6_connected_transfernets
1059
1060	test ${uso} -ne 0 || testtx_icmp6_connected_ifconfig_transfernets
1061	testtx_tcp6_connected_ifconfig_transfernets
1062	testtx_udp6_connected_ifconfig_transfernets
1063
1064	test ${uso} -ne 0 || testtx_icmp6_gateway
1065	testtx_tcp6_gateway
1066	testtx_udp6_gateway
1067
1068	test ${uso} -ne 0 || testtx_icmp6_transfernets_gateways
1069	testtx_tcp6_transfernets_gateways
1070	testtx_udp6_transfernets_gateways
1071
1072	test ${uso} -ne 0 || testtx_icmp6_transfernets_gateway
1073	testtx_tcp6_transfernets_gateway
1074	testtx_udp6_transfernets_gateway
1075done
1076
1077ipfw -f flush > /dev/null 2>&1
1078ipfw add 65000 permit ip from any to any > /dev/null 2>&1
1079
1080# We are receiver, but the FIBs are with us this time.
1081for uso in 0 1; do
1082
1083	USE_SOSETFIB=${uso}
1084
1085	# Only expect ICMP6 tests for the first loop.
1086	test ${uso} -ne 0 || testrx_icmp6_same_addr_one_fib_a_time
1087	testrx_tcp6_same_addr_one_fib_a_time
1088	testrx_udp6_same_addr_one_fib_a_time
1089
1090	testrx_tcp6_same_addr_all_fibs_a_time
1091	testrx_udp6_same_addr_all_fibs_a_time
1092
1093done
1094
1095cleanup
1096
1097# end
1098