88597370a0
1) _x=$((_x + 1)) does not work while x=$((x + 1)) does. 2) Parameter Expansion, esp. "${x%%bar}" does not work if quoted. Correct typos and improve some details forwarding.sh already had in initiator, esp. related to ipfw accepting if the default is deny. Add an extra stat call to the "delay" function in addition to the touch which together is still a lot faster than sleep 1 but seems to help a lot more to mitigate the unrelated kernel race seen. Sponsored by: Cisco Systems, Inc.
1653 lines
38 KiB
Bash
Executable File
1653 lines
38 KiB
Bash
Executable File
#!/bin/sh
|
|
#-
|
|
# Copyright (c) 2012 Cisco Systems, Inc.
|
|
# All rights reserved.
|
|
#
|
|
# This software was developed by Bjoern Zeeb under contract to
|
|
# Cisco Systems, Inc..
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
# SUCH DAMAGE.
|
|
#
|
|
# $FreeBSD$
|
|
#
|
|
|
|
# Test setup:
|
|
#
|
|
# left ------------------------- middle ------------------------- right
|
|
# IFACE IFACE IFACEFAR IFACE
|
|
# LEFTADDR MIDDLELEFTADDR MIDDLERIGHTADDR RIGHTADDR
|
|
# forwarding=1
|
|
# initiator FIB tests reflector
|
|
|
|
# We will use the RFC5180 (and Errata) benchmarking working group prefix
|
|
# 2001:0002::/48 for testing.
|
|
PREFIX="2001:2:"
|
|
|
|
# Set IFACE to the real interface you want to run the test on.
|
|
# IFACEFAR is only relevant on the middle (forwarding) node and will be the
|
|
# 'right' side (far end) one.
|
|
: ${IFACE:=lo0}
|
|
: ${IFACEFAR:=lo0}
|
|
|
|
# Number of seconds to wait for peer node to synchronize for test.
|
|
: ${WAITS:=120}
|
|
|
|
# Control port we use to exchange messages between nodes to sync. tests, etc.
|
|
: ${CTRLPORT:=6666}
|
|
|
|
# Get the number of FIBs from the kernel.
|
|
RT_NUMFIBS=`sysctl -n net.fibs`
|
|
|
|
# This is the initiator and connected middle node.
|
|
LEFTADDR="2001:2:fe00::1"
|
|
MIDDLELEFTADDR="2001:2:fe00::2"
|
|
# This is the far end middle node and receiver side.
|
|
MIDDLERIGHTADDR="2001:2:ff00::1"
|
|
RIGHTADDR="2001:2:ff00::2"
|
|
|
|
# By default all commands must succeed. Individual tests may disable this
|
|
# temporary.
|
|
set -e
|
|
|
|
# Debug magic.
|
|
case "${DEBUG}" in
|
|
42) set -x ;;
|
|
esac
|
|
|
|
|
|
################################################################################
|
|
#
|
|
# Input validation.
|
|
#
|
|
|
|
node=$1
|
|
case ${node} in
|
|
left) ;;
|
|
middle) ;;
|
|
right) ;;
|
|
*) echo "ERROR: invalid node name '${node}'. Must be left, middle or" \
|
|
" right" >&1
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
################################################################################
|
|
#
|
|
# Helper functions.
|
|
#
|
|
check_rc()
|
|
{
|
|
local _rc _exp _testno _testname _msg _r
|
|
_rc=$1
|
|
_exp=$2
|
|
_testno=$3
|
|
_testname="$4"
|
|
_msg="$5"
|
|
|
|
_r="not ok"
|
|
if test ${_rc} -eq ${_exp}; then
|
|
_r="ok"
|
|
fi
|
|
echo "${_r} ${_testno} ${_testname} # ${_msg} ${_rc} ${_exp}"
|
|
}
|
|
|
|
print_debug()
|
|
{
|
|
local _msg
|
|
_msg="$*"
|
|
|
|
case ${DEBUG} in
|
|
''|0) ;;
|
|
*) echo "DEBUG: ${_msg}" >&2 ;;
|
|
esac
|
|
}
|
|
|
|
die()
|
|
{
|
|
local _msg
|
|
_msg="$*"
|
|
|
|
echo "ERROR: ${_msg}" >&2
|
|
exit 1
|
|
}
|
|
|
|
|
|
################################################################################
|
|
#
|
|
# Functions to configure networking and do a basic reachability check.
|
|
#
|
|
|
|
setup_networking()
|
|
{
|
|
|
|
print_debug "Setting up networking"
|
|
case ${node} in
|
|
left) ifconfig ${IFACE} inet6 ${LEFTADDR}/64 -alias \
|
|
> /dev/null 2>&1 || true
|
|
ifconfig ${IFACE} inet6 ${LEFTADDR}/64 alias up
|
|
ifconfig ${IFACE} fib 0
|
|
sysctl net.inet6.ip6.forwarding=0 > /dev/null
|
|
route delete -net -inet6 default > /dev/null 2>&1 || true
|
|
route delete -host -inet6 ${RIGHTADDR} ${MIDDLELEFTADDR} \
|
|
> /dev/null 2>&1 || true
|
|
route add -host -inet6 ${RIGHTADDR} ${MIDDLELEFTADDR} \
|
|
> /dev/null
|
|
route delete -host -inet6 ${MIDDLERIGHTADDR} ${MIDDLELEFTADDR} \
|
|
> /dev/null 2>&1 || true
|
|
route add -host -inet6 ${MIDDLERIGHTADDR} ${MIDDLELEFTADDR} \
|
|
> /dev/null 2>&1 || true
|
|
;;
|
|
middle) ifconfig ${IFACE} inet6 ${MIDDLELEFTADDR}/64 -alias \
|
|
> /dev/null 2>&1 || true
|
|
ifconfig ${IFACE} inet6 ${MIDDLELEFTADDR}/64 alias up
|
|
ifconfig ${IFACE} fib 0
|
|
ifconfig ${IFACEFAR} inet6 ${MIDDLERIGHTADDR}/64 -alias \
|
|
> /dev/null 2>&1 || true
|
|
ifconfig ${IFACEFAR} inet6 ${MIDDLERIGHTADDR}/64 alias up
|
|
ifconfig ${IFACEFAR} fib 0
|
|
sysctl net.inet6.ip6.forwarding=1 > /dev/null
|
|
;;
|
|
right) ifconfig ${IFACE} inet6 ${RIGHTADDR}/64 -alias \
|
|
> /dev/null 2>&1 || true
|
|
ifconfig ${IFACE} inet6 ${RIGHTADDR}/64 alias up
|
|
ifconfig ${IFACE} fib 0
|
|
sysctl net.inet6.ip6.forwarding=0 > /dev/null
|
|
route delete -net -inet6 default > /dev/null 2>&1 || true
|
|
route delete -host -inet6 ${LEFTADDR} ${MIDDLERIGHTADDR} \
|
|
> /dev/null 2>&1 || true
|
|
route add -host -inet6 ${LEFTADDR} ${MIDDLERIGHTADDR} \
|
|
> /dev/null
|
|
route delete -host -inet6 ${MIDDLELEFTADDR} ${MIDDLERIGHTADDR} \
|
|
> /dev/null 2>&1 || true
|
|
route add -host -inet6 ${MIDDLELEFTADDR} ${MIDDLERIGHTADDR} \
|
|
> /dev/null
|
|
;;
|
|
esac
|
|
|
|
# Let things settle.
|
|
print_debug "Waiting 4 seconds for things to settle"
|
|
sleep 4
|
|
}
|
|
|
|
cleanup_networking()
|
|
{
|
|
|
|
case ${node} in
|
|
left) ifconfig ${IFACE} inet6 ${LEFTADDR}/64 -alias
|
|
;;
|
|
middle) ifconfig ${IFACE} inet6 ${MIDDLELEFTADDR}/64 -alias
|
|
ifconfig ${IFACEFAR} inet6 ${MIDDLERIGHTADDR}/64 -alias
|
|
sysctl net.inet6.ip6.forwarding=0 > /dev/null
|
|
;;
|
|
right) ifconfig ${IFACE} inet6 ${RIGHTADDR}/64 -alias
|
|
;;
|
|
esac
|
|
print_debug "Cleaned up networking"
|
|
}
|
|
|
|
_reachability_check()
|
|
{
|
|
local _addr _rc
|
|
_addr="$1"
|
|
|
|
ping6 -n -c1 ${_addr} > /dev/null 2>&1
|
|
_rc=$?
|
|
case ${_rc} in
|
|
0) ;;
|
|
*) print_debug "cannot ping6 ${_addr}, rc=${_rc}"
|
|
return 1
|
|
;;
|
|
esac
|
|
return 0
|
|
}
|
|
|
|
reachability_check()
|
|
{
|
|
local _i rc
|
|
|
|
# Try to reach all control addresses on other nodes.
|
|
# We need to loop for a while as we cannot expect all to be up
|
|
# the very same moment.
|
|
i=1
|
|
rc=42
|
|
while test ${rc} -ne 0 -a ${i} -le ${WAITS}; do
|
|
print_debug "${i}/${WAITS} trying to ping6 control addresses."
|
|
rc=0
|
|
set +e
|
|
case ${node} in
|
|
left) _reachability_check ${MIDDLELEFTADDR}
|
|
rc=$((rc + $?))
|
|
_reachability_check ${MIDDLERIGHTADDR}
|
|
rc=$((rc + $?))
|
|
_reachability_check ${RIGHTADDR}
|
|
rc=$((rc + $?))
|
|
;;
|
|
middle) _reachability_check ${LEFTADDR}
|
|
rc=$((rc + $?))
|
|
_reachability_check ${RIGHTADDR}
|
|
rc=$((rc + $?))
|
|
;;
|
|
right) _reachability_check ${MIDDLERIGHTADDR}
|
|
rc=$((rc + $?))
|
|
_reachability_check ${MIDDLELEFTADDR}
|
|
rc=$((rc + $?))
|
|
_reachability_check ${LEFTADDR}
|
|
rc=$((rc + $?))
|
|
;;
|
|
esac
|
|
set -e
|
|
sleep 1
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
################################################################################
|
|
#
|
|
# "Greeting" handling to sync notes to the agreed upon next test case.
|
|
#
|
|
send_control_msg()
|
|
{
|
|
local _case _addr i rc _msg _keyword _fibs
|
|
_case="$1"
|
|
_addr="$2"
|
|
|
|
set +e
|
|
i=0
|
|
rc=-1
|
|
while test ${i} -lt ${WAITS} -a ${rc} -ne 0; do
|
|
print_debug "Sending control msg #${i} to peer ${_addr}"
|
|
_msg=`echo "${_case} ${RT_NUMFIBS}" | \
|
|
nc -6 -w 1 ${_addr} ${CTRLPORT}`
|
|
rc=$?
|
|
i=$((i + 1))
|
|
# Might sleep longer in total but better than to DoS
|
|
# and not get anywhere.
|
|
sleep 1
|
|
done
|
|
set -e
|
|
|
|
read _keyword _fibs <<EOI
|
|
${_msg}
|
|
EOI
|
|
print_debug "_keyword=${_keyword}"
|
|
print_debug "_fibs=${_fibs}"
|
|
case ${_keyword} in
|
|
${_case});;
|
|
*) die "Got invalid keyword from ${_addr} in control message:" \
|
|
"${_msg}"
|
|
;;
|
|
esac
|
|
if test ${_fibs} -ne ${RT_NUMFIBS}; then
|
|
die "Number of FIBs not matching ours (${RT_NUMFIBS}) in" \
|
|
"control message from ${_addr}: ${_msg}"
|
|
fi
|
|
|
|
print_debug "Successfully exchanged control message with ${_addr}."
|
|
}
|
|
|
|
send_control_msgs()
|
|
{
|
|
local _case _addr
|
|
_case="$1"
|
|
|
|
# Always start with the far end. Otherwise we will cut that off when
|
|
# cleanly taering down things again.
|
|
for _addr in ${RIGHTADDR} ${MIDDLELEFTADDR}; do
|
|
send_control_msg "${_case}" ${_addr}
|
|
done
|
|
|
|
# Allow us to flush ipfw counters etc before new packets will arrive.
|
|
sleep 1
|
|
}
|
|
|
|
# We are setup. Wait for the initiator to tell us that it is ready.
|
|
wait_remote_ready()
|
|
{
|
|
local _case _msg _keyword _fibs
|
|
_case="$1"
|
|
|
|
# Wait for the remote to connect and start things.
|
|
# We tell it the magic keyword, and our number of FIBs.
|
|
_msg=`echo "${_case} ${RT_NUMFIBS}" | nc -6 -l ${CTRLPORT}`
|
|
|
|
read _keyword _fibs <<EOI
|
|
${_msg}
|
|
EOI
|
|
print_debug "_keyword=${_keyword}"
|
|
print_debug "_fibs=${_fibs}"
|
|
case ${_keyword} in
|
|
${_case});;
|
|
*) die "Got invalid keyword in control message: ${_msg}"
|
|
;;
|
|
esac
|
|
if test ${_fibs} -ne ${RT_NUMFIBS}; then
|
|
die "Number of FIBs not matching ours (${RT_NUMFIBS}) in" \
|
|
"control message: ${_msg}"
|
|
fi
|
|
|
|
print_debug "Successfully received control message."
|
|
}
|
|
|
|
################################################################################
|
|
#
|
|
# Test case helper functions.
|
|
#
|
|
# Please note that neither on the intiator nor the reflector are FIBs despite
|
|
# a variable name might indicate. If such a variable is used it mirrors FIB
|
|
# numbers from the middle node to match for test cases.
|
|
#
|
|
test_icmp6()
|
|
{
|
|
local _maxfibs _addr _n _testno i _rc _ec
|
|
_maxfibs=$1
|
|
_addr="$2"
|
|
_n="$3"
|
|
|
|
printf "1..%d\n" ${_maxfibs}
|
|
_testno=1
|
|
set +e
|
|
i=0
|
|
while test ${i} -lt ${_maxfibs}; do
|
|
_txt="${_n}_${i}"
|
|
print_debug "Testing ${_txt}"
|
|
|
|
# Generate HEX for ping6 payload.
|
|
_fibtxt=`echo "${_txt}" | hd -v | cut -b11-60 | tr -d ' \r\n'`
|
|
|
|
eval _rc="\${rc_${i}}"
|
|
ping6 -n -c1 -p ${_fibtxt} ${_addr} > /dev/null 2>&1
|
|
_ec=$?
|
|
# We need to normalize the exit code of ping6.
|
|
case ${_ec} in
|
|
0) ;;
|
|
*) _ec=1 ;;
|
|
esac
|
|
check_rc ${_ec} ${_rc} ${_testno} "${_txt}" "FIB ${i} ${_addr}"
|
|
testno=$((testno + 1))
|
|
i=$((i + 1))
|
|
done
|
|
set -e
|
|
}
|
|
|
|
test_ulp_reflect_one()
|
|
{
|
|
local _txt _opts port fib
|
|
_txt="$1"
|
|
_opts="$2"
|
|
port=$3
|
|
fib=$4
|
|
|
|
print_debug "./reflect -p $((port + 1 + fib)) -t ${_txt}" "${_opts}"
|
|
./reflect -p $((port + 1 + fib)) -t ${_txt} ${_opts}
|
|
print_debug "reflect '${_txt}' terminated without error."
|
|
}
|
|
|
|
test_ulp_reflect_multiple()
|
|
{
|
|
local _maxfibs _txt _opts i _jobs _p
|
|
_maxfibs=$1
|
|
_txt="$2"
|
|
_opts="$3"
|
|
|
|
i=0
|
|
_jobs=""
|
|
while test ${i} -lt ${_maxfibs}; do
|
|
print_debug "./reflect -p $((CTRLPORT + 1000 + i))" \
|
|
"-t ${_txt} ${_opts} -N -f ${i} &"
|
|
./reflect -p $((CTRLPORT + 1000 + i)) \
|
|
-t ${_txt} ${_opts} -N -f ${i} &
|
|
_p=$!
|
|
_jobs="${_jobs}${_p} "
|
|
i=$((i + 1))
|
|
done
|
|
|
|
# Start OOB control connection for START/DONE.
|
|
testrx_run_one "${_txt}" "${_opts}"
|
|
print_debug "KILL ${_jobs}"
|
|
for i in ${_jobs}; do
|
|
kill ${i} || true
|
|
done
|
|
#killall reflect || true
|
|
print_debug "reflects for '${_txt}' terminated without error."
|
|
}
|
|
|
|
nc_send_recv()
|
|
{
|
|
local _loops _msg _expreply _addr _port _opts i
|
|
_loops=$1
|
|
_msg="$2"
|
|
_expreply="$3"
|
|
_addr=$4
|
|
_port=$5
|
|
_opts="$6"
|
|
|
|
i=0
|
|
while test ${i} -lt ${_loops}; do
|
|
i=$((i + 1))
|
|
print_debug "e ${_msg} | nc -6 -w1 ${_opts} ${_addr} ${_port}"
|
|
_reply=`echo "${_msg}" | nc -6 -w1 ${_opts} ${_addr} ${_port}`
|
|
if test "${_reply}" != "${_expreply}"; then
|
|
if test ${i} -lt ${_loops}; then
|
|
sleep 1
|
|
else
|
|
# Must let caller decide how to handle the error.
|
|
# die "Got invalid reply from peer." \
|
|
# "Expected '${_expreply}', got '${_reply}'"
|
|
return 1
|
|
fi
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
return 0
|
|
}
|
|
|
|
test_ulp()
|
|
{
|
|
local maxfibs _msg _addr port fib i _txt testno _rc _reply
|
|
maxfibs=$1
|
|
_msg="$2"
|
|
_addr=$3
|
|
port=$4
|
|
fib=$5
|
|
|
|
printf "1..%d\n" $((${maxfibs} * 2))
|
|
testno=1
|
|
i=0
|
|
while test ${i} -lt ${maxfibs}; do
|
|
|
|
if test ${i} -eq $((${maxfibs} - 1)); then
|
|
# Last one; signal DONE.
|
|
_txt="DONE ${_msg}_${i}"
|
|
else
|
|
_txt="DONE ${_msg}_${i}"
|
|
fi
|
|
|
|
eval _rc="\${rc_${i}}"
|
|
|
|
# Test TCP.
|
|
nc_send_recv ${maxfibs} "${_txt}" "${_txt}" ${_addr} \
|
|
$((${port} + 1 + fib)) ""
|
|
check_rc $? ${_rc} ${testno} "${_msg}_${i}_tcp" \
|
|
"[${_addr}]:$((${port} + 1 + fib)) ${_reply}"
|
|
testno=$((testno + 1))
|
|
sleep 1
|
|
|
|
# Test UDP.
|
|
nc_send_recv ${maxfibs} "${_txt}" "${_txt}" ${_addr} \
|
|
$((${port} + 1 + fib)) "-u"
|
|
check_rc $? ${_rc} ${testno} "${_msg}_${i}_udp" \
|
|
"[${_addr}]:$((${port} + 1 + fib)) ${_reply}"
|
|
sleep 1
|
|
|
|
i=$((i + 1))
|
|
testno=$((testno + 1))
|
|
done
|
|
}
|
|
|
|
setup_ipfw_count()
|
|
{
|
|
local i port maxfib _p _fib _ofib
|
|
port=$1
|
|
maxfib=$2
|
|
_fib=$3
|
|
_ofib=$4
|
|
|
|
i=0
|
|
while test ${i} -lt ${maxfib}; do
|
|
|
|
case ${_ofib} in
|
|
-1) _p=$((port + 1 + i)) ;;
|
|
*) _p=$((port + 1 + maxfib - 1 - i)) ;;
|
|
esac
|
|
|
|
# Only count ICMP6 echo replies.
|
|
ipfw add $((10000 + i)) count ipv6-icmp from any to any \
|
|
icmp6types 129 fib ${i} via ${IFACE} out > /dev/null
|
|
ipfw add $((10000 + i)) count tcp from any to any \
|
|
src-port ${_p} fib ${i} via ${IFACE} out > /dev/null
|
|
ipfw add $((10000 + i)) count udp from any to any \
|
|
src-port ${_p} fib ${i} via ${IFACE} out > /dev/null
|
|
|
|
# Only count ICMP6 echo requests.
|
|
ipfw add $((20000 + i)) count ipv6-icmp from any to any \
|
|
icmp6types 128 fib ${i} via ${IFACEFAR} out > /dev/null
|
|
ipfw add $((20000 + i)) count tcp from any to any \
|
|
dst-port $((${port} + 1 + i)) fib ${i} \
|
|
via ${IFACEFAR} out > /dev/null
|
|
ipfw add $((20000 + i)) count udp from any to any \
|
|
dst-port $((${port} + 1 + i)) fib ${i} \
|
|
via ${IFACEFAR} out > /dev/null
|
|
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
report_ipfw_count()
|
|
{
|
|
local _fib _o i _rstr _c _req _p _opts base
|
|
_o="$2"
|
|
|
|
case ${DEBUG} in
|
|
''|0) ;;
|
|
*) ipfw show ;;
|
|
esac
|
|
|
|
_rstr="RESULTS "
|
|
for base in 10000 20000; do
|
|
for _o in i t u; do
|
|
case ${base} in
|
|
10000) _rstr="${_rstr}\nLEFT " ;;
|
|
20000) _rstr="${_rstr}\nRIGHT " ;;
|
|
esac
|
|
case ${_o} in
|
|
i) _rstr="${_rstr}ICMP6 " ;;
|
|
t) _rstr="${_rstr}TCP " ;;
|
|
u) _rstr="${_rstr}UDP " ;;
|
|
esac
|
|
i=0
|
|
while test ${i} -lt ${RT_NUMFIBS}; do
|
|
|
|
case "${_o}" in
|
|
i) _c=`ipfw show $((${base} + i)) | \
|
|
awk '/ ipv6-icmp / { print $2 }'` ;;
|
|
t) _c=`ipfw show $((${base} + i)) | \
|
|
awk '/ tcp / { print $2 }'` ;;
|
|
u) _c=`ipfw show $((${base} + i)) | \
|
|
awk '/ udp / { print $2 }'` ;;
|
|
esac
|
|
_rstr="${_rstr}${i} ${_c},"
|
|
|
|
i=$((i + 1))
|
|
done
|
|
done
|
|
i=0
|
|
while test ${i} -lt ${RT_NUMFIBS}; do
|
|
ipfw delete $((${base} + i)) > /dev/null 2>&1 || true
|
|
i=$((i + 1))
|
|
done
|
|
done
|
|
|
|
# We do not care about the request.
|
|
_req=`printf "${_rstr}" | nc -6 -l $((${CTRLPORT} - 1))`
|
|
print_debug "$? -- ${_req} -- ${_rstr}"
|
|
}
|
|
|
|
fetch_ipfw_count()
|
|
{
|
|
local _n _reply _line _edge _type _fib _count _rc _ec _status
|
|
_n="$1"
|
|
|
|
# Leave node some time to build result set.
|
|
sleep 3
|
|
|
|
print_debug "Asking for ipfw count results..."
|
|
set +e
|
|
nc_send_recv 1 "RESULT REQUEST" "" ${MIDDLELEFTADDR} \
|
|
$((${CTRLPORT} - 1)) ""
|
|
set -e
|
|
case "${_reply}" in
|
|
RESULTS\ *) ;;
|
|
*) die "Got invalid reply from peer." \
|
|
"Expected 'RESULTS ...', got '${_reply}'" ;;
|
|
esac
|
|
|
|
# Trim "RESULTS "
|
|
_reply=${_reply#* }
|
|
|
|
# FIBs * {left, right} * {icmp6, tcp, udp}
|
|
printf "1..%d\n" $((RT_NUMFIBS * 2 * 3))
|
|
testno=1
|
|
while read _line; do
|
|
print_debug "_line == ${_line}"
|
|
_edge=${_line%% *}
|
|
_line=${_line#* }
|
|
_type=${_line%% *}
|
|
_line=${_line#* }
|
|
|
|
while read _fib _count; do
|
|
eval _em="\${rc_${_n}_${_edge}_${_type}_${_fib}}"
|
|
: ${_em:=-42}
|
|
if test ${_count} -gt 0; then
|
|
_rc=1
|
|
else
|
|
_rc=0
|
|
fi
|
|
if test ${_rc} -eq ${_em}; then
|
|
_status="ok"
|
|
else
|
|
_status="not ok"
|
|
fi
|
|
printf "%s %d %s # count=%s _rc=%d _em=%d\n" \
|
|
"${_status}" ${testno} "${_n}_${_edge}_${_type}_${_fib}" \
|
|
${_count} ${_rc} ${_em}
|
|
testno=$((testno + 1))
|
|
done <<EOi
|
|
`printf "${_line}" | tr ',' '\n'`
|
|
EOi
|
|
|
|
done <<EOo
|
|
`printf "${_reply}" | grep -v "^$"`
|
|
EOo
|
|
|
|
print_debug "ipfw count results processed"
|
|
}
|
|
|
|
################################################################################
|
|
#
|
|
# Test cases.
|
|
#
|
|
# In general we set the FIB on in, but count on out.
|
|
#
|
|
|
|
_fwd_default_fib_symmetric_results()
|
|
{
|
|
local _n i _edge _type _rc
|
|
_n="$1"
|
|
|
|
i=0
|
|
while test ${i} -lt ${RT_NUMFIBS}; do
|
|
for _edge in "LEFT" "RIGHT"; do
|
|
for _type in "ICMP6" "TCP" "UDP"; do
|
|
|
|
case ${i} in
|
|
0) eval rc_${_n}_${_edge}_${_type}_${i}=1
|
|
#print_debug \
|
|
# "rc_${_n}_${_edge}_${_type}_${i}=1"
|
|
;;
|
|
*) eval rc_${_n}_${_edge}_${_type}_${i}=0
|
|
#print_debug \
|
|
# "rc_${_n}_${_edge}_${_type}_${i}=0"
|
|
;;
|
|
esac
|
|
|
|
done
|
|
done
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
_fwd_default_fib_symmetric_left()
|
|
{
|
|
local _n
|
|
_n="$1"
|
|
|
|
send_control_msgs "START_${_n}"
|
|
|
|
# Setup expected return code
|
|
rc_0=0
|
|
|
|
# Initiate probes for ICMP6, TCP and UDP.
|
|
test_icmp6 1 ${RIGHTADDR} "${_n}_icmp6"
|
|
test_ulp 1 "${_n}" ${RIGHTADDR} ${CTRLPORT} 0
|
|
|
|
send_control_msgs "STOP_${_n}"
|
|
_fwd_default_fib_symmetric_results "${_n}"
|
|
fetch_ipfw_count "${_n}"
|
|
}
|
|
|
|
_fwd_default_fib_symmetric_middle()
|
|
{
|
|
local _n
|
|
_n="$1"
|
|
|
|
setup_ipfw_count ${CTRLPORT} ${RT_NUMFIBS} 0 -1
|
|
wait_remote_ready "START_${_n}"
|
|
ipfw -q zero > /dev/null
|
|
# Nothing to do for the middle node testing the default.
|
|
sleep 1
|
|
wait_remote_ready "STOP_${_n}"
|
|
report_ipfw_count
|
|
}
|
|
|
|
_fwd_default_fib_symmetric_right()
|
|
{
|
|
local _n
|
|
_n="$1"
|
|
|
|
wait_remote_ready "START_${_n}"
|
|
|
|
# No need to do anything for ICMPv6.
|
|
# Start reflect for TCP and UDP.
|
|
test_ulp_reflect_one "${_n}_tcp" "-N -T TCP6" 0 ${CTRLPORT}
|
|
test_ulp_reflect_one "${_n}_udp" "-N -T UDP6" 0 ${CTRLPORT}
|
|
|
|
wait_remote_ready "STOP_${_n}"
|
|
}
|
|
|
|
fwd_default_fib_symmetric()
|
|
{
|
|
local _n
|
|
|
|
_n="fwd_default_fib_symmetric"
|
|
|
|
print_debug "${_n}"
|
|
case ${node} in
|
|
left) _fwd_default_fib_symmetric_left ${_n} ;;
|
|
middle) _fwd_default_fib_symmetric_middle ${_n} ;;
|
|
right) _fwd_default_fib_symmetric_right ${_n} ;;
|
|
esac
|
|
}
|
|
|
|
_fwd_default_fib_symmetric_middle_ifconfig()
|
|
{
|
|
local _n
|
|
_n="$1"
|
|
|
|
ifconfig ${IFACE} fib 0
|
|
ifconfig ${IFACEFAR} fib 0
|
|
setup_ipfw_count ${CTRLPORT} ${RT_NUMFIBS} 0 -1
|
|
wait_remote_ready "START_${_n}"
|
|
ipfw -q zero > /dev/null
|
|
# Nothing to do for the middle node testing the default.
|
|
sleep 1
|
|
wait_remote_ready "STOP_${_n}"
|
|
report_ipfw_count
|
|
}
|
|
|
|
fwd_default_fib_symmetric_ifconfig()
|
|
{
|
|
local _n
|
|
|
|
_n="fwd_default_fib_symmetric_ifconfig"
|
|
|
|
print_debug "${_n}"
|
|
case ${node} in
|
|
left) _fwd_default_fib_symmetric_left ${_n} ;;
|
|
middle) _fwd_default_fib_symmetric_middle_ifconfig ${_n} ;;
|
|
right) _fwd_default_fib_symmetric_right ${_n} ;;
|
|
esac
|
|
}
|
|
|
|
_fwd_default_fib_symmetric_middle_ipfw()
|
|
{
|
|
local _n
|
|
_n="$1"
|
|
|
|
ipfw add 100 setfib 0 ipv6-icmp from any to any \
|
|
icmp6types 128 via ${IFACE} in > /dev/null
|
|
ipfw add 100 setfib 0 ip6 from any to any \
|
|
proto tcp dst-port ${CTRLPORT} via ${IFACE} in > /dev/null
|
|
ipfw add 100 setfib 0 ip6 from any to any \
|
|
proto udp dst-port ${CTRLPORT} via ${IFACE} in > /dev/null
|
|
|
|
ipfw add 100 setfib 0 ipv6-icmp from any to any \
|
|
icmp6types 128 via ${IFACEFAR} in > /dev/null
|
|
ipfw add 100 setfib 0 tcp from any to any \
|
|
dst-port ${CTRLPORT} via ${IFACEFAR} in > /dev/null
|
|
ipfw add 100 setfib 0 udp from any to any \
|
|
dst-port ${CTRLPORT} via ${IFACEFAR} in > /dev/null
|
|
|
|
setup_ipfw_count ${CTRLPORT} ${RT_NUMFIBS} 0 -1
|
|
wait_remote_ready "START_${_n}"
|
|
ipfw -q zero > /dev/null
|
|
# Nothing to do for the middle node testing the default.
|
|
sleep 1
|
|
wait_remote_ready "STOP_${_n}"
|
|
report_ipfw_count
|
|
|
|
ipfw delete 100 > /dev/null
|
|
}
|
|
|
|
fwd_default_fib_symmetric_ipfw()
|
|
{
|
|
local _n
|
|
|
|
_n="fwd_default_fib_symmetric_ipfw"
|
|
|
|
print_debug "${_n}"
|
|
case ${node} in
|
|
left) _fwd_default_fib_symmetric_left ${_n} ;;
|
|
middle) _fwd_default_fib_symmetric_middle_ipfw ${_n} ;;
|
|
right) _fwd_default_fib_symmetric_right ${_n} ;;
|
|
esac
|
|
}
|
|
|
|
################################################################################
|
|
|
|
_fwd_fib_symmetric_results()
|
|
{
|
|
local _n _fib i _edge _type _rc
|
|
_n="$1"
|
|
_fib=$2
|
|
|
|
i=0
|
|
while test ${i} -lt ${RT_NUMFIBS}; do
|
|
for _edge in "LEFT" "RIGHT"; do
|
|
for _type in "ICMP6" "TCP" "UDP"; do
|
|
|
|
case ${i} in
|
|
${_fib}) eval rc_${_n}_${_edge}_${_type}_${i}=1
|
|
#print_debug \
|
|
# "rc_${_n}_${_edge}_${_type}_${i}=1"
|
|
;;
|
|
*) eval rc_${_n}_${_edge}_${_type}_${i}=0
|
|
#print_debug \
|
|
# "rc_${_n}_${_edge}_${_type}_${i}=0"
|
|
;;
|
|
esac
|
|
|
|
done
|
|
done
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
_fwd_fib_symmetric_left()
|
|
{
|
|
local _n _maxfib i
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
# Setup expected return code
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
eval rc_${i}=0
|
|
i=$((i + 1))
|
|
done
|
|
|
|
# Initiate probes for ICMP6, TCP and UDP.
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
|
|
sleep 1
|
|
|
|
send_control_msgs "START_${_n}_${i}"
|
|
|
|
test_icmp6 1 ${RIGHTADDR} "${_n}_${i}_icmp6"
|
|
test_ulp 1 "${_n}_${i}" ${RIGHTADDR} ${CTRLPORT} ${i}
|
|
|
|
send_control_msgs "STOP_${_n}_${i}"
|
|
_fwd_fib_symmetric_results "${_n}_${i}" ${i}
|
|
fetch_ipfw_count "${_n}_${i}"
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
_fwd_fib_symmetric_right()
|
|
{
|
|
local _n _maxfib i
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
wait_remote_ready "START_${_n}_${i}"
|
|
|
|
# No need to do anything for ICMPv6.
|
|
# Start reflect for TCP and UDP.
|
|
test_ulp_reflect_one "${_n}_tcp" "-N -T TCP6" ${i} ${CTRLPORT}
|
|
test_ulp_reflect_one "${_n}_udp" "-N -T UDP6" ${i} ${CTRLPORT}
|
|
|
|
wait_remote_ready "STOP_${_n}_${i}"
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
_fwd_fib_symmetric_middle_ifconfig()
|
|
{
|
|
local _n _maxfib i
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
ifconfig ${IFACE} fib ${i}
|
|
ifconfig ${IFACEFAR} fib ${i}
|
|
setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
|
|
wait_remote_ready "START_${_n}_${i}"
|
|
ipfw -q zero > /dev/null
|
|
# Nothing to do for the middle node testing the default.
|
|
sleep 1
|
|
wait_remote_ready "STOP_${_n}_${i}"
|
|
report_ipfw_count
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
_fwd_fib_symmetric_middle_ipfw()
|
|
{
|
|
local _n _maxfib i _port
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
_port=$((CTRLPORT + 1 + i))
|
|
ipfw add 100 setfib ${i} ipv6-icmp from any to any \
|
|
icmp6types 128 via ${IFACE} in > /dev/null
|
|
ipfw add 100 setfib ${i} tcp from any to any \
|
|
dst-port ${_port} via ${IFACE} in > /dev/null
|
|
ipfw add 100 setfib ${i} udp from any to any \
|
|
dst-port ${_port} via ${IFACE} in > /dev/null
|
|
|
|
ipfw add 100 setfib ${i} ipv6-icmp from any to any \
|
|
icmp6types 129 via ${IFACEFAR} in > /dev/null
|
|
ipfw add 100 setfib ${i} tcp from any to any \
|
|
src-port ${_port} via ${IFACEFAR} in > /dev/null
|
|
ipfw add 100 setfib ${i} udp from any to any \
|
|
src-port ${_port} via ${IFACEFAR} in > /dev/null
|
|
|
|
setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
|
|
wait_remote_ready "START_${_n}_${i}"
|
|
ipfw -q zero > /dev/null
|
|
# Nothing to do for the middle node testing the default.
|
|
sleep 1
|
|
wait_remote_ready "STOP_${_n}_${i}"
|
|
report_ipfw_count
|
|
|
|
ipfw delete 100 > /dev/null
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
fwd_fib_symmetric_ifconfig()
|
|
{
|
|
local _maxfib _n
|
|
_maxfib=$1
|
|
|
|
_n="fwd_fib_symmetric_ifconfig"
|
|
|
|
print_debug "${_n} ${_maxfib}"
|
|
case ${node} in
|
|
left) _fwd_fib_symmetric_left ${_n} ${_maxfib} ;;
|
|
middle) _fwd_fib_symmetric_middle_ifconfig ${_n} ${_maxfib} ;;
|
|
right) _fwd_fib_symmetric_right ${_n} ${_maxfib} ;;
|
|
esac
|
|
}
|
|
|
|
fwd_fib_symmetric_ipfw()
|
|
{
|
|
local _maxfib _n
|
|
_maxfib=$1
|
|
|
|
_n="fwd_fib_symmetric_ipfw"
|
|
|
|
print_debug "${_n} ${_maxfib}"
|
|
case ${node} in
|
|
left) _fwd_fib_symmetric_left ${_n} ${_maxfib} ;;
|
|
middle) _fwd_fib_symmetric_middle_ipfw ${_n} ${_maxfib} ;;
|
|
right) _fwd_fib_symmetric_right ${_n} ${_maxfib} ;;
|
|
esac
|
|
}
|
|
|
|
################################################################################
|
|
|
|
_fwd_fib_asymmetric_results()
|
|
{
|
|
local _n fib maxfib i _edge _type _rc
|
|
_n="$1"
|
|
fib=$2
|
|
maxfib=$3
|
|
|
|
i=0
|
|
while test ${i} -lt ${maxfib}; do
|
|
_edge="RIGHT"
|
|
for _type in "ICMP6" "TCP" "UDP"; do
|
|
|
|
case ${i} in
|
|
${fib}) eval rc_${_n}_${_edge}_${_type}_${i}=1
|
|
#print_debug \
|
|
# "rc_${_n}_${_edge}_${_type}_${i}=1"
|
|
;;
|
|
*) eval rc_${_n}_${_edge}_${_type}_${i}=0
|
|
#print_debug \
|
|
# "rc_${_n}_${_edge}_${_type}_${i}=0"
|
|
;;
|
|
esac
|
|
|
|
done
|
|
i=$((i + 1))
|
|
done
|
|
fib=$((maxfib - 1 - fib))
|
|
i=0
|
|
while test ${i} -lt ${maxfib}; do
|
|
_edge="LEFT"
|
|
for _type in "ICMP6" "TCP" "UDP"; do
|
|
|
|
case ${i} in
|
|
${fib}) eval rc_${_n}_${_edge}_${_type}_${i}=1
|
|
#print_debug \
|
|
# "rc_${_n}_${_edge}_${_type}_${i}=1"
|
|
;;
|
|
*) eval rc_${_n}_${_edge}_${_type}_${i}=0
|
|
#print_debug \
|
|
# "rc_${_n}_${_edge}_${_type}_${i}=0"
|
|
;;
|
|
esac
|
|
|
|
done
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
_fwd_fib_asymmetric_left()
|
|
{
|
|
local _n _maxfib i
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
# Setup expected return code
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
eval rc_${i}=0
|
|
i=$((i + 1))
|
|
done
|
|
|
|
# Initiate probes for ICMP6, TCP and UDP.
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
|
|
sleep 1
|
|
|
|
send_control_msgs "START_${_n}_${i}"
|
|
|
|
test_icmp6 1 ${RIGHTADDR} "${_n}_${i}_icmp6"
|
|
test_ulp 1 "${_n}_${i}" ${RIGHTADDR} ${CTRLPORT} ${i}
|
|
|
|
send_control_msgs "STOP_${_n}_${i}"
|
|
_fwd_fib_asymmetric_results "${_n}_${i}" ${i} ${_maxfib}
|
|
fetch_ipfw_count "${_n}_${i}"
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
_fwd_fib_asymmetric_middle_ifconfig()
|
|
{
|
|
local _n maxfib i
|
|
_n="$1"
|
|
maxfib=$2
|
|
|
|
i=0
|
|
while test ${i} -lt ${maxfib}; do
|
|
ifconfig ${IFACE} fib ${i}
|
|
ifconfig ${IFACEFAR} fib $((${maxfib} - 1 - ${i}))
|
|
setup_ipfw_count ${CTRLPORT} ${maxfib} ${i} \
|
|
$((${maxfib} - 1 - ${i}))
|
|
wait_remote_ready "START_${_n}_${i}"
|
|
ipfw -q zero > /dev/null
|
|
# Nothing to do for the middle node testing the default.
|
|
sleep 1
|
|
wait_remote_ready "STOP_${_n}_${i}"
|
|
report_ipfw_count
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
_fwd_fib_asymmetric_middle_ipfw()
|
|
{
|
|
local _n maxfib i j _port
|
|
_n="$1"
|
|
maxfib=$2
|
|
|
|
i=0
|
|
while test ${i} -lt ${maxfib}; do
|
|
|
|
_port=$((CTRLPORT + 1 + i))
|
|
ipfw add 100 setfib ${i} ipv6-icmp from any to any \
|
|
icmp6types 128 via ${IFACE} in > /dev/null
|
|
ipfw add 100 setfib ${i} tcp from any to any \
|
|
dst-port ${_port} via ${IFACE} in > /dev/null
|
|
ipfw add 100 setfib ${i} udp from any to any \
|
|
dst-port ${_port} via ${IFACE} in > /dev/null
|
|
|
|
j=$((${maxfib} - 1 - ${i}))
|
|
ipfw add 100 setfib ${j} ipv6-icmp from any to any \
|
|
icmp6types 129 via ${IFACEFAR} in > /dev/null
|
|
ipfw add 100 setfib ${j} tcp from any to any \
|
|
src-port ${_port} via ${IFACEFAR} in > /dev/null
|
|
ipfw add 100 setfib ${j} udp from any to any \
|
|
src-port ${_port} via ${IFACEFAR} in > /dev/null
|
|
|
|
setup_ipfw_count ${CTRLPORT} ${maxfib} ${i} ${j}
|
|
wait_remote_ready "START_${_n}_${i}"
|
|
ipfw -q zero > /dev/null
|
|
# Nothing to do for the middle node testing the default.
|
|
sleep 1
|
|
wait_remote_ready "STOP_${_n}_${i}"
|
|
report_ipfw_count
|
|
|
|
ipfw delete 100 > /dev/null
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
fwd_fib_asymmetric_ifconfig()
|
|
{
|
|
local _maxfib _n
|
|
_maxfib=$1
|
|
|
|
_n="fwd_fib_asymmetric_ifconfig"
|
|
|
|
print_debug "${_n} ${_maxfib}"
|
|
case ${node} in
|
|
left) _fwd_fib_asymmetric_left ${_n} ${_maxfib} ;;
|
|
middle) _fwd_fib_asymmetric_middle_ifconfig ${_n} ${_maxfib} ;;
|
|
right) _fwd_fib_symmetric_right ${_n} ${_maxfib} ;;
|
|
esac
|
|
}
|
|
|
|
fwd_fib_asymmetric_ipfw()
|
|
{
|
|
local _maxfib _n
|
|
_maxfib=$1
|
|
|
|
_n="fwd_fib_asymmetric_ipfw"
|
|
|
|
print_debug "${_n} ${_maxfib}"
|
|
case ${node} in
|
|
left) _fwd_fib_asymmetric_left ${_n} ${_maxfib} ;;
|
|
middle) _fwd_fib_asymmetric_middle_ipfw ${_n} ${_maxfib} ;;
|
|
right) _fwd_fib_symmetric_right ${_n} ${_maxfib} ;;
|
|
esac
|
|
}
|
|
|
|
################################################################################
|
|
|
|
_fwd_fib_symmetric_destructive_left()
|
|
{
|
|
local _n _maxfib i _addr
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
# Setup expected return code
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
eval rc_${i}=0
|
|
i=$((i + 1))
|
|
done
|
|
|
|
# Add default route.
|
|
route add -net -inet6 default ${MIDDLELEFTADDR} > /dev/null
|
|
|
|
# Initiate probes for ICMP6, TCP and UDP.
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
|
|
sleep 1
|
|
|
|
send_control_msgs "START_${_n}_${i}"
|
|
|
|
_addr="2001:2:${i}::2"
|
|
test_icmp6 1 ${_addr} "${_n}_${i}_icmp6"
|
|
test_ulp 1 "${_n}_${i}" ${_addr} ${CTRLPORT} ${i}
|
|
|
|
send_control_msgs "STOP_${_n}_${i}"
|
|
_fwd_fib_symmetric_results "${_n}_${i}" ${i}
|
|
fetch_ipfw_count "${_n}_${i}"
|
|
i=$((i + 1))
|
|
done
|
|
|
|
# Cleanup networking.
|
|
route delete -net -inet6 default > /dev/null
|
|
}
|
|
|
|
_fwd_fib_symmetric_destructive_right()
|
|
{
|
|
local _n _maxfib i _addr
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
# Setup networking (ideally we'd use the link-local).
|
|
route add -net -inet6 default ${MIDDLERIGHTADDR} > /dev/null 2>&1
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
ifconfig ${IFACE} inet6 2001:2:${i}::2/64 alias
|
|
i=$((i + 1))
|
|
done
|
|
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
wait_remote_ready "START_${_n}_${i}"
|
|
|
|
# No need to do anything for ICMPv6.
|
|
# Start reflect for TCP and UDP.
|
|
_addr="2001:2:${i}::2"
|
|
test_ulp_reflect_one "${_n}_tcp" "-N -T TCP6 -A ${_addr}" \
|
|
${i} ${CTRLPORT}
|
|
test_ulp_reflect_one "${_n}_udp" "-N -T UDP6 -A ${_addr}" \
|
|
${i} ${CTRLPORT}
|
|
|
|
wait_remote_ready "STOP_${_n}_${i}"
|
|
i=$((i + 1))
|
|
done
|
|
|
|
# Cleanup networking again.
|
|
route delete -net -inet6 default > /dev/null 2>&1
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
ifconfig ${IFACE} inet6 2001:2:${i}::2/64 -alias
|
|
i=$((i + 1))
|
|
done
|
|
|
|
}
|
|
|
|
|
|
_fwd_fib_symmetric_destructive_middle_setup_networking()
|
|
{
|
|
local _maxfib i j
|
|
_maxfib=$1
|
|
|
|
# Setup networking.
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 -alias \
|
|
> /dev/null 2>&1 || true
|
|
ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 alias
|
|
j=0
|
|
while test ${j} -lt ${_maxfib}; do
|
|
# Only work on all other FIBs.
|
|
if test ${j} -ne ${i}; then
|
|
setfib -F ${j} route delete -net -inet6 \
|
|
2001:2:${i}::/64 > /dev/null
|
|
fi
|
|
j=$((j + 1))
|
|
done
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
_fwd_fib_symmetric_destructive_middle_cleanup_networking()
|
|
{
|
|
local _maxfib i
|
|
_maxfib=$1
|
|
|
|
# Cleanup networking again.
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 -alias
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
_fwd_fib_symmetric_destructive_middle_ifconfig()
|
|
{
|
|
local _n _maxfib i
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
_fwd_fib_symmetric_destructive_middle_setup_networking ${_maxfib}
|
|
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
ifconfig ${IFACE} fib ${i}
|
|
ifconfig ${IFACEFAR} fib ${i}
|
|
setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
|
|
wait_remote_ready "START_${_n}_${i}"
|
|
ipfw -q zero > /dev/null
|
|
# Nothing to do for the middle node testing the default.
|
|
sleep 1
|
|
wait_remote_ready "STOP_${_n}_${i}"
|
|
report_ipfw_count
|
|
i=$((i + 1))
|
|
done
|
|
|
|
_fwd_fib_symmetric_destructive_middle_cleanup_networking ${_maxfib}
|
|
}
|
|
|
|
_fwd_fib_symmetric_destructive_middle_ipfw()
|
|
{
|
|
local _n _maxfib i _port
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
_fwd_fib_symmetric_destructive_middle_setup_networking ${_maxfib}
|
|
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
_port=$((CTRLPORT + 1 + i))
|
|
ipfw add 100 setfib ${i} ipv6-icmp from any to any \
|
|
icmp6types 128 via ${IFACE} in > /dev/null
|
|
ipfw add 100 setfib ${i} tcp from any to any \
|
|
dst-port ${_port} via ${IFACE} in > /dev/null
|
|
ipfw add 100 setfib ${i} udp from any to any \
|
|
dst-port ${_port} via ${IFACE} in > /dev/null
|
|
|
|
ipfw add 100 setfib ${i} ipv6-icmp from any to any \
|
|
icmp6types 129 via ${IFACEFAR} in > /dev/null
|
|
ipfw add 100 setfib ${i} tcp from any to any \
|
|
src-port ${_port} via ${IFACEFAR} in > /dev/null
|
|
ipfw add 100 setfib ${i} udp from any to any \
|
|
src-port ${_port} via ${IFACEFAR} in > /dev/null
|
|
|
|
setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
|
|
wait_remote_ready "START_${_n}_${i}"
|
|
ipfw -q zero > /dev/null
|
|
# Nothing to do for the middle node testing the default.
|
|
sleep 1
|
|
wait_remote_ready "STOP_${_n}_${i}"
|
|
report_ipfw_count
|
|
|
|
ipfw delete 100 > /dev/null
|
|
i=$((i + 1))
|
|
done
|
|
|
|
_fwd_fib_symmetric_destructive_middle_cleanup_networking ${_maxfib}
|
|
}
|
|
|
|
fwd_fib_symmetric_destructive_ifconfig()
|
|
{
|
|
local _maxfib _n
|
|
_maxfib=$1
|
|
|
|
_n="fwd_fib_symmetric_destructive_ifconfig"
|
|
|
|
print_debug "${_n} ${_maxfib}"
|
|
case ${node} in
|
|
left) _fwd_fib_symmetric_destructive_left ${_n} ${_maxfib} ;;
|
|
middle) _fwd_fib_symmetric_destructive_middle_ifconfig \
|
|
${_n} ${_maxfib} ;;
|
|
right) _fwd_fib_symmetric_destructive_right ${_n} ${_maxfib} ;;
|
|
esac
|
|
}
|
|
|
|
fwd_fib_symmetric_destructive_ipfw()
|
|
{
|
|
local _maxfib _n
|
|
_maxfib=$1
|
|
|
|
_n="fwd_fib_symmetric_destructive_ipfw"
|
|
|
|
print_debug "${_n} ${_maxfib}"
|
|
case ${node} in
|
|
left) _fwd_fib_symmetric_destructive_left ${_n} ${_maxfib} ;;
|
|
middle) _fwd_fib_symmetric_destructive_middle_ipfw \
|
|
${_n} ${_maxfib} ;;
|
|
right) _fwd_fib_symmetric_destructive_right ${_n} ${_maxfib} ;;
|
|
esac
|
|
}
|
|
|
|
################################################################################
|
|
|
|
_fwd_fib_symmetric_destructive_defroute_left()
|
|
{
|
|
local _n _maxfib i _addr
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
# Setup expected return code
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
eval rc_${i}=0
|
|
i=$((i + 1))
|
|
done
|
|
|
|
# Add default route.
|
|
route delete -net -inet6 default > /dev/null 2>&1 || true
|
|
route add -net -inet6 default ${MIDDLELEFTADDR} > /dev/null
|
|
|
|
# Initiate probes for ICMP6, TCP and UDP.
|
|
_addr="2001:2:1234::2"
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
|
|
sleep 1
|
|
|
|
send_control_msgs "START_${_n}_${i}"
|
|
|
|
test_icmp6 1 "${_addr}" "${_n}_${i}_icmp6"
|
|
test_ulp 1 "${_n}_${i}" "${_addr}" ${CTRLPORT} ${i}
|
|
|
|
send_control_msgs "STOP_${_n}_${i}"
|
|
_fwd_fib_symmetric_results "${_n}_${i}" ${i}
|
|
fetch_ipfw_count "${_n}_${i}"
|
|
i=$((i + 1))
|
|
done
|
|
|
|
# Cleanup networking.
|
|
route delete -net -inet6 default > /dev/null 2>&1
|
|
}
|
|
|
|
_fwd_fib_symmetric_destructive_defroute_right()
|
|
{
|
|
local _n _maxfib i _addr
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
# Setup networking (ideally we'd use the link-local).
|
|
route delete -net -inet6 default > /dev/null 2>&1 || true
|
|
route add -net -inet6 default ${MIDDLERIGHTADDR} > /dev/null 2>&1
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
ifconfig ${IFACE} inet6 2001:2:${i}::2/64 -alias \
|
|
> /dev/null 2>&1 || true
|
|
ifconfig ${IFACE} inet6 2001:2:${i}::2/64 alias
|
|
i=$((i + 1))
|
|
done
|
|
_addr="2001:2:1234::2"
|
|
ifconfig lo0 inet6 ${_addr}/128 alias
|
|
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
wait_remote_ready "START_${_n}_${i}"
|
|
|
|
# No need to do anything for ICMPv6.
|
|
# Start reflect for TCP and UDP.
|
|
test_ulp_reflect_one "${_n}_tcp" "-N -T TCP6 -A ${_addr}" \
|
|
${i} ${CTRLPORT}
|
|
test_ulp_reflect_one "${_n}_udp" "-N -T UDP6 -A ${_addr}" \
|
|
${i} ${CTRLPORT}
|
|
|
|
wait_remote_ready "STOP_${_n}_${i}"
|
|
i=$((i + 1))
|
|
done
|
|
|
|
# Cleanup networking again.
|
|
route delete -net -inet6 default > /dev/null 2>&1
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
ifconfig ${IFACE} inet6 2001:2:${i}::2/64 -alias
|
|
i=$((i + 1))
|
|
done
|
|
ifconfig lo0 inet6 ${_addr}/128 -alias
|
|
|
|
}
|
|
|
|
_fwd_fib_symmetric_destructive_defroute_middle_setup_networking()
|
|
{
|
|
local _maxfib i j
|
|
_maxfib=$1
|
|
|
|
# Setup networking.
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 -alias \
|
|
> /dev/null 2>&1 || true
|
|
ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 alias
|
|
j=0
|
|
while test ${j} -lt ${_maxfib}; do
|
|
# Only work on all other FIBs.
|
|
if test ${j} -ne ${i}; then
|
|
setfib -F ${j} route delete -net -inet6 \
|
|
2001:2:${i}::/64 > /dev/null
|
|
fi
|
|
j=$((j + 1))
|
|
done
|
|
setfib -F ${i} route delete -net -inet6 \
|
|
2001:2:1234::2 2001:2:${i}::2 > /dev/null 2>&1 || true
|
|
setfib -F ${i} route add -net -inet6 \
|
|
2001:2:1234::2 2001:2:${i}::2 > /dev/null
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
_fwd_fib_symmetric_destructive_defroute_middle_cleanup_networking()
|
|
{
|
|
local _maxfib i
|
|
_maxfib=$1
|
|
|
|
# Cleanup networking again.
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 -alias
|
|
setfib -F ${i} route delete -net -inet6 \
|
|
2001:2:1234::2 2001:2:${i}::2 > /dev/null
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
_fwd_fib_symmetric_destructive_defroute_middle_ifconfig()
|
|
{
|
|
local _n _maxfib i
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
_fwd_fib_symmetric_destructive_defroute_middle_setup_networking \
|
|
${_maxfib}
|
|
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
ifconfig ${IFACE} fib ${i}
|
|
ifconfig ${IFACEFAR} fib ${i}
|
|
setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
|
|
wait_remote_ready "START_${_n}_${i}"
|
|
ipfw -q zero > /dev/null
|
|
# Nothing to do for the middle node testing the default.
|
|
sleep 1
|
|
wait_remote_ready "STOP_${_n}_${i}"
|
|
report_ipfw_count
|
|
i=$((i + 1))
|
|
done
|
|
|
|
_fwd_fib_symmetric_destructive_defroute_middle_cleanup_networking \
|
|
${_maxfib}
|
|
}
|
|
|
|
_fwd_fib_symmetric_destructive_defroute_middle_ipfw()
|
|
{
|
|
local _n _maxfib i _port
|
|
_n="$1"
|
|
_maxfib=$2
|
|
|
|
_fwd_fib_symmetric_destructive_defroute_middle_setup_networking \
|
|
${_maxfib}
|
|
|
|
i=0
|
|
while test ${i} -lt ${_maxfib}; do
|
|
_port=$((CTRLPORT + 1 + i))
|
|
ipfw add 100 setfib ${i} ipv6-icmp from any to any \
|
|
icmp6types 128 via ${IFACE} in > /dev/null
|
|
ipfw add 100 setfib ${i} tcp from any to any \
|
|
dst-port ${_port} via ${IFACE} in > /dev/null
|
|
ipfw add 100 setfib ${i} udp from any to any \
|
|
dst-port ${_port} via ${IFACE} in > /dev/null
|
|
|
|
ipfw add 100 setfib ${i} ipv6-icmp from any to any \
|
|
icmp6types 129 via ${IFACEFAR} in > /dev/null
|
|
ipfw add 100 setfib ${i} tcp from any to any \
|
|
src-port ${_port} via ${IFACEFAR} in > /dev/null
|
|
ipfw add 100 setfib ${i} udp from any to any \
|
|
src-port ${_port} via ${IFACEFAR} in > /dev/null
|
|
|
|
setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
|
|
wait_remote_ready "START_${_n}_${i}"
|
|
ipfw -q zero > /dev/null
|
|
# Nothing to do for the middle node testing the default.
|
|
sleep 1
|
|
wait_remote_ready "STOP_${_n}_${i}"
|
|
report_ipfw_count
|
|
|
|
ipfw delete 100 > /dev/null
|
|
i=$((i + 1))
|
|
done
|
|
|
|
_fwd_fib_symmetric_destructive_defroute_middle_cleanup_networking \
|
|
${_maxfib}
|
|
}
|
|
|
|
fwd_fib_symmetric_destructive_defroute_ifconfig()
|
|
{
|
|
local _maxfib _n
|
|
_maxfib=$1
|
|
|
|
_n="fwd_fib_symmetric_destructive_defroute_ifconfig"
|
|
|
|
print_debug "${_n} ${_maxfib}"
|
|
case ${node} in
|
|
left) _fwd_fib_symmetric_destructive_defroute_left \
|
|
${_n} ${_maxfib} ;;
|
|
middle) _fwd_fib_symmetric_destructive_defroute_middle_ifconfig \
|
|
${_n} ${_maxfib} ;;
|
|
right) _fwd_fib_symmetric_destructive_defroute_right \
|
|
${_n} ${_maxfib} ;;
|
|
esac
|
|
}
|
|
|
|
fwd_fib_symmetric_destructive_defroute_ipfw()
|
|
{
|
|
local _maxfib _n
|
|
_maxfib=$1
|
|
|
|
_n="fwd_fib_symmetric_destructive_defroute_ipfw"
|
|
|
|
print_debug "${_n} ${_maxfib}"
|
|
case ${node} in
|
|
left) _fwd_fib_symmetric_destructive_defroute_left \
|
|
${_n} ${_maxfib} ;;
|
|
middle) _fwd_fib_symmetric_destructive_defroute_middle_ipfw \
|
|
${_n} ${_maxfib} ;;
|
|
right) _fwd_fib_symmetric_destructive_defroute_right \
|
|
${_n} ${_maxfib} ;;
|
|
esac
|
|
}
|
|
|
|
################################################################################
|
|
#
|
|
# MAIN
|
|
#
|
|
|
|
# Same for all hosts.
|
|
if test `sysctl -n security.jail.jailed` -eq 0; then
|
|
kldload ipfw > /dev/null 2>&1 || kldstat -v | grep -q ipfw
|
|
fi
|
|
ipfw -f flush > /dev/null 2>&1 || die "please load ipfw in base system"
|
|
ipfw add 65000 permit ip from any to any > /dev/null 2>&1
|
|
|
|
# Per host setup.
|
|
setup_networking
|
|
reachability_check
|
|
|
|
#
|
|
# Tests
|
|
#
|
|
|
|
fwd_default_fib_symmetric
|
|
fwd_default_fib_symmetric_ifconfig
|
|
fwd_default_fib_symmetric_ipfw
|
|
|
|
fwd_fib_symmetric_ifconfig ${RT_NUMFIBS}
|
|
fwd_fib_symmetric_ipfw ${RT_NUMFIBS}
|
|
|
|
fwd_fib_asymmetric_ifconfig ${RT_NUMFIBS}
|
|
fwd_fib_asymmetric_ipfw ${RT_NUMFIBS}
|
|
|
|
fwd_fib_symmetric_destructive_ifconfig ${RT_NUMFIBS}
|
|
fwd_fib_symmetric_destructive_ipfw ${RT_NUMFIBS}
|
|
|
|
fwd_fib_symmetric_destructive_defroute_ifconfig ${RT_NUMFIBS}
|
|
fwd_fib_symmetric_destructive_defroute_ipfw ${RT_NUMFIBS}
|
|
|
|
# Per host cleanup.
|
|
cleanup_networking
|
|
|
|
# end
|