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