11d6f5f21SKristof Provost# Utility functions 21d6f5f21SKristof Provost## 34d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause 465d553b0SKristof Provost# 565d553b0SKristof Provost# Copyright (c) 2017 Kristof Provost <kp@FreeBSD.org> 638e2d5dbSKristof Provost# Copyright (c) 2023 Kajetan Staszkiewicz <vegeta@tuxpowered.net> 765d553b0SKristof Provost# 865d553b0SKristof Provost# Redistribution and use in source and binary forms, with or without 965d553b0SKristof Provost# modification, are permitted provided that the following conditions 1065d553b0SKristof Provost# are met: 1165d553b0SKristof Provost# 1. Redistributions of source code must retain the above copyright 1265d553b0SKristof Provost# notice, this list of conditions and the following disclaimer. 1365d553b0SKristof Provost# 2. Redistributions in binary form must reproduce the above copyright 1465d553b0SKristof Provost# notice, this list of conditions and the following disclaimer in the 1565d553b0SKristof Provost# documentation and/or other materials provided with the distribution. 1665d553b0SKristof Provost# 1765d553b0SKristof Provost# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1865d553b0SKristof Provost# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1965d553b0SKristof Provost# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2065d553b0SKristof Provost# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2165d553b0SKristof Provost# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2265d553b0SKristof Provost# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2365d553b0SKristof Provost# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2465d553b0SKristof Provost# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2565d553b0SKristof Provost# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2665d553b0SKristof Provost# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2765d553b0SKristof Provost# SUCH DAMAGE. 281d6f5f21SKristof Provost 2906aac31aSKristof Provost. $(atf_get_srcdir)/../../common/vnet.subr 3038e2d5dbSKristof Provostcommon_dir=$(atf_get_srcdir)/../common 3106aac31aSKristof Provost 324826406bSKristof Provostpft_onerror() 334826406bSKristof Provost{ 344826406bSKristof Provost status=$? 354826406bSKristof Provost 364826406bSKristof Provost echo "Debug log." 374826406bSKristof Provost echo "==========" 384826406bSKristof Provost echo "Test exit status: $?" 394826406bSKristof Provost echo 404826406bSKristof Provost 414826406bSKristof Provost if [ -f created_jails.lst ]; then 424826406bSKristof Provost for jailname in `cat created_jails.lst` 434826406bSKristof Provost do 444826406bSKristof Provost echo "Jail ${jailname}" 454826406bSKristof Provost echo "----------------" 464826406bSKristof Provost jexec ${jailname} ifconfig 474826406bSKristof Provost jexec ${jailname} netstat -rn 484826406bSKristof Provost jexec ${jailname} pfctl -sa -v 494826406bSKristof Provost done 504826406bSKristof Provost fi 514826406bSKristof Provost 524826406bSKristof Provost echo "Created interfaces:" 534826406bSKristof Provost echo "-------------------" 544826406bSKristof Provost cat created_interfaces.lst 554826406bSKristof Provost 564826406bSKristof Provost echo "Host interfaces:" 574826406bSKristof Provost echo "----------------" 584826406bSKristof Provost ifconfig 594826406bSKristof Provost} 604826406bSKristof Provost 611d6f5f21SKristof Provostpft_init() 621d6f5f21SKristof Provost{ 6334478b73SKristof Provost if [ "$1" == "debug" ] 6434478b73SKristof Provost then 654826406bSKristof Provost trap pft_onerror EXIT 6634478b73SKristof Provost fi 674826406bSKristof Provost 6806aac31aSKristof Provost vnet_init 6906aac31aSKristof Provost 701d6f5f21SKristof Provost if [ ! -c /dev/pf ]; then 711d6f5f21SKristof Provost atf_skip "This test requires pf" 721d6f5f21SKristof Provost fi 731d6f5f21SKristof Provost} 741d6f5f21SKristof Provost 756ab3ac5aSKristof Provostpfsynct_init() 766ab3ac5aSKristof Provost{ 776ab3ac5aSKristof Provost pft_init 786ab3ac5aSKristof Provost 796ab3ac5aSKristof Provost if ! kldstat -q -m pfsync; then 806ab3ac5aSKristof Provost atf_skip "This test requires pfsync" 816ab3ac5aSKristof Provost fi 826ab3ac5aSKristof Provost} 836ab3ac5aSKristof Provost 8450816111SKristof Provostpflog_init() 8550816111SKristof Provost{ 86ae8d5881SKristof Provost pft_init 87ae8d5881SKristof Provost 8850816111SKristof Provost if ! kldstat -q -m pflog; then 8950816111SKristof Provost atf_skip "This test requires pflog" 9050816111SKristof Provost fi 9150816111SKristof Provost} 9250816111SKristof Provost 93fb0c7468SKristof Provostpflow_init() 94fb0c7468SKristof Provost{ 95fb0c7468SKristof Provost pft_init 96fb0c7468SKristof Provost 97fb0c7468SKristof Provost if ! kldstat -q -m pflow; then 98fb0c7468SKristof Provost atf_skip "This test requires pflow" 99fb0c7468SKristof Provost fi 100fb0c7468SKristof Provost} 101fb0c7468SKristof Provost 1021977d9a3SKristof Provostdummynet_init() 1031977d9a3SKristof Provost{ 1041977d9a3SKristof Provost pft_init 1051977d9a3SKristof Provost 1061977d9a3SKristof Provost if ! kldstat -q -m dummynet; then 1071977d9a3SKristof Provost atf_skip "This test requires dummynet" 1081977d9a3SKristof Provost fi 1091977d9a3SKristof Provost} 1101977d9a3SKristof Provost 111ba22aeacSKristof Provostpft_set_rules() 112ba22aeacSKristof Provost{ 113ba22aeacSKristof Provost jname=$1 114ba22aeacSKristof Provost shift 115ba22aeacSKristof Provost 116b9dee1ffSKristof Provost if [ $jname == "noflush" ]; 117b9dee1ffSKristof Provost then 118b9dee1ffSKristof Provost jname=$1 119b9dee1ffSKristof Provost shift 120b9dee1ffSKristof Provost else 121ba22aeacSKristof Provost # Flush all states, rules, fragments, ... 122ba22aeacSKristof Provost jexec ${jname} pfctl -F all 123b9dee1ffSKristof Provost fi 124ba22aeacSKristof Provost 125ba22aeacSKristof Provost while [ $# -gt 0 ]; do 126ba22aeacSKristof Provost printf "$1\n" 127ba22aeacSKristof Provost shift 128ba22aeacSKristof Provost done | jexec ${jname} pfctl -f - 129b20ff7b9SKristof Provost if [ $? -ne 0 ]; 130b20ff7b9SKristof Provost then 131b20ff7b9SKristof Provost atf_fail "Failed to set PF rules in ${jname}" 132b20ff7b9SKristof Provost fi 133ba22aeacSKristof Provost} 134ba22aeacSKristof Provost 1351d6f5f21SKristof Provostpft_cleanup() 1361d6f5f21SKristof Provost{ 13706aac31aSKristof Provost vnet_cleanup 1381d6f5f21SKristof Provost} 1396ab3ac5aSKristof Provost 1406ab3ac5aSKristof Provostpfsynct_cleanup() 1416ab3ac5aSKristof Provost{ 1426ab3ac5aSKristof Provost pft_cleanup 1436ab3ac5aSKristof Provost} 14416b38333SKristof Provost 14516b38333SKristof Provostis_altq_supported() 14616b38333SKristof Provost{ 14716b38333SKristof Provost sysctl -q kern.features.altq >/dev/null || \ 14816b38333SKristof Provost atf_skip "Test requires ALTQ" 14916b38333SKristof Provost 15016b38333SKristof Provost while [ -n "$1" ] 15116b38333SKristof Provost do 15216b38333SKristof Provost sysctl -q kern.features.altq.${1} >/dev/null || \ 15316b38333SKristof Provost atf_skip "Test required ALTQ_${1}" 15416b38333SKristof Provost shift 15516b38333SKristof Provost done 15616b38333SKristof Provost} 15716b38333SKristof Provost 15816b38333SKristof Provostaltq_init() 15916b38333SKristof Provost{ 16016b38333SKristof Provost pft_init 16116b38333SKristof Provost is_altq_supported 16216b38333SKristof Provost} 16316b38333SKristof Provost 16416b38333SKristof Provostaltq_cleanup() 16516b38333SKristof Provost{ 16616b38333SKristof Provost pft_cleanup 16716b38333SKristof Provost} 16838e2d5dbSKristof Provost 16938e2d5dbSKristof Provost# Create a bare router jail. 17038e2d5dbSKristof Provost# This function lacks target configuration. 17138e2d5dbSKristof Provostsetup_router_ipv4() 17238e2d5dbSKristof Provost{ 17338e2d5dbSKristof Provost pft_init 17438e2d5dbSKristof Provost 17538e2d5dbSKristof Provost epair_tester=$(vnet_mkepair) 17638e2d5dbSKristof Provost epair_server=$(vnet_mkepair) 17738e2d5dbSKristof Provost 17838e2d5dbSKristof Provost net_tester=192.0.2.0/24 17938e2d5dbSKristof Provost net_tester_mask=24 18038e2d5dbSKristof Provost net_tester_host_router=192.0.2.1 18138e2d5dbSKristof Provost net_tester_host_tester=192.0.2.2 18238e2d5dbSKristof Provost 18338e2d5dbSKristof Provost net_server=198.51.100.0/24 18438e2d5dbSKristof Provost net_server_mask=24 18538e2d5dbSKristof Provost net_server_host_router=198.51.100.1 18638e2d5dbSKristof Provost net_server_host_server=198.51.100.2 18738e2d5dbSKristof Provost 18838e2d5dbSKristof Provost vnet_mkjail router ${epair_tester}b ${epair_server}a 18938e2d5dbSKristof Provost 19038e2d5dbSKristof Provost ifconfig ${epair_tester}a ${net_tester_host_tester}/${net_tester_mask} up 19138e2d5dbSKristof Provost route add -net ${net_server} ${net_tester_host_router} 19238e2d5dbSKristof Provost 19338e2d5dbSKristof Provost jexec router ifconfig ${epair_tester}b ${net_tester_host_router}/${net_tester_mask} up 19438e2d5dbSKristof Provost jexec router sysctl net.inet.ip.forwarding=1 19538e2d5dbSKristof Provost jexec router ifconfig ${epair_server}a ${net_server_host_router}/${net_server_mask} up 19638e2d5dbSKristof Provost 19738e2d5dbSKristof Provost jexec router pfctl -e 19838e2d5dbSKristof Provost} 19938e2d5dbSKristof Provost 20038e2d5dbSKristof Provost# Create a router jail. 20138e2d5dbSKristof Provost# The target for tests does not exist but a static ARP entry does 20238e2d5dbSKristof Provost# so packets to it can be properly routed. 20338e2d5dbSKristof Provostsetup_router_dummy_ipv4() 20438e2d5dbSKristof Provost{ 20538e2d5dbSKristof Provost setup_router_ipv4 20638e2d5dbSKristof Provost jexec router arp -s ${net_server_host_server} 00:01:02:03:04:05 20738e2d5dbSKristof Provost ifconfig ${epair_server}b up 20838e2d5dbSKristof Provost} 20938e2d5dbSKristof Provost 21038e2d5dbSKristof Provost# Create a router and a server jail. 21138e2d5dbSKristof Provost# The server is capable of responding to pings from the tester. 21238e2d5dbSKristof Provostsetup_router_server_ipv4() 21338e2d5dbSKristof Provost{ 21438e2d5dbSKristof Provost setup_router_ipv4 21538e2d5dbSKristof Provost vnet_mkjail server ${epair_server}b 21638e2d5dbSKristof Provost jexec server ifconfig ${epair_server}b ${net_server_host_server}/${net_server_mask} up 21738e2d5dbSKristof Provost jexec server route add -net ${net_tester} ${net_server_host_router} 2186ffd4aebSKajetan Staszkiewicz inetd_conf=$(mktemp) 2196ffd4aebSKajetan Staszkiewicz echo "discard stream tcp nowait root internal" > $inetd_conf 220c17a0f62SKristof Provost jexec server inetd -p ${PWD}/inetd.pid $inetd_conf 22138e2d5dbSKristof Provost} 22238e2d5dbSKristof Provost 22338e2d5dbSKristof Provost# Create a bare router jail. 22438e2d5dbSKristof Provost# This function lacks target configuration. 22538e2d5dbSKristof Provostsetup_router_ipv6() 22638e2d5dbSKristof Provost{ 22738e2d5dbSKristof Provost pft_init 22838e2d5dbSKristof Provost 22938e2d5dbSKristof Provost epair_tester=$(vnet_mkepair) 23038e2d5dbSKristof Provost epair_server=$(vnet_mkepair) 23138e2d5dbSKristof Provost 23238e2d5dbSKristof Provost net_tester=2001:db8:42::/64 23338e2d5dbSKristof Provost net_tester_mask=64 23438e2d5dbSKristof Provost net_tester_host_router=2001:db8:42::1 23538e2d5dbSKristof Provost net_tester_host_tester=2001:db8:42::2 23638e2d5dbSKristof Provost 23738e2d5dbSKristof Provost net_server=2001:db8:43::/64 23838e2d5dbSKristof Provost net_server_mask=64 23938e2d5dbSKristof Provost net_server_host_router=2001:db8:43::1 24038e2d5dbSKristof Provost net_server_host_server=2001:db8:43::2 24138e2d5dbSKristof Provost 24238e2d5dbSKristof Provost vnet_mkjail router ${epair_tester}b ${epair_server}a 24338e2d5dbSKristof Provost 24438e2d5dbSKristof Provost ifconfig ${epair_tester}a inet6 ${net_tester_host_tester}/${net_tester_mask}up no_dad 24538e2d5dbSKristof Provost route add -6 ${net_server} ${net_tester_host_router} 24638e2d5dbSKristof Provost 24738e2d5dbSKristof Provost jexec router ifconfig ${epair_tester}b inet6 ${net_tester_host_router}/${net_tester_mask} up no_dad 24838e2d5dbSKristof Provost jexec router sysctl net.inet6.ip6.forwarding=1 24938e2d5dbSKristof Provost jexec router ifconfig ${epair_server}a inet6 ${net_server_host_router}/${net_server_mask} up no_dad 25038e2d5dbSKristof Provost 25138e2d5dbSKristof Provost jexec router pfctl -e 25238e2d5dbSKristof Provost} 25338e2d5dbSKristof Provost 25438e2d5dbSKristof Provost# Create a router jail. 25538e2d5dbSKristof Provost# The target for tests does not exist but a static NDP entry does 25638e2d5dbSKristof Provost# so packets to it can be properly routed. 25738e2d5dbSKristof Provostsetup_router_dummy_ipv6() 25838e2d5dbSKristof Provost{ 25938e2d5dbSKristof Provost setup_router_ipv6 26038e2d5dbSKristof Provost jexec router ndp -s ${net_server_host_server} 00:01:02:03:04:05 26138e2d5dbSKristof Provost ifconfig ${epair_server}b up 26238e2d5dbSKristof Provost} 26338e2d5dbSKristof Provost 26438e2d5dbSKristof Provost# Create a router and a server jail. 26538e2d5dbSKristof Provost# The server is capable of responding to pings from tester. 26638e2d5dbSKristof Provostsetup_router_server_ipv6() 26738e2d5dbSKristof Provost{ 26838e2d5dbSKristof Provost setup_router_ipv6 26938e2d5dbSKristof Provost vnet_mkjail server ${epair_server}b 27038e2d5dbSKristof Provost jexec server ifconfig ${epair_server}b inet6 ${net_server_host_server}/${net_server_mask} up no_dad 27138e2d5dbSKristof Provost jexec server route add -6 ${net_tester} ${net_server_host_router} 2726ffd4aebSKajetan Staszkiewicz inetd_conf=$(mktemp) 2736ffd4aebSKajetan Staszkiewicz echo "discard stream tcp6 nowait root internal" > $inetd_conf 274c17a0f62SKristof Provost jexec server inetd -p ${PWD}/inetd.pid $inetd_conf 27538e2d5dbSKristof Provost} 27638e2d5dbSKristof Provost 27738e2d5dbSKristof Provost# Ping the dummy static NDP target. 27838e2d5dbSKristof Provost# Check for pings being forwarded through the router towards the target. 27938e2d5dbSKristof Provostping_dummy_check_request() 28038e2d5dbSKristof Provost{ 28138e2d5dbSKristof Provost exit_condition=$1 28238e2d5dbSKristof Provost shift 28338e2d5dbSKristof Provost params=$@ 28438e2d5dbSKristof Provost atf_check -s ${exit_condition} ${common_dir}/pft_ping.py \ 28538e2d5dbSKristof Provost --sendif ${epair_tester}a \ 28638e2d5dbSKristof Provost --to ${net_server_host_server} \ 28738e2d5dbSKristof Provost --recvif ${epair_server}b \ 28838e2d5dbSKristof Provost $params 28938e2d5dbSKristof Provost} 29038e2d5dbSKristof Provost 29138e2d5dbSKristof Provost# Ping the server jail. 29238e2d5dbSKristof Provost# Check for responses coming back throught the router back to the tester. 29338e2d5dbSKristof Provostping_server_check_reply() 29438e2d5dbSKristof Provost{ 29538e2d5dbSKristof Provost exit_condition=$1 29638e2d5dbSKristof Provost shift 29738e2d5dbSKristof Provost params=$@ 29838e2d5dbSKristof Provost atf_check -s ${exit_condition} ${common_dir}/pft_ping.py \ 29938e2d5dbSKristof Provost --sendif ${epair_tester}a \ 30038e2d5dbSKristof Provost --to ${net_server_host_server} \ 30138e2d5dbSKristof Provost --replyif ${epair_tester}a \ 30238e2d5dbSKristof Provost $params 30338e2d5dbSKristof Provost} 304*65b20771SKajetan Staszkiewicz 305*65b20771SKajetan Staszkiewicznormalize_pfctl_s() 306*65b20771SKajetan Staszkiewicz{ 307*65b20771SKajetan Staszkiewicz # `pfctl -s[rsS]` output is divided into sections. Each rule, state or 308*65b20771SKajetan Staszkiewicz # source node starts with the beginning of a line and next lines with leading 309*65b20771SKajetan Staszkiewicz # spaces are various parameters of said rule, state or source node. 310*65b20771SKajetan Staszkiewicz # Convert it into a single line per entry, and remove multiple spaces, 311*65b20771SKajetan Staszkiewicz # so that regular expressions for matching them in tests can be simpler. 312*65b20771SKajetan Staszkiewicz awk '{ if ($0 ~ /^[^ ]/ && NR > 1) print(""); gsub(/ +/, " ", $0); printf("%s", $0); } END {print("");}' 313*65b20771SKajetan Staszkiewicz} 314