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