xref: /freebsd/tests/sys/netpfil/pf/utils.subr (revision 22cf89c938886d14f5796fc49f9f020c23ea8eaf)
1# Utility functions
2##
3# SPDX-License-Identifier: BSD-2-Clause
4#
5# Copyright (c) 2017 Kristof Provost <kp@FreeBSD.org>
6# Copyright (c) 2023 Kajetan Staszkiewicz <vegeta@tuxpowered.net>
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions
10# are met:
11# 1. Redistributions of source code must retain the above copyright
12#    notice, this list of conditions and the following disclaimer.
13# 2. Redistributions in binary form must reproduce the above copyright
14#    notice, this list of conditions and the following disclaimer in the
15#    documentation and/or other materials provided with the distribution.
16#
17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27# SUCH DAMAGE.
28
29. $(atf_get_srcdir)/../../common/vnet.subr
30common_dir=$(atf_get_srcdir)/../common
31
32pft_onerror()
33{
34	status=$?
35
36	echo "Debug log."
37	echo "=========="
38	echo "Test exit status: $?"
39	echo
40
41	if [ -f created_jails.lst ]; then
42		for jailname in `cat created_jails.lst`
43		do
44			echo "Jail ${jailname}"
45			echo "----------------"
46			jexec ${jailname} ifconfig
47			jexec ${jailname} netstat -rn
48			jexec ${jailname} pfctl -sa -v
49		done
50	fi
51
52	echo "Created interfaces:"
53	echo "-------------------"
54	cat created_interfaces.lst
55
56	echo "Host interfaces:"
57	echo "----------------"
58	ifconfig
59}
60
61pft_init()
62{
63	if [ "$1" == "debug" ]
64	then
65		trap pft_onerror EXIT
66	fi
67
68	vnet_init
69
70	if [ ! -c /dev/pf ]; then
71		atf_skip "This test requires pf"
72	fi
73}
74
75pfsynct_init()
76{
77	pft_init
78
79	if ! kldstat -q -m pfsync; then
80		atf_skip "This test requires pfsync"
81	fi
82}
83
84pflog_init()
85{
86	if ! kldstat -q -m pflog; then
87		atf_skip "This test requires pflog"
88	fi
89}
90
91dummynet_init()
92{
93	pft_init
94
95	if ! kldstat -q -m dummynet; then
96		atf_skip "This test requires dummynet"
97	fi
98}
99
100pft_set_rules()
101{
102	jname=$1
103	shift
104
105	if [ $jname == "noflush" ];
106	then
107		jname=$1
108		shift
109	else
110		# Flush all states, rules, fragments, ...
111		jexec ${jname} pfctl -F all
112	fi
113
114	while [ $# -gt 0 ]; do
115		printf "$1\n"
116		shift
117	done | jexec ${jname} pfctl -f -
118	if [ $? -ne 0 ];
119	then
120		atf_fail "Failed to set PF rules in ${jname}"
121	fi
122}
123
124pft_cleanup()
125{
126	vnet_cleanup
127}
128
129pfsynct_cleanup()
130{
131	pft_cleanup
132}
133
134is_altq_supported()
135{
136	sysctl -q kern.features.altq >/dev/null || \
137	    atf_skip "Test requires ALTQ"
138
139	while [ -n "$1" ]
140	do
141		sysctl -q kern.features.altq.${1} >/dev/null || \
142		    atf_skip "Test required ALTQ_${1}"
143		shift
144	done
145}
146
147altq_init()
148{
149	pft_init
150	is_altq_supported
151}
152
153altq_cleanup()
154{
155	pft_cleanup
156}
157
158# Create a bare router jail.
159# This function lacks target configuration.
160setup_router_ipv4()
161{
162	pft_init
163
164	epair_tester=$(vnet_mkepair)
165	epair_server=$(vnet_mkepair)
166
167	net_tester=192.0.2.0/24
168	net_tester_mask=24
169	net_tester_host_router=192.0.2.1
170	net_tester_host_tester=192.0.2.2
171
172	net_server=198.51.100.0/24
173	net_server_mask=24
174	net_server_host_router=198.51.100.1
175	net_server_host_server=198.51.100.2
176
177	vnet_mkjail router ${epair_tester}b ${epair_server}a
178
179	ifconfig ${epair_tester}a ${net_tester_host_tester}/${net_tester_mask} up
180	route add -net ${net_server} ${net_tester_host_router}
181
182	jexec router ifconfig ${epair_tester}b ${net_tester_host_router}/${net_tester_mask} up
183	jexec router sysctl net.inet.ip.forwarding=1
184	jexec router ifconfig ${epair_server}a ${net_server_host_router}/${net_server_mask} up
185
186	jexec router pfctl -e
187}
188
189# Create a router jail.
190# The target for tests does not exist but a static ARP entry does
191# so packets to it can be properly routed.
192setup_router_dummy_ipv4()
193{
194	setup_router_ipv4
195	jexec router arp -s ${net_server_host_server} 00:01:02:03:04:05
196	ifconfig ${epair_server}b up
197}
198
199# Create a router and a server jail.
200# The server is capable of responding to pings from the tester.
201setup_router_server_ipv4()
202{
203	setup_router_ipv4
204	vnet_mkjail server ${epair_server}b
205	jexec server ifconfig ${epair_server}b ${net_server_host_server}/${net_server_mask} up
206	jexec server route add -net ${net_tester} ${net_server_host_router}
207	jexec server nc -4l 666 &
208	sleep 1 # Give nc time to start and listen
209}
210
211# Create a bare router jail.
212# This function lacks target configuration.
213setup_router_ipv6()
214{
215	pft_init
216
217	epair_tester=$(vnet_mkepair)
218	epair_server=$(vnet_mkepair)
219
220	net_tester=2001:db8:42::/64
221	net_tester_mask=64
222	net_tester_host_router=2001:db8:42::1
223	net_tester_host_tester=2001:db8:42::2
224
225	net_server=2001:db8:43::/64
226	net_server_mask=64
227	net_server_host_router=2001:db8:43::1
228	net_server_host_server=2001:db8:43::2
229
230	vnet_mkjail router ${epair_tester}b ${epair_server}a
231
232	ifconfig ${epair_tester}a inet6 ${net_tester_host_tester}/${net_tester_mask}up no_dad
233	route add -6 ${net_server} ${net_tester_host_router}
234
235	jexec router ifconfig ${epair_tester}b inet6 ${net_tester_host_router}/${net_tester_mask} up no_dad
236	jexec router sysctl net.inet6.ip6.forwarding=1
237	jexec router ifconfig ${epair_server}a inet6 ${net_server_host_router}/${net_server_mask} up no_dad
238
239	jexec router pfctl -e
240}
241
242# Create a router jail.
243# The target for tests does not exist but a static NDP entry does
244# so packets to it can be properly routed.
245setup_router_dummy_ipv6()
246{
247	setup_router_ipv6
248	jexec router ndp -s ${net_server_host_server} 00:01:02:03:04:05
249	ifconfig ${epair_server}b up
250}
251
252# Create a router and a server jail.
253# The server is capable of responding to pings from tester.
254setup_router_server_ipv6()
255{
256	setup_router_ipv6
257	vnet_mkjail server ${epair_server}b
258	jexec server ifconfig ${epair_server}b inet6 ${net_server_host_server}/${net_server_mask} up no_dad
259	jexec server route add -6 ${net_tester} ${net_server_host_router}
260	jexec server nc -6l 666 &
261	sleep 1 # Give nc time to start and listen
262}
263
264# Ping the dummy static NDP target.
265# Check for pings being forwarded through the router towards the target.
266ping_dummy_check_request()
267{
268	exit_condition=$1
269	shift
270	params=$@
271	atf_check -s ${exit_condition} ${common_dir}/pft_ping.py \
272	    --sendif ${epair_tester}a \
273	    --to ${net_server_host_server} \
274	    --recvif ${epair_server}b \
275	$params
276}
277
278# Ping the server jail.
279# Check for responses coming back throught the router back to the tester.
280ping_server_check_reply()
281{
282	exit_condition=$1
283	shift
284	params=$@
285	atf_check -s ${exit_condition} ${common_dir}/pft_ping.py \
286	    --sendif ${epair_tester}a \
287	    --to ${net_server_host_server} \
288	    --replyif ${epair_tester}a \
289	$params
290}
291