xref: /freebsd/tests/sys/netpfil/pf/pfsync.sh (revision b214fcceacad6b842545150664bd2695c1c2b34f)
1# $FreeBSD$
2#
3# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4#
5# Copyright (c) 2018 Orange Business Services
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27
28. $(atf_get_srcdir)/utils.subr
29
30common_dir=$(atf_get_srcdir)/../common
31
32atf_test_case "basic" "cleanup"
33basic_head()
34{
35	atf_set descr 'Basic pfsync test'
36	atf_set require.user root
37}
38
39basic_body()
40{
41	common_body
42}
43
44common_body()
45{
46	defer=$1
47	pfsynct_init
48
49	epair_sync=$(vnet_mkepair)
50	epair_one=$(vnet_mkepair)
51	epair_two=$(vnet_mkepair)
52
53	vnet_mkjail one ${epair_one}a ${epair_sync}a
54	vnet_mkjail two ${epair_two}a ${epair_sync}b
55
56	# pfsync interface
57	jexec one ifconfig ${epair_sync}a 192.0.2.1/24 up
58	jexec one ifconfig ${epair_one}a 198.51.100.1/24 up
59	jexec one ifconfig pfsync0 \
60		syncdev ${epair_sync}a \
61		maxupd 1 \
62		$defer \
63		up
64	jexec two ifconfig ${epair_two}a 198.51.100.2/24 up
65	jexec two ifconfig ${epair_sync}b 192.0.2.2/24 up
66	jexec two ifconfig pfsync0 \
67		syncdev ${epair_sync}b \
68		maxupd 1 \
69		$defer \
70		up
71
72	# Enable pf!
73	jexec one pfctl -e
74	pft_set_rules one \
75		"set skip on ${epair_sync}a" \
76		"pass keep state"
77	jexec two pfctl -e
78	pft_set_rules two \
79		"set skip on ${epair_sync}b" \
80		"pass keep state"
81
82	ifconfig ${epair_one}b 198.51.100.254/24 up
83
84	ping -c 1 -S 198.51.100.254 198.51.100.1
85
86	# Give pfsync time to do its thing
87	sleep 2
88
89	if ! jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \
90	    grep 198.51.100.2 ; then
91		atf_fail "state not found on synced host"
92	fi
93}
94
95basic_cleanup()
96{
97	pfsynct_cleanup
98}
99
100atf_test_case "basic_defer" "cleanup"
101basic_defer_head()
102{
103	atf_set descr 'Basic defer mode pfsync test'
104	atf_set require.user root
105}
106
107basic_defer_body()
108{
109	common_body defer
110}
111
112basic_defer_cleanup()
113{
114	pfsynct_cleanup
115}
116
117atf_test_case "defer" "cleanup"
118defer_head()
119{
120	atf_set descr 'Defer mode pfsync test'
121	atf_set require.user root
122}
123
124defer_body()
125{
126	pfsynct_init
127
128	epair_sync=$(vnet_mkepair)
129	epair_in=$(vnet_mkepair)
130	epair_out=$(vnet_mkepair)
131
132	vnet_mkjail alcatraz ${epair_sync}a ${epair_in}a ${epair_out}a
133
134	jexec alcatraz ifconfig ${epair_sync}a 192.0.2.1/24 up
135	jexec alcatraz ifconfig ${epair_out}a 198.51.100.1/24 up
136	jexec alcatraz ifconfig ${epair_in}a 203.0.113.1/24 up
137	jexec alcatraz arp -s 203.0.113.2 00:01:02:03:04:05
138	jexec alcatraz sysctl net.inet.ip.forwarding=1
139
140	jexec alcatraz ifconfig pfsync0 \
141		syncdev ${epair_sync}a \
142		maxupd 1 \
143		defer \
144		up
145
146	ifconfig ${epair_sync}b 192.0.2.2/24 up
147	ifconfig ${epair_out}b 198.51.100.2/24 up
148	ifconfig ${epair_in}b up
149	route add -net 203.0.113.0/24 198.51.100.1
150
151	# Enable pf
152	jexec alcatraz pfctl -e
153	pft_set_rules alcatraz \
154		"set skip on ${epair_sync}a" \
155		"pass keep state"
156
157	atf_check -s exit:0 env PYTHONPATH=${common_dir} \
158		$(atf_get_srcdir)/pfsync_defer.py \
159		--syncdev ${epair_sync}b \
160		--indev ${epair_in}b \
161		--outdev ${epair_out}b
162
163	# Now disable defer mode and expect failure.
164	jexec alcatraz ifconfig pfsync0 -defer
165
166	# Flush state
167	pft_set_rules alcatraz \
168		"set skip on ${epair_sync}a" \
169		"pass keep state"
170
171	atf_check -s exit:1 env PYTHONPATH=${common_dir} \
172		$(atf_get_srcdir)/pfsync_defer.py \
173		--syncdev ${epair_sync}b \
174		--indev ${epair_in}b \
175		--outdev ${epair_out}b
176}
177
178defer_cleanup()
179{
180	pfsynct_cleanup
181}
182
183atf_test_case "bulk" "cleanup"
184bulk_head()
185{
186	atf_set descr 'Test bulk updates'
187	atf_set require.user root
188}
189
190bulk_body()
191{
192	pfsynct_init
193
194	epair_sync=$(vnet_mkepair)
195	epair_one=$(vnet_mkepair)
196	epair_two=$(vnet_mkepair)
197
198	vnet_mkjail one ${epair_one}a ${epair_sync}a
199	vnet_mkjail two ${epair_two}a ${epair_sync}b
200
201	# pfsync interface
202	jexec one ifconfig ${epair_sync}a 192.0.2.1/24 up
203	jexec one ifconfig ${epair_one}a 198.51.100.1/24 up
204	jexec one ifconfig pfsync0 \
205		syncdev ${epair_sync}a \
206		maxupd 1\
207		up
208	jexec two ifconfig ${epair_two}a 198.51.100.2/24 up
209	jexec two ifconfig ${epair_sync}b 192.0.2.2/24 up
210
211	# Enable pf
212	jexec one pfctl -e
213	pft_set_rules one \
214		"set skip on ${epair_sync}a" \
215		"pass keep state"
216	jexec two pfctl -e
217	pft_set_rules two \
218		"set skip on ${epair_sync}b" \
219		"pass keep state"
220
221	ifconfig ${epair_one}b 198.51.100.254/24 up
222
223	# Create state prior to setting up pfsync
224	ping -c 1 -S 198.51.100.254 198.51.100.1
225
226	# Wait before setting up pfsync on two, so we don't accidentally catch
227	# the update anyway.
228	sleep 1
229
230	# Now set up pfsync in jail two
231	jexec two ifconfig pfsync0 \
232		syncdev ${epair_sync}b \
233		up
234
235	# Give pfsync time to do its thing
236	sleep 2
237
238	jexec two pfctl -s states
239	if ! jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \
240	    grep 198.51.100.2 ; then
241		atf_fail "state not found on synced host"
242	fi
243}
244
245bulk_cleanup()
246{
247	pfsynct_cleanup
248}
249
250atf_init_test_cases()
251{
252	atf_add_test_case "basic"
253	atf_add_test_case "basic_defer"
254	atf_add_test_case "defer"
255	atf_add_test_case "bulk"
256}
257