xref: /freebsd/tests/sys/netpfil/pf/utils.subr (revision ba7b7f94c239ce43343d7af403734fdc941b7664)
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
91pflow_init()
92{
93	pft_init
94
95	if ! kldstat -q -m pflow; then
96		atf_skip "This test requires pflow"
97	fi
98}
99
100dummynet_init()
101{
102	pft_init
103
104	if ! kldstat -q -m dummynet; then
105		atf_skip "This test requires dummynet"
106	fi
107}
108
109pft_set_rules()
110{
111	jname=$1
112	shift
113
114	if [ $jname == "noflush" ];
115	then
116		jname=$1
117		shift
118	else
119		# Flush all states, rules, fragments, ...
120		jexec ${jname} pfctl -F all
121	fi
122
123	while [ $# -gt 0 ]; do
124		printf "$1\n"
125		shift
126	done | jexec ${jname} pfctl -f -
127	if [ $? -ne 0 ];
128	then
129		atf_fail "Failed to set PF rules in ${jname}"
130	fi
131}
132
133pft_cleanup()
134{
135	vnet_cleanup
136}
137
138pfsynct_cleanup()
139{
140	pft_cleanup
141}
142
143is_altq_supported()
144{
145	sysctl -q kern.features.altq >/dev/null || \
146	    atf_skip "Test requires ALTQ"
147
148	while [ -n "$1" ]
149	do
150		sysctl -q kern.features.altq.${1} >/dev/null || \
151		    atf_skip "Test required ALTQ_${1}"
152		shift
153	done
154}
155
156altq_init()
157{
158	pft_init
159	is_altq_supported
160}
161
162altq_cleanup()
163{
164	pft_cleanup
165}
166
167# Create a bare router jail.
168# This function lacks target configuration.
169setup_router_ipv4()
170{
171	pft_init
172
173	epair_tester=$(vnet_mkepair)
174	epair_server=$(vnet_mkepair)
175
176	net_tester=192.0.2.0/24
177	net_tester_mask=24
178	net_tester_host_router=192.0.2.1
179	net_tester_host_tester=192.0.2.2
180
181	net_server=198.51.100.0/24
182	net_server_mask=24
183	net_server_host_router=198.51.100.1
184	net_server_host_server=198.51.100.2
185
186	vnet_mkjail router ${epair_tester}b ${epair_server}a
187
188	ifconfig ${epair_tester}a ${net_tester_host_tester}/${net_tester_mask} up
189	route add -net ${net_server} ${net_tester_host_router}
190
191	jexec router ifconfig ${epair_tester}b ${net_tester_host_router}/${net_tester_mask} up
192	jexec router sysctl net.inet.ip.forwarding=1
193	jexec router ifconfig ${epair_server}a ${net_server_host_router}/${net_server_mask} up
194
195	jexec router pfctl -e
196}
197
198# Create a router jail.
199# The target for tests does not exist but a static ARP entry does
200# so packets to it can be properly routed.
201setup_router_dummy_ipv4()
202{
203	setup_router_ipv4
204	jexec router arp -s ${net_server_host_server} 00:01:02:03:04:05
205	ifconfig ${epair_server}b up
206}
207
208# Create a router and a server jail.
209# The server is capable of responding to pings from the tester.
210setup_router_server_ipv4()
211{
212	setup_router_ipv4
213	vnet_mkjail server ${epair_server}b
214	jexec server ifconfig ${epair_server}b ${net_server_host_server}/${net_server_mask} up
215	jexec server route add -net ${net_tester} ${net_server_host_router}
216	jexec server nc -4l 666 &
217	sleep 1 # Give nc time to start and listen
218}
219
220# Create a bare router jail.
221# This function lacks target configuration.
222setup_router_ipv6()
223{
224	pft_init
225
226	epair_tester=$(vnet_mkepair)
227	epair_server=$(vnet_mkepair)
228
229	net_tester=2001:db8:42::/64
230	net_tester_mask=64
231	net_tester_host_router=2001:db8:42::1
232	net_tester_host_tester=2001:db8:42::2
233
234	net_server=2001:db8:43::/64
235	net_server_mask=64
236	net_server_host_router=2001:db8:43::1
237	net_server_host_server=2001:db8:43::2
238
239	vnet_mkjail router ${epair_tester}b ${epair_server}a
240
241	ifconfig ${epair_tester}a inet6 ${net_tester_host_tester}/${net_tester_mask}up no_dad
242	route add -6 ${net_server} ${net_tester_host_router}
243
244	jexec router ifconfig ${epair_tester}b inet6 ${net_tester_host_router}/${net_tester_mask} up no_dad
245	jexec router sysctl net.inet6.ip6.forwarding=1
246	jexec router ifconfig ${epair_server}a inet6 ${net_server_host_router}/${net_server_mask} up no_dad
247
248	jexec router pfctl -e
249}
250
251# Create a router jail.
252# The target for tests does not exist but a static NDP entry does
253# so packets to it can be properly routed.
254setup_router_dummy_ipv6()
255{
256	setup_router_ipv6
257	jexec router ndp -s ${net_server_host_server} 00:01:02:03:04:05
258	ifconfig ${epair_server}b up
259}
260
261# Create a router and a server jail.
262# The server is capable of responding to pings from tester.
263setup_router_server_ipv6()
264{
265	setup_router_ipv6
266	vnet_mkjail server ${epair_server}b
267	jexec server ifconfig ${epair_server}b inet6 ${net_server_host_server}/${net_server_mask} up no_dad
268	jexec server route add -6 ${net_tester} ${net_server_host_router}
269	jexec server nc -6l 666 &
270	sleep 1 # Give nc time to start and listen
271}
272
273# Ping the dummy static NDP target.
274# Check for pings being forwarded through the router towards the target.
275ping_dummy_check_request()
276{
277	exit_condition=$1
278	shift
279	params=$@
280	atf_check -s ${exit_condition} ${common_dir}/pft_ping.py \
281	    --sendif ${epair_tester}a \
282	    --to ${net_server_host_server} \
283	    --recvif ${epair_server}b \
284	$params
285}
286
287# Ping the server jail.
288# Check for responses coming back throught the router back to the tester.
289ping_server_check_reply()
290{
291	exit_condition=$1
292	shift
293	params=$@
294	atf_check -s ${exit_condition} ${common_dir}/pft_ping.py \
295	    --sendif ${epair_tester}a \
296	    --to ${net_server_host_server} \
297	    --replyif ${epair_tester}a \
298	$params
299}
300