1231858Sbz#!/bin/sh
2231858Sbz#-
3231858Sbz# Copyright (c) 2012 Cisco Systems, Inc.
4231858Sbz# All rights reserved.
5231858Sbz#
6231858Sbz# This software was developed by Bjoern Zeeb under contract to
7231858Sbz# Cisco Systems, Inc..
8231858Sbz#
9231858Sbz# Redistribution and use in source and binary forms, with or without
10231858Sbz# modification, are permitted provided that the following conditions
11231858Sbz# are met:
12231858Sbz# 1. Redistributions of source code must retain the above copyright
13231858Sbz#    notice, this list of conditions and the following disclaimer.
14231858Sbz# 2. Redistributions in binary form must reproduce the above copyright
15231858Sbz#    notice, this list of conditions and the following disclaimer in the
16231858Sbz#    documentation and/or other materials provided with the distribution.
17231858Sbz#
18231858Sbz# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19231858Sbz# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20231858Sbz# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21231858Sbz# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22231858Sbz# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23231858Sbz# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24231858Sbz# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25231858Sbz# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26231858Sbz# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27231858Sbz# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28231858Sbz# SUCH DAMAGE.
29231858Sbz#
30231858Sbz# $FreeBSD: releng/10.3/tools/test/netfibs/forwarding.sh 232114 2012-02-24 14:13:06Z bz $
31231858Sbz#
32231858Sbz
33231858Sbz# Test setup:
34231858Sbz#
35231858Sbz#  left ------------------------- middle ------------------------- right
36231858Sbz#    IFACE                     IFACE  IFACEFAR                  IFACE
37231858Sbz#    LEFTADDR         MIDDLELEFTADDR  MIDDLERIGHTADDR       RIGHTADDR
38231858Sbz#                               forwarding=1
39231858Sbz#    initiator                   FIB tests                  reflector
40231858Sbz
41231858Sbz# We will use the RFC5180 (and Errata) benchmarking working group prefix
42231858Sbz# 2001:0002::/48 for testing.
43231858SbzPREFIX="2001:2:"
44231858Sbz
45231858Sbz# Set IFACE to the real interface you want to run the test on.
46231858Sbz# IFACEFAR is only relevant on the middle (forwarding) node and will be the
47231858Sbz# 'right' side (far end) one.
48231858Sbz: ${IFACE:=lo0}
49231858Sbz: ${IFACEFAR:=lo0}
50231858Sbz
51231858Sbz# Number of seconds to wait for peer node to synchronize for test.
52231858Sbz: ${WAITS:=120}
53231858Sbz
54231858Sbz# Control port we use to exchange messages between nodes to sync. tests, etc.
55231858Sbz: ${CTRLPORT:=6666}
56231858Sbz
57231858Sbz# Get the number of FIBs from the kernel.
58231858SbzRT_NUMFIBS=`sysctl -n net.fibs`
59231858Sbz
60231858Sbz# This is the initiator and connected middle node.
61231858SbzLEFTADDR="2001:2:fe00::1"
62231858SbzMIDDLELEFTADDR="2001:2:fe00::2"
63231858Sbz# This is the far end middle node and receiver side.
64231858SbzMIDDLERIGHTADDR="2001:2:ff00::1"
65231858SbzRIGHTADDR="2001:2:ff00::2"
66231858Sbz
67231858Sbz# By default all commands must succeed.  Individual tests may disable this
68231858Sbz# temporary.
69231858Sbzset -e
70231858Sbz
71231858Sbz# Debug magic.
72231858Sbzcase "${DEBUG}" in
73231858Sbz42)	set -x ;;
74231858Sbzesac
75231858Sbz
76231858Sbz
77231858Sbz################################################################################
78231858Sbz#
79231858Sbz# Input validation.
80231858Sbz#
81231858Sbz
82231858Sbznode=$1
83231858Sbzcase ${node} in
84231858Sbzleft)	;;
85231858Sbzmiddle)	;;
86231858Sbzright)	;;
87231858Sbz*)	echo "ERROR: invalid node name '${node}'. Must be left, middle or" \
88231858Sbz	    " right" >&1
89231858Sbz	exit 1
90231858Sbz	;;
91231858Sbzesac
92231858Sbz
93231858Sbz################################################################################
94231858Sbz#
95231858Sbz# Helper functions.
96231858Sbz#
97231858Sbzcheck_rc()
98231858Sbz{
99231858Sbz	local _rc _exp _testno _testname _msg _r
100231858Sbz	_rc=$1
101231858Sbz	_exp=$2
102231858Sbz	_testno=$3
103231858Sbz	_testname="$4"
104231858Sbz	_msg="$5"
105231858Sbz
106231858Sbz	_r="not ok"
107231858Sbz	if test ${_rc} -eq ${_exp}; then
108231858Sbz		_r="ok"
109231858Sbz	fi
110231858Sbz	echo "${_r} ${_testno} ${_testname} # ${_msg} ${_rc} ${_exp}"
111231858Sbz}
112231858Sbz
113231858Sbzprint_debug()
114231858Sbz{
115231858Sbz	local _msg
116231858Sbz	_msg="$*"
117231858Sbz
118231858Sbz	case ${DEBUG} in
119231858Sbz	''|0)	;;
120231858Sbz	*)	echo "DEBUG: ${_msg}" >&2 ;;
121231858Sbz	esac
122231858Sbz}
123231858Sbz
124231858Sbzdie()
125231858Sbz{
126231858Sbz	local _msg
127231858Sbz	_msg="$*"
128231858Sbz
129231858Sbz	echo "ERROR: ${_msg}" >&2
130231858Sbz	exit 1
131231858Sbz}
132231858Sbz
133231858Sbz
134231858Sbz################################################################################
135231858Sbz#
136231858Sbz# Functions to configure networking and do a basic reachability check.
137231858Sbz#
138231858Sbz
139231858Sbzsetup_networking()
140231858Sbz{
141231858Sbz
142231858Sbz	print_debug "Setting up networking"
143231858Sbz	case ${node} in
144231858Sbz	left)	ifconfig ${IFACE} inet6 ${LEFTADDR}/64 -alias \
145231858Sbz		    > /dev/null 2>&1 || true
146231858Sbz		ifconfig ${IFACE} inet6 ${LEFTADDR}/64 alias up
147231858Sbz		ifconfig ${IFACE} fib 0
148231858Sbz		sysctl net.inet6.ip6.forwarding=0 > /dev/null
149231858Sbz		route delete -net -inet6 default > /dev/null 2>&1 || true
150231858Sbz		route delete -host -inet6 ${RIGHTADDR} ${MIDDLELEFTADDR} \
151231858Sbz		    > /dev/null 2>&1 || true
152231858Sbz		route add -host -inet6 ${RIGHTADDR} ${MIDDLELEFTADDR} \
153231858Sbz		    > /dev/null
154231858Sbz		route delete -host -inet6 ${MIDDLERIGHTADDR} ${MIDDLELEFTADDR} \
155231858Sbz		    > /dev/null 2>&1 || true
156231858Sbz		route add -host -inet6 ${MIDDLERIGHTADDR} ${MIDDLELEFTADDR} \
157231858Sbz		    > /dev/null 2>&1 || true
158231858Sbz		;;
159231858Sbz	middle)	ifconfig ${IFACE} inet6 ${MIDDLELEFTADDR}/64 -alias \
160231858Sbz		    > /dev/null 2>&1 || true
161231858Sbz		ifconfig ${IFACE} inet6 ${MIDDLELEFTADDR}/64 alias up
162231858Sbz		ifconfig ${IFACE} fib 0
163231858Sbz		ifconfig ${IFACEFAR} inet6 ${MIDDLERIGHTADDR}/64 -alias \
164231858Sbz		    > /dev/null 2>&1 || true
165231858Sbz		ifconfig ${IFACEFAR} inet6 ${MIDDLERIGHTADDR}/64 alias up
166231858Sbz		ifconfig ${IFACEFAR} fib 0
167231858Sbz		sysctl net.inet6.ip6.forwarding=1 > /dev/null
168231858Sbz		;;
169231858Sbz	right)	ifconfig ${IFACE} inet6 ${RIGHTADDR}/64 -alias \
170231858Sbz		    > /dev/null 2>&1 || true
171231858Sbz		ifconfig ${IFACE} inet6 ${RIGHTADDR}/64 alias up
172231858Sbz		ifconfig ${IFACE} fib 0
173231858Sbz		sysctl net.inet6.ip6.forwarding=0 > /dev/null
174231858Sbz		route delete -net -inet6 default > /dev/null 2>&1 || true
175231858Sbz		route delete -host -inet6 ${LEFTADDR} ${MIDDLERIGHTADDR} \
176231858Sbz		    > /dev/null 2>&1 || true
177231858Sbz		route add -host -inet6 ${LEFTADDR} ${MIDDLERIGHTADDR} \
178231858Sbz		    > /dev/null
179231858Sbz		route delete -host -inet6 ${MIDDLELEFTADDR} ${MIDDLERIGHTADDR} \
180231858Sbz		    > /dev/null 2>&1 || true
181231858Sbz		route add -host -inet6 ${MIDDLELEFTADDR} ${MIDDLERIGHTADDR} \
182231858Sbz		    > /dev/null
183231858Sbz		;;
184231858Sbz	esac
185231858Sbz
186231858Sbz	# Let things settle.
187231858Sbz	print_debug "Waiting 4 seconds for things to settle"
188231858Sbz	sleep 4
189231858Sbz}
190231858Sbz
191231858Sbzcleanup_networking()
192231858Sbz{
193231858Sbz
194231858Sbz	case ${node} in
195231858Sbz	left)	ifconfig ${IFACE} inet6 ${LEFTADDR}/64 -alias
196231858Sbz		;;
197231858Sbz	middle)	ifconfig ${IFACE} inet6 ${MIDDLELEFTADDR}/64 -alias
198231858Sbz		ifconfig ${IFACEFAR} inet6 ${MIDDLERIGHTADDR}/64 -alias
199231858Sbz		sysctl net.inet6.ip6.forwarding=0 > /dev/null
200231858Sbz		;;
201231858Sbz	right)	ifconfig ${IFACE} inet6 ${RIGHTADDR}/64 -alias
202231858Sbz		;;
203231858Sbz	esac
204231858Sbz	print_debug "Cleaned up networking"
205231858Sbz}
206231858Sbz
207231858Sbz_reachability_check()
208231858Sbz{
209231858Sbz	local _addr _rc
210231858Sbz	_addr="$1"
211231858Sbz
212231858Sbz	ping6 -n -c1 ${_addr} > /dev/null 2>&1
213231858Sbz	_rc=$?
214231858Sbz	case ${_rc} in
215231858Sbz	0)	;;
216231858Sbz	*)	print_debug "cannot ping6 ${_addr}, rc=${_rc}"
217231858Sbz		return 1
218231858Sbz		;;
219231858Sbz	esac
220231858Sbz	return 0
221231858Sbz}
222231858Sbz
223231858Sbzreachability_check()
224231858Sbz{
225232114Sbz	local _i rc
226231858Sbz
227231858Sbz	# Try to reach all control addresses on other nodes.
228231858Sbz	# We need to loop for a while as we cannot expect all to be up
229231858Sbz	# the very same moment.
230231858Sbz	i=1
231232114Sbz	rc=42
232232114Sbz	while test ${rc} -ne 0 -a ${i} -le ${WAITS}; do
233231858Sbz		print_debug "${i}/${WAITS} trying to ping6 control addresses."
234232114Sbz		rc=0
235231858Sbz		set +e
236231858Sbz		case ${node} in
237231858Sbz		left)	_reachability_check ${MIDDLELEFTADDR}
238232114Sbz			rc=$((rc + $?))
239231858Sbz			_reachability_check ${MIDDLERIGHTADDR}
240232114Sbz			rc=$((rc + $?))
241231858Sbz			_reachability_check ${RIGHTADDR}
242232114Sbz			rc=$((rc + $?))
243231858Sbz			;;
244231858Sbz		middle)	_reachability_check ${LEFTADDR}
245232114Sbz			rc=$((rc + $?))
246231858Sbz			_reachability_check ${RIGHTADDR}
247232114Sbz			rc=$((rc + $?))
248231858Sbz			;;
249231858Sbz		right)	_reachability_check ${MIDDLERIGHTADDR}
250232114Sbz			rc=$((rc + $?))
251231858Sbz			_reachability_check ${MIDDLELEFTADDR}
252232114Sbz			rc=$((rc + $?))
253231858Sbz			_reachability_check ${LEFTADDR}
254232114Sbz			rc=$((rc + $?))
255231858Sbz			;;
256231858Sbz		esac
257231858Sbz		set -e
258231858Sbz		sleep 1
259231858Sbz		i=$((i + 1))
260231858Sbz	done
261231858Sbz}
262231858Sbz
263231858Sbz################################################################################
264231858Sbz#
265231858Sbz# "Greeting" handling to sync notes to the agreed upon next test case.
266231858Sbz#
267231858Sbzsend_control_msg()
268231858Sbz{
269231858Sbz        local _case _addr i rc _msg _keyword _fibs
270231858Sbz	_case="$1"
271231858Sbz	_addr="$2"
272231858Sbz
273231858Sbz	set +e
274231858Sbz	i=0
275231858Sbz	rc=-1
276231858Sbz	while test ${i} -lt ${WAITS} -a ${rc} -ne 0; do
277231858Sbz		print_debug "Sending control msg #${i} to peer ${_addr}"
278231858Sbz		_msg=`echo "${_case} ${RT_NUMFIBS}" | \
279231858Sbz		    nc -6 -w 1 ${_addr} ${CTRLPORT}`
280231858Sbz		rc=$?
281231858Sbz		i=$((i + 1))
282231858Sbz		# Might sleep longer in total but better than to DoS
283231858Sbz		# and not get anywhere.
284231858Sbz		sleep 1
285231858Sbz	done
286231858Sbz	set -e
287231858Sbz
288231858Sbz	read _keyword _fibs <<EOI
289231858Sbz${_msg}
290231858SbzEOI
291231858Sbz	print_debug "_keyword=${_keyword}"
292231858Sbz	print_debug "_fibs=${_fibs}"
293231858Sbz	case ${_keyword} in
294231858Sbz	${_case});;
295231858Sbz	*)	die "Got invalid keyword from ${_addr} in control message:" \
296231858Sbz		    "${_msg}"
297231858Sbz	;;
298231858Sbz	esac
299231858Sbz	if test ${_fibs} -ne ${RT_NUMFIBS}; then
300231858Sbz		die "Number of FIBs not matching ours (${RT_NUMFIBS}) in" \
301231858Sbz		    "control message from ${_addr}: ${_msg}"
302231858Sbz	fi
303231858Sbz
304231858Sbz	print_debug "Successfully exchanged control message with ${_addr}."
305231858Sbz}
306231858Sbz
307231858Sbzsend_control_msgs()
308231858Sbz{
309231858Sbz	local _case _addr
310231858Sbz	_case="$1"
311231858Sbz	
312231858Sbz	# Always start with the far end.  Otherwise we will cut that off when
313231858Sbz	# cleanly taering down things again.
314231858Sbz	for _addr in ${RIGHTADDR} ${MIDDLELEFTADDR}; do
315231858Sbz		send_control_msg "${_case}" ${_addr}
316231858Sbz	done
317231858Sbz
318231858Sbz	# Allow us to flush ipfw counters etc before new packets will arrive.
319231858Sbz	sleep 1
320231858Sbz}
321231858Sbz
322231858Sbz# We are setup.  Wait for the initiator to tell us that it is ready.
323231858Sbzwait_remote_ready()
324231858Sbz{
325231858Sbz        local _case _msg _keyword _fibs
326231858Sbz	_case="$1"
327231858Sbz
328231858Sbz	# Wait for the remote to connect and start things.
329231858Sbz	# We tell it the magic keyword, and our number of FIBs.
330231858Sbz	_msg=`echo "${_case} ${RT_NUMFIBS}" | nc -6 -l ${CTRLPORT}`
331231858Sbz
332231858Sbz	read _keyword _fibs <<EOI
333231858Sbz${_msg}
334231858SbzEOI
335231858Sbz	print_debug "_keyword=${_keyword}"
336231858Sbz	print_debug "_fibs=${_fibs}"
337231858Sbz	case ${_keyword} in
338231858Sbz	${_case});;
339231858Sbz	*)	die "Got invalid keyword in control message: ${_msg}"
340231858Sbz		;;
341231858Sbz	esac
342231858Sbz	if test ${_fibs} -ne ${RT_NUMFIBS}; then
343231858Sbz		die "Number of FIBs not matching ours (${RT_NUMFIBS}) in" \
344231858Sbz		    "control message: ${_msg}"
345231858Sbz	fi
346231858Sbz
347231858Sbz	print_debug "Successfully received control message."
348231858Sbz}
349231858Sbz
350231858Sbz################################################################################
351231858Sbz#
352231858Sbz# Test case helper functions.
353231858Sbz#
354231858Sbz# Please note that neither on the intiator nor the reflector are FIBs despite
355231858Sbz# a variable name might indicate.  If such a variable is used it mirrors FIB
356231858Sbz# numbers from the middle node to match for test cases.
357231858Sbz#
358231858Sbztest_icmp6()
359231858Sbz{
360231858Sbz	local _maxfibs _addr _n _testno i _rc _ec
361231858Sbz	_maxfibs=$1
362231858Sbz	_addr="$2"
363231858Sbz	_n="$3"
364231858Sbz
365231858Sbz	printf "1..%d\n" ${_maxfibs}
366231858Sbz	_testno=1
367231858Sbz	set +e
368231858Sbz	i=0
369231858Sbz	while test ${i} -lt ${_maxfibs}; do
370231858Sbz		_txt="${_n}_${i}"
371231858Sbz		print_debug "Testing ${_txt}"
372231858Sbz
373231858Sbz		# Generate HEX for ping6 payload.
374231858Sbz		_fibtxt=`echo "${_txt}" | hd -v | cut -b11-60 | tr -d ' \r\n'`
375231858Sbz
376231858Sbz		eval _rc="\${rc_${i}}"
377231858Sbz		ping6 -n -c1 -p ${_fibtxt} ${_addr} > /dev/null 2>&1
378231858Sbz		_ec=$?
379231858Sbz		# We need to normalize the exit code of ping6.
380231858Sbz		case ${_ec} in
381231858Sbz		0)	;;
382231858Sbz		*)	_ec=1 ;;
383231858Sbz		esac
384231858Sbz		check_rc ${_ec} ${_rc} ${_testno} "${_txt}" "FIB ${i} ${_addr}"
385231858Sbz		testno=$((testno + 1))
386231858Sbz		i=$((i + 1))
387231858Sbz	done
388231858Sbz	set -e
389231858Sbz}
390231858Sbz
391231858Sbztest_ulp_reflect_one()
392231858Sbz{
393232114Sbz	local _txt _opts port fib
394231858Sbz	_txt="$1"
395231858Sbz	_opts="$2"
396232114Sbz	port=$3
397232114Sbz	fib=$4
398231858Sbz
399232114Sbz	print_debug "./reflect -p $((port + 1 + fib)) -t ${_txt}" "${_opts}"
400232114Sbz	./reflect -p $((port + 1 + fib)) -t ${_txt} ${_opts}
401231858Sbz	print_debug "reflect '${_txt}' terminated without error."
402231858Sbz}
403231858Sbz
404231858Sbztest_ulp_reflect_multiple()
405231858Sbz{
406231858Sbz	local _maxfibs _txt _opts i _jobs _p
407231858Sbz	_maxfibs=$1
408231858Sbz	_txt="$2"
409231858Sbz	_opts="$3"
410231858Sbz
411231858Sbz	i=0
412231858Sbz	_jobs=""
413231858Sbz	while test ${i} -lt ${_maxfibs}; do
414231858Sbz		print_debug "./reflect -p $((CTRLPORT + 1000 + i))" \
415231858Sbz		    "-t ${_txt} ${_opts} -N -f ${i} &"
416231858Sbz		./reflect -p $((CTRLPORT + 1000 + i)) \
417231858Sbz		    -t ${_txt} ${_opts} -N -f ${i} &
418231858Sbz		_p=$!
419231858Sbz		_jobs="${_jobs}${_p} "
420231858Sbz		i=$((i + 1))
421231858Sbz	done
422231858Sbz
423231858Sbz	# Start OOB control connection for START/DONE.
424231858Sbz	testrx_run_one "${_txt}" "${_opts}"
425231858Sbz	print_debug "KILL ${_jobs}"
426231858Sbz	for i in ${_jobs}; do
427231858Sbz		kill ${i} || true
428231858Sbz	done
429231858Sbz	#killall reflect || true
430231858Sbz	print_debug "reflects for '${_txt}' terminated without error."
431231858Sbz}
432231858Sbz
433231858Sbznc_send_recv()
434231858Sbz{
435231858Sbz	local _loops _msg _expreply _addr _port _opts i
436231858Sbz	_loops=$1
437231858Sbz	_msg="$2"
438231858Sbz	_expreply="$3"
439231858Sbz	_addr=$4
440231858Sbz	_port=$5
441231858Sbz	_opts="$6"
442231858Sbz
443231858Sbz	i=0
444231858Sbz	while test ${i} -lt ${_loops}; do
445231858Sbz		i=$((i + 1))
446231858Sbz		print_debug "e ${_msg} | nc -6 -w1 ${_opts} ${_addr} ${_port}"
447231858Sbz		_reply=`echo "${_msg}" | nc -6 -w1 ${_opts} ${_addr} ${_port}`
448231858Sbz		if test "${_reply}" != "${_expreply}"; then
449231858Sbz			if test ${i} -lt ${_loops}; then
450231858Sbz				sleep 1
451231858Sbz			else
452231858Sbz			# Must let caller decide how to handle the error.
453231858Sbz			#	die "Got invalid reply from peer." \
454231858Sbz			#	    "Expected '${_expreply}', got '${_reply}'"
455231858Sbz				return 1
456231858Sbz			fi
457231858Sbz		else
458231858Sbz			break
459231858Sbz		fi
460231858Sbz	done
461231858Sbz	return 0
462231858Sbz}
463231858Sbz
464231858Sbztest_ulp()
465231858Sbz{
466232114Sbz	local maxfibs _msg _addr port fib i _txt testno _rc _reply
467232114Sbz	maxfibs=$1
468231858Sbz	_msg="$2"
469231858Sbz	_addr=$3
470232114Sbz	port=$4
471232114Sbz	fib=$5
472231858Sbz
473232114Sbz	printf "1..%d\n" $((${maxfibs} * 2))
474231858Sbz	testno=1
475231858Sbz	i=0
476232114Sbz	while test ${i} -lt ${maxfibs}; do
477231858Sbz
478232114Sbz		if test ${i} -eq $((${maxfibs} - 1)); then
479231858Sbz			# Last one; signal DONE.
480231858Sbz			_txt="DONE ${_msg}_${i}"
481231858Sbz		else
482231858Sbz			_txt="DONE ${_msg}_${i}"
483231858Sbz		fi
484231858Sbz
485231858Sbz		eval _rc="\${rc_${i}}"
486231858Sbz
487231858Sbz		# Test TCP.
488232114Sbz		nc_send_recv ${maxfibs} "${_txt}" "${_txt}" ${_addr} \
489232114Sbz		    $((${port} + 1 + fib)) ""
490231858Sbz		check_rc $? ${_rc} ${testno} "${_msg}_${i}_tcp" \
491232114Sbz		    "[${_addr}]:$((${port} + 1 + fib)) ${_reply}"
492231858Sbz		testno=$((testno + 1))
493231858Sbz		sleep 1
494231858Sbz
495231858Sbz		# Test UDP.
496232114Sbz		nc_send_recv ${maxfibs} "${_txt}" "${_txt}" ${_addr} \
497232114Sbz		    $((${port} + 1 + fib)) "-u"
498231858Sbz		check_rc $? ${_rc} ${testno} "${_msg}_${i}_udp" \
499232114Sbz		    "[${_addr}]:$((${port} + 1 + fib)) ${_reply}"
500231858Sbz		sleep 1
501231858Sbz
502231858Sbz		i=$((i + 1))
503231858Sbz		testno=$((testno + 1))
504231858Sbz	done
505231858Sbz}
506231858Sbz
507231858Sbzsetup_ipfw_count()
508231858Sbz{
509232114Sbz	local i port maxfib _p _fib _ofib
510232114Sbz	port=$1
511232114Sbz	maxfib=$2
512231858Sbz	_fib=$3
513231858Sbz	_ofib=$4
514231858Sbz
515231858Sbz	i=0
516232114Sbz	while test ${i} -lt ${maxfib}; do
517231858Sbz
518231858Sbz		case ${_ofib} in
519232114Sbz		-1)	_p=$((port + 1 + i)) ;;
520232114Sbz		*)	_p=$((port + 1 + maxfib - 1 - i)) ;;
521231858Sbz		esac
522231858Sbz
523231858Sbz		# Only count ICMP6 echo replies.
524231858Sbz		ipfw add $((10000 + i)) count ipv6-icmp from any to any \
525231858Sbz		    icmp6types 129 fib ${i} via ${IFACE} out > /dev/null
526231858Sbz		ipfw add $((10000 + i)) count tcp from any to any \
527231858Sbz		    src-port ${_p} fib ${i}  via ${IFACE} out > /dev/null
528231858Sbz		ipfw add $((10000 + i)) count udp from any to any \
529231858Sbz		    src-port ${_p} fib ${i} via ${IFACE} out > /dev/null
530231858Sbz
531231858Sbz		# Only count ICMP6 echo requests.
532231858Sbz		ipfw add $((20000 + i)) count ipv6-icmp from any to any \
533231858Sbz		    icmp6types 128 fib ${i} via ${IFACEFAR} out > /dev/null
534231858Sbz		ipfw add $((20000 + i)) count tcp from any to any \
535232114Sbz		    dst-port $((${port} + 1 + i)) fib ${i} \
536231858Sbz		    via ${IFACEFAR} out > /dev/null
537231858Sbz		ipfw add $((20000 + i)) count udp from any to any \
538232114Sbz		    dst-port $((${port} + 1 + i)) fib ${i} \
539231858Sbz		    via ${IFACEFAR} out > /dev/null
540231858Sbz
541231858Sbz		i=$((i + 1))
542231858Sbz	done
543231858Sbz}
544231858Sbz
545231858Sbzreport_ipfw_count()
546231858Sbz{
547232114Sbz	local _fib _o i _rstr _c _req _p _opts base
548231858Sbz	_o="$2"
549231858Sbz
550231858Sbz	case ${DEBUG} in
551231858Sbz	''|0)	;;
552231858Sbz	*)	ipfw show ;;
553231858Sbz	esac
554231858Sbz
555231858Sbz	_rstr="RESULTS "
556232114Sbz	for base in 10000 20000; do
557231858Sbz		for _o in i t u; do
558232114Sbz			case ${base} in
559231858Sbz			10000)	_rstr="${_rstr}\nLEFT " ;;
560231858Sbz			20000)	_rstr="${_rstr}\nRIGHT " ;;
561231858Sbz			esac
562231858Sbz			case ${_o} in
563231858Sbz			i)	_rstr="${_rstr}ICMP6 " ;;
564231858Sbz			t)	_rstr="${_rstr}TCP " ;;
565231858Sbz			u)	_rstr="${_rstr}UDP " ;;
566231858Sbz			esac
567231858Sbz			i=0
568231858Sbz			while test ${i} -lt ${RT_NUMFIBS}; do
569231858Sbz
570231858Sbz				case "${_o}" in
571232114Sbz				i)	_c=`ipfw show $((${base} + i)) | \
572231858Sbz					    awk '/ ipv6-icmp / { print $2 }'` ;;
573232114Sbz				t)	_c=`ipfw show $((${base} + i)) | \
574231858Sbz					    awk '/ tcp / { print $2 }'` ;;
575232114Sbz				u)	_c=`ipfw show $((${base} + i)) | \
576231858Sbz					    awk '/ udp / { print $2 }'` ;;
577231858Sbz				esac
578231858Sbz				_rstr="${_rstr}${i} ${_c},"
579231858Sbz
580231858Sbz				i=$((i + 1))
581231858Sbz			done
582231858Sbz		done
583231858Sbz		i=0
584231858Sbz		while test ${i} -lt ${RT_NUMFIBS}; do
585232114Sbz			ipfw delete $((${base} + i)) > /dev/null 2>&1 || true
586231858Sbz			i=$((i + 1))
587231858Sbz		done
588231858Sbz	done
589231858Sbz
590231858Sbz	# We do not care about the request.
591231858Sbz	_req=`printf "${_rstr}" | nc -6 -l $((${CTRLPORT} - 1))`
592231858Sbz	print_debug "$? -- ${_req} -- ${_rstr}"
593231858Sbz}
594231858Sbz
595231858Sbzfetch_ipfw_count()
596231858Sbz{
597231858Sbz	local _n _reply _line _edge _type _fib _count _rc _ec _status
598231858Sbz	_n="$1"
599231858Sbz
600231858Sbz	# Leave node some time to build result set.
601231858Sbz	sleep 3
602231858Sbz
603231858Sbz	print_debug "Asking for ipfw count results..."
604231858Sbz	set +e
605231858Sbz	nc_send_recv 1 "RESULT REQUEST" "" ${MIDDLELEFTADDR} \
606231858Sbz	    $((${CTRLPORT} - 1)) ""
607231858Sbz	set -e
608231858Sbz	case "${_reply}" in
609231858Sbz	RESULTS\ *)	;;
610231858Sbz	*)		die "Got invalid reply from peer." \
611231858Sbz			    "Expected 'RESULTS ...', got '${_reply}'" ;;
612231858Sbz	esac
613231858Sbz
614231858Sbz	# Trim "RESULTS "
615231858Sbz	_reply=${_reply#* }
616231858Sbz
617231858Sbz	# FIBs * {left, right} * {icmp6, tcp, udp}
618231858Sbz	printf "1..%d\n" $((RT_NUMFIBS * 2 * 3))
619231858Sbz	testno=1
620231858Sbz	while read _line; do
621231858Sbz		print_debug "_line == ${_line}"
622231858Sbz		_edge=${_line%% *}
623231858Sbz		_line=${_line#* }
624231858Sbz		_type=${_line%% *}
625231858Sbz		_line=${_line#* }
626231858Sbz
627231858Sbz		while read _fib _count; do
628231858Sbz			eval _em="\${rc_${_n}_${_edge}_${_type}_${_fib}}"
629231858Sbz			: ${_em:=-42}
630231858Sbz			if test ${_count} -gt 0; then
631231858Sbz				_rc=1
632231858Sbz			else
633231858Sbz				_rc=0
634231858Sbz			fi
635231858Sbz			if test ${_rc} -eq ${_em}; then
636231858Sbz				_status="ok"
637231858Sbz			else
638231858Sbz				_status="not ok"
639231858Sbz			fi
640231858Sbz			printf "%s %d %s # count=%s _rc=%d _em=%d\n" \
641231858Sbz			    "${_status}" ${testno} "${_n}_${_edge}_${_type}_${_fib}" \
642231858Sbz			    ${_count} ${_rc} ${_em}
643231858Sbz			testno=$((testno + 1))
644231858Sbz		done <<EOi
645231858Sbz`printf "${_line}" | tr ',' '\n'`
646231858SbzEOi
647231858Sbz		
648231858Sbz	done <<EOo
649231858Sbz`printf "${_reply}" | grep -v "^$"`
650231858SbzEOo
651231858Sbz
652231858Sbz	print_debug "ipfw count results processed"
653231858Sbz}
654231858Sbz
655231858Sbz################################################################################
656231858Sbz#
657231858Sbz# Test cases.
658231858Sbz#
659231858Sbz# In general we set the FIB on in, but count on out.
660231858Sbz#
661231858Sbz
662231858Sbz_fwd_default_fib_symmetric_results()
663231858Sbz{
664231858Sbz	local _n i _edge _type _rc
665231858Sbz	_n="$1"
666231858Sbz
667231858Sbz	i=0
668231858Sbz	while test ${i} -lt ${RT_NUMFIBS}; do
669231858Sbz		for _edge in "LEFT" "RIGHT"; do
670231858Sbz			for _type in "ICMP6" "TCP" "UDP"; do
671231858Sbz
672231858Sbz				case ${i} in
673231858Sbz				0)	eval rc_${_n}_${_edge}_${_type}_${i}=1
674231858Sbz					#print_debug \
675231858Sbz					#   "rc_${_n}_${_edge}_${_type}_${i}=1"
676231858Sbz					;;
677231858Sbz				*)	eval rc_${_n}_${_edge}_${_type}_${i}=0
678231858Sbz					#print_debug \
679231858Sbz					#   "rc_${_n}_${_edge}_${_type}_${i}=0"
680231858Sbz					;;
681231858Sbz				esac
682231858Sbz
683231858Sbz			done
684231858Sbz		done
685231858Sbz		i=$((i + 1))
686231858Sbz	done
687231858Sbz}
688231858Sbz
689231858Sbz_fwd_default_fib_symmetric_left()
690231858Sbz{
691231858Sbz	local _n
692231858Sbz	_n="$1"
693231858Sbz
694231858Sbz	send_control_msgs "START_${_n}"
695231858Sbz
696231858Sbz	# Setup expected return code
697231858Sbz	rc_0=0
698231858Sbz
699231858Sbz	# Initiate probes for ICMP6, TCP and UDP.
700231858Sbz	test_icmp6 1 ${RIGHTADDR} "${_n}_icmp6"
701231858Sbz	test_ulp 1 "${_n}" ${RIGHTADDR} ${CTRLPORT} 0
702231858Sbz
703231858Sbz	send_control_msgs "STOP_${_n}"
704231858Sbz	_fwd_default_fib_symmetric_results "${_n}"
705231858Sbz	fetch_ipfw_count "${_n}"
706231858Sbz}
707231858Sbz
708231858Sbz_fwd_default_fib_symmetric_middle()
709231858Sbz{
710231858Sbz	local _n
711231858Sbz	_n="$1"
712231858Sbz
713231858Sbz	setup_ipfw_count ${CTRLPORT} ${RT_NUMFIBS} 0 -1
714231858Sbz	wait_remote_ready "START_${_n}"
715231858Sbz	ipfw -q zero > /dev/null
716231858Sbz	# Nothing to do for the middle node testing the default.
717231858Sbz	sleep 1
718231858Sbz	wait_remote_ready "STOP_${_n}"
719231858Sbz	report_ipfw_count
720231858Sbz}
721231858Sbz
722231858Sbz_fwd_default_fib_symmetric_right()
723231858Sbz{
724231858Sbz	local _n
725231858Sbz	_n="$1"
726231858Sbz
727231858Sbz	wait_remote_ready "START_${_n}"
728231858Sbz
729231858Sbz	# No need to do anything for ICMPv6.
730231858Sbz	# Start reflect for TCP and UDP.
731231858Sbz	test_ulp_reflect_one "${_n}_tcp" "-N -T TCP6" 0 ${CTRLPORT}
732231858Sbz	test_ulp_reflect_one "${_n}_udp" "-N -T UDP6" 0 ${CTRLPORT}
733231858Sbz
734231858Sbz	wait_remote_ready "STOP_${_n}"
735231858Sbz}
736231858Sbz
737231858Sbzfwd_default_fib_symmetric()
738231858Sbz{
739231858Sbz	local _n
740231858Sbz
741231858Sbz	_n="fwd_default_fib_symmetric"
742231858Sbz
743231858Sbz	print_debug "${_n}"
744231858Sbz	case ${node} in
745231858Sbz	left)	_fwd_default_fib_symmetric_left ${_n} ;;
746231858Sbz	middle)	_fwd_default_fib_symmetric_middle ${_n} ;;
747231858Sbz	right)	_fwd_default_fib_symmetric_right ${_n} ;;
748231858Sbz	esac
749231858Sbz}
750231858Sbz
751231858Sbz_fwd_default_fib_symmetric_middle_ifconfig()
752231858Sbz{
753231858Sbz	local _n
754231858Sbz	_n="$1"
755231858Sbz
756231858Sbz	ifconfig ${IFACE} fib 0
757231858Sbz	ifconfig ${IFACEFAR} fib 0
758231858Sbz	setup_ipfw_count ${CTRLPORT} ${RT_NUMFIBS} 0 -1
759231858Sbz	wait_remote_ready "START_${_n}"
760231858Sbz	ipfw -q zero > /dev/null
761231858Sbz	# Nothing to do for the middle node testing the default.
762231858Sbz	sleep 1
763231858Sbz	wait_remote_ready "STOP_${_n}"
764231858Sbz	report_ipfw_count
765231858Sbz}
766231858Sbz
767231858Sbzfwd_default_fib_symmetric_ifconfig()
768231858Sbz{
769231858Sbz	local _n
770231858Sbz
771231858Sbz	_n="fwd_default_fib_symmetric_ifconfig"
772231858Sbz
773231858Sbz	print_debug "${_n}"
774231858Sbz	case ${node} in
775231858Sbz	left)	_fwd_default_fib_symmetric_left ${_n} ;;
776231858Sbz	middle)	_fwd_default_fib_symmetric_middle_ifconfig ${_n} ;;
777231858Sbz	right)	_fwd_default_fib_symmetric_right ${_n} ;;
778231858Sbz	esac
779231858Sbz}
780231858Sbz
781231858Sbz_fwd_default_fib_symmetric_middle_ipfw()
782231858Sbz{
783231858Sbz	local _n
784231858Sbz	_n="$1"
785231858Sbz
786231858Sbz	ipfw add 100 setfib 0 ipv6-icmp from any to any \
787231858Sbz	    icmp6types 128 via ${IFACE} in > /dev/null
788231858Sbz	ipfw add 100 setfib 0 ip6 from any to any \
789231858Sbz	    proto tcp dst-port ${CTRLPORT} via ${IFACE} in > /dev/null
790231858Sbz	ipfw add 100 setfib 0 ip6 from any to any \
791231858Sbz	    proto udp dst-port ${CTRLPORT} via ${IFACE} in > /dev/null
792231858Sbz
793231858Sbz	ipfw add 100 setfib 0 ipv6-icmp from any to any \
794231858Sbz	    icmp6types 128 via ${IFACEFAR} in > /dev/null
795231858Sbz	ipfw add 100 setfib 0 tcp from any to any \
796231858Sbz	    dst-port ${CTRLPORT} via ${IFACEFAR} in > /dev/null
797231858Sbz	ipfw add 100 setfib 0 udp from any to any \
798231858Sbz	    dst-port ${CTRLPORT} via ${IFACEFAR} in > /dev/null
799231858Sbz
800231858Sbz	setup_ipfw_count ${CTRLPORT} ${RT_NUMFIBS} 0 -1
801231858Sbz	wait_remote_ready "START_${_n}"
802231858Sbz	ipfw -q zero > /dev/null
803231858Sbz	# Nothing to do for the middle node testing the default.
804231858Sbz	sleep 1
805231858Sbz	wait_remote_ready "STOP_${_n}"
806231858Sbz	report_ipfw_count
807231858Sbz
808231858Sbz	ipfw delete 100 > /dev/null
809231858Sbz}
810231858Sbz
811231858Sbzfwd_default_fib_symmetric_ipfw()
812231858Sbz{
813231858Sbz	local _n
814231858Sbz
815231858Sbz	_n="fwd_default_fib_symmetric_ipfw"
816231858Sbz
817231858Sbz	print_debug "${_n}"
818231858Sbz	case ${node} in
819231858Sbz	left)	_fwd_default_fib_symmetric_left ${_n} ;;
820231858Sbz	middle)	_fwd_default_fib_symmetric_middle_ipfw ${_n} ;;
821231858Sbz	right)	_fwd_default_fib_symmetric_right ${_n} ;;
822231858Sbz	esac
823231858Sbz}
824231858Sbz
825231858Sbz################################################################################
826231858Sbz
827231858Sbz_fwd_fib_symmetric_results()
828231858Sbz{
829231858Sbz	local _n _fib i _edge _type _rc
830231858Sbz	_n="$1"
831231858Sbz	_fib=$2
832231858Sbz
833231858Sbz	i=0
834231858Sbz	while test ${i} -lt ${RT_NUMFIBS}; do
835231858Sbz		for _edge in "LEFT" "RIGHT"; do
836231858Sbz			for _type in "ICMP6" "TCP" "UDP"; do
837231858Sbz
838231858Sbz				case ${i} in
839231858Sbz				${_fib}) eval rc_${_n}_${_edge}_${_type}_${i}=1
840231858Sbz					#print_debug \
841231858Sbz					#   "rc_${_n}_${_edge}_${_type}_${i}=1"
842231858Sbz					;;
843231858Sbz				*)	eval rc_${_n}_${_edge}_${_type}_${i}=0
844231858Sbz					#print_debug \
845231858Sbz					#   "rc_${_n}_${_edge}_${_type}_${i}=0"
846231858Sbz					;;
847231858Sbz				esac
848231858Sbz
849231858Sbz			done
850231858Sbz		done
851231858Sbz		i=$((i + 1))
852231858Sbz	done
853231858Sbz}
854231858Sbz
855231858Sbz_fwd_fib_symmetric_left()
856231858Sbz{
857231858Sbz	local _n _maxfib i
858231858Sbz	_n="$1"
859231858Sbz	_maxfib=$2
860231858Sbz
861231858Sbz	# Setup expected return code
862231858Sbz	i=0
863231858Sbz	while test ${i} -lt ${_maxfib}; do
864231858Sbz		eval rc_${i}=0
865231858Sbz		i=$((i + 1))
866231858Sbz	done
867231858Sbz
868231858Sbz	# Initiate probes for ICMP6, TCP and UDP.
869231858Sbz	i=0
870231858Sbz	while test ${i} -lt ${_maxfib}; do
871231858Sbz
872231858Sbz		sleep 1
873231858Sbz
874231858Sbz		send_control_msgs "START_${_n}_${i}"
875231858Sbz
876231858Sbz		test_icmp6 1 ${RIGHTADDR} "${_n}_${i}_icmp6"
877231858Sbz		test_ulp 1 "${_n}_${i}" ${RIGHTADDR} ${CTRLPORT} ${i}
878231858Sbz
879231858Sbz		send_control_msgs "STOP_${_n}_${i}"
880231858Sbz		_fwd_fib_symmetric_results "${_n}_${i}" ${i}
881231858Sbz		fetch_ipfw_count "${_n}_${i}"
882231858Sbz		i=$((i + 1))
883231858Sbz	done
884231858Sbz}
885231858Sbz
886231858Sbz_fwd_fib_symmetric_right()
887231858Sbz{
888231858Sbz	local _n _maxfib i
889231858Sbz	_n="$1"
890231858Sbz	_maxfib=$2
891231858Sbz
892231858Sbz	i=0
893231858Sbz	while test ${i} -lt ${_maxfib}; do
894231858Sbz		wait_remote_ready "START_${_n}_${i}"
895231858Sbz
896231858Sbz		# No need to do anything for ICMPv6.
897231858Sbz		# Start reflect for TCP and UDP.
898231858Sbz		test_ulp_reflect_one "${_n}_tcp" "-N -T TCP6" ${i} ${CTRLPORT}
899231858Sbz		test_ulp_reflect_one "${_n}_udp" "-N -T UDP6" ${i} ${CTRLPORT}
900231858Sbz
901231858Sbz		wait_remote_ready "STOP_${_n}_${i}"
902231858Sbz		i=$((i + 1))
903231858Sbz	done
904231858Sbz}
905231858Sbz
906231858Sbz_fwd_fib_symmetric_middle_ifconfig()
907231858Sbz{
908231858Sbz	local _n _maxfib i
909231858Sbz	_n="$1"
910231858Sbz	_maxfib=$2
911231858Sbz
912231858Sbz	i=0
913231858Sbz	while test ${i} -lt ${_maxfib}; do
914231858Sbz		ifconfig ${IFACE} fib ${i}
915231858Sbz		ifconfig ${IFACEFAR} fib ${i}
916231858Sbz		setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
917231858Sbz		wait_remote_ready "START_${_n}_${i}"
918231858Sbz		ipfw -q zero > /dev/null
919231858Sbz		# Nothing to do for the middle node testing the default.
920231858Sbz		sleep 1
921231858Sbz		wait_remote_ready "STOP_${_n}_${i}"
922231858Sbz		report_ipfw_count
923231858Sbz		i=$((i + 1))
924231858Sbz	done
925231858Sbz}
926231858Sbz
927231858Sbz_fwd_fib_symmetric_middle_ipfw()
928231858Sbz{
929231858Sbz	local _n _maxfib i _port
930231858Sbz	_n="$1"
931231858Sbz	_maxfib=$2
932231858Sbz
933231858Sbz	i=0
934231858Sbz	while test ${i} -lt ${_maxfib}; do
935231858Sbz		_port=$((CTRLPORT + 1 + i))
936231858Sbz		ipfw add 100 setfib ${i} ipv6-icmp from any to any \
937231858Sbz		    icmp6types 128 via ${IFACE} in > /dev/null
938231858Sbz		ipfw add 100 setfib ${i} tcp from any to any \
939231858Sbz		    dst-port ${_port} via ${IFACE} in > /dev/null
940231858Sbz		ipfw add 100 setfib ${i} udp from any to any \
941231858Sbz		    dst-port ${_port} via ${IFACE} in > /dev/null
942231858Sbz
943231858Sbz		ipfw add 100 setfib ${i} ipv6-icmp from any to any \
944231858Sbz		    icmp6types 129 via ${IFACEFAR} in > /dev/null
945231858Sbz		ipfw add 100 setfib ${i} tcp from any to any \
946231858Sbz		    src-port ${_port} via ${IFACEFAR} in > /dev/null
947231858Sbz		ipfw add 100 setfib ${i} udp from any to any \
948231858Sbz		    src-port ${_port} via ${IFACEFAR} in > /dev/null
949231858Sbz
950231858Sbz		setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
951231858Sbz		wait_remote_ready "START_${_n}_${i}"
952231858Sbz		ipfw -q zero > /dev/null
953231858Sbz		# Nothing to do for the middle node testing the default.
954231858Sbz		sleep 1
955231858Sbz		wait_remote_ready "STOP_${_n}_${i}"
956231858Sbz		report_ipfw_count
957231858Sbz
958231858Sbz		ipfw delete 100 > /dev/null
959231858Sbz		i=$((i + 1))
960231858Sbz	done
961231858Sbz}
962231858Sbz
963231858Sbzfwd_fib_symmetric_ifconfig()
964231858Sbz{
965231858Sbz	local _maxfib _n
966231858Sbz	_maxfib=$1
967231858Sbz
968231858Sbz	_n="fwd_fib_symmetric_ifconfig"
969231858Sbz
970231858Sbz	print_debug "${_n} ${_maxfib}"
971231858Sbz	case ${node} in
972231858Sbz	left)	_fwd_fib_symmetric_left ${_n} ${_maxfib} ;;
973231858Sbz	middle)	_fwd_fib_symmetric_middle_ifconfig ${_n} ${_maxfib} ;;
974231858Sbz	right)	_fwd_fib_symmetric_right ${_n} ${_maxfib} ;;
975231858Sbz	esac
976231858Sbz}
977231858Sbz
978231858Sbzfwd_fib_symmetric_ipfw()
979231858Sbz{
980231858Sbz	local _maxfib _n
981231858Sbz	_maxfib=$1
982231858Sbz
983231858Sbz	_n="fwd_fib_symmetric_ipfw"
984231858Sbz
985231858Sbz	print_debug "${_n} ${_maxfib}"
986231858Sbz	case ${node} in
987231858Sbz	left)	_fwd_fib_symmetric_left ${_n} ${_maxfib} ;;
988231858Sbz	middle)	_fwd_fib_symmetric_middle_ipfw ${_n} ${_maxfib} ;;
989231858Sbz	right)	_fwd_fib_symmetric_right ${_n} ${_maxfib} ;;
990231858Sbz	esac
991231858Sbz}
992231858Sbz
993231858Sbz################################################################################
994231858Sbz
995231858Sbz_fwd_fib_asymmetric_results()
996231858Sbz{
997232114Sbz	local _n fib maxfib i _edge _type _rc
998231858Sbz	_n="$1"
999232114Sbz	fib=$2
1000232114Sbz	maxfib=$3
1001231858Sbz
1002231858Sbz	i=0
1003232114Sbz	while test ${i} -lt ${maxfib}; do
1004231858Sbz		_edge="RIGHT"
1005231858Sbz			for _type in "ICMP6" "TCP" "UDP"; do
1006231858Sbz
1007231858Sbz				case ${i} in
1008232114Sbz				${fib}) eval rc_${_n}_${_edge}_${_type}_${i}=1
1009231858Sbz					#print_debug \
1010231858Sbz					#   "rc_${_n}_${_edge}_${_type}_${i}=1"
1011231858Sbz					;;
1012231858Sbz				*)	eval rc_${_n}_${_edge}_${_type}_${i}=0
1013231858Sbz					#print_debug \
1014231858Sbz					#   "rc_${_n}_${_edge}_${_type}_${i}=0"
1015231858Sbz					;;
1016231858Sbz				esac
1017231858Sbz
1018231858Sbz			done
1019231858Sbz		i=$((i + 1))
1020231858Sbz	done
1021232114Sbz	fib=$((maxfib - 1 - fib))
1022231858Sbz	i=0
1023232114Sbz	while test ${i} -lt ${maxfib}; do
1024231858Sbz		_edge="LEFT"
1025231858Sbz			for _type in "ICMP6" "TCP" "UDP"; do
1026231858Sbz
1027231858Sbz				case ${i} in
1028232114Sbz				${fib}) eval rc_${_n}_${_edge}_${_type}_${i}=1
1029231858Sbz					#print_debug \
1030231858Sbz					#   "rc_${_n}_${_edge}_${_type}_${i}=1"
1031231858Sbz					;;
1032231858Sbz				*)	eval rc_${_n}_${_edge}_${_type}_${i}=0
1033231858Sbz					#print_debug \
1034231858Sbz					#   "rc_${_n}_${_edge}_${_type}_${i}=0"
1035231858Sbz					;;
1036231858Sbz				esac
1037231858Sbz
1038231858Sbz			done
1039231858Sbz		i=$((i + 1))
1040231858Sbz	done
1041231858Sbz}
1042231858Sbz
1043231858Sbz_fwd_fib_asymmetric_left()
1044231858Sbz{
1045231858Sbz	local _n _maxfib i
1046231858Sbz	_n="$1"
1047231858Sbz	_maxfib=$2
1048231858Sbz
1049231858Sbz	# Setup expected return code
1050231858Sbz	i=0
1051231858Sbz	while test ${i} -lt ${_maxfib}; do
1052231858Sbz		eval rc_${i}=0
1053231858Sbz		i=$((i + 1))
1054231858Sbz	done
1055231858Sbz
1056231858Sbz	# Initiate probes for ICMP6, TCP and UDP.
1057231858Sbz	i=0
1058231858Sbz	while test ${i} -lt ${_maxfib}; do
1059231858Sbz
1060231858Sbz		sleep 1
1061231858Sbz
1062231858Sbz		send_control_msgs "START_${_n}_${i}"
1063231858Sbz
1064231858Sbz		test_icmp6 1 ${RIGHTADDR} "${_n}_${i}_icmp6"
1065231858Sbz		test_ulp 1 "${_n}_${i}" ${RIGHTADDR} ${CTRLPORT} ${i}
1066231858Sbz
1067231858Sbz		send_control_msgs "STOP_${_n}_${i}"
1068231858Sbz		_fwd_fib_asymmetric_results "${_n}_${i}" ${i} ${_maxfib}
1069231858Sbz		fetch_ipfw_count "${_n}_${i}"
1070231858Sbz		i=$((i + 1))
1071231858Sbz	done
1072231858Sbz}
1073231858Sbz
1074231858Sbz_fwd_fib_asymmetric_middle_ifconfig()
1075231858Sbz{
1076232114Sbz	local _n maxfib i
1077231858Sbz	_n="$1"
1078232114Sbz	maxfib=$2
1079231858Sbz
1080231858Sbz	i=0
1081232114Sbz	while test ${i} -lt ${maxfib}; do
1082231858Sbz		ifconfig ${IFACE} fib ${i}
1083232114Sbz		ifconfig ${IFACEFAR} fib $((${maxfib} - 1 - ${i}))
1084232114Sbz		setup_ipfw_count ${CTRLPORT} ${maxfib} ${i} \
1085232114Sbz		    $((${maxfib} - 1 - ${i}))
1086231858Sbz		wait_remote_ready "START_${_n}_${i}"
1087231858Sbz		ipfw -q zero > /dev/null
1088231858Sbz		# Nothing to do for the middle node testing the default.
1089231858Sbz		sleep 1
1090231858Sbz		wait_remote_ready "STOP_${_n}_${i}"
1091231858Sbz		report_ipfw_count
1092231858Sbz		i=$((i + 1))
1093231858Sbz	done
1094231858Sbz}
1095231858Sbz
1096231858Sbz_fwd_fib_asymmetric_middle_ipfw()
1097231858Sbz{
1098232114Sbz	local _n maxfib i j _port
1099231858Sbz	_n="$1"
1100232114Sbz	maxfib=$2
1101231858Sbz
1102231858Sbz	i=0
1103232114Sbz	while test ${i} -lt ${maxfib}; do
1104231858Sbz
1105231858Sbz		_port=$((CTRLPORT + 1 + i))
1106231858Sbz		ipfw add 100 setfib ${i} ipv6-icmp from any to any \
1107231858Sbz		    icmp6types 128 via ${IFACE} in > /dev/null
1108231858Sbz		ipfw add 100 setfib ${i} tcp from any to any \
1109231858Sbz		    dst-port ${_port} via ${IFACE} in > /dev/null
1110231858Sbz		ipfw add 100 setfib ${i} udp from any to any \
1111231858Sbz		    dst-port ${_port} via ${IFACE} in > /dev/null
1112231858Sbz
1113232114Sbz		j=$((${maxfib} - 1 - ${i}))
1114231858Sbz		ipfw add 100 setfib ${j} ipv6-icmp from any to any \
1115231858Sbz		    icmp6types 129 via ${IFACEFAR} in > /dev/null
1116231858Sbz		ipfw add 100 setfib ${j} tcp from any to any \
1117231858Sbz		    src-port ${_port} via ${IFACEFAR} in > /dev/null
1118231858Sbz		ipfw add 100 setfib ${j} udp from any to any \
1119231858Sbz		    src-port ${_port} via ${IFACEFAR} in > /dev/null
1120231858Sbz
1121232114Sbz		setup_ipfw_count ${CTRLPORT} ${maxfib} ${i} ${j}
1122231858Sbz		wait_remote_ready "START_${_n}_${i}"
1123231858Sbz		ipfw -q zero > /dev/null
1124231858Sbz		# Nothing to do for the middle node testing the default.
1125231858Sbz		sleep 1
1126231858Sbz		wait_remote_ready "STOP_${_n}_${i}"
1127231858Sbz		report_ipfw_count
1128231858Sbz
1129231858Sbz		ipfw delete 100 > /dev/null
1130231858Sbz		i=$((i + 1))
1131231858Sbz	done
1132231858Sbz}
1133231858Sbz
1134231858Sbzfwd_fib_asymmetric_ifconfig()
1135231858Sbz{
1136231858Sbz	local _maxfib _n
1137231858Sbz	_maxfib=$1
1138231858Sbz
1139231858Sbz	_n="fwd_fib_asymmetric_ifconfig"
1140231858Sbz
1141231858Sbz	print_debug "${_n} ${_maxfib}"
1142231858Sbz	case ${node} in
1143231858Sbz	left)	_fwd_fib_asymmetric_left ${_n} ${_maxfib} ;;
1144231858Sbz	middle)	_fwd_fib_asymmetric_middle_ifconfig ${_n} ${_maxfib} ;;
1145231858Sbz	right)	_fwd_fib_symmetric_right ${_n} ${_maxfib} ;;
1146231858Sbz	esac
1147231858Sbz}
1148231858Sbz
1149231858Sbzfwd_fib_asymmetric_ipfw()
1150231858Sbz{
1151231858Sbz	local _maxfib _n
1152231858Sbz	_maxfib=$1
1153231858Sbz
1154231858Sbz	_n="fwd_fib_asymmetric_ipfw"
1155231858Sbz
1156231858Sbz	print_debug "${_n} ${_maxfib}"
1157231858Sbz	case ${node} in
1158231858Sbz	left)	_fwd_fib_asymmetric_left ${_n} ${_maxfib} ;;
1159231858Sbz	middle)	_fwd_fib_asymmetric_middle_ipfw ${_n} ${_maxfib} ;;
1160231858Sbz	right)	_fwd_fib_symmetric_right ${_n} ${_maxfib} ;;
1161231858Sbz	esac
1162231858Sbz}
1163231858Sbz
1164231858Sbz################################################################################
1165231858Sbz
1166231858Sbz_fwd_fib_symmetric_destructive_left()
1167231858Sbz{
1168231858Sbz	local _n _maxfib i _addr
1169231858Sbz	_n="$1"
1170231858Sbz	_maxfib=$2
1171231858Sbz
1172231858Sbz	# Setup expected return code
1173231858Sbz	i=0
1174231858Sbz	while test ${i} -lt ${_maxfib}; do
1175231858Sbz		eval rc_${i}=0
1176231858Sbz		i=$((i + 1))
1177231858Sbz	done
1178231858Sbz
1179231858Sbz	# Add default route.
1180231858Sbz	route add -net -inet6 default ${MIDDLELEFTADDR} > /dev/null
1181231858Sbz
1182231858Sbz	# Initiate probes for ICMP6, TCP and UDP.
1183231858Sbz	i=0
1184231858Sbz	while test ${i} -lt ${_maxfib}; do
1185231858Sbz
1186231858Sbz		sleep 1
1187231858Sbz
1188231858Sbz		send_control_msgs "START_${_n}_${i}"
1189231858Sbz
1190231858Sbz		_addr="2001:2:${i}::2"
1191231858Sbz		test_icmp6 1 ${_addr} "${_n}_${i}_icmp6"
1192231858Sbz		test_ulp 1 "${_n}_${i}" ${_addr} ${CTRLPORT} ${i}
1193231858Sbz
1194231858Sbz		send_control_msgs "STOP_${_n}_${i}"
1195231858Sbz		_fwd_fib_symmetric_results "${_n}_${i}" ${i}
1196231858Sbz		fetch_ipfw_count "${_n}_${i}"
1197231858Sbz		i=$((i + 1))
1198231858Sbz	done
1199231858Sbz
1200231858Sbz	# Cleanup networking.
1201231858Sbz	route delete -net -inet6 default > /dev/null
1202231858Sbz}
1203231858Sbz
1204231858Sbz_fwd_fib_symmetric_destructive_right()
1205231858Sbz{
1206231858Sbz	local _n _maxfib i _addr
1207231858Sbz	_n="$1"
1208231858Sbz	_maxfib=$2
1209231858Sbz
1210231858Sbz	# Setup networking (ideally we'd use the link-local).
1211231858Sbz	route add -net -inet6 default ${MIDDLERIGHTADDR} > /dev/null 2>&1
1212231858Sbz	i=0
1213231858Sbz	while test ${i} -lt ${_maxfib}; do
1214231858Sbz		ifconfig ${IFACE} inet6 2001:2:${i}::2/64 alias
1215231858Sbz		i=$((i + 1))
1216231858Sbz	done
1217231858Sbz
1218231858Sbz	i=0
1219231858Sbz	while test ${i} -lt ${_maxfib}; do
1220231858Sbz		wait_remote_ready "START_${_n}_${i}"
1221231858Sbz
1222231858Sbz		# No need to do anything for ICMPv6.
1223231858Sbz		# Start reflect for TCP and UDP.
1224231858Sbz		_addr="2001:2:${i}::2"
1225231858Sbz		test_ulp_reflect_one "${_n}_tcp" "-N -T TCP6 -A ${_addr}" \
1226231858Sbz		    ${i} ${CTRLPORT}
1227231858Sbz		test_ulp_reflect_one "${_n}_udp" "-N -T UDP6 -A ${_addr}" \
1228231858Sbz		    ${i} ${CTRLPORT}
1229231858Sbz
1230231858Sbz		wait_remote_ready "STOP_${_n}_${i}"
1231231858Sbz		i=$((i + 1))
1232231858Sbz	done
1233231858Sbz
1234231858Sbz	# Cleanup networking again.
1235231858Sbz	route delete -net -inet6 default > /dev/null 2>&1
1236231858Sbz	i=0
1237231858Sbz	while test ${i} -lt ${_maxfib}; do
1238231858Sbz		ifconfig ${IFACE} inet6 2001:2:${i}::2/64 -alias
1239231858Sbz		i=$((i + 1))
1240231858Sbz	done
1241231858Sbz
1242231858Sbz}
1243231858Sbz
1244231858Sbz
1245231858Sbz_fwd_fib_symmetric_destructive_middle_setup_networking()
1246231858Sbz{
1247231858Sbz	local _maxfib i j
1248231858Sbz	_maxfib=$1
1249231858Sbz
1250231858Sbz	# Setup networking.
1251231858Sbz	i=0
1252231858Sbz	while test ${i} -lt ${_maxfib}; do
1253231858Sbz		ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 -alias \
1254231858Sbz		    > /dev/null 2>&1 || true
1255231858Sbz		ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 alias
1256231858Sbz		j=0
1257231858Sbz		while test ${j} -lt ${_maxfib}; do
1258231858Sbz			# Only work on all other FIBs.
1259231858Sbz			if test ${j} -ne ${i}; then
1260231858Sbz				setfib -F ${j} route delete -net -inet6 \
1261231858Sbz				     2001:2:${i}::/64 > /dev/null
1262231858Sbz			fi
1263231858Sbz			j=$((j + 1))
1264231858Sbz		done
1265231858Sbz		i=$((i + 1))
1266231858Sbz	done
1267231858Sbz}
1268231858Sbz
1269231858Sbz_fwd_fib_symmetric_destructive_middle_cleanup_networking()
1270231858Sbz{
1271231858Sbz	local _maxfib i
1272231858Sbz	_maxfib=$1
1273231858Sbz
1274231858Sbz	# Cleanup networking again.
1275231858Sbz	i=0
1276231858Sbz	while test ${i} -lt ${_maxfib}; do
1277231858Sbz		ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 -alias
1278231858Sbz		i=$((i + 1))
1279231858Sbz	done
1280231858Sbz}
1281231858Sbz
1282231858Sbz_fwd_fib_symmetric_destructive_middle_ifconfig()
1283231858Sbz{
1284231858Sbz	local _n _maxfib i
1285231858Sbz	_n="$1"
1286231858Sbz	_maxfib=$2
1287231858Sbz
1288231858Sbz	_fwd_fib_symmetric_destructive_middle_setup_networking ${_maxfib}
1289231858Sbz
1290231858Sbz	i=0
1291231858Sbz	while test ${i} -lt ${_maxfib}; do
1292231858Sbz		ifconfig ${IFACE} fib ${i}
1293231858Sbz		ifconfig ${IFACEFAR} fib ${i}
1294231858Sbz		setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
1295231858Sbz		wait_remote_ready "START_${_n}_${i}"
1296231858Sbz		ipfw -q zero > /dev/null
1297231858Sbz		# Nothing to do for the middle node testing the default.
1298231858Sbz		sleep 1
1299231858Sbz		wait_remote_ready "STOP_${_n}_${i}"
1300231858Sbz		report_ipfw_count
1301231858Sbz		i=$((i + 1))
1302231858Sbz	done
1303231858Sbz
1304231858Sbz	_fwd_fib_symmetric_destructive_middle_cleanup_networking ${_maxfib}
1305231858Sbz}
1306231858Sbz
1307231858Sbz_fwd_fib_symmetric_destructive_middle_ipfw()
1308231858Sbz{
1309231858Sbz	local _n _maxfib i _port
1310231858Sbz	_n="$1"
1311231858Sbz	_maxfib=$2
1312231858Sbz
1313231858Sbz	_fwd_fib_symmetric_destructive_middle_setup_networking ${_maxfib}
1314231858Sbz
1315231858Sbz	i=0
1316231858Sbz	while test ${i} -lt ${_maxfib}; do
1317231858Sbz		_port=$((CTRLPORT + 1 + i))
1318231858Sbz		ipfw add 100 setfib ${i} ipv6-icmp from any to any \
1319231858Sbz		    icmp6types 128 via ${IFACE} in > /dev/null
1320231858Sbz		ipfw add 100 setfib ${i} tcp from any to any \
1321231858Sbz		    dst-port ${_port} via ${IFACE} in > /dev/null
1322231858Sbz		ipfw add 100 setfib ${i} udp from any to any \
1323231858Sbz		    dst-port ${_port} via ${IFACE} in > /dev/null
1324231858Sbz
1325231858Sbz		ipfw add 100 setfib ${i} ipv6-icmp from any to any \
1326231858Sbz		    icmp6types 129 via ${IFACEFAR} in > /dev/null
1327231858Sbz		ipfw add 100 setfib ${i} tcp from any to any \
1328231858Sbz		    src-port ${_port} via ${IFACEFAR} in > /dev/null
1329231858Sbz		ipfw add 100 setfib ${i} udp from any to any \
1330231858Sbz		    src-port ${_port} via ${IFACEFAR} in > /dev/null
1331231858Sbz
1332231858Sbz		setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
1333231858Sbz		wait_remote_ready "START_${_n}_${i}"
1334231858Sbz		ipfw -q zero > /dev/null
1335231858Sbz		# Nothing to do for the middle node testing the default.
1336231858Sbz		sleep 1
1337231858Sbz		wait_remote_ready "STOP_${_n}_${i}"
1338231858Sbz		report_ipfw_count
1339231858Sbz
1340231858Sbz		ipfw delete 100 > /dev/null
1341231858Sbz		i=$((i + 1))
1342231858Sbz	done
1343231858Sbz
1344231858Sbz	_fwd_fib_symmetric_destructive_middle_cleanup_networking ${_maxfib}
1345231858Sbz}
1346231858Sbz
1347231858Sbzfwd_fib_symmetric_destructive_ifconfig()
1348231858Sbz{
1349231858Sbz	local _maxfib _n
1350231858Sbz	_maxfib=$1
1351231858Sbz
1352231858Sbz	_n="fwd_fib_symmetric_destructive_ifconfig"
1353231858Sbz
1354231858Sbz	print_debug "${_n} ${_maxfib}"
1355231858Sbz	case ${node} in
1356231858Sbz	left)	_fwd_fib_symmetric_destructive_left ${_n} ${_maxfib} ;;
1357231858Sbz	middle)	_fwd_fib_symmetric_destructive_middle_ifconfig \
1358231858Sbz		    ${_n} ${_maxfib} ;;
1359231858Sbz	right)	_fwd_fib_symmetric_destructive_right ${_n} ${_maxfib} ;;
1360231858Sbz	esac
1361231858Sbz}
1362231858Sbz
1363231858Sbzfwd_fib_symmetric_destructive_ipfw()
1364231858Sbz{
1365231858Sbz	local _maxfib _n
1366231858Sbz	_maxfib=$1
1367231858Sbz
1368231858Sbz	_n="fwd_fib_symmetric_destructive_ipfw"
1369231858Sbz
1370231858Sbz	print_debug "${_n} ${_maxfib}"
1371231858Sbz	case ${node} in
1372231858Sbz	left)	_fwd_fib_symmetric_destructive_left ${_n} ${_maxfib} ;;
1373231858Sbz	middle)	_fwd_fib_symmetric_destructive_middle_ipfw \
1374231858Sbz		    ${_n} ${_maxfib} ;;
1375231858Sbz	right)	_fwd_fib_symmetric_destructive_right ${_n} ${_maxfib} ;;
1376231858Sbz	esac
1377231858Sbz}
1378231858Sbz
1379231858Sbz################################################################################
1380231858Sbz
1381231858Sbz_fwd_fib_symmetric_destructive_defroute_left()
1382231858Sbz{
1383231858Sbz	local _n _maxfib i _addr
1384231858Sbz	_n="$1"
1385231858Sbz	_maxfib=$2
1386231858Sbz
1387231858Sbz	# Setup expected return code
1388231858Sbz	i=0
1389231858Sbz	while test ${i} -lt ${_maxfib}; do
1390231858Sbz		eval rc_${i}=0
1391231858Sbz		i=$((i + 1))
1392231858Sbz	done
1393231858Sbz
1394231858Sbz	# Add default route.
1395231858Sbz	route delete -net -inet6 default > /dev/null 2>&1 || true
1396231858Sbz	route add -net -inet6 default ${MIDDLELEFTADDR} > /dev/null
1397231858Sbz
1398231858Sbz	# Initiate probes for ICMP6, TCP and UDP.
1399231858Sbz	_addr="2001:2:1234::2"
1400231858Sbz	i=0
1401231858Sbz	while test ${i} -lt ${_maxfib}; do
1402231858Sbz
1403231858Sbz		sleep 1
1404231858Sbz
1405231858Sbz		send_control_msgs "START_${_n}_${i}"
1406231858Sbz
1407231858Sbz		test_icmp6 1 "${_addr}" "${_n}_${i}_icmp6"
1408231858Sbz		test_ulp 1 "${_n}_${i}" "${_addr}" ${CTRLPORT} ${i}
1409231858Sbz
1410231858Sbz		send_control_msgs "STOP_${_n}_${i}"
1411231858Sbz		_fwd_fib_symmetric_results "${_n}_${i}" ${i}
1412231858Sbz		fetch_ipfw_count "${_n}_${i}"
1413231858Sbz		i=$((i + 1))
1414231858Sbz	done
1415231858Sbz
1416231858Sbz	# Cleanup networking.
1417231858Sbz	route delete -net -inet6 default > /dev/null 2>&1
1418231858Sbz}
1419231858Sbz
1420231858Sbz_fwd_fib_symmetric_destructive_defroute_right()
1421231858Sbz{
1422231858Sbz	local _n _maxfib i _addr
1423231858Sbz	_n="$1"
1424231858Sbz	_maxfib=$2
1425231858Sbz
1426231858Sbz	# Setup networking (ideally we'd use the link-local).
1427231858Sbz	route delete -net -inet6 default > /dev/null 2>&1 ||  true
1428231858Sbz	route add -net -inet6 default ${MIDDLERIGHTADDR} > /dev/null 2>&1
1429231858Sbz	i=0
1430231858Sbz	while test ${i} -lt ${_maxfib}; do
1431231858Sbz		ifconfig ${IFACE} inet6 2001:2:${i}::2/64 -alias \
1432231858Sbz		    > /dev/null 2>&1 || true
1433231858Sbz		ifconfig ${IFACE} inet6 2001:2:${i}::2/64 alias
1434231858Sbz		i=$((i + 1))
1435231858Sbz	done
1436231858Sbz	_addr="2001:2:1234::2"
1437231858Sbz	ifconfig lo0 inet6 ${_addr}/128 alias
1438231858Sbz
1439231858Sbz	i=0
1440231858Sbz	while test ${i} -lt ${_maxfib}; do
1441231858Sbz		wait_remote_ready "START_${_n}_${i}"
1442231858Sbz
1443231858Sbz		# No need to do anything for ICMPv6.
1444231858Sbz		# Start reflect for TCP and UDP.
1445231858Sbz		test_ulp_reflect_one "${_n}_tcp" "-N -T TCP6 -A ${_addr}" \
1446231858Sbz		    ${i} ${CTRLPORT}
1447231858Sbz		test_ulp_reflect_one "${_n}_udp" "-N -T UDP6 -A ${_addr}" \
1448231858Sbz		    ${i} ${CTRLPORT}
1449231858Sbz
1450231858Sbz		wait_remote_ready "STOP_${_n}_${i}"
1451231858Sbz		i=$((i + 1))
1452231858Sbz	done
1453231858Sbz
1454231858Sbz	# Cleanup networking again.
1455231858Sbz	route delete -net -inet6 default > /dev/null 2>&1
1456231858Sbz	i=0
1457231858Sbz	while test ${i} -lt ${_maxfib}; do
1458231858Sbz		ifconfig ${IFACE} inet6 2001:2:${i}::2/64 -alias
1459231858Sbz		i=$((i + 1))
1460231858Sbz	done
1461231858Sbz	ifconfig lo0 inet6 ${_addr}/128 -alias
1462231858Sbz
1463231858Sbz}
1464231858Sbz
1465231858Sbz_fwd_fib_symmetric_destructive_defroute_middle_setup_networking()
1466231858Sbz{
1467231858Sbz	local _maxfib i j
1468231858Sbz	_maxfib=$1
1469231858Sbz
1470231858Sbz	# Setup networking.
1471231858Sbz	i=0
1472231858Sbz	while test ${i} -lt ${_maxfib}; do
1473231858Sbz		ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 -alias \
1474231858Sbz		    > /dev/null 2>&1 || true
1475231858Sbz		ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 alias
1476231858Sbz		j=0
1477231858Sbz		while test ${j} -lt ${_maxfib}; do
1478231858Sbz			# Only work on all other FIBs.
1479231858Sbz			if test ${j} -ne ${i}; then
1480231858Sbz				setfib -F ${j} route delete -net -inet6 \
1481231858Sbz				     2001:2:${i}::/64 > /dev/null
1482231858Sbz			fi
1483231858Sbz			j=$((j + 1))
1484231858Sbz		done
1485231858Sbz		setfib -F ${i} route delete -net -inet6 \
1486231858Sbz		     2001:2:1234::2 2001:2:${i}::2 > /dev/null 2>&1 || true
1487231858Sbz		setfib -F ${i} route add -net -inet6 \
1488231858Sbz		     2001:2:1234::2 2001:2:${i}::2 > /dev/null
1489231858Sbz		i=$((i + 1))
1490231858Sbz	done
1491231858Sbz}
1492231858Sbz
1493231858Sbz_fwd_fib_symmetric_destructive_defroute_middle_cleanup_networking()
1494231858Sbz{
1495231858Sbz	local _maxfib i
1496231858Sbz	_maxfib=$1
1497231858Sbz
1498231858Sbz	# Cleanup networking again.
1499231858Sbz	i=0
1500231858Sbz	while test ${i} -lt ${_maxfib}; do
1501231858Sbz		ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 -alias
1502231858Sbz		setfib -F ${i} route delete -net -inet6 \
1503231858Sbz		     2001:2:1234::2 2001:2:${i}::2 > /dev/null
1504231858Sbz		i=$((i + 1))
1505231858Sbz	done
1506231858Sbz}
1507231858Sbz
1508231858Sbz_fwd_fib_symmetric_destructive_defroute_middle_ifconfig()
1509231858Sbz{
1510231858Sbz	local _n _maxfib i
1511231858Sbz	_n="$1"
1512231858Sbz	_maxfib=$2
1513231858Sbz
1514231858Sbz	_fwd_fib_symmetric_destructive_defroute_middle_setup_networking \
1515231858Sbz	     ${_maxfib}
1516231858Sbz
1517231858Sbz	i=0
1518231858Sbz	while test ${i} -lt ${_maxfib}; do
1519231858Sbz		ifconfig ${IFACE} fib ${i}
1520231858Sbz		ifconfig ${IFACEFAR} fib ${i}
1521231858Sbz		setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
1522231858Sbz		wait_remote_ready "START_${_n}_${i}"
1523231858Sbz		ipfw -q zero > /dev/null
1524231858Sbz		# Nothing to do for the middle node testing the default.
1525231858Sbz		sleep 1
1526231858Sbz		wait_remote_ready "STOP_${_n}_${i}"
1527231858Sbz		report_ipfw_count
1528231858Sbz		i=$((i + 1))
1529231858Sbz	done
1530231858Sbz
1531231858Sbz	_fwd_fib_symmetric_destructive_defroute_middle_cleanup_networking \
1532231858Sbz	    ${_maxfib}
1533231858Sbz}
1534231858Sbz
1535231858Sbz_fwd_fib_symmetric_destructive_defroute_middle_ipfw()
1536231858Sbz{
1537231858Sbz	local _n _maxfib i _port
1538231858Sbz	_n="$1"
1539231858Sbz	_maxfib=$2
1540231858Sbz
1541231858Sbz	_fwd_fib_symmetric_destructive_defroute_middle_setup_networking \
1542231858Sbz	    ${_maxfib}
1543231858Sbz
1544231858Sbz	i=0
1545231858Sbz	while test ${i} -lt ${_maxfib}; do
1546231858Sbz		_port=$((CTRLPORT + 1 + i))
1547231858Sbz		ipfw add 100 setfib ${i} ipv6-icmp from any to any \
1548231858Sbz		    icmp6types 128 via ${IFACE} in > /dev/null
1549231858Sbz		ipfw add 100 setfib ${i} tcp from any to any \
1550231858Sbz		    dst-port ${_port} via ${IFACE} in > /dev/null
1551231858Sbz		ipfw add 100 setfib ${i} udp from any to any \
1552231858Sbz		    dst-port ${_port} via ${IFACE} in > /dev/null
1553231858Sbz
1554231858Sbz		ipfw add 100 setfib ${i} ipv6-icmp from any to any \
1555231858Sbz		    icmp6types 129 via ${IFACEFAR} in > /dev/null
1556231858Sbz		ipfw add 100 setfib ${i} tcp from any to any \
1557231858Sbz		    src-port ${_port} via ${IFACEFAR} in > /dev/null
1558231858Sbz		ipfw add 100 setfib ${i} udp from any to any \
1559231858Sbz		    src-port ${_port} via ${IFACEFAR} in > /dev/null
1560231858Sbz
1561231858Sbz		setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
1562231858Sbz		wait_remote_ready "START_${_n}_${i}"
1563231858Sbz		ipfw -q zero > /dev/null
1564231858Sbz		# Nothing to do for the middle node testing the default.
1565231858Sbz		sleep 1
1566231858Sbz		wait_remote_ready "STOP_${_n}_${i}"
1567231858Sbz		report_ipfw_count
1568231858Sbz
1569231858Sbz		ipfw delete 100 > /dev/null
1570231858Sbz		i=$((i + 1))
1571231858Sbz	done
1572231858Sbz
1573231858Sbz	_fwd_fib_symmetric_destructive_defroute_middle_cleanup_networking \
1574231858Sbz	    ${_maxfib}
1575231858Sbz}
1576231858Sbz
1577231858Sbzfwd_fib_symmetric_destructive_defroute_ifconfig()
1578231858Sbz{
1579231858Sbz	local _maxfib _n
1580231858Sbz	_maxfib=$1
1581231858Sbz
1582231858Sbz	_n="fwd_fib_symmetric_destructive_defroute_ifconfig"
1583231858Sbz
1584231858Sbz	print_debug "${_n} ${_maxfib}"
1585231858Sbz	case ${node} in
1586231858Sbz	left)	_fwd_fib_symmetric_destructive_defroute_left \
1587231858Sbz		    ${_n} ${_maxfib} ;;
1588231858Sbz	middle)	_fwd_fib_symmetric_destructive_defroute_middle_ifconfig \
1589231858Sbz		    ${_n} ${_maxfib} ;;
1590231858Sbz	right)	_fwd_fib_symmetric_destructive_defroute_right \
1591231858Sbz		    ${_n} ${_maxfib} ;;
1592231858Sbz	esac
1593231858Sbz}
1594231858Sbz
1595231858Sbzfwd_fib_symmetric_destructive_defroute_ipfw()
1596231858Sbz{
1597231858Sbz	local _maxfib _n
1598231858Sbz	_maxfib=$1
1599231858Sbz
1600231858Sbz	_n="fwd_fib_symmetric_destructive_defroute_ipfw"
1601231858Sbz
1602231858Sbz	print_debug "${_n} ${_maxfib}"
1603231858Sbz	case ${node} in
1604231858Sbz	left)	_fwd_fib_symmetric_destructive_defroute_left \
1605231858Sbz		    ${_n} ${_maxfib} ;;
1606231858Sbz	middle)	_fwd_fib_symmetric_destructive_defroute_middle_ipfw \
1607231858Sbz		    ${_n} ${_maxfib} ;;
1608231858Sbz	right)	_fwd_fib_symmetric_destructive_defroute_right \
1609231858Sbz		    ${_n} ${_maxfib} ;;
1610231858Sbz	esac
1611231858Sbz}
1612231858Sbz
1613231858Sbz################################################################################
1614231858Sbz#
1615231858Sbz# MAIN
1616231858Sbz#
1617231858Sbz
1618231858Sbz# Same for all hosts.
1619231858Sbzif test `sysctl -n security.jail.jailed` -eq 0; then
1620231858Sbz	kldload ipfw > /dev/null 2>&1 || kldstat -v | grep -q ipfw 
1621231858Sbzfi
1622231858Sbzipfw -f flush > /dev/null 2>&1 || die "please load ipfw in base system"
1623231858Sbzipfw add 65000 permit ip from any to any > /dev/null 2>&1
1624231858Sbz
1625231858Sbz# Per host setup.
1626231858Sbzsetup_networking
1627231858Sbzreachability_check
1628231858Sbz
1629231858Sbz#
1630231858Sbz# Tests
1631231858Sbz#
1632231858Sbz
1633231858Sbzfwd_default_fib_symmetric
1634231858Sbzfwd_default_fib_symmetric_ifconfig
1635231858Sbzfwd_default_fib_symmetric_ipfw
1636231858Sbz
1637231858Sbzfwd_fib_symmetric_ifconfig ${RT_NUMFIBS}
1638231858Sbzfwd_fib_symmetric_ipfw ${RT_NUMFIBS}
1639231858Sbz
1640231858Sbzfwd_fib_asymmetric_ifconfig ${RT_NUMFIBS}
1641231858Sbzfwd_fib_asymmetric_ipfw ${RT_NUMFIBS}
1642231858Sbz
1643231858Sbzfwd_fib_symmetric_destructive_ifconfig ${RT_NUMFIBS}
1644231858Sbzfwd_fib_symmetric_destructive_ipfw ${RT_NUMFIBS}
1645231858Sbz
1646231858Sbzfwd_fib_symmetric_destructive_defroute_ifconfig ${RT_NUMFIBS}
1647231858Sbzfwd_fib_symmetric_destructive_defroute_ipfw ${RT_NUMFIBS}
1648231858Sbz
1649231858Sbz# Per host cleanup.
1650231858Sbzcleanup_networking
1651231858Sbz
1652231858Sbz# end
1653