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