diff --git a/tests/sys/common/vnet.subr b/tests/sys/common/vnet.subr index 183f7284d614..fd67385655fc 100644 --- a/tests/sys/common/vnet.subr +++ b/tests/sys/common/vnet.subr @@ -1,104 +1,111 @@ # VNET/jail utility functions ## list_interface() { echo $1 >> created_interfaces.lst } unlist_interface() { sed -i "" /^$1\$/d created_interfaces.lst } vnet_init() { if [ "`sysctl -i -n kern.features.vimage`" != 1 ]; then atf_skip "This test requires VIMAGE" fi } vnet_mkepair() { ifname=$(ifconfig epair create) list_interface $ifname list_interface ${ifname%a}b echo ${ifname%a} } +vnet_init_bridge() +{ + if ! kldstat -q -m if_bridge; then + atf_skip "This test requires if_bridge" + fi +} + vnet_mkbridge() { ifname=$(ifconfig bridge create) list_interface $ifname echo ${ifname} } vnet_mkvlan() { ifname=$(ifconfig vlan create) list_interface $ifname echo ${ifname} } vnet_mkloopback() { ifname=$(ifconfig lo create) list_interface $ifname echo ${ifname} } vnet_mkjail() { jailname=$1 shift vnet_interfaces= for ifname in $@ do vnet_interfaces="${vnet_interfaces} vnet.interface=${ifname}" unlist_interface $ifname done jail -c name=${jailname} persist vnet ${vnet_interfaces} echo $jailname $@ >> created_jails.lst } vnet_ifmove() { ifname=$1 jailname=$2 ifconfig ${ifname} vnet ${jailname} unlist_interface $ifname sed -i "" "/^${jailname}/s/\$/ ${ifname}/" created_jails.lst } vnet_ifrename_jail() { jailname=$1 ifname=$2 ifnewname=$3 ifconfig -j ${jailname} $ifname name $ifnewname sed -i "" "/^${jailname}/s/${ifname}/${ifnewname}/" created_jails.lst } vnet_cleanup() { if [ -f created_jails.lst ]; then while read jailname ifnames; do for ifname in ${ifnames}; do ifconfig -j ${jailname} ${ifname} destroy done jail -r ${jailname} done < created_jails.lst rm created_jails.lst fi if [ -f created_interfaces.lst ]; then while read ifname; do ifconfig ${ifname} destroy done < created_interfaces.lst rm created_interfaces.lst fi } diff --git a/tests/sys/net/if_bridge_test.sh b/tests/sys/net/if_bridge_test.sh index 44370a905223..66656be1d84f 100755 --- a/tests/sys/net/if_bridge_test.sh +++ b/tests/sys/net/if_bridge_test.sh @@ -1,708 +1,721 @@ # # SPDX-License-Identifier: BSD-2-Clause # # Copyright (c) 2020 The FreeBSD Foundation # # This software was developed by Kristof Provost under sponsorship # from the FreeBSD Foundation. # # 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. . $(atf_get_srcdir)/../common/vnet.subr atf_test_case "bridge_transmit_ipv4_unicast" "cleanup" bridge_transmit_ipv4_unicast_head() { atf_set descr 'bridge_transmit_ipv4_unicast bridging test' atf_set require.user root } bridge_transmit_ipv4_unicast_body() { vnet_init + vnet_init_bridge epair_alcatraz=$(vnet_mkepair) epair_singsing=$(vnet_mkepair) vnet_mkjail alcatraz ${epair_alcatraz}b vnet_mkjail singsing ${epair_singsing}b jexec alcatraz ifconfig ${epair_alcatraz}b 192.0.2.1/24 up jexec singsing ifconfig ${epair_singsing}b 192.0.2.2/24 up bridge=$(vnet_mkbridge) ifconfig ${bridge} up ifconfig ${epair_alcatraz}a up ifconfig ${epair_singsing}a up ifconfig ${bridge} addm ${epair_alcatraz}a ifconfig ${bridge} addm ${epair_singsing}a atf_check -s exit:0 -o ignore jexec alcatraz ping -c 3 -t 1 192.0.2.2 atf_check -s exit:0 -o ignore jexec singsing ping -c 3 -t 1 192.0.2.1 } bridge_transmit_ipv4_unicast_cleanup() { vnet_cleanup } atf_test_case "stp" "cleanup" stp_head() { atf_set descr 'Spanning tree test' atf_set require.user root } stp_body() { vnet_init + vnet_init_bridge epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) bridge_a=$(vnet_mkbridge) bridge_b=$(vnet_mkbridge) vnet_mkjail a ${bridge_a} ${epair_one}a ${epair_two}a vnet_mkjail b ${bridge_b} ${epair_one}b ${epair_two}b jexec a ifconfig ${epair_one}a up jexec a ifconfig ${epair_two}a up jexec a ifconfig ${bridge_a} addm ${epair_one}a jexec a ifconfig ${bridge_a} addm ${epair_two}a jexec b ifconfig ${epair_one}b up jexec b ifconfig ${epair_two}b up jexec b ifconfig ${bridge_b} addm ${epair_one}b jexec b ifconfig ${bridge_b} addm ${epair_two}b jexec a ifconfig ${bridge_a} 192.0.2.1/24 # Enable spanning tree jexec a ifconfig ${bridge_a} stp ${epair_one}a jexec a ifconfig ${bridge_a} stp ${epair_two}a jexec b ifconfig ${bridge_b} stp ${epair_one}b jexec b ifconfig ${bridge_b} stp ${epair_two}b jexec b ifconfig ${bridge_b} up jexec a ifconfig ${bridge_a} up # Give STP time to do its thing sleep 5 a_discard=$(jexec a ifconfig ${bridge_a} | grep discarding) b_discard=$(jexec b ifconfig ${bridge_b} | grep discarding) if [ -z "${a_discard}" ] && [ -z "${b_discard}" ] then atf_fail "STP failed to detect bridging loop" fi # We must also have at least some forwarding interfaces a_forwarding=$(jexec a ifconfig ${bridge_a} | grep forwarding) b_forwarding=$(jexec b ifconfig ${bridge_b} | grep forwarding) if [ -z "${a_forwarding}" ] && [ -z "${b_forwarding}" ] then atf_fail "STP failed to detect bridging loop" fi } stp_cleanup() { vnet_cleanup } atf_test_case "stp_vlan" "cleanup" stp_vlan_head() { atf_set descr 'Spanning tree on VLAN test' atf_set require.user root } stp_vlan_body() { vnet_init + vnet_init_bridge epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) bridge_a=$(vnet_mkbridge) bridge_b=$(vnet_mkbridge) vnet_mkjail a ${bridge_a} ${epair_one}a ${epair_two}a vnet_mkjail b ${bridge_b} ${epair_one}b ${epair_two}b jexec a ifconfig ${epair_one}a up jexec a ifconfig ${epair_two}a up vlan_a_one=$(jexec a ifconfig vlan create vlandev ${epair_one}a vlan 42) vlan_a_two=$(jexec a ifconfig vlan create vlandev ${epair_two}a vlan 42) jexec a ifconfig ${vlan_a_one} up jexec a ifconfig ${vlan_a_two} up jexec a ifconfig ${bridge_a} addm ${vlan_a_one} jexec a ifconfig ${bridge_a} addm ${vlan_a_two} jexec b ifconfig ${epair_one}b up jexec b ifconfig ${epair_two}b up vlan_b_one=$(jexec b ifconfig vlan create vlandev ${epair_one}b vlan 42) vlan_b_two=$(jexec b ifconfig vlan create vlandev ${epair_two}b vlan 42) jexec b ifconfig ${vlan_b_one} up jexec b ifconfig ${vlan_b_two} up jexec b ifconfig ${bridge_b} addm ${vlan_b_one} jexec b ifconfig ${bridge_b} addm ${vlan_b_two} jexec a ifconfig ${bridge_a} 192.0.2.1/24 # Enable spanning tree jexec a ifconfig ${bridge_a} stp ${vlan_a_one} jexec a ifconfig ${bridge_a} stp ${vlan_a_two} jexec b ifconfig ${bridge_b} stp ${vlan_b_one} jexec b ifconfig ${bridge_b} stp ${vlan_b_two} jexec b ifconfig ${bridge_b} up jexec a ifconfig ${bridge_a} up # Give STP time to do its thing sleep 5 a_discard=$(jexec a ifconfig ${bridge_a} | grep discarding) b_discard=$(jexec b ifconfig ${bridge_b} | grep discarding) if [ -z "${a_discard}" ] && [ -z "${b_discard}" ] then atf_fail "STP failed to detect bridging loop" fi # We must also have at least some forwarding interfaces a_forwarding=$(jexec a ifconfig ${bridge_a} | grep forwarding) b_forwarding=$(jexec b ifconfig ${bridge_b} | grep forwarding) if [ -z "${a_forwarding}" ] && [ -z "${b_forwarding}" ] then atf_fail "STP failed to detect bridging loop" fi } stp_vlan_cleanup() { vnet_cleanup } atf_test_case "static" "cleanup" static_head() { atf_set descr 'Bridge static address test' atf_set require.user root } static_body() { vnet_init + vnet_init_bridge epair=$(vnet_mkepair) bridge=$(vnet_mkbridge) vnet_mkjail one ${bridge} ${epair}a ifconfig ${epair}b up jexec one ifconfig ${bridge} up jexec one ifconfig ${epair}a up jexec one ifconfig ${bridge} addm ${epair}a # Wrong interface atf_check -s exit:1 -o ignore -e ignore \ jexec one ifconfig ${bridge} static ${epair}b 00:01:02:03:04:05 # Bad address format atf_check -s exit:1 -o ignore -e ignore \ jexec one ifconfig ${bridge} static ${epair}a 00:01:02:03:04 # Correct add atf_check -s exit:0 -o ignore \ jexec one ifconfig ${bridge} static ${epair}a 00:01:02:03:04:05 # List addresses atf_check -s exit:0 -o ignore \ jexec one ifconfig ${bridge} addr # Delete with bad address format atf_check -s exit:1 -o ignore -e ignore \ jexec one ifconfig ${bridge} deladdr 00:01:02:03:04 # Delete with unlisted address atf_check -s exit:1 -o ignore -e ignore \ jexec one ifconfig ${bridge} deladdr 00:01:02:03:04:06 # Correct delete atf_check -s exit:0 -o ignore \ jexec one ifconfig ${bridge} deladdr 00:01:02:03:04:05 } static_cleanup() { vnet_cleanup } atf_test_case "span" "cleanup" span_head() { atf_set descr 'Bridge span test' atf_set require.user root atf_set require.progs scapy } span_body() { vnet_init + vnet_init_bridge epair=$(vnet_mkepair) epair_span=$(vnet_mkepair) bridge=$(vnet_mkbridge) vnet_mkjail one ${bridge} ${epair}a ${epair_span}a ifconfig ${epair}b up ifconfig ${epair_span}b up jexec one ifconfig ${bridge} up jexec one ifconfig ${epair}a up jexec one ifconfig ${epair_span}a up jexec one ifconfig ${bridge} addm ${epair}a jexec one ifconfig ${bridge} span ${epair_span}a jexec one ifconfig ${bridge} 192.0.2.1/24 # Send some traffic through the span jexec one ping -c 1 -t 1 192.0.2.2 # Check that we see the traffic on the span interface atf_check -s exit:0 \ $(atf_get_srcdir)/../netpfil/common/pft_ping.py \ --sendif ${epair}b \ --to 192.0.2.2 \ --recvif ${epair_span}b jexec one ifconfig ${bridge} -span ${epair_span}a # And no more traffic after we remove the span atf_check -s exit:1 \ $(atf_get_srcdir)/../netpfil/common/pft_ping.py \ --sendif ${epair}b \ --to 192.0.2.2 \ --recvif ${epair_span}b } span_cleanup() { vnet_cleanup } atf_test_case "delete_with_members" "cleanup" delete_with_members_head() { atf_set descr 'Delete a bridge which still has member interfaces' atf_set require.user root } delete_with_members_body() { vnet_init + vnet_init_bridge bridge=$(vnet_mkbridge) epair=$(vnet_mkepair) ifconfig ${bridge} 192.0.2.1/24 up ifconfig ${epair}a up ifconfig ${bridge} addm ${epair}a ifconfig ${bridge} destroy } delete_with_members_cleanup() { vnet_cleanup } atf_test_case "mac_conflict" "cleanup" mac_conflict_head() { atf_set descr 'Ensure that bridges in different jails get different mac addresses' atf_set require.user root } mac_conflict_body() { vnet_init + vnet_init_bridge epair=$(vnet_mkepair) # Ensure the bridge module is loaded so jails can use it. tmpbridge=$(vnet_mkbridge) vnet_mkjail bridge_mac_conflict_one ${epair}a vnet_mkjail bridge_mac_conflict_two ${epair}b jexec bridge_mac_conflict_one ifconfig bridge create jexec bridge_mac_conflict_one ifconfig bridge0 192.0.2.1/24 up \ addm ${epair}a jexec bridge_mac_conflict_one ifconfig ${epair}a up jexec bridge_mac_conflict_two ifconfig bridge create jexec bridge_mac_conflict_two ifconfig bridge0 192.0.2.2/24 up \ addm ${epair}b jexec bridge_mac_conflict_two ifconfig ${epair}b up atf_check -s exit:0 -o ignore \ jexec bridge_mac_conflict_one ping -c 3 192.0.2.2 } mac_conflict_cleanup() { vnet_cleanup } atf_test_case "inherit_mac" "cleanup" inherit_mac_head() { atf_set descr 'Bridge inherit_mac test, #216510' atf_set require.user root } inherit_mac_body() { vnet_init + vnet_init_bridge bridge=$(vnet_mkbridge) epair=$(vnet_mkepair) vnet_mkjail one ${bridge} ${epair}a jexec one sysctl net.link.bridge.inherit_mac=1 # Attempt to provoke the panic described in #216510 jexec one ifconfig ${bridge} 192.0.0.1/24 up jexec one ifconfig ${bridge} addm ${epair}a } inherit_mac_cleanup() { vnet_cleanup } atf_test_case "stp_validation" "cleanup" stp_validation_head() { atf_set descr 'Check STP validation' atf_set require.user root atf_set require.progs scapy } stp_validation_body() { vnet_init + vnet_init_bridge epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) bridge=$(vnet_mkbridge) ifconfig ${bridge} up ifconfig ${bridge} addm ${epair_one}a addm ${epair_two}a ifconfig ${bridge} stp ${epair_one}a stp ${epair_two}a ifconfig ${epair_one}a up ifconfig ${epair_one}b up ifconfig ${epair_two}a up ifconfig ${epair_two}b up # Wait until the interfaces are no longer discarding while ifconfig ${bridge} | grep 'state discarding' >/dev/null do sleep 1 done # Now inject invalid STP BPDUs on epair_one and see if they're repeated # on epair_two atf_check -s exit:0 \ $(atf_get_srcdir)/stp.py \ --sendif ${epair_one}b \ --recvif ${epair_two}b } stp_validation_cleanup() { vnet_cleanup } atf_test_case "gif" "cleanup" gif_head() { atf_set descr 'gif as a bridge member' atf_set require.user root } gif_body() { vnet_init + vnet_init_bridge epair=$(vnet_mkepair) vnet_mkjail one ${epair}a vnet_mkjail two ${epair}b jexec one sysctl net.link.gif.max_nesting=2 jexec two sysctl net.link.gif.max_nesting=2 jexec one ifconfig ${epair}a 192.0.2.1/24 up jexec two ifconfig ${epair}b 192.0.2.2/24 up # Tunnel gif_one=$(jexec one ifconfig gif create) gif_two=$(jexec two ifconfig gif create) jexec one ifconfig ${gif_one} tunnel 192.0.2.1 192.0.2.2 jexec one ifconfig ${gif_one} up jexec two ifconfig ${gif_two} tunnel 192.0.2.2 192.0.2.1 jexec two ifconfig ${gif_two} up bridge_one=$(jexec one ifconfig bridge create) bridge_two=$(jexec two ifconfig bridge create) jexec one ifconfig ${bridge_one} 198.51.100.1/24 up jexec one ifconfig ${bridge_one} addm ${gif_one} jexec two ifconfig ${bridge_two} 198.51.100.2/24 up jexec two ifconfig ${bridge_two} addm ${gif_two} # Sanity check atf_check -s exit:0 -o ignore \ jexec one ping -c 1 192.0.2.2 # Test tunnel atf_check -s exit:0 -o ignore \ jexec one ping -c 1 198.51.100.2 atf_check -s exit:0 -o ignore \ jexec one ping -c 1 -s 1200 198.51.100.2 atf_check -s exit:0 -o ignore \ jexec one ping -c 1 -s 2000 198.51.100.2 # Higher MTU on the tunnel than on the underlying interface jexec one ifconfig ${epair}a mtu 1000 jexec two ifconfig ${epair}b mtu 1000 atf_check -s exit:0 -o ignore \ jexec one ping -c 1 -s 1200 198.51.100.2 atf_check -s exit:0 -o ignore \ jexec one ping -c 1 -s 2000 198.51.100.2 } gif_cleanup() { vnet_cleanup } atf_test_case "mtu" "cleanup" mtu_head() { atf_set descr 'Bridge MTU changes' atf_set require.user root } get_mtu() { intf=$1 ifconfig ${intf} ether | awk '$5 == "mtu" { print $6 }' } check_mtu() { intf=$1 expected=$2 mtu=$(get_mtu $intf) if [ $mtu -ne $expected ]; then atf_fail "Expected MTU of $expected on $intf but found $mtu" fi } mtu_body() { vnet_init + vnet_init_bridge epair=$(vnet_mkepair) gif=$(ifconfig gif create) echo ${gif} >> created_interfaces.lst bridge=$(vnet_mkbridge) atf_check -s exit:0 \ ifconfig ${bridge} addm ${epair}a ifconfig ${gif} mtu 1500 atf_check -s exit:0 \ ifconfig ${bridge} addm ${gif} # Changing MTU changes it for all member interfaces atf_check -s exit:0 \ ifconfig ${bridge} mtu 2000 check_mtu ${bridge} 2000 check_mtu ${gif} 2000 check_mtu ${epair}a 2000 # Rejected MTUs mean none of the MTUs change atf_check -s exit:1 -e ignore \ ifconfig ${bridge} mtu 9000 check_mtu ${bridge} 2000 check_mtu ${gif} 2000 check_mtu ${epair}a 2000 # We're not allowed to change the MTU of a member interface atf_check -s exit:1 -e ignore \ ifconfig ${epair}a mtu 1900 check_mtu ${epair}a 2000 # Test adding an interface with a different MTU new_epair=$(vnet_mkepair) check_mtu ${new_epair}a 1500 atf_check -s exit:0 -e ignore \ ifconfig ${bridge} addm ${new_epair}a check_mtu ${bridge} 2000 check_mtu ${gif} 2000 check_mtu ${epair}a 2000 check_mtu ${new_epair}a 2000 } mtu_cleanup() { vnet_cleanup } atf_test_case "vlan" "cleanup" vlan_head() { atf_set descr 'Ensure the bridge takes vlan ID into account, PR#270559' atf_set require.user root } vlan_body() { vnet_init + vnet_init_bridge vid=1 epaira=$(vnet_mkepair) epairb=$(vnet_mkepair) br=$(vnet_mkbridge) vnet_mkjail one ${epaira}b vnet_mkjail two ${epairb}b ifconfig ${br} up ifconfig ${epaira}a up ifconfig ${epairb}a up ifconfig ${br} addm ${epaira}a addm ${epairb}a jexec one ifconfig ${epaira}b up jexec one ifconfig ${epaira}b.${vid} create jexec two ifconfig ${epairb}b up jexec two ifconfig ${epairb}b.${vid} create # Create a MAC address conflict between an untagged and tagged interface jexec two ifconfig ${epairb}b.${vid} ether 02:05:6e:06:28:1a jexec one ifconfig ${epaira}b ether 02:05:6e:06:28:1a jexec one ifconfig ${epaira}b.${vid} ether 02:05:6e:06:28:1b # Add ip address, will also populate $br's fowarding table, by ARP announcement jexec one ifconfig ${epaira}b.${vid} 192.0.2.1/24 up jexec two ifconfig ${epairb}b.${vid} 192.0.2.2/24 up sleep 0.5 ifconfig ${br} jexec one ifconfig jexec two ifconfig ifconfig ${br} addr atf_check -s exit:0 -o ignore \ jexec one ping -c 1 -t 1 192.0.2.2 # This will trigger a mac flap (by ARP announcement) jexec one ifconfig ${epaira}b 192.0.2.1/24 up sleep 0.5 ifconfig ${br} addr atf_check -s exit:0 -o ignore \ jexec one ping -c 1 -t 1 192.0.2.2 } vlan_cleanup() { vnet_cleanup } atf_test_case "many_bridge_members" "cleanup" many_bridge_members_head() { atf_set descr 'many_bridge_members ifconfig test' atf_set require.user root } many_bridge_members_body() { vnet_init + vnet_init_bridge bridge=$(vnet_mkbridge) ifcount=256 for _ in $(seq 1 $ifcount); do epair=$(vnet_mkepair) ifconfig "${bridge}" addm "${epair}"a done atf_check -s exit:0 -o inline:"$ifcount\n" \ sh -c "ifconfig ${bridge} | grep member: | wc -l | xargs" } many_bridge_members_cleanup() { vnet_cleanup } atf_init_test_cases() { atf_add_test_case "bridge_transmit_ipv4_unicast" atf_add_test_case "stp" atf_add_test_case "stp_vlan" atf_add_test_case "static" atf_add_test_case "span" atf_add_test_case "inherit_mac" atf_add_test_case "delete_with_members" atf_add_test_case "mac_conflict" atf_add_test_case "stp_validation" atf_add_test_case "gif" atf_add_test_case "mtu" atf_add_test_case "vlan" atf_add_test_case "many_bridge_members" } diff --git a/tests/sys/net/if_ovpn/if_ovpn.sh b/tests/sys/net/if_ovpn/if_ovpn.sh index 22da82312dbc..77007c967333 100644 --- a/tests/sys/net/if_ovpn/if_ovpn.sh +++ b/tests/sys/net/if_ovpn/if_ovpn.sh @@ -1,1063 +1,1065 @@ ## # SPDX-License-Identifier: BSD-2-Clause # # Copyright (c) 2022 Rubicon Communications, LLC ("Netgate") # # 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. . $(atf_get_srcdir)/utils.subr . $(atf_get_srcdir)/../../netpfil/pf/utils.subr atf_test_case "4in4" "cleanup" 4in4_head() { atf_set descr 'IPv4 in IPv4 tunnel' atf_set require.user root atf_set require.progs openvpn } 4in4_body() { ovpn_init l=$(vnet_mkepair) vnet_mkjail a ${l}a jexec a ifconfig ${l}a 192.0.2.1/24 up vnet_mkjail b ${l}b jexec b ifconfig ${l}b 192.0.2.2/24 up # Sanity check atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2 ovpn_start a " dev ovpn0 dev-type tun proto udp4 cipher AES-256-GCM auth SHA256 local 192.0.2.1 server 198.51.100.0 255.255.255.0 ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/server.crt key $(atf_get_srcdir)/server.key dh $(atf_get_srcdir)/dh.pem mode server script-security 2 auth-user-pass-verify /usr/bin/true via-env topology subnet keepalive 100 600 " ovpn_start b " dev tun0 dev-type tun client remote 192.0.2.1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client.crt key $(atf_get_srcdir)/client.key dh $(atf_get_srcdir)/dh.pem keepalive 100 600 " # Give the tunnel time to come up sleep 10 atf_check -s exit:0 -o ignore jexec b ping -c 1 198.51.100.1 echo 'foo' | jexec b nc -u -w 2 192.0.2.1 1194 atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1 # Test routing loop protection jexec b route add 192.0.2.1 198.51.100.1 atf_check -s exit:2 -o ignore jexec b ping -t 1 -c 1 198.51.100.1 } 4in4_cleanup() { ovpn_cleanup } atf_test_case "4mapped" "cleanup" 4mapped_head() { atf_set descr 'IPv4 mapped addresses' atf_set require.user root atf_set require.progs openvpn } 4mapped_body() { ovpn_init l=$(vnet_mkepair) vnet_mkjail a ${l}a jexec a ifconfig ${l}a 192.0.2.1/24 up vnet_mkjail b ${l}b jexec b ifconfig ${l}b 192.0.2.2/24 up # Sanity check atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2 #jexec a ifconfig ${l}a ovpn_start a " dev ovpn0 dev-type tun cipher AES-256-GCM auth SHA256 server 198.51.100.0 255.255.255.0 ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/server.crt key $(atf_get_srcdir)/server.key dh $(atf_get_srcdir)/dh.pem mode server script-security 2 auth-user-pass-verify /usr/bin/true via-env topology subnet keepalive 100 600 " ovpn_start b " dev tun0 dev-type tun client remote 192.0.2.1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client.crt key $(atf_get_srcdir)/client.key dh $(atf_get_srcdir)/dh.pem keepalive 100 600 " # Give the tunnel time to come up sleep 10 atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1 } 4mapped_cleanup() { ovpn_cleanup } atf_test_case "6in4" "cleanup" 6in4_head() { atf_set descr 'IPv6 in IPv4 tunnel' atf_set require.user root atf_set require.progs openvpn } 6in4_body() { ovpn_init l=$(vnet_mkepair) vnet_mkjail a ${l}a jexec a ifconfig ${l}a 192.0.2.1/24 up vnet_mkjail b ${l}b jexec b ifconfig ${l}b 192.0.2.2/24 up # Sanity check atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2 ovpn_start a " dev ovpn0 dev-type tun proto udp cipher AES-256-GCM auth SHA256 local 192.0.2.1 server-ipv6 2001:db8:1::/64 ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/server.crt key $(atf_get_srcdir)/server.key dh $(atf_get_srcdir)/dh.pem mode server script-security 2 auth-user-pass-verify /usr/bin/true via-env topology subnet keepalive 100 600 " ovpn_start b " dev tun0 dev-type tun client remote 192.0.2.1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client.crt key $(atf_get_srcdir)/client.key dh $(atf_get_srcdir)/dh.pem keepalive 100 600 " # Give the tunnel time to come up sleep 10 atf_check -s exit:0 -o ignore jexec b ping6 -c 3 2001:db8:1::1 } 6in4_cleanup() { ovpn_cleanup } atf_test_case "4in6" "cleanup" 4in6_head() { atf_set descr 'IPv4 in IPv6 tunnel' atf_set require.user root atf_set require.progs openvpn } 4in6_body() { ovpn_init l=$(vnet_mkepair) vnet_mkjail a ${l}a jexec a ifconfig ${l}a inet6 2001:db8::1/64 up no_dad vnet_mkjail b ${l}b jexec b ifconfig ${l}b inet6 2001:db8::2/64 up no_dad # Sanity check atf_check -s exit:0 -o ignore jexec a ping6 -c 1 2001:db8::2 ovpn_start a " dev ovpn0 dev-type tun proto udp6 cipher AES-256-GCM auth SHA256 local 2001:db8::1 server 198.51.100.0 255.255.255.0 ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/server.crt key $(atf_get_srcdir)/server.key dh $(atf_get_srcdir)/dh.pem mode server script-security 2 auth-user-pass-verify /usr/bin/true via-env topology subnet keepalive 100 600 " ovpn_start b " dev tun0 dev-type tun client remote 2001:db8::1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client.crt key $(atf_get_srcdir)/client.key dh $(atf_get_srcdir)/dh.pem keepalive 100 600 " dd if=/dev/random of=test.img bs=1024 count=1024 cat test.img | jexec a nc -N -l 1234 & # Give the tunnel time to come up sleep 10 atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1 # MTU sweep for i in `seq 1000 1500` do atf_check -s exit:0 -o ignore jexec b \ ping -c 1 -s $i 198.51.100.1 done rcvmd5=$(jexec b nc -N -w 3 198.51.100.1 1234 | md5) md5=$(md5 test.img) if [ $md5 != $rcvmd5 ]; then atf_fail "Transmit corruption!" fi } 4in6_cleanup() { ovpn_cleanup } atf_test_case "6in6" "cleanup" 6in6_head() { atf_set descr 'IPv6 in IPv6 tunnel' atf_set require.user root atf_set require.progs openvpn } 6in6_body() { ovpn_init l=$(vnet_mkepair) vnet_mkjail a ${l}a jexec a ifconfig ${l}a inet6 2001:db8::1/64 up no_dad vnet_mkjail b ${l}b jexec b ifconfig ${l}b inet6 2001:db8::2/64 up no_dad # Sanity check atf_check -s exit:0 -o ignore jexec a ping6 -c 1 2001:db8::2 ovpn_start a " dev ovpn0 dev-type tun proto udp6 cipher AES-256-GCM auth SHA256 local 2001:db8::1 server-ipv6 2001:db8:1::/64 ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/server.crt key $(atf_get_srcdir)/server.key dh $(atf_get_srcdir)/dh.pem mode server script-security 2 auth-user-pass-verify /usr/bin/true via-env topology subnet keepalive 100 600 " ovpn_start b " dev tun0 dev-type tun client remote 2001:db8::1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client.crt key $(atf_get_srcdir)/client.key dh $(atf_get_srcdir)/dh.pem keepalive 100 600 " # Give the tunnel time to come up sleep 10 atf_check -s exit:0 -o ignore jexec b ping6 -c 3 2001:db8:1::1 atf_check -s exit:0 -o ignore jexec b ping6 -c 3 -z 16 2001:db8:1::1 # Test routing loop protection jexec b route add -6 2001:db8::1 2001:db8:1::1 atf_check -s exit:2 -o ignore jexec b ping6 -t 1 -c 3 2001:db8:1::1 } 6in6_cleanup() { ovpn_cleanup } atf_test_case "timeout_client" "cleanup" timeout_client_head() { atf_set descr 'IPv4 in IPv4 tunnel' atf_set require.user root atf_set require.progs openvpn } timeout_client_body() { ovpn_init l=$(vnet_mkepair) vnet_mkjail a ${l}a jexec a ifconfig ${l}a 192.0.2.1/24 up jexec a ifconfig lo0 127.0.0.1/8 up vnet_mkjail b ${l}b jexec b ifconfig ${l}b 192.0.2.2/24 up # Sanity check atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2 ovpn_start a " dev ovpn0 dev-type tun proto udp4 cipher AES-256-GCM auth SHA256 local 192.0.2.1 server 198.51.100.0 255.255.255.0 ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/server.crt key $(atf_get_srcdir)/server.key dh $(atf_get_srcdir)/dh.pem mode server script-security 2 auth-user-pass-verify /usr/bin/true via-env topology subnet keepalive 2 10 management 192.0.2.1 1234 " ovpn_start b " dev tun0 dev-type tun client remote 192.0.2.1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client.crt key $(atf_get_srcdir)/client.key dh $(atf_get_srcdir)/dh.pem keepalive 2 10 " # Give the tunnel time to come up sleep 10 atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1 # Kill the client jexec b killall openvpn # Now wait for the server to notice sleep 15 while echo "status" | jexec a nc -N 192.0.2.1 1234 | grep 192.0.2.2; do echo "Client disconnect not discovered" sleep 1 done } timeout_client_cleanup() { ovpn_cleanup } atf_test_case "explicit_exit" "cleanup" explicit_exit_head() { atf_set descr 'Test explicit exit notification' atf_set require.user root atf_set require.progs openvpn } explicit_exit_body() { ovpn_init l=$(vnet_mkepair) vnet_mkjail a ${l}a jexec a ifconfig ${l}a 192.0.2.1/24 up jexec a ifconfig lo0 127.0.0.1/8 up vnet_mkjail b ${l}b jexec b ifconfig ${l}b 192.0.2.2/24 up # Sanity check atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2 ovpn_start a " dev ovpn0 dev-type tun proto udp4 cipher AES-256-GCM auth SHA256 local 192.0.2.1 server 198.51.100.0 255.255.255.0 ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/server.crt key $(atf_get_srcdir)/server.key dh $(atf_get_srcdir)/dh.pem mode server script-security 2 auth-user-pass-verify /usr/bin/true via-env topology subnet management 192.0.2.1 1234 " ovpn_start b " dev tun0 dev-type tun client remote 192.0.2.1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client.crt key $(atf_get_srcdir)/client.key dh $(atf_get_srcdir)/dh.pem explicit-exit-notify " # Give the tunnel time to come up sleep 10 atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1 if ! echo "status" | jexec a nc -N 192.0.2.1 1234 | grep 192.0.2.2; then atf_fail "Client not found in status list!" fi # Kill the client jexec b killall openvpn while echo "status" | jexec a nc -N 192.0.2.1 1234 | grep 192.0.2.2; do jexec a ps auxf echo "Client disconnect not discovered" sleep 1 done } explicit_exit_cleanup() { ovpn_cleanup } atf_test_case "multi_client" "cleanup" multi_client_head() { atf_set descr 'Multiple simultaneous clients' atf_set require.user root atf_set require.progs openvpn } multi_client_body() { ovpn_init + vnet_init_bridge bridge=$(vnet_mkbridge) srv=$(vnet_mkepair) one=$(vnet_mkepair) two=$(vnet_mkepair) ifconfig ${bridge} up ifconfig ${srv}a up ifconfig ${bridge} addm ${srv}a ifconfig ${one}a up ifconfig ${bridge} addm ${one}a ifconfig ${two}a up ifconfig ${bridge} addm ${two}a vnet_mkjail srv ${srv}b jexec srv ifconfig ${srv}b 192.0.2.1/24 up vnet_mkjail one ${one}b jexec one ifconfig ${one}b 192.0.2.2/24 up vnet_mkjail two ${two}b jexec two ifconfig ${two}b 192.0.2.3/24 up jexec two ifconfig lo0 127.0.0.1/8 up jexec two ifconfig lo0 inet alias 203.0.113.1/24 # Sanity checks atf_check -s exit:0 -o ignore jexec one ping -c 1 192.0.2.1 atf_check -s exit:0 -o ignore jexec two ping -c 1 192.0.2.1 jexec srv sysctl net.inet.ip.forwarding=1 ovpn_start srv " dev ovpn0 dev-type tun proto udp4 cipher AES-256-GCM auth SHA256 local 192.0.2.1 server 198.51.100.0 255.255.255.0 push \"route 203.0.113.0 255.255.255.0 198.51.100.1\" ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/server.crt key $(atf_get_srcdir)/server.key dh $(atf_get_srcdir)/dh.pem mode server duplicate-cn script-security 2 auth-user-pass-verify /usr/bin/true via-env topology subnet keepalive 100 600 client-config-dir $(atf_get_srcdir)/ccd " ovpn_start one " dev tun0 dev-type tun client remote 192.0.2.1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client.crt key $(atf_get_srcdir)/client.key dh $(atf_get_srcdir)/dh.pem keepalive 100 600 " ovpn_start two " dev tun0 dev-type tun client remote 192.0.2.1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client2.crt key $(atf_get_srcdir)/client2.key dh $(atf_get_srcdir)/dh.pem keepalive 100 600 " # Give the tunnel time to come up sleep 10 atf_check -s exit:0 -o ignore jexec one ping -c 3 198.51.100.1 atf_check -s exit:0 -o ignore jexec two ping -c 3 198.51.100.1 # Client-to-client communication atf_check -s exit:0 -o ignore jexec one ping -c 3 198.51.100.3 atf_check -s exit:0 -o ignore jexec two ping -c 3 198.51.100.2 # iroute test atf_check -s exit:0 -o ignore jexec one ping -c 3 203.0.113.1 } multi_client_cleanup() { ovpn_cleanup } atf_test_case "route_to" "cleanup" route_to_head() { atf_set descr "Test pf's route-to with OpenVPN tunnels" atf_set require.user root atf_set require.progs openvpn } route_to_body() { pft_init ovpn_init l=$(vnet_mkepair) n=$(vnet_mkepair) vnet_mkjail a ${l}a jexec a ifconfig ${l}a 192.0.2.1/24 up vnet_mkjail b ${l}b ${n}a jexec b ifconfig ${l}b 192.0.2.2/24 up jexec b ifconfig ${n}a up # Sanity check atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2 ovpn_start a " dev ovpn0 dev-type tun proto udp4 cipher AES-256-GCM auth SHA256 local 192.0.2.1 server 198.51.100.0 255.255.255.0 ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/server.crt key $(atf_get_srcdir)/server.key dh $(atf_get_srcdir)/dh.pem mode server script-security 2 auth-user-pass-verify /usr/bin/true via-env topology subnet keepalive 100 600 " ovpn_start b " dev tun0 dev-type tun client remote 192.0.2.1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client.crt key $(atf_get_srcdir)/client.key dh $(atf_get_srcdir)/dh.pem keepalive 100 600 " # Give the tunnel time to come up sleep 10 jexec a ifconfig ovpn0 inet alias 198.51.100.254/24 # Check the tunnel atf_check -s exit:0 -o ignore jexec b ping -c 1 -S 198.51.100.2 198.51.100.1 atf_check -s exit:0 -o ignore jexec b ping -c 1 -S 198.51.100.2 198.51.100.254 # Break our route to .254 so that we need a route-to to make things work. jexec b ifconfig ${n}a 203.0.113.1/24 up jexec b route add 198.51.100.254 -interface ${n}a # Make sure it's broken. atf_check -s exit:2 -o ignore jexec b ping -c 1 -S 198.51.100.2 198.51.100.254 jexec b pfctl -e pft_set_rules b \ "pass out route-to (tun0 198.51.100.1) proto icmp from 198.51.100.2 " atf_check -s exit:0 -o ignore jexec b ping -c 3 -S 198.51.100.2 198.51.100.254 } route_to_cleanup() { ovpn_cleanup pft_cleanup } atf_test_case "ra" "cleanup" ra_head() { atf_set descr 'Remote access with multiple clients' atf_set require.user root atf_set require.progs openvpn } ra_body() { ovpn_init + vnet_init_bridge bridge=$(vnet_mkbridge) srv=$(vnet_mkepair) lan=$(vnet_mkepair) one=$(vnet_mkepair) two=$(vnet_mkepair) ifconfig ${bridge} up ifconfig ${srv}a up ifconfig ${bridge} addm ${srv}a ifconfig ${one}a up ifconfig ${bridge} addm ${one}a ifconfig ${two}a up ifconfig ${bridge} addm ${two}a vnet_mkjail srv ${srv}b ${lan}a jexec srv ifconfig lo0 inet 127.0.0.1/8 up jexec srv ifconfig ${srv}b 192.0.2.1/24 up jexec srv ifconfig ${lan}a 203.0.113.1/24 up vnet_mkjail lan ${lan}b jexec lan ifconfig lo0 inet 127.0.0.1/8 up jexec lan ifconfig ${lan}b 203.0.113.2/24 up jexec lan route add default 203.0.113.1 vnet_mkjail one ${one}b jexec one ifconfig lo0 inet 127.0.0.1/8 up jexec one ifconfig ${one}b 192.0.2.2/24 up vnet_mkjail two ${two}b jexec two ifconfig lo0 inet 127.0.0.1/8 up jexec two ifconfig ${two}b 192.0.2.3/24 up # Sanity checks atf_check -s exit:0 -o ignore jexec one ping -c 1 192.0.2.1 atf_check -s exit:0 -o ignore jexec two ping -c 1 192.0.2.1 atf_check -s exit:0 -o ignore jexec srv ping -c 1 203.0.113.2 jexec srv sysctl net.inet.ip.forwarding=1 ovpn_start srv " dev ovpn0 dev-type tun proto udp4 cipher AES-256-GCM auth SHA256 local 192.0.2.1 server 198.51.100.0 255.255.255.0 push \"route 203.0.113.0 255.255.255.0\" ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/server.crt key $(atf_get_srcdir)/server.key dh $(atf_get_srcdir)/dh.pem mode server duplicate-cn script-security 2 auth-user-pass-verify /usr/bin/true via-env topology subnet keepalive 100 600 " ovpn_start one " dev tun0 dev-type tun client remote 192.0.2.1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client.crt key $(atf_get_srcdir)/client.key dh $(atf_get_srcdir)/dh.pem keepalive 100 600 " sleep 2 ovpn_start two " dev tun0 dev-type tun client remote 192.0.2.1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client2.crt key $(atf_get_srcdir)/client2.key dh $(atf_get_srcdir)/dh.pem keepalive 100 600 " # Give the tunnel time to come up sleep 10 atf_check -s exit:0 -o ignore jexec one ping -c 1 198.51.100.1 atf_check -s exit:0 -o ignore jexec two ping -c 1 198.51.100.1 # Client-to-client communication atf_check -s exit:0 -o ignore jexec one ping -c 1 198.51.100.3 atf_check -s exit:0 -o ignore jexec one ping -c 1 198.51.100.2 atf_check -s exit:0 -o ignore jexec two ping -c 1 198.51.100.2 atf_check -s exit:0 -o ignore jexec two ping -c 1 198.51.100.3 # RA test atf_check -s exit:0 -o ignore jexec one ping -c 1 203.0.113.1 atf_check -s exit:0 -o ignore jexec two ping -c 1 203.0.113.1 atf_check -s exit:0 -o ignore jexec srv ping -c 1 -S 203.0.113.1 198.51.100.2 atf_check -s exit:0 -o ignore jexec srv ping -c 1 -S 203.0.113.1 198.51.100.3 atf_check -s exit:0 -o ignore jexec one ping -c 1 203.0.113.2 atf_check -s exit:0 -o ignore jexec two ping -c 1 203.0.113.2 atf_check -s exit:0 -o ignore jexec lan ping -c 1 198.51.100.1 atf_check -s exit:0 -o ignore jexec lan ping -c 1 198.51.100.2 atf_check -s exit:0 -o ignore jexec lan ping -c 1 198.51.100.3 atf_check -s exit:2 -o ignore jexec lan ping -c 1 198.51.100.4 } ra_cleanup() { ovpn_cleanup } ovpn_algo_body() { algo=$1 ovpn_init l=$(vnet_mkepair) vnet_mkjail a ${l}a jexec a ifconfig ${l}a 192.0.2.1/24 up vnet_mkjail b ${l}b jexec b ifconfig ${l}b 192.0.2.2/24 up # Sanity check atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2 ovpn_start a " dev ovpn0 dev-type tun proto udp4 cipher ${algo} data-ciphers ${algo} auth SHA256 local 192.0.2.1 server 198.51.100.0 255.255.255.0 ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/server.crt key $(atf_get_srcdir)/server.key dh $(atf_get_srcdir)/dh.pem mode server script-security 2 auth-user-pass-verify /usr/bin/true via-env topology subnet keepalive 100 600 " ovpn_start b " dev tun0 dev-type tun client cipher ${algo} data-ciphers ${algo} remote 192.0.2.1 auth-user-pass $(atf_get_srcdir)/user.pass ca $(atf_get_srcdir)/ca.crt cert $(atf_get_srcdir)/client.crt key $(atf_get_srcdir)/client.key dh $(atf_get_srcdir)/dh.pem keepalive 100 600 " # Give the tunnel time to come up sleep 10 atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1 } atf_test_case "chacha" "cleanup" chacha_head() { atf_set descr 'Test DCO with the chacha algorithm' atf_set require.user root atf_set require.progs openvpn } chacha_body() { ovpn_algo_body CHACHA20-POLY1305 } chacha_cleanup() { ovpn_cleanup } atf_test_case "gcm_128" "cleanup" gcm_128_head() { atf_set descr 'Test DCO with AES-128-GCM' atf_set require.user root atf_set require.progs openvpn } gcm_128_body() { ovpn_algo_body AES-128-GCM } gcm_128_cleanup() { ovpn_cleanup } atf_init_test_cases() { atf_add_test_case "4in4" atf_add_test_case "4mapped" atf_add_test_case "6in4" atf_add_test_case "6in6" atf_add_test_case "4in6" atf_add_test_case "timeout_client" atf_add_test_case "explicit_exit" atf_add_test_case "multi_client" atf_add_test_case "route_to" atf_add_test_case "ra" atf_add_test_case "chacha" atf_add_test_case "gcm_128" } diff --git a/tests/sys/netinet/carp.sh b/tests/sys/netinet/carp.sh index e10e24747c2d..39cfad14907c 100755 --- a/tests/sys/netinet/carp.sh +++ b/tests/sys/netinet/carp.sh @@ -1,575 +1,583 @@ # # SPDX-License-Identifier: BSD-2-Clause # # Copyright (c) 2020 Kristof Provost # # 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. . $(atf_get_srcdir)/../common/vnet.subr is_master() { jail=$1 itf=$2 jexec ${jail} ifconfig ${itf} | grep -E '(carp|vrrp)' | grep MASTER } wait_for_carp() { jail1=$1 itf1=$2 jail2=$3 itf2=$4 while [ -z "$(is_master ${jail1} ${itf1})" ] && [ -z "$(is_master ${jail2} ${itf2})" ]; do sleep 1 done if [ -n "$(is_master ${jail1} ${itf1})" ] && [ -n "$(is_master ${jail2} ${itf2})" ]; then atf_fail "Both jails are master" fi } carp_init() { if ! kldstat -q -m carp; then atf_skip "This test requires carp" fi vnet_init } atf_test_case "basic_v4" "cleanup" basic_v4_head() { atf_set descr 'Basic CARP test (IPv4)' atf_set require.user root } basic_v4_body() { carp_init + vnet_init_bridge bridge=$(vnet_mkbridge) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) vnet_mkjail carp_basic_v4_one ${bridge} ${epair_one}a ${epair_two}a vnet_mkjail carp_basic_v4_two ${epair_one}b vnet_mkjail carp_basic_v4_three ${epair_two}b jexec carp_basic_v4_one ifconfig ${bridge} 192.0.2.4/29 up jexec carp_basic_v4_one ifconfig ${bridge} addm ${epair_one}a \ addm ${epair_two}a jexec carp_basic_v4_one ifconfig ${epair_one}a up jexec carp_basic_v4_one ifconfig ${epair_two}a up jexec carp_basic_v4_two ifconfig ${epair_one}b 192.0.2.202/29 up jexec carp_basic_v4_two ifconfig ${epair_one}b add vhid 1 192.0.2.1/29 jexec carp_basic_v4_three ifconfig ${epair_two}b 192.0.2.203/29 up jexec carp_basic_v4_three ifconfig ${epair_two}b add vhid 1 \ 192.0.2.1/29 wait_for_carp carp_basic_v4_two ${epair_one}b \ carp_basic_v4_three ${epair_two}b atf_check -s exit:0 -o ignore jexec carp_basic_v4_one \ ping -c 3 192.0.2.1 } basic_v4_cleanup() { vnet_cleanup } atf_test_case "vrrp_v4" "cleanup" vrrp_v4_head() { atf_set descr 'Basic VRRP test (IPv4)' atf_set require.user root } vrrp_v4_body() { carp_init + vnet_init_bridge j=vrrp_basic_v4 bridge=$(vnet_mkbridge) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) vnet_mkjail ${j}_one ${bridge} ${epair_one}a ${epair_two}a vnet_mkjail ${j}_two ${epair_one}b vnet_mkjail ${j}_three ${epair_two}b jexec ${j}_one ifconfig ${bridge} 192.0.2.4/29 up jexec ${j}_one ifconfig ${bridge} addm ${epair_one}a \ addm ${epair_two}a jexec ${j}_one ifconfig ${epair_one}a up jexec ${j}_one ifconfig ${epair_two}a up jexec ${j}_two ifconfig ${epair_one}b 192.0.2.202/29 up jexec ${j}_two ifconfig ${epair_one}b add vhid 1 carpver 3 192.0.2.1/29 jexec ${j}_three ifconfig ${epair_two}b 192.0.2.203/29 up jexec ${j}_three ifconfig ${epair_two}b add vhid 1 carpver 3 \ 192.0.2.1/29 wait_for_carp ${j}_two ${epair_one}b \ ${j}_three ${epair_two}b atf_check -s exit:0 -o ignore jexec ${j}_one \ ping -c 3 192.0.2.1 } vrrp_v4_cleanup() { vnet_cleanup } atf_test_case "unicast_v4" "cleanup" unicast_v4_head() { atf_set descr 'Unicast CARP test (IPv4)' atf_set require.user root } unicast_v4_body() { carp_init + vnet_init_bridge bridge=$(vnet_mkbridge) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) vnet_mkjail carp_uni_v4_one ${bridge} ${epair_one}a ${epair_two}a vnet_mkjail carp_uni_v4_two ${epair_one}b vnet_mkjail carp_uni_v4_three ${epair_two}b jexec carp_uni_v4_one ifconfig ${bridge} 192.0.2.4/29 up jexec carp_uni_v4_one sysctl net.inet.ip.forwarding=1 jexec carp_uni_v4_one ifconfig ${bridge} addm ${epair_one}a \ addm ${epair_two}a jexec carp_uni_v4_one ifconfig ${epair_one}a up jexec carp_uni_v4_one ifconfig ${epair_two}a up jexec carp_uni_v4_one ifconfig ${bridge} inet alias 198.51.100.1/25 jexec carp_uni_v4_one ifconfig ${bridge} inet alias 198.51.100.129/25 jexec carp_uni_v4_two ifconfig ${epair_one}b 198.51.100.2/25 up jexec carp_uni_v4_two route add default 198.51.100.1 jexec carp_uni_v4_two ifconfig ${epair_one}b add vhid 1 \ peer 198.51.100.130 192.0.2.1/29 jexec carp_uni_v4_three ifconfig ${epair_two}b 198.51.100.130/25 up jexec carp_uni_v4_three route add default 198.51.100.129 jexec carp_uni_v4_three ifconfig ${epair_two}b add vhid 1 \ peer 198.51.100.2 192.0.2.1/29 # Sanity check atf_check -s exit:0 -o ignore jexec carp_uni_v4_two \ ping -c 1 198.51.100.130 wait_for_carp carp_uni_v4_two ${epair_one}b \ carp_uni_v4_three ${epair_two}b atf_check -s exit:0 -o ignore jexec carp_uni_v4_one \ ping -c 3 192.0.2.1 jexec carp_uni_v4_two ifconfig jexec carp_uni_v4_three ifconfig } unicast_v4_cleanup() { vnet_cleanup } atf_test_case "basic_v6" "cleanup" basic_v6_head() { atf_set descr 'Basic CARP test (IPv6)' atf_set require.user root } basic_v6_body() { carp_init + vnet_init_bridge bridge=$(vnet_mkbridge) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) vnet_mkjail carp_basic_v6_one ${bridge} ${epair_one}a ${epair_two}a vnet_mkjail carp_basic_v6_two ${epair_one}b vnet_mkjail carp_basic_v6_three ${epair_two}b jexec carp_basic_v6_one ifconfig ${bridge} inet6 2001:db8::0:4/64 up \ no_dad jexec carp_basic_v6_one ifconfig ${bridge} addm ${epair_one}a \ addm ${epair_two}a jexec carp_basic_v6_one ifconfig ${epair_one}a up jexec carp_basic_v6_one ifconfig ${epair_two}a up jexec carp_basic_v6_two ifconfig ${epair_one}b inet6 \ 2001:db8::1:2/64 up no_dad jexec carp_basic_v6_two ifconfig ${epair_one}b inet6 add vhid 1 \ 2001:db8::0:1/64 jexec carp_basic_v6_three ifconfig ${epair_two}b inet6 2001:db8::1:3/64 up no_dad jexec carp_basic_v6_three ifconfig ${epair_two}b inet6 add vhid 1 \ 2001:db8::0:1/64 wait_for_carp carp_basic_v6_two ${epair_one}b \ carp_basic_v6_three ${epair_two}b atf_check -s exit:0 -o ignore jexec carp_basic_v6_one \ ping -6 -c 3 2001:db8::0:1 } basic_v6_cleanup() { vnet_cleanup } atf_test_case "vrrp_v6" "cleanup" vrrp_v6_head() { atf_set descr 'Basic VRRP test (IPv6)' atf_set require.user root } vrrp_v6_body() { carp_init + vnet_init_bridge j=carp_basic_v6 bridge=$(vnet_mkbridge) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) vnet_mkjail ${j}_one ${bridge} ${epair_one}a ${epair_two}a vnet_mkjail ${j}_two ${epair_one}b vnet_mkjail ${j}_three ${epair_two}b jexec ${j}_one ifconfig ${bridge} inet6 2001:db8::0:4/64 up \ no_dad jexec ${j}_one ifconfig ${bridge} addm ${epair_one}a \ addm ${epair_two}a jexec ${j}_one ifconfig ${epair_one}a up jexec ${j}_one ifconfig ${epair_two}a up jexec ${j}_two ifconfig ${epair_one}b inet6 \ 2001:db8::1:2/64 up no_dad jexec ${j}_two ifconfig ${epair_one}b inet6 add vhid 1 carpver 3 \ 2001:db8::0:1/64 jexec ${j}_three ifconfig ${epair_two}b inet6 2001:db8::1:3/64 up no_dad jexec ${j}_three ifconfig ${epair_two}b inet6 add vhid 1 carpver 3 \ 2001:db8::0:1/64 wait_for_carp ${j}_two ${epair_one}b \ ${j}_three ${epair_two}b atf_check -s exit:0 -o ignore jexec ${j}_one \ ping -6 -c 3 2001:db8::0:1 } vrrp_v6_cleanup() { vnet_cleanup } atf_test_case "unicast_v6" "cleanup" unicast_v6_head() { atf_set descr 'Unicast CARP test (IPv6)' atf_set require.user root } unicast_v6_body() { carp_init + vnet_init_bridge bridge=$(vnet_mkbridge) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) vnet_mkjail carp_uni_v6_one ${bridge} ${epair_one}a ${epair_two}a vnet_mkjail carp_uni_v6_two ${epair_one}b vnet_mkjail carp_uni_v6_three ${epair_two}b jexec carp_uni_v6_one sysctl net.inet6.ip6.forwarding=1 jexec carp_uni_v6_one ifconfig ${bridge} addm ${epair_one}a \ addm ${epair_two}a jexec carp_uni_v6_one ifconfig ${epair_one}a up jexec carp_uni_v6_one ifconfig ${epair_two}a up jexec carp_uni_v6_one ifconfig ${bridge} inet6 2001:db8::0:4/64 up \ no_dad jexec carp_uni_v6_one ifconfig ${bridge} inet6 alias 2001:db8:1::1/64 \ no_dad up jexec carp_uni_v6_one ifconfig ${bridge} inet6 alias 2001:db8:2::1/64 \ no_dad up jexec carp_uni_v6_two ifconfig ${epair_one}b inet6 2001:db8:1::2/64 \ no_dad up jexec carp_uni_v6_two route -6 add default 2001:db8:1::1 jexec carp_uni_v6_two ifconfig ${epair_one}b inet6 add vhid 1 \ peer6 2001:db8:2::2 \ 2001:db8::0:1/64 jexec carp_uni_v6_three ifconfig ${epair_two}b inet6 2001:db8:2::2/64 \ no_dad up jexec carp_uni_v6_three route -6 add default 2001:db8:2::1 jexec carp_uni_v6_three ifconfig ${epair_two}b inet6 add vhid 1 \ peer6 2001:db8:1::2 \ 2001:db8::0:1/64 # Sanity check atf_check -s exit:0 -o ignore jexec carp_uni_v6_two \ ping -6 -c 1 2001:db8:2::2 wait_for_carp carp_uni_v6_two ${epair_one}b \ carp_uni_v6_three ${epair_two}b atf_check -s exit:0 -o ignore jexec carp_uni_v6_one \ ping -6 -c 3 2001:db8::0:1 } unicast_v6_cleanup() { vnet_cleanup } atf_test_case "unicast_ll_v6" "cleanup" unicast_ll_v6_head() { atf_set descr 'Unicast CARP test (IPv6, link-local)' atf_set require.user root } unicast_ll_v6_body() { carp_init + vnet_init_bridge j=carp_uni_ll_v6 bridge=$(vnet_mkbridge) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) vnet_mkjail ${j}_one ${bridge} ${epair_one}a ${epair_two}a vnet_mkjail ${j}_two ${epair_one}b vnet_mkjail ${j}_three ${epair_two}b jexec ${j}_one ifconfig ${bridge} addm ${epair_one}a \ addm ${epair_two}a jexec ${j}_one ifconfig ${epair_one}a up jexec ${j}_one ifconfig ${epair_two}a up jexec ${j}_one ifconfig ${bridge} inet6 2001:db8::0:4/64 up \ no_dad jexec ${j}_one ifconfig ${bridge} inet6 alias 2001:db8:1::1/64 \ no_dad up jexec ${j}_two ifconfig ${epair_one}b inet6 2001:db8:1::2/64 \ no_dad up jexec ${j}_three ifconfig ${epair_two}b inet6 2001:db8:1::3/64 \ no_dad up ll_one=$(jexec ${j}_two ifconfig ${epair_one}b | awk "/ .*%${epair_one}b.* / { print \$2 }" | cut -d % -f 1) ll_two=$(jexec ${j}_three ifconfig ${epair_two}b | awk "/ .*%${epair_two}b.* / { print \$2 }" | cut -d % -f 1) jexec ${j}_two ifconfig ${epair_one}b inet6 add vhid 1 \ peer6 ${ll_two} \ 2001:db8::0:1/64 jexec ${j}_three ifconfig ${epair_two}b inet6 add vhid 1 \ peer6 ${ll_one} \ 2001:db8::0:1/64 # Sanity check atf_check -s exit:0 -o ignore jexec ${j}_two \ ping -6 -c 1 2001:db8:1::3 wait_for_carp ${j}_two ${epair_one}b \ ${j}_three ${epair_two}b atf_check -s exit:0 -o ignore jexec ${j}_one \ ping -6 -c 3 2001:db8::0:1 } unicast_ll_v6_cleanup() { vnet_cleanup } atf_test_case "negative_demotion" "cleanup" negative_demotion_head() { atf_set descr 'Test PR #259528' atf_set require.user root } negative_demotion_body() { carp_init epair=$(vnet_mkepair) vnet_mkjail one ${epair}a jexec one sysctl net.inet.carp.preempt=1 jexec one ifconfig ${epair}a 192.0.2.1/24 up jexec one ifconfig ${epair}a add vhid 1 192.0.2.254/24 \ advskew 0 pass foobar vnet_mkjail two ${epair}b jexec two sysctl net.inet.carp.preempt=1 jexec two ifconfig ${epair}b 192.0.2.2/24 up jexec two ifconfig ${epair}b add vhid 1 192.0.2.254/24 \ advskew 100 pass foobar # Allow things to settle wait_for_carp one ${epair}a two ${epair}b if is_master one ${epair}a && is_master two ${epair}b then atf_fail "Two masters!" fi jexec one sysctl net.inet.carp.demotion=-1 sleep 3 if is_master one ${epair}a && is_master two ${epair}b then atf_fail "Two masters!" fi } negative_demotion_cleanup() { vnet_cleanup } atf_test_case "nd6_ns_source_mac" "cleanup" nd6_ns_source_mac_head() { atf_set descr 'CARP ndp neighbor solicitation MAC source test (IPv6)' atf_set require.user root } nd6_ns_source_mac_body() { carp_init + vnet_init_bridge bridge=$(vnet_mkbridge) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) vnet_mkjail carp_ndp_v6_bridge ${bridge} ${epair_one}a ${epair_two}a vnet_mkjail carp_ndp_v6_master ${epair_one}b vnet_mkjail carp_ndp_v6_slave ${epair_two}b jexec carp_ndp_v6_bridge ifconfig ${bridge} inet6 2001:db8::0:4/64 up \ no_dad jexec carp_ndp_v6_bridge ifconfig ${bridge} addm ${epair_one}a \ addm ${epair_two}a jexec carp_ndp_v6_bridge ifconfig ${epair_one}a up jexec carp_ndp_v6_bridge ifconfig ${epair_two}a up jexec carp_ndp_v6_master ifconfig ${epair_one}b inet6 \ 2001:db8::1:2/64 up no_dad jexec carp_ndp_v6_master ifconfig ${epair_one}b inet6 add vhid 1 \ advskew 0 2001:db8::0:1/64 jexec carp_ndp_v6_slave ifconfig ${epair_two}b inet6 \ 2001:db8::1:3/64 up no_dad jexec carp_ndp_v6_slave ifconfig ${epair_two}b inet6 add vhid 1 \ advskew 100 2001:db8::0:1/64 wait_for_carp carp_ndp_v6_master ${epair_one}b \ carp_ndp_v6_slave ${epair_two}b # carp_ndp_v6_master is MASTER # trigger a NS from the virtual IP from the BACKUP atf_check -s exit:2 -o ignore jexec carp_ndp_v6_slave \ ping -6 -c 3 -S 2001:db8::0:1 2001:db8::0:4 # trigger a NS from the virtual IP from the MASTER, # this ping should work atf_check -s exit:0 -o ignore jexec carp_ndp_v6_master \ ping -6 -c 3 -S 2001:db8::0:1 2001:db8::0:4 # ndp entry should be for the virtual mac atf_check -o match:'2001:db8::1 +00:00:5e:00:01:01' \ jexec carp_ndp_v6_bridge ndp -an } nd6_ns_source_mac_cleanup() { vnet_cleanup } atf_test_case "switch" "cleanup" switch_head() { atf_set descr 'Switch between master and backup' atf_set require.user root } switch_body() { carp_init epair=$(vnet_mkepair) ifconfig ${epair}a up ifconfig ${epair}a vhid 1 advskew 100 192.0.2.1/24 ifconfig ${epair}a vhid 1 state backup ifconfig ${epair}a vhid 1 state master } switch_cleanup() { vnet_cleanup } atf_init_test_cases() { atf_add_test_case "basic_v4" atf_add_test_case "vrrp_v4" atf_add_test_case "unicast_v4" atf_add_test_case "basic_v6" atf_add_test_case "vrrp_v6" atf_add_test_case "unicast_v6" atf_add_test_case "unicast_ll_v6" atf_add_test_case "negative_demotion" atf_add_test_case "nd6_ns_source_mac" atf_add_test_case "switch" } diff --git a/tests/sys/netpfil/common/rdr.sh b/tests/sys/netpfil/common/rdr.sh index 7d6297870e6c..0d6f27694c8c 100644 --- a/tests/sys/netpfil/common/rdr.sh +++ b/tests/sys/netpfil/common/rdr.sh @@ -1,136 +1,137 @@ # # SPDX-License-Identifier: BSD-2-Clause # # Copyright (c) 2018 Kristof Provost # # 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. . $(atf_get_srcdir)/utils.subr . $(atf_get_srcdir)/runner.subr basic_head() { atf_set descr 'Basic IPv4 NAT test' atf_set require.user root } basic_body() { firewall=$1 firewall_init $firewall nat_init $firewall epair=$(vnet_mkepair) vnet_mkjail alcatraz ${epair}b ifconfig ${epair}a 192.0.2.2/24 up route add -net 198.51.100.0/24 192.0.2.1 jexec alcatraz ifconfig ${epair}b 192.0.2.1/24 up jexec alcatraz sysctl net.inet.ip.forwarding=1 # Enable redirect filter rule firewall_config alcatraz ${firewall} \ "pf" \ "rdr pass on ${epair}b proto tcp from any to 198.51.100.0/24 port 1234 -> 192.0.2.1 port 4321" \ "ipfnat" \ "rdr ${epair}b from any to 198.51.100.0/24 port = 1234 -> 192.0.2.1 port 4321 tcp" echo "foo" | jexec alcatraz nc -N -l 4321 & sleep 1 result=$(nc -N -w 3 198.51.100.2 1234) if [ "$result" != "foo" ]; then atf_fail "Redirect failed" fi } basic_cleanup() { firewall=$1 firewall_cleanup $firewall } local_redirect_head() { atf_set descr 'Redirect local traffic test' atf_set require.user root } local_redirect_body() { firewall=$1 firewall_init $firewall nat_init $firewall + vnet_init_bridge bridge=$(vnet_mkbridge) ifconfig ${bridge} 192.0.2.1/24 up epair1=$(vnet_mkepair) epair2=$(vnet_mkepair) vnet_mkjail first ${epair1}b ifconfig ${epair1}a up ifconfig ${bridge} addm ${epair1}a jexec first ifconfig ${epair1}b 192.0.2.2/24 up jexec first ifconfig lo0 127.0.0.1/8 up vnet_mkjail second ${epair2}b ifconfig ${epair2}a up ifconfig ${bridge} addm ${epair2}a jexec second ifconfig ${epair2}b 192.0.2.3/24 up jexec second ifconfig lo0 127.0.0.1/8 up jexec second sysctl net.inet.ip.forwarding=1 # Enable redirect filter rule firewall_config second ${firewall} \ "pf" \ "rdr pass proto tcp from any to 192.0.2.3/24 port 1234 -> 192.0.2.2 port 4321" \ "ipfnat" \ "rdr '*' from any to 192.0.2.3/24 port = 1234 -> 192.0.2.2 port 4321 tcp" echo "foo" | jexec first nc -N -l 4321 & sleep 1 # Verify that second can use its rule to redirect local connections to first result=$(jexec second nc -N -w 3 192.0.2.3 1234) if [ "$result" != "foo" ]; then atf_fail "Redirect failed" fi } local_redirect_cleanup() { firewall=$1 firewall_cleanup $firewall } setup_tests \ basic \ pf \ ipfnat \ local_redirect \ pf \ ipfnat diff --git a/tests/sys/netpfil/pf/altq.sh b/tests/sys/netpfil/pf/altq.sh index 57a9edf11366..a902c7caaf4f 100644 --- a/tests/sys/netpfil/pf/altq.sh +++ b/tests/sys/netpfil/pf/altq.sh @@ -1,348 +1,346 @@ . $(atf_get_srcdir)/utils.subr atf_test_case "hfsc" "cleanup" hfsc_head() { atf_set descr 'Basic HFSC test' atf_set require.user root } hfsc_body() { altq_init is_altq_supported hfsc epair=$(vnet_mkepair) vnet_mkjail altq_hfsc ${epair}b ifconfig ${epair}a 192.0.2.1/24 up jexec altq_hfsc ifconfig ${epair}b 192.0.2.2/24 up # Sanity check atf_check -s exit:0 -o ignore ping -i .1 -c 3 -s 1200 192.0.2.2 jexec altq_hfsc pfctl -e pft_set_rules altq_hfsc \ "altq on ${epair}b bandwidth 100b hfsc queue { default }" \ "queue default hfsc(default linkshare 80b)" \ "pass proto icmp " # single ping succeeds just fine atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 # "Saturate the link" ping -i .1 -c 5 -s 1200 192.0.2.2 # We should now be hitting the limits and get this packet dropped. atf_check -s exit:2 -o ignore ping -c 1 -s 1200 192.0.2.2 } hfsc_cleanup() { altq_cleanup } atf_test_case "match" "cleanup" match_head() { atf_set descr 'Basic match keyword test' atf_set require.user root } match_body() { altq_init is_altq_supported hfsc epair=$(vnet_mkepair) vnet_mkjail altq_match ${epair}b ifconfig ${epair}a 192.0.2.1/24 up jexec altq_match ifconfig ${epair}b 192.0.2.2/24 up # Sanity check atf_check -s exit:0 -o ignore ping -i .1 -c 3 -s 1200 192.0.2.2 jexec altq_match pfctl -e pft_set_rules altq_match \ "altq on ${epair}b bandwidth 100000000b hfsc queue { default, slow }" \ "queue default hfsc(default linkshare 80000000b)" \ "queue slow hfsc(linkshare 80b upperlimit 80b)" \ "match proto icmp queue slow" \ "pass" # single ping succeeds just fine atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 # "Saturate the link" ping -i .1 -c 5 -s 1200 192.0.2.2 # We should now be hitting the limits and get this packet dropped. atf_check -s exit:2 -o ignore ping -c 1 -s 1200 192.0.2.2 } match_cleanup() { altq_cleanup } atf_test_case "cbq_vlan" "cleanup" cbq_vlan_head() { atf_set descr 'CBQ over VLAN test' atf_set require.user root } cbq_vlan_body() { altq_init is_altq_supported cbq epair=$(vnet_mkepair) vnet_mkjail altq_cbq_vlan ${epair}b vlan=$(vnet_mkvlan) ifconfig ${vlan} vlan 42 vlandev ${epair}a ifconfig ${vlan} 192.0.2.1/24 up ifconfig ${epair}a up vlanj=$(jexec altq_cbq_vlan ifconfig vlan create) echo ${vlanj} >> created_interfaces.lst jexec altq_cbq_vlan ifconfig ${epair}b up jexec altq_cbq_vlan ifconfig ${vlanj} vlan 42 vlandev ${epair}b jexec altq_cbq_vlan ifconfig ${vlanj} 192.0.2.2/24 up # Sanity check atf_check -s exit:0 -o ignore ping -i .1 -c 3 -s 1200 192.0.2.2 jexec altq_cbq_vlan pfctl -e pft_set_rules altq_cbq_vlan \ "altq on ${vlanj} bandwidth 14000b cbq queue { default }" \ "queue default bandwidth 14000b cbq(default) { slow } " \ "queue slow bandwidth 6000b cbq(borrow)" \ "match proto icmp queue slow" \ "match proto tcp queue default" \ "pass" # single ping succeeds just fine atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 # "Saturate the link" ping -i .01 -c 50 -s 1200 192.0.2.2 # We should now be hitting the limits and get these packet dropped. rcv=$(ping -i .1 -c 5 -s 1200 192.0.2.2 | tr "," "\n" | awk '/packets received/ { print $1; }') echo "Received $rcv packets" if [ ${rcv} -gt 1 ] then atf_fail "Received ${rcv} packets in a saturated link" fi } cbq_vlan_cleanup() { altq_cleanup } atf_test_case "codel_bridge" "cleanup" codel_bridge_head() { atf_set descr 'codel over if_bridge test' atf_set require.user root } codel_bridge_body() { altq_init is_altq_supported codel - if ! kldstat -q -m if_bridge; then - atf_skip "This test requires if_bridge" - fi + vnet_init_bridge epair=$(vnet_mkepair) ifconfig ${epair}a 192.0.2.1/24 up vnet_mkjail altq_codel_bridge ${epair}b bridge=$(jexec altq_codel_bridge ifconfig bridge create) jexec altq_codel_bridge ifconfig ${bridge} addm ${epair}b jexec altq_codel_bridge ifconfig ${epair}b up jexec altq_codel_bridge ifconfig ${bridge} 192.0.2.2/24 up # Sanity check atf_check -s exit:0 -o ignore ping -i .1 -c 3 -s 1200 192.0.2.2 jexec altq_codel_bridge pfctl -e pft_set_rules altq_codel_bridge \ "altq on ${bridge} bandwidth 1000b codelq queue { slow }" \ "match queue slow" \ "pass" # "Saturate the link" ping -i .1 -c 5 -s 1200 192.0.2.2 # We should now be hitting the limits and get these packet dropped. rcv=$(ping -i .1 -c 5 -s 1200 192.0.2.2 | tr "," "\n" | awk '/packets received/ { print $1; }') echo "Received $rcv packets" if [ ${rcv} -gt 1 ] then atf_fail "Received ${rcv} packets in a saturated link" fi } codel_bridge_cleanup() { altq_cleanup } atf_test_case "prioritise" "cleanup" prioritise_head() { atf_set descr "Test prioritising one type of traffic over the other" atf_set require.user root } prioritise_body() { altq_init is_altq_supported cbq epair=$(vnet_mkepair) vnet_mkjail altq_prioritise ${epair}b ifconfig ${epair}a 192.0.2.1/24 up jexec altq_prioritise ifconfig ${epair}b 192.0.2.2/24 up jexec altq_prioritise /usr/sbin/inetd -p inetd-altq.pid \ $(atf_get_srcdir)/../pf/echo_inetd.conf # Sanity check atf_check -s exit:0 -o ignore ping -i .1 -c 3 -s 1200 192.0.2.2 jexec altq_prioritise pfctl -e pft_set_rules altq_prioritise \ "altq on ${epair}b bandwidth 6000b cbq queue { default, slow }" \ "queue default priority 7 cbq(default)" \ "queue slow priority 1 cbq" \ "match proto icmp queue slow" \ "match proto tcp queue default" \ "pass" # single ping succeeds just fine atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 # Unsaturated TCP succeeds reply=$(echo "foo" | nc -w 5 -N 192.0.2.2 7) if [ "$reply" != "foo" ]; then atf_fail "Unsaturated echo failed" fi # "Saturate the link" ping -i .01 -c 50 -s 1200 192.0.2.2 # We should now be hitting the limits and get these packet dropped. rcv=$(ping -i .1 -c 5 -s 1200 192.0.2.2 | tr "," "\n" | awk '/packets received/ { print $1; }') echo "Received $rcv packets" if [ ${rcv} -gt 1 ] then atf_fail "Received ${rcv} packets in a saturated link" fi # TCP should still pass for i in `seq 1 10` do reply=$(echo "foo_${i}" | nc -w 5 -N 192.0.2.2 7) if [ "$reply" != "foo_${i}" ]; then atf_fail "Prioritised echo failed ${i}" fi done # Now reverse priority pft_set_rules altq_prioritise \ "altq on ${epair}b bandwidth 6000b cbq queue { default, slow }" \ "queue default priority 7 cbq(default)" \ "queue slow priority 1 cbq" \ "match proto tcp queue slow" \ "match proto icmp queue default" \ "pass" atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2 ping -i .01 -c 50 -s 1200 192.0.2.2 for i in `seq 1 10` do reply=$(echo "foo_${i}" | nc -w 5 -N 192.0.2.2 7) if [ "$reply" == "foo_${i}" ]; then atf_fail "Unexpected echo success" fi done } prioritise_cleanup() { altq_cleanup } atf_test_case "codel_vlan" "cleanup" codel_vlan_head() { atf_set descr 'Test double-pass through ALTQ with codel' atf_set require.user root } codel_vlan_body() { altq_init is_altq_supported priq is_altq_supported codel j=altq_vlan_codel epair=$(vnet_mkepair) vnet_mkjail ${j}a ${epair}a va=$(jexec ${j}a ifconfig vlan create) jexec ${j}a ifconfig ${epair}a up jexec ${j}a ifconfig ${va} vlan 42 vlandev ${epair}a up jexec ${j}a ifconfig ${va} inet 192.0.2.1/24 vnet_mkjail ${j}b ${epair}b vb=$(jexec ${j}b ifconfig vlan create) jexec ${j}b ifconfig ${epair}b up jexec ${j}b ifconfig ${vb} vlan 42 vlandev ${epair}b up jexec ${j}b ifconfig ${vb} inet 192.0.2.2/24 # Sanity check atf_check -s exit:0 -o ignore \ jexec ${j}a ping -c 1 192.0.2.2 jexec ${j}a pfctl -e pft_set_rules ${j}a \ "altq on ${epair}a priq bandwidth 10Mb queue { slow }" \ "queue slow priority 6 qlimit 50 priq ( default codel )" \ "altq on ${va} priq bandwidth 10Mb queue { vslow }" \ "queue vslow priority 6 qlimit 50 priq ( default codel )" \ "pass queue (slow)" atf_check -s exit:0 -o ignore \ jexec ${j}a ping -c 1 192.0.2.2 } codel_vlan_cleanup() { altq_cleanup } atf_init_test_cases() { atf_add_test_case "hfsc" atf_add_test_case "match" atf_add_test_case "cbq_vlan" atf_add_test_case "codel_bridge" atf_add_test_case "prioritise" atf_add_test_case "codel_vlan" } diff --git a/tests/sys/netpfil/pf/pfsync.sh b/tests/sys/netpfil/pf/pfsync.sh index 87dfcf748d3c..b97b06c5f9a2 100644 --- a/tests/sys/netpfil/pf/pfsync.sh +++ b/tests/sys/netpfil/pf/pfsync.sh @@ -1,945 +1,946 @@ # # SPDX-License-Identifier: BSD-2-Clause # # Copyright (c) 2018 Orange Business Services # # 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. . $(atf_get_srcdir)/utils.subr common_dir=$(atf_get_srcdir)/../common atf_test_case "basic" "cleanup" basic_head() { atf_set descr 'Basic pfsync test' atf_set require.user root } basic_body() { common_body } common_body() { defer=$1 pfsynct_init epair_sync=$(vnet_mkepair) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) vnet_mkjail one ${epair_one}a ${epair_sync}a vnet_mkjail two ${epair_two}a ${epair_sync}b # pfsync interface jexec one ifconfig ${epair_sync}a 192.0.2.1/24 up jexec one ifconfig ${epair_one}a 198.51.100.1/24 up jexec one ifconfig pfsync0 \ syncdev ${epair_sync}a \ maxupd 1 \ $defer \ up jexec two ifconfig ${epair_two}a 198.51.100.2/24 up jexec two ifconfig ${epair_sync}b 192.0.2.2/24 up jexec two ifconfig pfsync0 \ syncdev ${epair_sync}b \ maxupd 1 \ $defer \ up # Enable pf! jexec one pfctl -e pft_set_rules one \ "set skip on ${epair_sync}a" \ "pass out keep state" jexec two pfctl -e pft_set_rules two \ "set skip on ${epair_sync}b" \ "pass out keep state" hostid_one=$(jexec one pfctl -si -v | awk '/Hostid:/ { gsub(/0x/, "", $2); printf($2); }') ifconfig ${epair_one}b 198.51.100.254/24 up ping -c 1 -S 198.51.100.254 198.51.100.1 # Give pfsync time to do its thing sleep 2 if ! jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \ grep 198.51.100.254 ; then atf_fail "state not found on synced host" fi if ! jexec two pfctl -sc | grep ""${hostid_one}""; then jexec two pfctl -sc atf_fail "HostID for host one not found on two" fi } basic_cleanup() { pfsynct_cleanup } atf_test_case "basic_defer" "cleanup" basic_defer_head() { atf_set descr 'Basic defer mode pfsync test' atf_set require.user root } basic_defer_body() { common_body defer } basic_defer_cleanup() { pfsynct_cleanup } atf_test_case "defer" "cleanup" defer_head() { atf_set descr 'Defer mode pfsync test' atf_set require.user root atf_set require.progs scapy } defer_body() { pfsynct_init epair_sync=$(vnet_mkepair) epair_in=$(vnet_mkepair) epair_out=$(vnet_mkepair) vnet_mkjail alcatraz ${epair_sync}a ${epair_in}a ${epair_out}a jexec alcatraz ifconfig ${epair_sync}a 192.0.2.1/24 up jexec alcatraz ifconfig ${epair_out}a 198.51.100.1/24 up jexec alcatraz ifconfig ${epair_in}a 203.0.113.1/24 up jexec alcatraz arp -s 203.0.113.2 00:01:02:03:04:05 jexec alcatraz sysctl net.inet.ip.forwarding=1 # Set a long defer delay jexec alcatraz sysctl net.pfsync.defer_delay=2500 jexec alcatraz ifconfig pfsync0 \ syncdev ${epair_sync}a \ maxupd 1 \ defer \ up ifconfig ${epair_sync}b 192.0.2.2/24 up ifconfig ${epair_out}b 198.51.100.2/24 up ifconfig ${epair_in}b up route add -net 203.0.113.0/24 198.51.100.1 # Enable pf jexec alcatraz sysctl net.pf.filter_local=0 jexec alcatraz pfctl -e pft_set_rules alcatraz \ "set skip on ${epair_sync}a" \ "pass keep state" atf_check -s exit:0 env PYTHONPATH=${common_dir} \ $(atf_get_srcdir)/pfsync_defer.py \ --syncdev ${epair_sync}b \ --indev ${epair_in}b \ --outdev ${epair_out}b # Now disable defer mode and expect failure. jexec alcatraz ifconfig pfsync0 -defer # Flush state pft_set_rules alcatraz \ "set skip on ${epair_sync}a" \ "pass keep state" atf_check -s exit:3 env PYTHONPATH=${common_dir} \ $(atf_get_srcdir)/pfsync_defer.py \ --syncdev ${epair_sync}b \ --indev ${epair_in}b \ --outdev ${epair_out}b } defer_cleanup() { pfsynct_cleanup } atf_test_case "bulk" "cleanup" bulk_head() { atf_set descr 'Test bulk updates' atf_set require.user root } bulk_body() { pfsynct_init epair_sync=$(vnet_mkepair) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) vnet_mkjail one ${epair_one}a ${epair_sync}a vnet_mkjail two ${epair_two}a ${epair_sync}b # pfsync interface jexec one ifconfig ${epair_sync}a 192.0.2.1/24 up jexec one ifconfig ${epair_one}a 198.51.100.1/24 up jexec one ifconfig pfsync0 \ syncdev ${epair_sync}a \ maxupd 1\ up jexec two ifconfig ${epair_two}a 198.51.100.2/24 up jexec two ifconfig ${epair_sync}b 192.0.2.2/24 up # Enable pf jexec one pfctl -e pft_set_rules one \ "set skip on ${epair_sync}a" \ "pass keep state" jexec two pfctl -e pft_set_rules two \ "set skip on ${epair_sync}b" \ "pass keep state" ifconfig ${epair_one}b 198.51.100.254/24 up # Create state prior to setting up pfsync ping -c 1 -S 198.51.100.254 198.51.100.1 # Wait before setting up pfsync on two, so we don't accidentally catch # the update anyway. sleep 1 # Now set up pfsync in jail two jexec two ifconfig pfsync0 \ syncdev ${epair_sync}b \ up # Give pfsync time to do its thing sleep 2 jexec two pfctl -s states if ! jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \ grep 198.51.100.2 ; then atf_fail "state not found on synced host" fi } bulk_cleanup() { pfsynct_cleanup } atf_test_case "pbr" "cleanup" pbr_head() { atf_set descr 'route_to and reply_to directives test' atf_set require.user root atf_set timeout '600' } pbr_body() { pbr_common_body } pbr_cleanup() { pbr_common_cleanup } atf_test_case "pfsync_pbr" "cleanup" pfsync_pbr_head() { atf_set descr 'route_to and reply_to directives pfsync test' atf_set require.user root atf_set timeout '600' } pfsync_pbr_body() { pbr_common_body backup_promotion } pfsync_pbr_cleanup() { pbr_common_cleanup } pbr_common_body() { # + builds bellow topology and initiate a single ping session # from client to server. # + gw* forward traffic through pbr not fib lookups. # + if backup_promotion arg is given, a carp failover event occurs # during the ping session on both gateways. # ┌──────┐ # │client│ # └───┬──┘ # │ # ┌───┴───┐ # │bridge0│ # └┬─────┬┘ # │ │ # ┌────────────────┴─┐ ┌─┴────────────────┐ # │gw_route_to_master├─┤gw_route_to_backup│ # └────────────────┬─┘ └─┬────────────────┘ # │ │ # ┌┴─────┴┐ # │bridge1│ # └┬─────┬┘ # │ │ # ┌────────────────┴─┐ ┌─┴────────────────┐ # │gw_reply_to_master├─┤gw_reply_to_backup│ # └────────────────┬─┘ └─┬────────────────┘ # │ │ # ┌┴─────┴┐ # │bridge2│ # └───┬───┘ # │ # ┌───┴──┐ # │server│ # └──────┘ if ! kldstat -q -m carp then atf_skip "This test requires carp" fi pfsynct_init + vnet_init_bridge bridge0=$(vnet_mkbridge) bridge1=$(vnet_mkbridge) bridge2=$(vnet_mkbridge) epair_sync_gw_route_to=$(vnet_mkepair) epair_sync_gw_reply_to=$(vnet_mkepair) epair_client_bridge0=$(vnet_mkepair) epair_gw_route_to_master_bridge0=$(vnet_mkepair) epair_gw_route_to_backup_bridge0=$(vnet_mkepair) epair_gw_route_to_master_bridge1=$(vnet_mkepair) epair_gw_route_to_backup_bridge1=$(vnet_mkepair) epair_gw_reply_to_master_bridge1=$(vnet_mkepair) epair_gw_reply_to_backup_bridge1=$(vnet_mkepair) epair_gw_reply_to_master_bridge2=$(vnet_mkepair) epair_gw_reply_to_backup_bridge2=$(vnet_mkepair) epair_server_bridge2=$(vnet_mkepair) ifconfig ${bridge0} up ifconfig ${epair_client_bridge0}b up ifconfig ${epair_gw_route_to_master_bridge0}b up ifconfig ${epair_gw_route_to_backup_bridge0}b up ifconfig ${bridge0} \ addm ${epair_client_bridge0}b \ addm ${epair_gw_route_to_master_bridge0}b \ addm ${epair_gw_route_to_backup_bridge0}b ifconfig ${bridge1} up ifconfig ${epair_gw_route_to_master_bridge1}b up ifconfig ${epair_gw_route_to_backup_bridge1}b up ifconfig ${epair_gw_reply_to_master_bridge1}b up ifconfig ${epair_gw_reply_to_backup_bridge1}b up ifconfig ${bridge1} \ addm ${epair_gw_route_to_master_bridge1}b \ addm ${epair_gw_route_to_backup_bridge1}b \ addm ${epair_gw_reply_to_master_bridge1}b \ addm ${epair_gw_reply_to_backup_bridge1}b ifconfig ${bridge2} up ifconfig ${epair_gw_reply_to_master_bridge2}b up ifconfig ${epair_gw_reply_to_backup_bridge2}b up ifconfig ${epair_server_bridge2}b up ifconfig ${bridge2} \ addm ${epair_gw_reply_to_master_bridge2}b \ addm ${epair_gw_reply_to_backup_bridge2}b \ addm ${epair_server_bridge2}b vnet_mkjail client ${epair_client_bridge0}a jexec client hostname client vnet_mkjail gw_route_to_master \ ${epair_gw_route_to_master_bridge0}a \ ${epair_gw_route_to_master_bridge1}a \ ${epair_sync_gw_route_to}a jexec gw_route_to_master hostname gw_route_to_master vnet_mkjail gw_route_to_backup \ ${epair_gw_route_to_backup_bridge0}a \ ${epair_gw_route_to_backup_bridge1}a \ ${epair_sync_gw_route_to}b jexec gw_route_to_backup hostname gw_route_to_backup vnet_mkjail gw_reply_to_master \ ${epair_gw_reply_to_master_bridge1}a \ ${epair_gw_reply_to_master_bridge2}a \ ${epair_sync_gw_reply_to}a jexec gw_reply_to_master hostname gw_reply_to_master vnet_mkjail gw_reply_to_backup \ ${epair_gw_reply_to_backup_bridge1}a \ ${epair_gw_reply_to_backup_bridge2}a \ ${epair_sync_gw_reply_to}b jexec gw_reply_to_backup hostname gw_reply_to_backup vnet_mkjail server ${epair_server_bridge2}a jexec server hostname server jexec client ifconfig ${epair_client_bridge0}a inet 198.18.0.1/24 up jexec client route add 198.18.2.0/24 198.18.0.10 jexec gw_route_to_master ifconfig ${epair_sync_gw_route_to}a \ inet 198.19.10.1/24 up jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge0}a \ inet 198.18.0.8/24 up jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge0}a \ alias 198.18.0.10/32 vhid 10 pass 3WjvVVw7 advskew 50 jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge1}a \ inet 198.18.1.8/24 up jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge1}a \ alias 198.18.1.10/32 vhid 11 pass 3WjvVVw7 advskew 50 jexec gw_route_to_master sysctl net.inet.ip.forwarding=1 jexec gw_route_to_master sysctl net.inet.carp.preempt=1 vnet_ifrename_jail gw_route_to_master ${epair_sync_gw_route_to}a if_pfsync vnet_ifrename_jail gw_route_to_master ${epair_gw_route_to_master_bridge0}a if_br0 vnet_ifrename_jail gw_route_to_master ${epair_gw_route_to_master_bridge1}a if_br1 jexec gw_route_to_master ifconfig pfsync0 \ syncpeer 198.19.10.2 \ syncdev if_pfsync \ maxupd 1 \ up pft_set_rules gw_route_to_master \ "keep_state = 'tag auth_packet keep state'" \ "set timeout { icmp.first 120, icmp.error 60 }" \ "block log all" \ "pass quick on if_pfsync proto pfsync keep state (no-sync)" \ "pass quick on { if_br0 if_br1 } proto carp keep state (no-sync)" \ "block drop in quick to 224.0.0.18/32" \ "pass out quick tagged auth_packet keep state" \ "pass in quick log on if_br0 route-to (if_br1 198.18.1.20) proto { icmp udp tcp } from 198.18.0.0/24 to 198.18.2.0/24 \$keep_state" jexec gw_route_to_master pfctl -e jexec gw_route_to_backup ifconfig ${epair_sync_gw_route_to}b \ inet 198.19.10.2/24 up jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge0}a \ inet 198.18.0.9/24 up jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge0}a \ alias 198.18.0.10/32 vhid 10 pass 3WjvVVw7 advskew 100 jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge1}a \ inet 198.18.1.9/24 up jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge1}a \ alias 198.18.1.10/32 vhid 11 pass 3WjvVVw7 advskew 100 jexec gw_route_to_backup sysctl net.inet.ip.forwarding=1 jexec gw_route_to_backup sysctl net.inet.carp.preempt=1 vnet_ifrename_jail gw_route_to_backup ${epair_sync_gw_route_to}b if_pfsync vnet_ifrename_jail gw_route_to_backup ${epair_gw_route_to_backup_bridge0}a if_br0 vnet_ifrename_jail gw_route_to_backup ${epair_gw_route_to_backup_bridge1}a if_br1 jexec gw_route_to_backup ifconfig pfsync0 \ syncpeer 198.19.10.1 \ syncdev if_pfsync \ up pft_set_rules gw_route_to_backup \ "keep_state = 'tag auth_packet keep state'" \ "set timeout { icmp.first 120, icmp.error 60 }" \ "block log all" \ "pass quick on if_pfsync proto pfsync keep state (no-sync)" \ "pass quick on { if_br0 if_br1 } proto carp keep state (no-sync)" \ "block drop in quick to 224.0.0.18/32" \ "pass out quick tagged auth_packet keep state" \ "pass in quick log on if_br0 route-to (if_br1 198.18.1.20) proto { icmp udp tcp } from 198.18.0.0/24 to 198.18.2.0/24 \$keep_state" jexec gw_route_to_backup pfctl -e jexec gw_reply_to_master ifconfig ${epair_sync_gw_reply_to}a \ inet 198.19.20.1/24 up jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge1}a \ inet 198.18.1.18/24 up jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge1}a \ alias 198.18.1.20/32 vhid 21 pass 3WjvVVw7 advskew 50 jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge2}a \ inet 198.18.2.18/24 up jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge2}a \ alias 198.18.2.20/32 vhid 22 pass 3WjvVVw7 advskew 50 jexec gw_reply_to_master sysctl net.inet.ip.forwarding=1 jexec gw_reply_to_master sysctl net.inet.carp.preempt=1 vnet_ifrename_jail gw_reply_to_master ${epair_sync_gw_reply_to}a if_pfsync vnet_ifrename_jail gw_reply_to_master ${epair_gw_reply_to_master_bridge1}a if_br1 vnet_ifrename_jail gw_reply_to_master ${epair_gw_reply_to_master_bridge2}a if_br2 jexec gw_reply_to_master ifconfig pfsync0 \ syncpeer 198.19.20.2 \ syncdev if_pfsync \ maxupd 1 \ up pft_set_rules gw_reply_to_master \ "set timeout { icmp.first 120, icmp.error 60 }" \ "block log all" \ "pass quick on if_pfsync proto pfsync keep state (no-sync)" \ "pass quick on { if_br1 if_br2 } proto carp keep state (no-sync)" \ "block drop in quick to 224.0.0.18/32" \ "pass out quick on if_br2 reply-to (if_br1 198.18.1.10) tagged auth_packet_reply_to keep state" \ "pass in quick log on if_br1 proto { icmp udp tcp } from 198.18.0.0/24 to 198.18.2.0/24 tag auth_packet_reply_to keep state" jexec gw_reply_to_master pfctl -e jexec gw_reply_to_backup ifconfig ${epair_sync_gw_reply_to}b \ inet 198.19.20.2/24 up jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge1}a \ inet 198.18.1.19/24 up jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge1}a \ alias 198.18.1.20/32 vhid 21 pass 3WjvVVw7 advskew 100 jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge2}a \ inet 198.18.2.19/24 up jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge2}a \ alias 198.18.2.20/32 vhid 22 pass 3WjvVVw7 advskew 100 jexec gw_reply_to_backup sysctl net.inet.ip.forwarding=1 jexec gw_reply_to_backup sysctl net.inet.carp.preempt=1 vnet_ifrename_jail gw_reply_to_backup ${epair_sync_gw_reply_to}b if_pfsync vnet_ifrename_jail gw_reply_to_backup ${epair_gw_reply_to_backup_bridge1}a if_br1 vnet_ifrename_jail gw_reply_to_backup ${epair_gw_reply_to_backup_bridge2}a if_br2 jexec gw_reply_to_backup ifconfig pfsync0 \ syncpeer 198.19.20.1 \ syncdev if_pfsync \ up pft_set_rules gw_reply_to_backup \ "set timeout { icmp.first 120, icmp.error 60 }" \ "block log all" \ "pass quick on if_pfsync proto pfsync keep state (no-sync)" \ "pass quick on { if_br1 if_br2 } proto carp keep state (no-sync)" \ "block drop in quick to 224.0.0.18/32" \ "pass out quick on if_br2 reply-to (if_br1 198.18.1.10) tagged auth_packet_reply_to keep state" \ "pass in quick log on if_br1 proto { icmp udp tcp } from 198.18.0.0/24 to 198.18.2.0/24 tag auth_packet_reply_to keep state" jexec gw_reply_to_backup pfctl -e jexec server ifconfig ${epair_server_bridge2}a inet 198.18.2.1/24 up jexec server route add 198.18.0.0/24 198.18.2.20 # Waiting for platform to settle while ! jexec gw_route_to_backup ifconfig | grep 'carp: BACKUP' do sleep 1 done while ! jexec gw_reply_to_backup ifconfig | grep 'carp: BACKUP' do sleep 1 done while ! jexec client ping -c 10 198.18.2.1 | grep ', 0.0% packet loss' do sleep 1 done # Checking cluster members pf.conf checksums match gw_route_to_master_checksum=$(jexec gw_route_to_master pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2) gw_route_to_backup_checksum=$(jexec gw_route_to_backup pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2) gw_reply_to_master_checksum=$(jexec gw_reply_to_master pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2) gw_reply_to_backup_checksum=$(jexec gw_reply_to_backup pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2) if [ "$gw_route_to_master_checksum" != "$gw_route_to_backup_checksum" ] then atf_fail "gw_route_to cluster members pf.conf do not match each others" fi if [ "$gw_reply_to_master_checksum" != "$gw_reply_to_backup_checksum" ] then atf_fail "gw_reply_to cluster members pf.conf do not match each others" fi # Creating state entries (jexec client ping -c 10 198.18.2.1 >ping.stdout) & if [ "$1" = "backup_promotion" ] then sleep 1 jexec gw_route_to_backup ifconfig if_br0 vhid 10 advskew 0 jexec gw_route_to_backup ifconfig if_br1 vhid 11 advskew 0 jexec gw_reply_to_backup ifconfig if_br1 vhid 21 advskew 0 jexec gw_reply_to_backup ifconfig if_br2 vhid 22 advskew 0 fi while ! grep -q -e 'packet loss' ping.stdout do sleep 1 done atf_check -s exit:0 -e ignore -o ignore grep ', 0.0% packet loss' ping.stdout } pbr_common_cleanup() { pft_cleanup } atf_test_case "ipsec" "cleanup" ipsec_head() { atf_set descr 'Transport pfsync over IPSec' atf_set require.user root } ipsec_body() { if ! sysctl -q kern.features.ipsec >/dev/null ; then atf_skip "This test requires ipsec" fi # Run the common test, to set up pfsync common_body # But we want unicast pfsync jexec one ifconfig pfsync0 syncpeer 192.0.2.2 jexec two ifconfig pfsync0 syncpeer 192.0.2.1 # Flush existing states jexec one pfctl -Fs jexec two pfctl -Fs # Now define an ipsec policy to run over the epair_sync interfaces echo "flush; spdflush; spdadd 192.0.2.1/32 192.0.2.2/32 any -P out ipsec esp/transport//require; spdadd 192.0.2.2/32 192.0.2.1/32 any -P in ipsec esp/transport//require; add 192.0.2.1 192.0.2.2 esp 0x1000 -E aes-gcm-16 \"12345678901234567890\"; add 192.0.2.2 192.0.2.1 esp 0x1001 -E aes-gcm-16 \"12345678901234567890\";" \ | jexec one setkey -c echo "flush; spdflush; spdadd 192.0.2.2/32 192.0.2.1/32 any -P out ipsec esp/transport//require; spdadd 192.0.2.1/32 192.0.2.2/32 any -P in ipsec esp/transport//require; add 192.0.2.1 192.0.2.2 esp 0x1000 -E aes-gcm-16 \"12345678901234567891\"; add 192.0.2.2 192.0.2.1 esp 0x1001 -E aes-gcm-16 \"12345678901234567891\";" \ | jexec two setkey -c # We've set incompatible keys, so pfsync will be broken. ping -c 1 -S 198.51.100.254 198.51.100.1 # Give pfsync time to do its thing sleep 2 if jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \ grep 198.51.100.2 ; then atf_fail "state synced although IPSec should have prevented it" fi # Flush existing states jexec one pfctl -Fs jexec two pfctl -Fs # Fix the IPSec key to match echo "flush; spdflush; spdadd 192.0.2.2/32 192.0.2.1/32 any -P out ipsec esp/transport//require; spdadd 192.0.2.1/32 192.0.2.2/32 any -P in ipsec esp/transport//require; add 192.0.2.1 192.0.2.2 esp 0x1000 -E aes-gcm-16 \"12345678901234567890\"; add 192.0.2.2 192.0.2.1 esp 0x1001 -E aes-gcm-16 \"12345678901234567890\";" \ | jexec two setkey -c ping -c 1 -S 198.51.100.254 198.51.100.1 # Give pfsync time to do its thing sleep 2 if ! jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \ grep 198.51.100.2 ; then atf_fail "state not found on synced host" fi } ipsec_cleanup() { pft_cleanup } atf_test_case "timeout" "cleanup" timeout_head() { atf_set descr 'Trigger pfsync_timeout()' atf_set require.user root } timeout_body() { pft_init vnet_mkjail one jexec one ifconfig lo0 127.0.0.1/8 up jexec one ifconfig lo0 inet6 ::1/128 up pft_set_rules one \ "pass all" jexec one pfctl -e jexec one ifconfig pfsync0 defer up jexec one ping -c 1 ::1 jexec one ping -c 1 127.0.0.1 # Give pfsync_timeout() time to fire (a callout on a 1 second delay) sleep 2 } timeout_cleanup() { pft_cleanup } atf_test_case "basic_ipv6_unicast" "cleanup" basic_ipv6_unicast_head() { atf_set descr 'Basic pfsync test (IPv6)' atf_set require.user root } basic_ipv6_unicast_body() { pfsynct_init epair_sync=$(vnet_mkepair) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) vnet_mkjail one ${epair_one}a ${epair_sync}a vnet_mkjail two ${epair_two}a ${epair_sync}b # pfsync interface jexec one ifconfig ${epair_sync}a inet6 fd2c::1/64 no_dad up jexec one ifconfig ${epair_one}a inet6 fd2b::1/64 no_dad up jexec one ifconfig pfsync0 \ syncdev ${epair_sync}a \ syncpeer fd2c::2 \ maxupd 1 \ up jexec two ifconfig ${epair_two}a inet6 fd2b::2/64 no_dad up jexec two ifconfig ${epair_sync}b inet6 fd2c::2/64 no_dad up jexec two ifconfig pfsync0 \ syncdev ${epair_sync}b \ syncpeer fd2c::1 \ maxupd 1 \ up # Enable pf! jexec one pfctl -e pft_set_rules one \ "block on ${epair_sync}a inet" \ "pass out keep state" jexec two pfctl -e pft_set_rules two \ "block on ${epair_sync}b inet" \ "pass out keep state" ifconfig ${epair_one}b inet6 fd2b::f0/64 no_dad up ping6 -c 1 -S fd2b::f0 fd2b::1 # Give pfsync time to do its thing sleep 2 if ! jexec two pfctl -s states | grep icmp | grep fd2b::1 | \ grep fd2b::f0 ; then atf_fail "state not found on synced host" fi } basic_ipv6_unicast_cleanup() { pfsynct_cleanup } atf_test_case "basic_ipv6" "cleanup" basic_ipv6_head() { atf_set descr 'Basic pfsync test (IPv6)' atf_set require.user root } basic_ipv6_body() { pfsynct_init epair_sync=$(vnet_mkepair) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) vnet_mkjail one ${epair_one}a ${epair_sync}a vnet_mkjail two ${epair_two}a ${epair_sync}b # pfsync interface jexec one ifconfig ${epair_sync}a inet6 fd2c::1/64 no_dad up jexec one ifconfig ${epair_one}a inet6 fd2b::1/64 no_dad up jexec one ifconfig pfsync0 \ syncdev ${epair_sync}a \ syncpeer ff12::f0 \ maxupd 1 \ up jexec two ifconfig ${epair_two}a inet6 fd2b::2/64 no_dad up jexec two ifconfig ${epair_sync}b inet6 fd2c::2/64 no_dad up jexec two ifconfig pfsync0 \ syncdev ${epair_sync}b \ syncpeer ff12::f0 \ maxupd 1 \ up # Enable pf! jexec one pfctl -e pft_set_rules one \ "block on ${epair_sync}a inet" \ "pass out keep state" jexec two pfctl -e pft_set_rules two \ "block on ${epair_sync}b inet" \ "pass out keep state" ifconfig ${epair_one}b inet6 fd2b::f0/64 no_dad up ping6 -c 1 -S fd2b::f0 fd2b::1 # Give pfsync time to do its thing sleep 2 if ! jexec two pfctl -s states | grep icmp | grep fd2b::1 | \ grep fd2b::f0 ; then atf_fail "state not found on synced host" fi } basic_ipv6_cleanup() { pfsynct_cleanup } atf_test_case "route_to" "cleanup" route_to_head() { atf_set descr 'Test route-to with default rule' atf_set require.user root atf_set require.progs scapy } route_to_body() { pfsynct_init epair_sync=$(vnet_mkepair) epair_one=$(vnet_mkepair) epair_two=$(vnet_mkepair) epair_out_one=$(vnet_mkepair) epair_out_two=$(vnet_mkepair) vnet_mkjail one ${epair_one}a ${epair_sync}a ${epair_out_one}a vnet_mkjail two ${epair_two}a ${epair_sync}b ${epair_out_two}a # pfsync interface jexec one ifconfig ${epair_sync}a 192.0.2.1/24 up jexec one ifconfig ${epair_one}a 198.51.100.1/24 up jexec one ifconfig ${epair_out_one}a 203.0.113.1/24 up jexec one ifconfig ${epair_out_one}a name outif jexec one sysctl net.inet.ip.forwarding=1 jexec one arp -s 203.0.113.254 00:01:02:03:04:05 jexec one ifconfig pfsync0 \ syncdev ${epair_sync}a \ maxupd 1 \ up jexec two ifconfig ${epair_sync}b 192.0.2.2/24 up jexec two ifconfig ${epair_two}a 198.51.100.2/24 up jexec two ifconfig ${epair_out_two}a 203.0.113.2/24 up #jexec two ifconfig ${epair_out_two}a name outif jexec two sysctl net.inet.ip.forwarding=1 jexec two arp -s 203.0.113.254 00:01:02:03:04:05 jexec two ifconfig pfsync0 \ syncdev ${epair_sync}b \ maxupd 1 \ up # Enable pf! jexec one pfctl -e pft_set_rules one \ "set skip on ${epair_sync}a" \ "pass out route-to (outif 203.0.113.254)" jexec two pfctl -e # Make sure we have different rulesets so the synced state is associated with # V_pf_default_rule pft_set_rules two \ "set skip on ${epair_sync}b" \ "pass out route-to (outif 203.0.113.254)" \ "pass out proto tcp" ifconfig ${epair_one}b 198.51.100.254/24 up ifconfig ${epair_two}b 198.51.100.253/24 up route add -net 203.0.113.0/24 198.51.100.1 ifconfig ${epair_two}b up ifconfig ${epair_out_one}b up ifconfig ${epair_out_two}b up atf_check -s exit:0 env PYTHONPATH=${common_dir} \ ${common_dir}/pft_ping.py \ --sendif ${epair_one}b \ --fromaddr 198.51.100.254 \ --to 203.0.113.254 \ --recvif ${epair_out_one}b # Allow time for sync ifconfig ${epair_one}b inet 198.51.100.254 -alias route del -net 203.0.113.0/24 198.51.100.1 route add -net 203.0.113.0/24 198.51.100.2 sleep 2 # Now try to trigger the state on the other pfsync member env PYTHONPATH=${common_dir} \ ${common_dir}/pft_ping.py \ --sendif ${epair_two}b \ --fromaddr 198.51.100.254 \ --to 203.0.113.254 \ --recvif ${epair_out_two}b true } route_to_cleanup() { pfsynct_cleanup } atf_init_test_cases() { atf_add_test_case "basic" atf_add_test_case "basic_defer" atf_add_test_case "defer" atf_add_test_case "bulk" atf_add_test_case "pbr" atf_add_test_case "pfsync_pbr" atf_add_test_case "ipsec" atf_add_test_case "timeout" atf_add_test_case "basic_ipv6_unicast" atf_add_test_case "basic_ipv6" atf_add_test_case "route_to" } diff --git a/tests/sys/netpfil/pf/sctp.sh b/tests/sys/netpfil/pf/sctp.sh index 66225e132d1c..c6dba1719d00 100644 --- a/tests/sys/netpfil/pf/sctp.sh +++ b/tests/sys/netpfil/pf/sctp.sh @@ -1,668 +1,669 @@ # # SPDX-License-Identifier: BSD-2-Clause-FreeBSD # # Copyright © 2023 Orange Business Services # # 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. . $(atf_get_srcdir)/utils.subr sctp_init() { pft_init if ! kldstat -q -m sctp; then atf_skip "This test requires SCTP" fi } atf_test_case "basic_v4" "cleanup" basic_v4_head() { atf_set descr 'Basic SCTP connection over IPv4 passthrough' atf_set require.user root } basic_v4_body() { sctp_init j="sctp:basic_v4" epair=$(vnet_mkepair) vnet_mkjail ${j}a ${epair}a vnet_mkjail ${j}b ${epair}b jexec ${j}a ifconfig ${epair}a 192.0.2.1/24 up jexec ${j}b ifconfig ${epair}b 192.0.2.2/24 up # Sanity check atf_check -s exit:0 -o ignore \ jexec ${j}a ping -c 1 192.0.2.2 jexec ${j}a pfctl -e pft_set_rules ${j}a \ "block" \ "pass in proto sctp to port 1234" echo "foo" | jexec ${j}a nc --sctp -N -l 1234 & # Wait for the server to start sleep 1 out=$(jexec ${j}b nc --sctp -N -w 3 192.0.2.1 1234) if [ "$out" != "foo" ]; then atf_fail "SCTP connection failed" fi # Now with scrub rules present, so normalization is done pft_set_rules ${j}a \ "scrub on ${j}a" \ "block" \ "pass in proto sctp to port 1234" echo "foo" | jexec ${j}a nc --sctp -N -l 1234 & sleep 1 out=$(jexec ${j}b nc --sctp -N -w 3 192.0.2.1 1234) if [ "$out" != "foo" ]; then atf_fail "SCTP connection failed" fi # Now fail with a blocked port echo "foo" | jexec ${j}a nc --sctp -N -l 1235 & sleep 1 out=$(jexec ${j}b nc --sctp -N -w 3 192.0.2.1 1235) if [ "$out" == "foo" ]; then atf_fail "SCTP port block failed" fi # Now fail with a blocked port but passing source port out=$(jexec ${j}b nc --sctp -N -w 3 -p 1234 192.0.2.1 1235) if [ "$out" == "foo" ]; then atf_fail "SCTP port block failed" fi } basic_v4_cleanup() { pft_cleanup } atf_test_case "basic_v6" "cleanup" basic_v6_head() { atf_set descr 'Basic SCTP connection over IPv6' atf_set require.user root } basic_v6_body() { sctp_init j="sctp:basic_v6" epair=$(vnet_mkepair) vnet_mkjail ${j}a ${epair}a vnet_mkjail ${j}b ${epair}b jexec ${j}a ifconfig ${epair}a inet6 2001:db8::a/64 up no_dad jexec ${j}b ifconfig ${epair}b inet6 2001:db8::b/64 up no_dad # Sanity check atf_check -s exit:0 -o ignore \ jexec ${j}a ping -6 -c 1 2001:db8::b jexec ${j}a pfctl -e pft_set_rules ${j}a \ "block proto sctp" \ "pass in proto sctp to port 1234" echo "foo" | jexec ${j}a nc -6 --sctp -N -l 1234 & # Wait for the server to start sleep 1 out=$(jexec ${j}b nc --sctp -N -w 3 2001:db8::a 1234) if [ "$out" != "foo" ]; then atf_fail "SCTP connection failed" fi # Now with scrub rules present, so normalization is done pft_set_rules ${j}a \ "scrub on ${j}a" \ "block proto sctp" \ "pass in proto sctp to port 1234" echo "foo" | jexec ${j}a nc -6 --sctp -N -l 1234 & sleep 1 out=$(jexec ${j}b nc --sctp -N -w 3 2001:db8::a 1234) if [ "$out" != "foo" ]; then atf_fail "SCTP connection failed" fi # Now fail with a blocked port echo "foo" | jexec ${j}a nc -6 --sctp -N -l 1235 & sleep 1 out=$(jexec ${j}b nc --sctp -N -w 3 2001:db8::a 1235) if [ "$out" == "foo" ]; then atf_fail "SCTP port block failed" fi # Now fail with a blocked port but passing source port out=$(jexec ${j}b nc --sctp -N -w 3 -p 1234 2001:db8::a 1235) if [ "$out" == "foo" ]; then atf_fail "SCTP port block failed" fi } basic_v6_cleanup() { pft_cleanup } atf_test_case "abort_v4" "cleanup" abort_v4_head() { atf_set descr 'Test sending ABORT messages' atf_set require.user root } abort_v4_body() { sctp_init j="sctp:abort_v4" epair=$(vnet_mkepair) vnet_mkjail ${j}a ${epair}a vnet_mkjail ${j}b ${epair}b jexec ${j}a ifconfig ${epair}a 192.0.2.1/24 up jexec ${j}b ifconfig ${epair}b 192.0.2.2/24 up # Sanity check atf_check -s exit:0 -o ignore \ jexec ${j}a ping -c 1 192.0.2.2 jexec ${j}a pfctl -e pft_set_rules ${j}a \ "block return in proto sctp to port 1234" echo "foo" | jexec ${j}a nc --sctp -N -l 1234 & # Wait for the server to start sleep 1 # If we get the abort we'll exit immediately, if we don't timeout will # stop nc. out=$(jexec ${j}b timeout 3 nc --sctp -N 192.0.2.1 1234) if [ $? -eq 124 ]; then atf_fail 'Abort not received' fi if [ "$out" == "foo" ]; then atf_fail "block failed entirely" fi # Without 'return' we will time out. pft_set_rules ${j}a \ "block in proto sctp to port 1234" out=$(jexec ${j}b timeout 3 nc --sctp -N 192.0.2.1 1234) if [ $? -ne 124 ]; then atf_fail 'Abort sent anyway?' fi } abort_v4_cleanup() { pft_cleanup } atf_test_case "abort_v6" "cleanup" abort_v6_head() { atf_set descr 'Test sending ABORT messages over IPv6' atf_set require.user root } abort_v6_body() { sctp_init j="sctp:abort_v6" epair=$(vnet_mkepair) vnet_mkjail ${j}a ${epair}a vnet_mkjail ${j}b ${epair}b jexec ${j}a ifconfig ${epair}a inet6 2001:db8::a/64 no_dad jexec ${j}b ifconfig ${epair}b inet6 2001:db8::b/64 no_dad # Sanity check atf_check -s exit:0 -o ignore \ jexec ${j}a ping -6 -c 1 2001:db8::b jexec ${j}a pfctl -e pft_set_rules ${j}a \ "block return in proto sctp to port 1234" echo "foo" | jexec ${j}a nc -6 --sctp -N -l 1234 & # Wait for the server to start sleep 1 # If we get the abort we'll exit immediately, if we don't timeout will # stop nc. out=$(jexec ${j}b timeout 3 nc --sctp -N 2001:db8::a 1234) if [ $? -eq 124 ]; then atf_fail 'Abort not received' fi if [ "$out" == "foo" ]; then atf_fail "block failed entirely" fi # Without 'return' we will time out. pft_set_rules ${j}a \ "block in proto sctp to port 1234" out=$(jexec ${j}b timeout 3 nc --sctp -N 2001:db8::a 1234) if [ $? -ne 124 ]; then atf_fail 'Abort sent anyway?' fi } abort_v6_cleanup() { pft_cleanup } atf_test_case "nat_v4" "cleanup" nat_v4_head() { atf_set descr 'Test NAT-ing SCTP over IPv4' atf_set require.user root } nat_v4_body() { sctp_init j="sctp:nat_v4" epair_c=$(vnet_mkepair) epair_srv=$(vnet_mkepair) vnet_mkjail ${j}srv ${epair_srv}a vnet_mkjail ${j}gw ${epair_srv}b ${epair_c}a vnet_mkjail ${j}c ${epair_c}b jexec ${j}srv ifconfig ${epair_srv}a 198.51.100.1/24 up # No default route in srv jail, to ensure we're NAT-ing jexec ${j}gw ifconfig ${epair_srv}b 198.51.100.2/24 up jexec ${j}gw ifconfig ${epair_c}a 192.0.2.1/24 up jexec ${j}gw sysctl net.inet.ip.forwarding=1 jexec ${j}c ifconfig ${epair_c}b 192.0.2.2/24 up jexec ${j}c route add default 192.0.2.1 jexec ${j}gw pfctl -e pft_set_rules ${j}gw \ "nat on ${epair_srv}b from 192.0.2.0/24 -> (${epair_srv}b)" \ "pass" # Sanity check atf_check -s exit:0 -o ignore \ jexec ${j}c ping -c 1 198.51.100.1 echo "foo" | jexec ${j}srv nc --sctp -N -l 1234 & # Wait for the server to start sleep 1 out=$(jexec ${j}c nc --sctp -N -w 3 198.51.100.1 1234) if [ "$out" != "foo" ]; then atf_fail "SCTP connection failed" fi } nat_v4_cleanup() { pft_cleanup } atf_test_case "nat_v6" "cleanup" nat_v6_head() { atf_set descr 'Test NAT-ing SCTP over IPv6' atf_set require.user root } nat_v6_body() { sctp_init j="sctp:nat_v6" epair_c=$(vnet_mkepair) epair_srv=$(vnet_mkepair) vnet_mkjail ${j}srv ${epair_srv}a vnet_mkjail ${j}gw ${epair_srv}b ${epair_c}a vnet_mkjail ${j}c ${epair_c}b jexec ${j}srv ifconfig ${epair_srv}a inet6 2001:db8::1/64 up no_dad # No default route in srv jail, to ensure we're NAT-ing jexec ${j}gw ifconfig ${epair_srv}b inet6 2001:db8::2/64 up no_dad jexec ${j}gw ifconfig ${epair_c}a inet6 2001:db8:1::1/64 up no_dad jexec ${j}gw sysctl net.inet6.ip6.forwarding=1 jexec ${j}c ifconfig ${epair_c}b inet6 2001:db8:1::2/64 up no_dad jexec ${j}c route add -6 default 2001:db8:1::1 jexec ${j}gw pfctl -e pft_set_rules ${j}gw \ "nat on ${epair_srv}b from 2001:db8:1::/64 -> (${epair_srv}b)" \ "pass" # Sanity check atf_check -s exit:0 -o ignore \ jexec ${j}c ping -6 -c 1 2001:db8::1 echo "foo" | jexec ${j}srv nc -6 --sctp -N -l 1234 & # Wait for the server to start sleep 1 out=$(jexec ${j}c nc --sctp -N -w 3 2001:db8::1 1234) if [ "$out" != "foo" ]; then atf_fail "SCTP connection failed" fi } nat_v6_cleanup() { pft_cleanup } atf_test_case "rdr_v4" "cleanup" rdr_v4_head() { atf_set descr 'Test rdr SCTP over IPv4' atf_set require.user root } rdr_v4_body() { sctp_init j="sctp:rdr_v4" epair_c=$(vnet_mkepair) epair_srv=$(vnet_mkepair) vnet_mkjail ${j}srv ${epair_srv}a vnet_mkjail ${j}gw ${epair_srv}b ${epair_c}a vnet_mkjail ${j}c ${epair_c}b jexec ${j}srv ifconfig ${epair_srv}a 198.51.100.1/24 up # No default route in srv jail, to ensure we're NAT-ing jexec ${j}gw ifconfig ${epair_srv}b 198.51.100.2/24 up jexec ${j}gw ifconfig ${epair_c}a 192.0.2.1/24 up jexec ${j}gw sysctl net.inet.ip.forwarding=1 jexec ${j}c ifconfig ${epair_c}b 192.0.2.2/24 up jexec ${j}c route add default 192.0.2.1 jexec ${j}gw pfctl -e pft_set_rules ${j}gw \ "rdr pass on ${epair_srv}b proto sctp from 198.51.100.0/24 to any port 1234 -> 192.0.2.2 port 1234" \ "pass" echo "foo" | jexec ${j}c nc --sctp -N -l 1234 & # Wait for the server to start sleep 1 out=$(jexec ${j}srv nc --sctp -N -w 3 198.51.100.2 1234) if [ "$out" != "foo" ]; then atf_fail "SCTP connection failed" fi # Despite configuring port changes pf will not do so. echo "bar" | jexec ${j}c nc --sctp -N -l 1234 & pft_set_rules ${j}gw \ "rdr pass on ${epair_srv}b proto sctp from 198.51.100.0/24 to any port 1234 -> 192.0.2.2 port 4321" \ "pass" # This will fail out=$(jexec ${j}srv nc --sctp -N -w 3 198.51.100.2 4321) if [ "$out" == "bar" ]; then atf_fail "Port was unexpectedly changed." fi # This succeeds out=$(jexec ${j}srv nc --sctp -N -w 3 198.51.100.2 1234) if [ "$out" != "bar" ]; then atf_fail "Port was unexpectedly changed." fi } rdr_v4_cleanup() { pft_cleanup } atf_test_case "pfsync" "cleanup" pfsync_head() { atf_set descr 'Test pfsync-ing SCTP connections' atf_set require.user root } pfsync_body() { # + Builds bellow topology and initiate an SCTP connection # from client to server. # + Tests that the connection remains open when we fail over from # router one to router two. # # ┌──────┐ # │client│ # └───┬──┘ # │ # ┌───┴───┐ # │bridge0│ # └┬─────┬┘ # │ │ # ┌────────────────┴─┐ ┌─┴────────────────┐ # │ one ├─┤ two │ # └────────────────┬─┘ └─┬────────────────┘ # │ │ # ┌┴─────┴┐ # │bridge1│ # └───┬───┘ # │ # ┌───┴──┐ # │server│ # └──────┘ sctp_init pfsynct_init + vnet_init_bridge if ! kldstat -q -m carp then atf_skip "This test requires carp" fi j="sctp:pfsync" tmp=`pwd` bridge0=$(vnet_mkbridge) bridge1=$(vnet_mkbridge) epair_c=$(vnet_mkepair) epair_one0=$(vnet_mkepair) epair_two0=$(vnet_mkepair) epair_sync=$(vnet_mkepair) epair_one1=$(vnet_mkepair) epair_two1=$(vnet_mkepair) epair_srv=$(vnet_mkepair) ifconfig ${bridge0} addm ${epair_c}a addm ${epair_one0}a addm ${epair_two0}a ifconfig ${epair_one0}a up ifconfig ${epair_two0}a up ifconfig ${epair_c}a up ifconfig ${bridge0} up ifconfig ${bridge1} addm ${epair_srv}a addm ${epair_one1}a addm ${epair_two1}a ifconfig ${epair_one1}a up ifconfig ${epair_two1}a up ifconfig ${epair_srv}a up ifconfig ${bridge1} up vnet_mkjail ${j}c ${epair_c}b jexec ${j}c ifconfig ${epair_c}b 192.0.2.2/24 up jexec ${j}c route add default 192.0.2.1 vnet_mkjail ${j}one ${epair_one0}b ${epair_one1}b ${epair_sync}a jexec ${j}one ifconfig ${epair_one0}b 192.0.2.3/24 up jexec ${j}one ifconfig ${epair_one0}b \ alias 192.0.2.1/32 vhid 1 pass 1234 jexec ${j}one ifconfig ${epair_one1}b 198.51.100.3/24 up jexec ${j}one ifconfig ${epair_one1}b \ alias 198.51.100.2/32 vhid 2 pass 4321 jexec ${j}one ifconfig ${epair_sync}a 203.0.113.1/24 up jexec ${j}one ifconfig pfsync0 \ syncdev ${epair_sync}a \ maxupd 1 \ up jexec ${j}one sysctl net.inet.ip.forwarding=1 vnet_mkjail ${j}two ${epair_two0}b ${epair_two1}b ${epair_sync}b jexec ${j}two ifconfig ${epair_two0}b 192.0.2.4/24 up jexec ${j}two ifconfig ${epair_two0}b \ alias 192.0.2.1/32 vhid 1 pass 1234 jexec ${j}two ifconfig ${epair_two1}b 198.51.100.4/24 up jexec ${j}two ifconfig ${epair_two1}b \ alias 198.51.100.2/32 vhid 2 pass 4321 jexec ${j}two ifconfig ${epair_sync}b 203.0.113.2/24 up jexec ${j}two ifconfig pfsync0 \ syncdev ${epair_sync}b \ maxupd 1 \ up jexec ${j}two sysctl net.inet.ip.forwarding=1 vnet_mkjail ${j}srv ${epair_srv}b jexec ${j}srv ifconfig ${epair_srv}b 198.51.100.1/24 up jexec ${j}srv route add default 198.51.100.2 # Demote two, to avoid dealing with asymmetric routing jexec ${j}two sysctl net.inet.carp.demotion=50 jexec ${j}one pfctl -e pft_set_rules ${j}one \ "block all" \ "pass proto { icmp, pfsync, carp }" \ "pass proto sctp to port 1234" \ "pass proto tcp to port 1234" jexec ${j}two pfctl -e pft_set_rules ${j}two \ "block all" \ "pass proto { icmp, pfsync, carp }" \ "pass proto sctp to port 1234" \ "pass proto tcp to port 1234" # Give carp time to get set up sleep 2 # Sanity check atf_check -s exit:0 -o ignore \ jexec ${j}c ping -c 1 198.51.100.1 # Now start up an SCTP connection touch ${tmp}/input tail -F ${tmp}/input | jexec ${j}srv nc --sctp -l 1234 & sleep 1 jexec ${j}c nc --sctp 198.51.100.1 1234 > ${tmp}/output & echo "1" >> ${tmp}/input # Give time for the traffic to arrive sleep 1 line=$(tail -n -1 ${tmp}/output) if [ "${line}" != "1" ]; then echo "Found ${line}" cat ${tmp}/output atf_fail "Initial SCTP connection failed" fi # Verify that two has the connection too state=$(jexec ${j}two pfctl -ss | grep sctp) if [ -z "${state}" ]; then jexec ${j}two pfctl -ss atf_fail "Failed to find SCTP state on secondary pfsync host" fi # Now fail over (both carp IPs should switch here) jexec ${j}one sysctl net.inet.carp.demotion=100 while ! jexec ${j}one ifconfig ${epair_one0}b | grep MASTER; do sleep 1 done while ! jexec ${j}one ifconfig ${epair_one1}b | grep MASTER; do sleep 1 done # Sanity check atf_check -s exit:0 -o ignore \ jexec ${j}c ping -c 1 198.51.100.1 # And check that the connection is still live echo "2" >> ${tmp}/input sleep 1 line=$(tail -n -1 ${tmp}/output) if [ "${line}" != "2" ]; then echo "Found ${line}" cat ${tmp}/output atf_fail "SCTP failover failed" fi } pfsync_cleanup() { pfsynct_cleanup } atf_init_test_cases() { atf_add_test_case "basic_v4" atf_add_test_case "basic_v6" atf_add_test_case "abort_v4" atf_add_test_case "abort_v6" atf_add_test_case "nat_v4" atf_add_test_case "nat_v6" atf_add_test_case "rdr_v4" atf_add_test_case "pfsync" } diff --git a/tests/sys/netpfil/pf/tcp.sh b/tests/sys/netpfil/pf/tcp.sh index 84536480b44e..f1bffdba2bfa 100644 --- a/tests/sys/netpfil/pf/tcp.sh +++ b/tests/sys/netpfil/pf/tcp.sh @@ -1,109 +1,110 @@ # # SPDX-License-Identifier: BSD-2-Clause # # Copyright (c) 2023 Rubicon Communications, LLC (Netgate) # # 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. . $(atf_get_srcdir)/utils.subr common_dir=$(atf_get_srcdir)/../common atf_test_case "rst" "cleanup" rst_head() { atf_set descr 'Check sequence number validation in RST packets' atf_set require.user root atf_set require.progs scapy } rst_body() { pft_init + vnet_init_bridge epair_srv=$(vnet_mkepair) epair_cl=$(vnet_mkepair) epair_attack=$(vnet_mkepair) br=$(vnet_mkbridge) ifconfig ${br} addm ${epair_srv}a ifconfig ${epair_srv}a up ifconfig ${br} addm ${epair_cl}a ifconfig ${epair_cl}a up ifconfig ${br} addm ${epair_attack}a ifconfig ${epair_attack}a up ifconfig ${br} up vnet_mkjail srv ${epair_srv}b jexec srv ifconfig ${epair_srv}b 192.0.2.1/24 up jexec srv ifconfig lo0 inet 127.0.0.1/8 up vnet_mkjail cl ${epair_cl}b jexec cl ifconfig ${epair_cl}b 192.0.2.2/24 up jexec cl ifconfig lo0 inet 127.0.0.1/8 up jexec cl pfctl -e pft_set_rules cl \ "pass keep state" # Not required, but pf should log the bad RST packet with this set. jexec cl pfctl -x loud vnet_mkjail attack ${epair_attack}b jexec attack ifconfig ${epair_attack}b 192.0.2.3/24 up # Sanity check atf_check -s exit:0 -o ignore \ jexec cl ping -c 1 192.0.2.1 echo "bar" | jexec srv nc -l 1234 & # Allow server time to start sleep 1 echo "foo" | jexec cl nc -p 4321 192.0.2.1 1234 & # Allow connection time to set up sleep 1 # Connection should be established now atf_check -s exit:0 -e ignore \ -o match:"ESTABLISHED:ESTABLISHED" \ jexec cl pfctl -ss -v # Now insert a fake RST atf_check -s exit:0 -o ignore \ jexec attack ${common_dir}/pft_rst.py 192.0.2.1 1234 192.0.2.2 4321 # Connection should remain established atf_check -s exit:0 -e ignore \ -o match:"ESTABLISHED:ESTABLISHED" \ jexec cl pfctl -ss -v } rst_cleanup() { pft_cleanup } atf_init_test_cases() { atf_add_test_case "rst" }