3 # Copyright (c) 2012 Cisco Systems, Inc.
6 # This software was developed by Bjoern Zeeb under contract to
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions
12 # 1. Redistributions of source code must retain the above copyright
13 # notice, this list of conditions and the following disclaimer.
14 # 2. Redistributions in binary form must reproduce the above copyright
15 # notice, this list of conditions and the following disclaimer in the
16 # documentation and/or other materials provided with the distribution.
18 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 # left ------------------------- middle ------------------------- right
36 # IFACE IFACE IFACEFAR IFACE
37 # LEFTADDR MIDDLELEFTADDR MIDDLERIGHTADDR RIGHTADDR
39 # initiator FIB tests reflector
41 # We will use the RFC5180 (and Errata) benchmarking working group prefix
42 # 2001:0002::/48 for testing.
45 # Set IFACE to the real interface you want to run the test on.
46 # IFACEFAR is only relevant on the middle (forwarding) node and will be the
47 # 'right' side (far end) one.
51 # Number of seconds to wait for peer node to synchronize for test.
54 # Control port we use to exchange messages between nodes to sync. tests, etc.
57 # Get the number of FIBs from the kernel.
58 RT_NUMFIBS=`sysctl -n net.fibs`
60 # This is the initiator and connected middle node.
61 LEFTADDR="2001:2:fe00::1"
62 MIDDLELEFTADDR="2001:2:fe00::2"
63 # This is the far end middle node and receiver side.
64 MIDDLERIGHTADDR="2001:2:ff00::1"
65 RIGHTADDR="2001:2:ff00::2"
67 # By default all commands must succeed. Individual tests may disable this
77 ################################################################################
87 *) echo "ERROR: invalid node name '${node}'. Must be left, middle or" \
93 ################################################################################
99 local _rc _exp _testno _testname _msg _r
107 if test ${_rc} -eq ${_exp}; then
110 echo "${_r} ${_testno} ${_testname} # ${_msg} ${_rc} ${_exp}"
120 *) echo "DEBUG: ${_msg}" >&2 ;;
129 echo "ERROR: ${_msg}" >&2
134 ################################################################################
136 # Functions to configure networking and do a basic reachability check.
142 print_debug "Setting up networking"
144 left) ifconfig ${IFACE} inet6 ${LEFTADDR}/64 -alias \
145 > /dev/null 2>&1 || true
146 ifconfig ${IFACE} inet6 ${LEFTADDR}/64 alias up
147 ifconfig ${IFACE} fib 0
148 sysctl net.inet6.ip6.forwarding=0 > /dev/null
149 route delete -net -inet6 default > /dev/null 2>&1 || true
150 route delete -host -inet6 ${RIGHTADDR} ${MIDDLELEFTADDR} \
151 > /dev/null 2>&1 || true
152 route add -host -inet6 ${RIGHTADDR} ${MIDDLELEFTADDR} \
154 route delete -host -inet6 ${MIDDLERIGHTADDR} ${MIDDLELEFTADDR} \
155 > /dev/null 2>&1 || true
156 route add -host -inet6 ${MIDDLERIGHTADDR} ${MIDDLELEFTADDR} \
157 > /dev/null 2>&1 || true
159 middle) ifconfig ${IFACE} inet6 ${MIDDLELEFTADDR}/64 -alias \
160 > /dev/null 2>&1 || true
161 ifconfig ${IFACE} inet6 ${MIDDLELEFTADDR}/64 alias up
162 ifconfig ${IFACE} fib 0
163 ifconfig ${IFACEFAR} inet6 ${MIDDLERIGHTADDR}/64 -alias \
164 > /dev/null 2>&1 || true
165 ifconfig ${IFACEFAR} inet6 ${MIDDLERIGHTADDR}/64 alias up
166 ifconfig ${IFACEFAR} fib 0
167 sysctl net.inet6.ip6.forwarding=1 > /dev/null
169 right) ifconfig ${IFACE} inet6 ${RIGHTADDR}/64 -alias \
170 > /dev/null 2>&1 || true
171 ifconfig ${IFACE} inet6 ${RIGHTADDR}/64 alias up
172 ifconfig ${IFACE} fib 0
173 sysctl net.inet6.ip6.forwarding=0 > /dev/null
174 route delete -net -inet6 default > /dev/null 2>&1 || true
175 route delete -host -inet6 ${LEFTADDR} ${MIDDLERIGHTADDR} \
176 > /dev/null 2>&1 || true
177 route add -host -inet6 ${LEFTADDR} ${MIDDLERIGHTADDR} \
179 route delete -host -inet6 ${MIDDLELEFTADDR} ${MIDDLERIGHTADDR} \
180 > /dev/null 2>&1 || true
181 route add -host -inet6 ${MIDDLELEFTADDR} ${MIDDLERIGHTADDR} \
187 print_debug "Waiting 4 seconds for things to settle"
195 left) ifconfig ${IFACE} inet6 ${LEFTADDR}/64 -alias
197 middle) ifconfig ${IFACE} inet6 ${MIDDLELEFTADDR}/64 -alias
198 ifconfig ${IFACEFAR} inet6 ${MIDDLERIGHTADDR}/64 -alias
199 sysctl net.inet6.ip6.forwarding=0 > /dev/null
201 right) ifconfig ${IFACE} inet6 ${RIGHTADDR}/64 -alias
204 print_debug "Cleaned up networking"
207 _reachability_check()
212 ping6 -n -c1 ${_addr} > /dev/null 2>&1
216 *) print_debug "cannot ping6 ${_addr}, rc=${_rc}"
227 # Try to reach all control addresses on other nodes.
228 # We need to loop for a while as we cannot expect all to be up
229 # the very same moment.
232 while test ${rc} -ne 0 -a ${i} -le ${WAITS}; do
233 print_debug "${i}/${WAITS} trying to ping6 control addresses."
237 left) _reachability_check ${MIDDLELEFTADDR}
239 _reachability_check ${MIDDLERIGHTADDR}
241 _reachability_check ${RIGHTADDR}
244 middle) _reachability_check ${LEFTADDR}
246 _reachability_check ${RIGHTADDR}
249 right) _reachability_check ${MIDDLERIGHTADDR}
251 _reachability_check ${MIDDLELEFTADDR}
253 _reachability_check ${LEFTADDR}
263 ################################################################################
265 # "Greeting" handling to sync notes to the agreed upon next test case.
269 local _case _addr i rc _msg _keyword _fibs
276 while test ${i} -lt ${WAITS} -a ${rc} -ne 0; do
277 print_debug "Sending control msg #${i} to peer ${_addr}"
278 _msg=`echo "${_case} ${RT_NUMFIBS}" | \
279 nc -6 -w 1 ${_addr} ${CTRLPORT}`
282 # Might sleep longer in total but better than to DoS
283 # and not get anywhere.
288 read _keyword _fibs <<EOI
291 print_debug "_keyword=${_keyword}"
292 print_debug "_fibs=${_fibs}"
295 *) die "Got invalid keyword from ${_addr} in control message:" \
299 if test ${_fibs} -ne ${RT_NUMFIBS}; then
300 die "Number of FIBs not matching ours (${RT_NUMFIBS}) in" \
301 "control message from ${_addr}: ${_msg}"
304 print_debug "Successfully exchanged control message with ${_addr}."
312 # Always start with the far end. Otherwise we will cut that off when
313 # cleanly taering down things again.
314 for _addr in ${RIGHTADDR} ${MIDDLELEFTADDR}; do
315 send_control_msg "${_case}" ${_addr}
318 # Allow us to flush ipfw counters etc before new packets will arrive.
322 # We are setup. Wait for the initiator to tell us that it is ready.
325 local _case _msg _keyword _fibs
328 # Wait for the remote to connect and start things.
329 # We tell it the magic keyword, and our number of FIBs.
330 _msg=`echo "${_case} ${RT_NUMFIBS}" | nc -6 -l ${CTRLPORT}`
332 read _keyword _fibs <<EOI
335 print_debug "_keyword=${_keyword}"
336 print_debug "_fibs=${_fibs}"
339 *) die "Got invalid keyword in control message: ${_msg}"
342 if test ${_fibs} -ne ${RT_NUMFIBS}; then
343 die "Number of FIBs not matching ours (${RT_NUMFIBS}) in" \
344 "control message: ${_msg}"
347 print_debug "Successfully received control message."
350 ################################################################################
352 # Test case helper functions.
354 # Please note that neither on the intiator nor the reflector are FIBs despite
355 # a variable name might indicate. If such a variable is used it mirrors FIB
356 # numbers from the middle node to match for test cases.
360 local _maxfibs _addr _n _testno i _rc _ec
365 printf "1..%d\n" ${_maxfibs}
369 while test ${i} -lt ${_maxfibs}; do
371 print_debug "Testing ${_txt}"
373 # Generate HEX for ping6 payload.
374 _fibtxt=`echo "${_txt}" | hd -v | cut -b11-60 | tr -d ' \r\n'`
376 eval _rc="\${rc_${i}}"
377 ping6 -n -c1 -p ${_fibtxt} ${_addr} > /dev/null 2>&1
379 # We need to normalize the exit code of ping6.
384 check_rc ${_ec} ${_rc} ${_testno} "${_txt}" "FIB ${i} ${_addr}"
385 testno=$((testno + 1))
391 test_ulp_reflect_one()
393 local _txt _opts port fib
399 print_debug "./reflect -p $((port + 1 + fib)) -t ${_txt}" "${_opts}"
400 ./reflect -p $((port + 1 + fib)) -t ${_txt} ${_opts}
401 print_debug "reflect '${_txt}' terminated without error."
404 test_ulp_reflect_multiple()
406 local _maxfibs _txt _opts i _jobs _p
413 while test ${i} -lt ${_maxfibs}; do
414 print_debug "./reflect -p $((CTRLPORT + 1000 + i))" \
415 "-t ${_txt} ${_opts} -N -f ${i} &"
416 ./reflect -p $((CTRLPORT + 1000 + i)) \
417 -t ${_txt} ${_opts} -N -f ${i} &
419 _jobs="${_jobs}${_p} "
423 # Start OOB control connection for START/DONE.
424 testrx_run_one "${_txt}" "${_opts}"
425 print_debug "KILL ${_jobs}"
426 for i in ${_jobs}; do
429 #killall reflect || true
430 print_debug "reflects for '${_txt}' terminated without error."
435 local _loops _msg _expreply _addr _port _opts i
444 while test ${i} -lt ${_loops}; do
446 print_debug "e ${_msg} | nc -6 -w1 ${_opts} ${_addr} ${_port}"
447 _reply=`echo "${_msg}" | nc -6 -w1 ${_opts} ${_addr} ${_port}`
448 if test "${_reply}" != "${_expreply}"; then
449 if test ${i} -lt ${_loops}; then
452 # Must let caller decide how to handle the error.
453 # die "Got invalid reply from peer." \
454 # "Expected '${_expreply}', got '${_reply}'"
466 local maxfibs _msg _addr port fib i _txt testno _rc _reply
473 printf "1..%d\n" $((${maxfibs} * 2))
476 while test ${i} -lt ${maxfibs}; do
478 if test ${i} -eq $((${maxfibs} - 1)); then
479 # Last one; signal DONE.
480 _txt="DONE ${_msg}_${i}"
482 _txt="DONE ${_msg}_${i}"
485 eval _rc="\${rc_${i}}"
488 nc_send_recv ${maxfibs} "${_txt}" "${_txt}" ${_addr} \
489 $((${port} + 1 + fib)) ""
490 check_rc $? ${_rc} ${testno} "${_msg}_${i}_tcp" \
491 "[${_addr}]:$((${port} + 1 + fib)) ${_reply}"
492 testno=$((testno + 1))
496 nc_send_recv ${maxfibs} "${_txt}" "${_txt}" ${_addr} \
497 $((${port} + 1 + fib)) "-u"
498 check_rc $? ${_rc} ${testno} "${_msg}_${i}_udp" \
499 "[${_addr}]:$((${port} + 1 + fib)) ${_reply}"
503 testno=$((testno + 1))
509 local i port maxfib _p _fib _ofib
516 while test ${i} -lt ${maxfib}; do
519 -1) _p=$((port + 1 + i)) ;;
520 *) _p=$((port + 1 + maxfib - 1 - i)) ;;
523 # Only count ICMP6 echo replies.
524 ipfw add $((10000 + i)) count ipv6-icmp from any to any \
525 icmp6types 129 fib ${i} via ${IFACE} out > /dev/null
526 ipfw add $((10000 + i)) count tcp from any to any \
527 src-port ${_p} fib ${i} via ${IFACE} out > /dev/null
528 ipfw add $((10000 + i)) count udp from any to any \
529 src-port ${_p} fib ${i} via ${IFACE} out > /dev/null
531 # Only count ICMP6 echo requests.
532 ipfw add $((20000 + i)) count ipv6-icmp from any to any \
533 icmp6types 128 fib ${i} via ${IFACEFAR} out > /dev/null
534 ipfw add $((20000 + i)) count tcp from any to any \
535 dst-port $((${port} + 1 + i)) fib ${i} \
536 via ${IFACEFAR} out > /dev/null
537 ipfw add $((20000 + i)) count udp from any to any \
538 dst-port $((${port} + 1 + i)) fib ${i} \
539 via ${IFACEFAR} out > /dev/null
547 local _fib _o i _rstr _c _req _p _opts base
556 for base in 10000 20000; do
559 10000) _rstr="${_rstr}\nLEFT " ;;
560 20000) _rstr="${_rstr}\nRIGHT " ;;
563 i) _rstr="${_rstr}ICMP6 " ;;
564 t) _rstr="${_rstr}TCP " ;;
565 u) _rstr="${_rstr}UDP " ;;
568 while test ${i} -lt ${RT_NUMFIBS}; do
571 i) _c=`ipfw show $((${base} + i)) | \
572 awk '/ ipv6-icmp / { print $2 }'` ;;
573 t) _c=`ipfw show $((${base} + i)) | \
574 awk '/ tcp / { print $2 }'` ;;
575 u) _c=`ipfw show $((${base} + i)) | \
576 awk '/ udp / { print $2 }'` ;;
578 _rstr="${_rstr}${i} ${_c},"
584 while test ${i} -lt ${RT_NUMFIBS}; do
585 ipfw delete $((${base} + i)) > /dev/null 2>&1 || true
590 # We do not care about the request.
591 _req=`printf "${_rstr}" | nc -6 -l $((${CTRLPORT} - 1))`
592 print_debug "$? -- ${_req} -- ${_rstr}"
597 local _n _reply _line _edge _type _fib _count _rc _ec _status
600 # Leave node some time to build result set.
603 print_debug "Asking for ipfw count results..."
605 nc_send_recv 1 "RESULT REQUEST" "" ${MIDDLELEFTADDR} \
606 $((${CTRLPORT} - 1)) ""
610 *) die "Got invalid reply from peer." \
611 "Expected 'RESULTS ...', got '${_reply}'" ;;
617 # FIBs * {left, right} * {icmp6, tcp, udp}
618 printf "1..%d\n" $((RT_NUMFIBS * 2 * 3))
621 print_debug "_line == ${_line}"
627 while read _fib _count; do
628 eval _em="\${rc_${_n}_${_edge}_${_type}_${_fib}}"
630 if test ${_count} -gt 0; then
635 if test ${_rc} -eq ${_em}; then
640 printf "%s %d %s # count=%s _rc=%d _em=%d\n" \
641 "${_status}" ${testno} "${_n}_${_edge}_${_type}_${_fib}" \
642 ${_count} ${_rc} ${_em}
643 testno=$((testno + 1))
645 `printf "${_line}" | tr ',' '\n'`
649 `printf "${_reply}" | grep -v "^$"`
652 print_debug "ipfw count results processed"
655 ################################################################################
659 # In general we set the FIB on in, but count on out.
662 _fwd_default_fib_symmetric_results()
664 local _n i _edge _type _rc
668 while test ${i} -lt ${RT_NUMFIBS}; do
669 for _edge in "LEFT" "RIGHT"; do
670 for _type in "ICMP6" "TCP" "UDP"; do
673 0) eval rc_${_n}_${_edge}_${_type}_${i}=1
675 # "rc_${_n}_${_edge}_${_type}_${i}=1"
677 *) eval rc_${_n}_${_edge}_${_type}_${i}=0
679 # "rc_${_n}_${_edge}_${_type}_${i}=0"
689 _fwd_default_fib_symmetric_left()
694 send_control_msgs "START_${_n}"
696 # Setup expected return code
699 # Initiate probes for ICMP6, TCP and UDP.
700 test_icmp6 1 ${RIGHTADDR} "${_n}_icmp6"
701 test_ulp 1 "${_n}" ${RIGHTADDR} ${CTRLPORT} 0
703 send_control_msgs "STOP_${_n}"
704 _fwd_default_fib_symmetric_results "${_n}"
705 fetch_ipfw_count "${_n}"
708 _fwd_default_fib_symmetric_middle()
713 setup_ipfw_count ${CTRLPORT} ${RT_NUMFIBS} 0 -1
714 wait_remote_ready "START_${_n}"
715 ipfw -q zero > /dev/null
716 # Nothing to do for the middle node testing the default.
718 wait_remote_ready "STOP_${_n}"
722 _fwd_default_fib_symmetric_right()
727 wait_remote_ready "START_${_n}"
729 # No need to do anything for ICMPv6.
730 # Start reflect for TCP and UDP.
731 test_ulp_reflect_one "${_n}_tcp" "-N -T TCP6" 0 ${CTRLPORT}
732 test_ulp_reflect_one "${_n}_udp" "-N -T UDP6" 0 ${CTRLPORT}
734 wait_remote_ready "STOP_${_n}"
737 fwd_default_fib_symmetric()
741 _n="fwd_default_fib_symmetric"
745 left) _fwd_default_fib_symmetric_left ${_n} ;;
746 middle) _fwd_default_fib_symmetric_middle ${_n} ;;
747 right) _fwd_default_fib_symmetric_right ${_n} ;;
751 _fwd_default_fib_symmetric_middle_ifconfig()
756 ifconfig ${IFACE} fib 0
757 ifconfig ${IFACEFAR} fib 0
758 setup_ipfw_count ${CTRLPORT} ${RT_NUMFIBS} 0 -1
759 wait_remote_ready "START_${_n}"
760 ipfw -q zero > /dev/null
761 # Nothing to do for the middle node testing the default.
763 wait_remote_ready "STOP_${_n}"
767 fwd_default_fib_symmetric_ifconfig()
771 _n="fwd_default_fib_symmetric_ifconfig"
775 left) _fwd_default_fib_symmetric_left ${_n} ;;
776 middle) _fwd_default_fib_symmetric_middle_ifconfig ${_n} ;;
777 right) _fwd_default_fib_symmetric_right ${_n} ;;
781 _fwd_default_fib_symmetric_middle_ipfw()
786 ipfw add 100 setfib 0 ipv6-icmp from any to any \
787 icmp6types 128 via ${IFACE} in > /dev/null
788 ipfw add 100 setfib 0 ip6 from any to any \
789 proto tcp dst-port ${CTRLPORT} via ${IFACE} in > /dev/null
790 ipfw add 100 setfib 0 ip6 from any to any \
791 proto udp dst-port ${CTRLPORT} via ${IFACE} in > /dev/null
793 ipfw add 100 setfib 0 ipv6-icmp from any to any \
794 icmp6types 128 via ${IFACEFAR} in > /dev/null
795 ipfw add 100 setfib 0 tcp from any to any \
796 dst-port ${CTRLPORT} via ${IFACEFAR} in > /dev/null
797 ipfw add 100 setfib 0 udp from any to any \
798 dst-port ${CTRLPORT} via ${IFACEFAR} in > /dev/null
800 setup_ipfw_count ${CTRLPORT} ${RT_NUMFIBS} 0 -1
801 wait_remote_ready "START_${_n}"
802 ipfw -q zero > /dev/null
803 # Nothing to do for the middle node testing the default.
805 wait_remote_ready "STOP_${_n}"
808 ipfw delete 100 > /dev/null
811 fwd_default_fib_symmetric_ipfw()
815 _n="fwd_default_fib_symmetric_ipfw"
819 left) _fwd_default_fib_symmetric_left ${_n} ;;
820 middle) _fwd_default_fib_symmetric_middle_ipfw ${_n} ;;
821 right) _fwd_default_fib_symmetric_right ${_n} ;;
825 ################################################################################
827 _fwd_fib_symmetric_results()
829 local _n _fib i _edge _type _rc
834 while test ${i} -lt ${RT_NUMFIBS}; do
835 for _edge in "LEFT" "RIGHT"; do
836 for _type in "ICMP6" "TCP" "UDP"; do
839 ${_fib}) eval rc_${_n}_${_edge}_${_type}_${i}=1
841 # "rc_${_n}_${_edge}_${_type}_${i}=1"
843 *) eval rc_${_n}_${_edge}_${_type}_${i}=0
845 # "rc_${_n}_${_edge}_${_type}_${i}=0"
855 _fwd_fib_symmetric_left()
861 # Setup expected return code
863 while test ${i} -lt ${_maxfib}; do
868 # Initiate probes for ICMP6, TCP and UDP.
870 while test ${i} -lt ${_maxfib}; do
874 send_control_msgs "START_${_n}_${i}"
876 test_icmp6 1 ${RIGHTADDR} "${_n}_${i}_icmp6"
877 test_ulp 1 "${_n}_${i}" ${RIGHTADDR} ${CTRLPORT} ${i}
879 send_control_msgs "STOP_${_n}_${i}"
880 _fwd_fib_symmetric_results "${_n}_${i}" ${i}
881 fetch_ipfw_count "${_n}_${i}"
886 _fwd_fib_symmetric_right()
893 while test ${i} -lt ${_maxfib}; do
894 wait_remote_ready "START_${_n}_${i}"
896 # No need to do anything for ICMPv6.
897 # Start reflect for TCP and UDP.
898 test_ulp_reflect_one "${_n}_tcp" "-N -T TCP6" ${i} ${CTRLPORT}
899 test_ulp_reflect_one "${_n}_udp" "-N -T UDP6" ${i} ${CTRLPORT}
901 wait_remote_ready "STOP_${_n}_${i}"
906 _fwd_fib_symmetric_middle_ifconfig()
913 while test ${i} -lt ${_maxfib}; do
914 ifconfig ${IFACE} fib ${i}
915 ifconfig ${IFACEFAR} fib ${i}
916 setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
917 wait_remote_ready "START_${_n}_${i}"
918 ipfw -q zero > /dev/null
919 # Nothing to do for the middle node testing the default.
921 wait_remote_ready "STOP_${_n}_${i}"
927 _fwd_fib_symmetric_middle_ipfw()
929 local _n _maxfib i _port
934 while test ${i} -lt ${_maxfib}; do
935 _port=$((CTRLPORT + 1 + i))
936 ipfw add 100 setfib ${i} ipv6-icmp from any to any \
937 icmp6types 128 via ${IFACE} in > /dev/null
938 ipfw add 100 setfib ${i} tcp from any to any \
939 dst-port ${_port} via ${IFACE} in > /dev/null
940 ipfw add 100 setfib ${i} udp from any to any \
941 dst-port ${_port} via ${IFACE} in > /dev/null
943 ipfw add 100 setfib ${i} ipv6-icmp from any to any \
944 icmp6types 129 via ${IFACEFAR} in > /dev/null
945 ipfw add 100 setfib ${i} tcp from any to any \
946 src-port ${_port} via ${IFACEFAR} in > /dev/null
947 ipfw add 100 setfib ${i} udp from any to any \
948 src-port ${_port} via ${IFACEFAR} in > /dev/null
950 setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
951 wait_remote_ready "START_${_n}_${i}"
952 ipfw -q zero > /dev/null
953 # Nothing to do for the middle node testing the default.
955 wait_remote_ready "STOP_${_n}_${i}"
958 ipfw delete 100 > /dev/null
963 fwd_fib_symmetric_ifconfig()
968 _n="fwd_fib_symmetric_ifconfig"
970 print_debug "${_n} ${_maxfib}"
972 left) _fwd_fib_symmetric_left ${_n} ${_maxfib} ;;
973 middle) _fwd_fib_symmetric_middle_ifconfig ${_n} ${_maxfib} ;;
974 right) _fwd_fib_symmetric_right ${_n} ${_maxfib} ;;
978 fwd_fib_symmetric_ipfw()
983 _n="fwd_fib_symmetric_ipfw"
985 print_debug "${_n} ${_maxfib}"
987 left) _fwd_fib_symmetric_left ${_n} ${_maxfib} ;;
988 middle) _fwd_fib_symmetric_middle_ipfw ${_n} ${_maxfib} ;;
989 right) _fwd_fib_symmetric_right ${_n} ${_maxfib} ;;
993 ################################################################################
995 _fwd_fib_asymmetric_results()
997 local _n fib maxfib i _edge _type _rc
1003 while test ${i} -lt ${maxfib}; do
1005 for _type in "ICMP6" "TCP" "UDP"; do
1008 ${fib}) eval rc_${_n}_${_edge}_${_type}_${i}=1
1010 # "rc_${_n}_${_edge}_${_type}_${i}=1"
1012 *) eval rc_${_n}_${_edge}_${_type}_${i}=0
1014 # "rc_${_n}_${_edge}_${_type}_${i}=0"
1021 fib=$((maxfib - 1 - fib))
1023 while test ${i} -lt ${maxfib}; do
1025 for _type in "ICMP6" "TCP" "UDP"; do
1028 ${fib}) eval rc_${_n}_${_edge}_${_type}_${i}=1
1030 # "rc_${_n}_${_edge}_${_type}_${i}=1"
1032 *) eval rc_${_n}_${_edge}_${_type}_${i}=0
1034 # "rc_${_n}_${_edge}_${_type}_${i}=0"
1043 _fwd_fib_asymmetric_left()
1049 # Setup expected return code
1051 while test ${i} -lt ${_maxfib}; do
1056 # Initiate probes for ICMP6, TCP and UDP.
1058 while test ${i} -lt ${_maxfib}; do
1062 send_control_msgs "START_${_n}_${i}"
1064 test_icmp6 1 ${RIGHTADDR} "${_n}_${i}_icmp6"
1065 test_ulp 1 "${_n}_${i}" ${RIGHTADDR} ${CTRLPORT} ${i}
1067 send_control_msgs "STOP_${_n}_${i}"
1068 _fwd_fib_asymmetric_results "${_n}_${i}" ${i} ${_maxfib}
1069 fetch_ipfw_count "${_n}_${i}"
1074 _fwd_fib_asymmetric_middle_ifconfig()
1081 while test ${i} -lt ${maxfib}; do
1082 ifconfig ${IFACE} fib ${i}
1083 ifconfig ${IFACEFAR} fib $((${maxfib} - 1 - ${i}))
1084 setup_ipfw_count ${CTRLPORT} ${maxfib} ${i} \
1085 $((${maxfib} - 1 - ${i}))
1086 wait_remote_ready "START_${_n}_${i}"
1087 ipfw -q zero > /dev/null
1088 # Nothing to do for the middle node testing the default.
1090 wait_remote_ready "STOP_${_n}_${i}"
1096 _fwd_fib_asymmetric_middle_ipfw()
1098 local _n maxfib i j _port
1103 while test ${i} -lt ${maxfib}; do
1105 _port=$((CTRLPORT + 1 + i))
1106 ipfw add 100 setfib ${i} ipv6-icmp from any to any \
1107 icmp6types 128 via ${IFACE} in > /dev/null
1108 ipfw add 100 setfib ${i} tcp from any to any \
1109 dst-port ${_port} via ${IFACE} in > /dev/null
1110 ipfw add 100 setfib ${i} udp from any to any \
1111 dst-port ${_port} via ${IFACE} in > /dev/null
1113 j=$((${maxfib} - 1 - ${i}))
1114 ipfw add 100 setfib ${j} ipv6-icmp from any to any \
1115 icmp6types 129 via ${IFACEFAR} in > /dev/null
1116 ipfw add 100 setfib ${j} tcp from any to any \
1117 src-port ${_port} via ${IFACEFAR} in > /dev/null
1118 ipfw add 100 setfib ${j} udp from any to any \
1119 src-port ${_port} via ${IFACEFAR} in > /dev/null
1121 setup_ipfw_count ${CTRLPORT} ${maxfib} ${i} ${j}
1122 wait_remote_ready "START_${_n}_${i}"
1123 ipfw -q zero > /dev/null
1124 # Nothing to do for the middle node testing the default.
1126 wait_remote_ready "STOP_${_n}_${i}"
1129 ipfw delete 100 > /dev/null
1134 fwd_fib_asymmetric_ifconfig()
1139 _n="fwd_fib_asymmetric_ifconfig"
1141 print_debug "${_n} ${_maxfib}"
1143 left) _fwd_fib_asymmetric_left ${_n} ${_maxfib} ;;
1144 middle) _fwd_fib_asymmetric_middle_ifconfig ${_n} ${_maxfib} ;;
1145 right) _fwd_fib_symmetric_right ${_n} ${_maxfib} ;;
1149 fwd_fib_asymmetric_ipfw()
1154 _n="fwd_fib_asymmetric_ipfw"
1156 print_debug "${_n} ${_maxfib}"
1158 left) _fwd_fib_asymmetric_left ${_n} ${_maxfib} ;;
1159 middle) _fwd_fib_asymmetric_middle_ipfw ${_n} ${_maxfib} ;;
1160 right) _fwd_fib_symmetric_right ${_n} ${_maxfib} ;;
1164 ################################################################################
1166 _fwd_fib_symmetric_destructive_left()
1168 local _n _maxfib i _addr
1172 # Setup expected return code
1174 while test ${i} -lt ${_maxfib}; do
1179 # Add default route.
1180 route add -net -inet6 default ${MIDDLELEFTADDR} > /dev/null
1182 # Initiate probes for ICMP6, TCP and UDP.
1184 while test ${i} -lt ${_maxfib}; do
1188 send_control_msgs "START_${_n}_${i}"
1190 _addr="2001:2:${i}::2"
1191 test_icmp6 1 ${_addr} "${_n}_${i}_icmp6"
1192 test_ulp 1 "${_n}_${i}" ${_addr} ${CTRLPORT} ${i}
1194 send_control_msgs "STOP_${_n}_${i}"
1195 _fwd_fib_symmetric_results "${_n}_${i}" ${i}
1196 fetch_ipfw_count "${_n}_${i}"
1200 # Cleanup networking.
1201 route delete -net -inet6 default > /dev/null
1204 _fwd_fib_symmetric_destructive_right()
1206 local _n _maxfib i _addr
1210 # Setup networking (ideally we'd use the link-local).
1211 route add -net -inet6 default ${MIDDLERIGHTADDR} > /dev/null 2>&1
1213 while test ${i} -lt ${_maxfib}; do
1214 ifconfig ${IFACE} inet6 2001:2:${i}::2/64 alias
1219 while test ${i} -lt ${_maxfib}; do
1220 wait_remote_ready "START_${_n}_${i}"
1222 # No need to do anything for ICMPv6.
1223 # Start reflect for TCP and UDP.
1224 _addr="2001:2:${i}::2"
1225 test_ulp_reflect_one "${_n}_tcp" "-N -T TCP6 -A ${_addr}" \
1227 test_ulp_reflect_one "${_n}_udp" "-N -T UDP6 -A ${_addr}" \
1230 wait_remote_ready "STOP_${_n}_${i}"
1234 # Cleanup networking again.
1235 route delete -net -inet6 default > /dev/null 2>&1
1237 while test ${i} -lt ${_maxfib}; do
1238 ifconfig ${IFACE} inet6 2001:2:${i}::2/64 -alias
1245 _fwd_fib_symmetric_destructive_middle_setup_networking()
1252 while test ${i} -lt ${_maxfib}; do
1253 ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 -alias \
1254 > /dev/null 2>&1 || true
1255 ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 alias
1257 while test ${j} -lt ${_maxfib}; do
1258 # Only work on all other FIBs.
1259 if test ${j} -ne ${i}; then
1260 setfib -F ${j} route delete -net -inet6 \
1261 2001:2:${i}::/64 > /dev/null
1269 _fwd_fib_symmetric_destructive_middle_cleanup_networking()
1274 # Cleanup networking again.
1276 while test ${i} -lt ${_maxfib}; do
1277 ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 -alias
1282 _fwd_fib_symmetric_destructive_middle_ifconfig()
1288 _fwd_fib_symmetric_destructive_middle_setup_networking ${_maxfib}
1291 while test ${i} -lt ${_maxfib}; do
1292 ifconfig ${IFACE} fib ${i}
1293 ifconfig ${IFACEFAR} fib ${i}
1294 setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
1295 wait_remote_ready "START_${_n}_${i}"
1296 ipfw -q zero > /dev/null
1297 # Nothing to do for the middle node testing the default.
1299 wait_remote_ready "STOP_${_n}_${i}"
1304 _fwd_fib_symmetric_destructive_middle_cleanup_networking ${_maxfib}
1307 _fwd_fib_symmetric_destructive_middle_ipfw()
1309 local _n _maxfib i _port
1313 _fwd_fib_symmetric_destructive_middle_setup_networking ${_maxfib}
1316 while test ${i} -lt ${_maxfib}; do
1317 _port=$((CTRLPORT + 1 + i))
1318 ipfw add 100 setfib ${i} ipv6-icmp from any to any \
1319 icmp6types 128 via ${IFACE} in > /dev/null
1320 ipfw add 100 setfib ${i} tcp from any to any \
1321 dst-port ${_port} via ${IFACE} in > /dev/null
1322 ipfw add 100 setfib ${i} udp from any to any \
1323 dst-port ${_port} via ${IFACE} in > /dev/null
1325 ipfw add 100 setfib ${i} ipv6-icmp from any to any \
1326 icmp6types 129 via ${IFACEFAR} in > /dev/null
1327 ipfw add 100 setfib ${i} tcp from any to any \
1328 src-port ${_port} via ${IFACEFAR} in > /dev/null
1329 ipfw add 100 setfib ${i} udp from any to any \
1330 src-port ${_port} via ${IFACEFAR} in > /dev/null
1332 setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
1333 wait_remote_ready "START_${_n}_${i}"
1334 ipfw -q zero > /dev/null
1335 # Nothing to do for the middle node testing the default.
1337 wait_remote_ready "STOP_${_n}_${i}"
1340 ipfw delete 100 > /dev/null
1344 _fwd_fib_symmetric_destructive_middle_cleanup_networking ${_maxfib}
1347 fwd_fib_symmetric_destructive_ifconfig()
1352 _n="fwd_fib_symmetric_destructive_ifconfig"
1354 print_debug "${_n} ${_maxfib}"
1356 left) _fwd_fib_symmetric_destructive_left ${_n} ${_maxfib} ;;
1357 middle) _fwd_fib_symmetric_destructive_middle_ifconfig \
1359 right) _fwd_fib_symmetric_destructive_right ${_n} ${_maxfib} ;;
1363 fwd_fib_symmetric_destructive_ipfw()
1368 _n="fwd_fib_symmetric_destructive_ipfw"
1370 print_debug "${_n} ${_maxfib}"
1372 left) _fwd_fib_symmetric_destructive_left ${_n} ${_maxfib} ;;
1373 middle) _fwd_fib_symmetric_destructive_middle_ipfw \
1375 right) _fwd_fib_symmetric_destructive_right ${_n} ${_maxfib} ;;
1379 ################################################################################
1381 _fwd_fib_symmetric_destructive_defroute_left()
1383 local _n _maxfib i _addr
1387 # Setup expected return code
1389 while test ${i} -lt ${_maxfib}; do
1394 # Add default route.
1395 route delete -net -inet6 default > /dev/null 2>&1 || true
1396 route add -net -inet6 default ${MIDDLELEFTADDR} > /dev/null
1398 # Initiate probes for ICMP6, TCP and UDP.
1399 _addr="2001:2:1234::2"
1401 while test ${i} -lt ${_maxfib}; do
1405 send_control_msgs "START_${_n}_${i}"
1407 test_icmp6 1 "${_addr}" "${_n}_${i}_icmp6"
1408 test_ulp 1 "${_n}_${i}" "${_addr}" ${CTRLPORT} ${i}
1410 send_control_msgs "STOP_${_n}_${i}"
1411 _fwd_fib_symmetric_results "${_n}_${i}" ${i}
1412 fetch_ipfw_count "${_n}_${i}"
1416 # Cleanup networking.
1417 route delete -net -inet6 default > /dev/null 2>&1
1420 _fwd_fib_symmetric_destructive_defroute_right()
1422 local _n _maxfib i _addr
1426 # Setup networking (ideally we'd use the link-local).
1427 route delete -net -inet6 default > /dev/null 2>&1 || true
1428 route add -net -inet6 default ${MIDDLERIGHTADDR} > /dev/null 2>&1
1430 while test ${i} -lt ${_maxfib}; do
1431 ifconfig ${IFACE} inet6 2001:2:${i}::2/64 -alias \
1432 > /dev/null 2>&1 || true
1433 ifconfig ${IFACE} inet6 2001:2:${i}::2/64 alias
1436 _addr="2001:2:1234::2"
1437 ifconfig lo0 inet6 ${_addr}/128 alias
1440 while test ${i} -lt ${_maxfib}; do
1441 wait_remote_ready "START_${_n}_${i}"
1443 # No need to do anything for ICMPv6.
1444 # Start reflect for TCP and UDP.
1445 test_ulp_reflect_one "${_n}_tcp" "-N -T TCP6 -A ${_addr}" \
1447 test_ulp_reflect_one "${_n}_udp" "-N -T UDP6 -A ${_addr}" \
1450 wait_remote_ready "STOP_${_n}_${i}"
1454 # Cleanup networking again.
1455 route delete -net -inet6 default > /dev/null 2>&1
1457 while test ${i} -lt ${_maxfib}; do
1458 ifconfig ${IFACE} inet6 2001:2:${i}::2/64 -alias
1461 ifconfig lo0 inet6 ${_addr}/128 -alias
1465 _fwd_fib_symmetric_destructive_defroute_middle_setup_networking()
1472 while test ${i} -lt ${_maxfib}; do
1473 ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 -alias \
1474 > /dev/null 2>&1 || true
1475 ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 alias
1477 while test ${j} -lt ${_maxfib}; do
1478 # Only work on all other FIBs.
1479 if test ${j} -ne ${i}; then
1480 setfib -F ${j} route delete -net -inet6 \
1481 2001:2:${i}::/64 > /dev/null
1485 setfib -F ${i} route delete -net -inet6 \
1486 2001:2:1234::2 2001:2:${i}::2 > /dev/null 2>&1 || true
1487 setfib -F ${i} route add -net -inet6 \
1488 2001:2:1234::2 2001:2:${i}::2 > /dev/null
1493 _fwd_fib_symmetric_destructive_defroute_middle_cleanup_networking()
1498 # Cleanup networking again.
1500 while test ${i} -lt ${_maxfib}; do
1501 ifconfig ${IFACEFAR} inet6 2001:2:${i}::1/64 -alias
1502 setfib -F ${i} route delete -net -inet6 \
1503 2001:2:1234::2 2001:2:${i}::2 > /dev/null
1508 _fwd_fib_symmetric_destructive_defroute_middle_ifconfig()
1514 _fwd_fib_symmetric_destructive_defroute_middle_setup_networking \
1518 while test ${i} -lt ${_maxfib}; do
1519 ifconfig ${IFACE} fib ${i}
1520 ifconfig ${IFACEFAR} fib ${i}
1521 setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
1522 wait_remote_ready "START_${_n}_${i}"
1523 ipfw -q zero > /dev/null
1524 # Nothing to do for the middle node testing the default.
1526 wait_remote_ready "STOP_${_n}_${i}"
1531 _fwd_fib_symmetric_destructive_defroute_middle_cleanup_networking \
1535 _fwd_fib_symmetric_destructive_defroute_middle_ipfw()
1537 local _n _maxfib i _port
1541 _fwd_fib_symmetric_destructive_defroute_middle_setup_networking \
1545 while test ${i} -lt ${_maxfib}; do
1546 _port=$((CTRLPORT + 1 + i))
1547 ipfw add 100 setfib ${i} ipv6-icmp from any to any \
1548 icmp6types 128 via ${IFACE} in > /dev/null
1549 ipfw add 100 setfib ${i} tcp from any to any \
1550 dst-port ${_port} via ${IFACE} in > /dev/null
1551 ipfw add 100 setfib ${i} udp from any to any \
1552 dst-port ${_port} via ${IFACE} in > /dev/null
1554 ipfw add 100 setfib ${i} ipv6-icmp from any to any \
1555 icmp6types 129 via ${IFACEFAR} in > /dev/null
1556 ipfw add 100 setfib ${i} tcp from any to any \
1557 src-port ${_port} via ${IFACEFAR} in > /dev/null
1558 ipfw add 100 setfib ${i} udp from any to any \
1559 src-port ${_port} via ${IFACEFAR} in > /dev/null
1561 setup_ipfw_count ${CTRLPORT} ${_maxfib} ${i} -1
1562 wait_remote_ready "START_${_n}_${i}"
1563 ipfw -q zero > /dev/null
1564 # Nothing to do for the middle node testing the default.
1566 wait_remote_ready "STOP_${_n}_${i}"
1569 ipfw delete 100 > /dev/null
1573 _fwd_fib_symmetric_destructive_defroute_middle_cleanup_networking \
1577 fwd_fib_symmetric_destructive_defroute_ifconfig()
1582 _n="fwd_fib_symmetric_destructive_defroute_ifconfig"
1584 print_debug "${_n} ${_maxfib}"
1586 left) _fwd_fib_symmetric_destructive_defroute_left \
1588 middle) _fwd_fib_symmetric_destructive_defroute_middle_ifconfig \
1590 right) _fwd_fib_symmetric_destructive_defroute_right \
1595 fwd_fib_symmetric_destructive_defroute_ipfw()
1600 _n="fwd_fib_symmetric_destructive_defroute_ipfw"
1602 print_debug "${_n} ${_maxfib}"
1604 left) _fwd_fib_symmetric_destructive_defroute_left \
1606 middle) _fwd_fib_symmetric_destructive_defroute_middle_ipfw \
1608 right) _fwd_fib_symmetric_destructive_defroute_right \
1613 ################################################################################
1618 # Same for all hosts.
1619 if test `sysctl -n security.jail.jailed` -eq 0; then
1620 kldload ipfw > /dev/null 2>&1 || kldstat -v | grep -q ipfw
1622 ipfw -f flush > /dev/null 2>&1 || die "please load ipfw in base system"
1623 ipfw add 65000 permit ip from any to any > /dev/null 2>&1
1633 fwd_default_fib_symmetric
1634 fwd_default_fib_symmetric_ifconfig
1635 fwd_default_fib_symmetric_ipfw
1637 fwd_fib_symmetric_ifconfig ${RT_NUMFIBS}
1638 fwd_fib_symmetric_ipfw ${RT_NUMFIBS}
1640 fwd_fib_asymmetric_ifconfig ${RT_NUMFIBS}
1641 fwd_fib_asymmetric_ipfw ${RT_NUMFIBS}
1643 fwd_fib_symmetric_destructive_ifconfig ${RT_NUMFIBS}
1644 fwd_fib_symmetric_destructive_ipfw ${RT_NUMFIBS}
1646 fwd_fib_symmetric_destructive_defroute_ifconfig ${RT_NUMFIBS}
1647 fwd_fib_symmetric_destructive_defroute_ipfw ${RT_NUMFIBS}