xref: /freebsd/tests/sys/netpfil/pf/pfsync.sh (revision 22cf89c938886d14f5796fc49f9f020c23ea8eaf)
1#
2# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright (c) 2018 Orange Business Services
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26
27. $(atf_get_srcdir)/utils.subr
28
29common_dir=$(atf_get_srcdir)/../common
30
31atf_test_case "basic" "cleanup"
32basic_head()
33{
34	atf_set descr 'Basic pfsync test'
35	atf_set require.user root
36}
37
38basic_body()
39{
40	common_body
41}
42
43common_body()
44{
45	defer=$1
46	pfsynct_init
47
48	epair_sync=$(vnet_mkepair)
49	epair_one=$(vnet_mkepair)
50	epair_two=$(vnet_mkepair)
51
52	vnet_mkjail one ${epair_one}a ${epair_sync}a
53	vnet_mkjail two ${epair_two}a ${epair_sync}b
54
55	# pfsync interface
56	jexec one ifconfig ${epair_sync}a 192.0.2.1/24 up
57	jexec one ifconfig ${epair_one}a 198.51.100.1/24 up
58	jexec one ifconfig pfsync0 \
59		syncdev ${epair_sync}a \
60		maxupd 1 \
61		$defer \
62		up
63	jexec two ifconfig ${epair_two}a 198.51.100.2/24 up
64	jexec two ifconfig ${epair_sync}b 192.0.2.2/24 up
65	jexec two ifconfig pfsync0 \
66		syncdev ${epair_sync}b \
67		maxupd 1 \
68		$defer \
69		up
70
71	# Enable pf!
72	jexec one pfctl -e
73	pft_set_rules one \
74		"set skip on ${epair_sync}a" \
75		"pass out keep state"
76	jexec two pfctl -e
77	pft_set_rules two \
78		"set skip on ${epair_sync}b" \
79		"pass out keep state"
80
81	ifconfig ${epair_one}b 198.51.100.254/24 up
82
83	ping -c 1 -S 198.51.100.254 198.51.100.1
84
85	# Give pfsync time to do its thing
86	sleep 2
87
88	if ! jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \
89	    grep 198.51.100.254 ; then
90		atf_fail "state not found on synced host"
91	fi
92}
93
94basic_cleanup()
95{
96	pfsynct_cleanup
97}
98
99atf_test_case "basic_defer" "cleanup"
100basic_defer_head()
101{
102	atf_set descr 'Basic defer mode pfsync test'
103	atf_set require.user root
104}
105
106basic_defer_body()
107{
108	common_body defer
109}
110
111basic_defer_cleanup()
112{
113	pfsynct_cleanup
114}
115
116atf_test_case "defer" "cleanup"
117defer_head()
118{
119	atf_set descr 'Defer mode pfsync test'
120	atf_set require.user root
121}
122
123defer_body()
124{
125	pfsynct_init
126
127	epair_sync=$(vnet_mkepair)
128	epair_in=$(vnet_mkepair)
129	epair_out=$(vnet_mkepair)
130
131	vnet_mkjail alcatraz ${epair_sync}a ${epair_in}a ${epair_out}a
132
133	jexec alcatraz ifconfig ${epair_sync}a 192.0.2.1/24 up
134	jexec alcatraz ifconfig ${epair_out}a 198.51.100.1/24 up
135	jexec alcatraz ifconfig ${epair_in}a 203.0.113.1/24 up
136	jexec alcatraz arp -s 203.0.113.2 00:01:02:03:04:05
137	jexec alcatraz sysctl net.inet.ip.forwarding=1
138
139	# Set a long defer delay
140	jexec alcatraz sysctl net.pfsync.defer_delay=2500
141
142	jexec alcatraz ifconfig pfsync0 \
143		syncdev ${epair_sync}a \
144		maxupd 1 \
145		defer \
146		up
147
148	ifconfig ${epair_sync}b 192.0.2.2/24 up
149	ifconfig ${epair_out}b 198.51.100.2/24 up
150	ifconfig ${epair_in}b up
151	route add -net 203.0.113.0/24 198.51.100.1
152
153	# Enable pf
154	jexec alcatraz sysctl net.pf.filter_local=0
155	jexec alcatraz pfctl -e
156	pft_set_rules alcatraz \
157		"set skip on ${epair_sync}a" \
158		"pass keep state"
159
160	atf_check -s exit:0 env PYTHONPATH=${common_dir} \
161		$(atf_get_srcdir)/pfsync_defer.py \
162		--syncdev ${epair_sync}b \
163		--indev ${epair_in}b \
164		--outdev ${epair_out}b
165
166	# Now disable defer mode and expect failure.
167	jexec alcatraz ifconfig pfsync0 -defer
168
169	# Flush state
170	pft_set_rules alcatraz \
171		"set skip on ${epair_sync}a" \
172		"pass keep state"
173
174	atf_check -s exit:3 env PYTHONPATH=${common_dir} \
175		$(atf_get_srcdir)/pfsync_defer.py \
176		--syncdev ${epair_sync}b \
177		--indev ${epair_in}b \
178		--outdev ${epair_out}b
179}
180
181defer_cleanup()
182{
183	pfsynct_cleanup
184}
185
186atf_test_case "bulk" "cleanup"
187bulk_head()
188{
189	atf_set descr 'Test bulk updates'
190	atf_set require.user root
191}
192
193bulk_body()
194{
195	pfsynct_init
196
197	epair_sync=$(vnet_mkepair)
198	epair_one=$(vnet_mkepair)
199	epair_two=$(vnet_mkepair)
200
201	vnet_mkjail one ${epair_one}a ${epair_sync}a
202	vnet_mkjail two ${epair_two}a ${epair_sync}b
203
204	# pfsync interface
205	jexec one ifconfig ${epair_sync}a 192.0.2.1/24 up
206	jexec one ifconfig ${epair_one}a 198.51.100.1/24 up
207	jexec one ifconfig pfsync0 \
208		syncdev ${epair_sync}a \
209		maxupd 1\
210		up
211	jexec two ifconfig ${epair_two}a 198.51.100.2/24 up
212	jexec two ifconfig ${epair_sync}b 192.0.2.2/24 up
213
214	# Enable pf
215	jexec one pfctl -e
216	pft_set_rules one \
217		"set skip on ${epair_sync}a" \
218		"pass keep state"
219	jexec two pfctl -e
220	pft_set_rules two \
221		"set skip on ${epair_sync}b" \
222		"pass keep state"
223
224	ifconfig ${epair_one}b 198.51.100.254/24 up
225
226	# Create state prior to setting up pfsync
227	ping -c 1 -S 198.51.100.254 198.51.100.1
228
229	# Wait before setting up pfsync on two, so we don't accidentally catch
230	# the update anyway.
231	sleep 1
232
233	# Now set up pfsync in jail two
234	jexec two ifconfig pfsync0 \
235		syncdev ${epair_sync}b \
236		up
237
238	# Give pfsync time to do its thing
239	sleep 2
240
241	jexec two pfctl -s states
242	if ! jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \
243	    grep 198.51.100.2 ; then
244		atf_fail "state not found on synced host"
245	fi
246}
247
248bulk_cleanup()
249{
250	pfsynct_cleanup
251}
252
253atf_test_case "pbr" "cleanup"
254pbr_head()
255{
256	atf_set descr 'route_to and reply_to directives test'
257	atf_set require.user root
258	atf_set timeout '600'
259}
260
261pbr_body()
262{
263	pbr_common_body
264}
265
266pbr_cleanup()
267{
268	pbr_common_cleanup
269}
270
271atf_test_case "pfsync_pbr" "cleanup"
272pfsync_pbr_head()
273{
274	atf_set descr 'route_to and reply_to directives pfsync test'
275	atf_set require.user root
276	atf_set timeout '600'
277}
278
279pfsync_pbr_body()
280{
281	pbr_common_body backup_promotion
282}
283
284pfsync_pbr_cleanup()
285{
286	pbr_common_cleanup
287}
288
289pbr_common_body()
290{
291	# + builds bellow topology and initiate a single ping session
292	#   from client to server.
293	# + gw* forward traffic through pbr not fib lookups.
294	# + if backup_promotion arg is given, a carp failover event occurs
295	#   during the ping session on both gateways.
296	#                   ┌──────┐
297	#                   │client│
298	#                   └───┬──┘
299	#                       │
300	#                   ┌───┴───┐
301	#                   │bridge0│
302	#                   └┬─────┬┘
303	#                    │     │
304	#   ┌────────────────┴─┐ ┌─┴────────────────┐
305	#   │gw_route_to_master├─┤gw_route_to_backup│
306	#   └────────────────┬─┘ └─┬────────────────┘
307	#                    │     │
308	#                   ┌┴─────┴┐
309	#                   │bridge1│
310	#                   └┬─────┬┘
311	#                    │     │
312	#   ┌────────────────┴─┐ ┌─┴────────────────┐
313	#   │gw_reply_to_master├─┤gw_reply_to_backup│
314	#   └────────────────┬─┘ └─┬────────────────┘
315	#                    │     │
316	#                   ┌┴─────┴┐
317	#                   │bridge2│
318	#                   └───┬───┘
319	#                       │
320	#                   ┌───┴──┐
321	#                   │server│
322	#                   └──────┘
323
324	if ! kldstat -q -m carp
325	then
326		atf_skip "This test requires carp"
327	fi
328	pfsynct_init
329
330	bridge0=$(vnet_mkbridge)
331	bridge1=$(vnet_mkbridge)
332	bridge2=$(vnet_mkbridge)
333
334	epair_sync_gw_route_to=$(vnet_mkepair)
335	epair_sync_gw_reply_to=$(vnet_mkepair)
336	epair_client_bridge0=$(vnet_mkepair)
337
338	epair_gw_route_to_master_bridge0=$(vnet_mkepair)
339	epair_gw_route_to_backup_bridge0=$(vnet_mkepair)
340	epair_gw_route_to_master_bridge1=$(vnet_mkepair)
341	epair_gw_route_to_backup_bridge1=$(vnet_mkepair)
342
343	epair_gw_reply_to_master_bridge1=$(vnet_mkepair)
344	epair_gw_reply_to_backup_bridge1=$(vnet_mkepair)
345	epair_gw_reply_to_master_bridge2=$(vnet_mkepair)
346	epair_gw_reply_to_backup_bridge2=$(vnet_mkepair)
347
348	epair_server_bridge2=$(vnet_mkepair)
349
350	ifconfig ${bridge0} up
351	ifconfig ${epair_client_bridge0}b up
352	ifconfig ${epair_gw_route_to_master_bridge0}b up
353	ifconfig ${epair_gw_route_to_backup_bridge0}b up
354	ifconfig ${bridge0} \
355		addm ${epair_client_bridge0}b \
356		addm ${epair_gw_route_to_master_bridge0}b \
357		addm ${epair_gw_route_to_backup_bridge0}b
358
359	ifconfig ${bridge1} up
360	ifconfig ${epair_gw_route_to_master_bridge1}b up
361	ifconfig ${epair_gw_route_to_backup_bridge1}b up
362	ifconfig ${epair_gw_reply_to_master_bridge1}b up
363	ifconfig ${epair_gw_reply_to_backup_bridge1}b up
364	ifconfig ${bridge1} \
365		addm ${epair_gw_route_to_master_bridge1}b \
366		addm ${epair_gw_route_to_backup_bridge1}b \
367		addm ${epair_gw_reply_to_master_bridge1}b \
368		addm ${epair_gw_reply_to_backup_bridge1}b
369
370	ifconfig ${bridge2} up
371	ifconfig ${epair_gw_reply_to_master_bridge2}b up
372	ifconfig ${epair_gw_reply_to_backup_bridge2}b up
373	ifconfig ${epair_server_bridge2}b up
374	ifconfig ${bridge2} \
375		addm ${epair_gw_reply_to_master_bridge2}b \
376		addm ${epair_gw_reply_to_backup_bridge2}b \
377		addm ${epair_server_bridge2}b
378
379	vnet_mkjail client ${epair_client_bridge0}a
380	jexec client hostname client
381	vnet_mkjail gw_route_to_master \
382		${epair_gw_route_to_master_bridge0}a \
383		${epair_gw_route_to_master_bridge1}a \
384		${epair_sync_gw_route_to}a
385	jexec gw_route_to_master hostname gw_route_to_master
386	vnet_mkjail gw_route_to_backup \
387		${epair_gw_route_to_backup_bridge0}a \
388		${epair_gw_route_to_backup_bridge1}a \
389		${epair_sync_gw_route_to}b
390	jexec gw_route_to_backup hostname gw_route_to_backup
391	vnet_mkjail gw_reply_to_master \
392		${epair_gw_reply_to_master_bridge1}a \
393		${epair_gw_reply_to_master_bridge2}a \
394		${epair_sync_gw_reply_to}a
395	jexec gw_reply_to_master hostname gw_reply_to_master
396	vnet_mkjail gw_reply_to_backup \
397		${epair_gw_reply_to_backup_bridge1}a \
398		${epair_gw_reply_to_backup_bridge2}a \
399		${epair_sync_gw_reply_to}b
400	jexec gw_reply_to_backup hostname gw_reply_to_backup
401	vnet_mkjail server ${epair_server_bridge2}a
402	jexec server hostname server
403
404	jexec client ifconfig ${epair_client_bridge0}a inet 198.18.0.1/24 up
405	jexec client route add 198.18.2.0/24 198.18.0.10
406
407	jexec gw_route_to_master ifconfig ${epair_sync_gw_route_to}a \
408		inet 198.19.10.1/24 up
409	jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge0}a \
410		inet 198.18.0.8/24 up
411	jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge0}a \
412		alias 198.18.0.10/32 vhid 10 pass 3WjvVVw7 advskew 50
413	jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge1}a \
414		inet 198.18.1.8/24 up
415	jexec gw_route_to_master ifconfig ${epair_gw_route_to_master_bridge1}a \
416		alias 198.18.1.10/32 vhid 11 pass 3WjvVVw7 advskew 50
417	jexec gw_route_to_master sysctl net.inet.ip.forwarding=1
418	jexec gw_route_to_master sysctl net.inet.carp.preempt=1
419
420	vnet_ifrename_jail gw_route_to_master ${epair_sync_gw_route_to}a if_pfsync
421	vnet_ifrename_jail gw_route_to_master ${epair_gw_route_to_master_bridge0}a if_br0
422	vnet_ifrename_jail gw_route_to_master ${epair_gw_route_to_master_bridge1}a if_br1
423
424	jexec gw_route_to_master ifconfig pfsync0 \
425		syncpeer 198.19.10.2 \
426		syncdev if_pfsync \
427		maxupd 1 \
428		up
429	pft_set_rules gw_route_to_master \
430		"keep_state = 'tag auth_packet keep state'" \
431		"set timeout { icmp.first 120, icmp.error 60 }" \
432		"block log all" \
433		"pass quick on if_pfsync proto pfsync keep state (no-sync)" \
434		"pass quick on { if_br0 if_br1 } proto carp keep state (no-sync)" \
435		"block drop in quick to 224.0.0.18/32" \
436		"pass out quick tagged auth_packet keep state" \
437		"pass in quick log on if_br0 route-to (if_br1 198.18.1.20) proto { icmp udp tcp } from 198.18.0.0/24 to 198.18.2.0/24 \$keep_state"
438	jexec gw_route_to_master pfctl -e
439
440	jexec gw_route_to_backup ifconfig ${epair_sync_gw_route_to}b \
441		inet 198.19.10.2/24 up
442	jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge0}a \
443		inet 198.18.0.9/24 up
444	jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge0}a \
445		alias 198.18.0.10/32 vhid 10 pass 3WjvVVw7 advskew 100
446	jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge1}a \
447		inet 198.18.1.9/24 up
448	jexec gw_route_to_backup ifconfig ${epair_gw_route_to_backup_bridge1}a \
449		alias 198.18.1.10/32 vhid 11 pass 3WjvVVw7 advskew 100
450	jexec gw_route_to_backup sysctl net.inet.ip.forwarding=1
451	jexec gw_route_to_backup sysctl net.inet.carp.preempt=1
452
453	vnet_ifrename_jail gw_route_to_backup ${epair_sync_gw_route_to}b if_pfsync
454	vnet_ifrename_jail gw_route_to_backup ${epair_gw_route_to_backup_bridge0}a if_br0
455	vnet_ifrename_jail gw_route_to_backup ${epair_gw_route_to_backup_bridge1}a if_br1
456
457	jexec gw_route_to_backup ifconfig pfsync0 \
458		syncpeer 198.19.10.1 \
459		syncdev if_pfsync \
460		up
461	pft_set_rules gw_route_to_backup \
462		"keep_state = 'tag auth_packet keep state'" \
463		"set timeout { icmp.first 120, icmp.error 60 }" \
464		"block log all" \
465		"pass quick on if_pfsync proto pfsync keep state (no-sync)" \
466		"pass quick on { if_br0 if_br1 } proto carp keep state (no-sync)" \
467		"block drop in quick to 224.0.0.18/32" \
468		"pass out quick tagged auth_packet keep state" \
469		"pass in quick log on if_br0 route-to (if_br1 198.18.1.20) proto { icmp udp tcp } from 198.18.0.0/24 to 198.18.2.0/24 \$keep_state"
470	jexec gw_route_to_backup pfctl -e
471
472	jexec gw_reply_to_master ifconfig ${epair_sync_gw_reply_to}a \
473		inet 198.19.20.1/24 up
474	jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge1}a \
475		inet 198.18.1.18/24 up
476	jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge1}a \
477		alias 198.18.1.20/32 vhid 21 pass 3WjvVVw7 advskew 50
478	jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge2}a \
479		inet 198.18.2.18/24 up
480	jexec gw_reply_to_master ifconfig ${epair_gw_reply_to_master_bridge2}a \
481		alias 198.18.2.20/32 vhid 22 pass 3WjvVVw7 advskew 50
482	jexec gw_reply_to_master sysctl net.inet.ip.forwarding=1
483	jexec gw_reply_to_master sysctl net.inet.carp.preempt=1
484
485	vnet_ifrename_jail gw_reply_to_master ${epair_sync_gw_reply_to}a if_pfsync
486	vnet_ifrename_jail gw_reply_to_master ${epair_gw_reply_to_master_bridge1}a if_br1
487	vnet_ifrename_jail gw_reply_to_master ${epair_gw_reply_to_master_bridge2}a if_br2
488
489	jexec gw_reply_to_master ifconfig pfsync0 \
490		syncpeer 198.19.20.2 \
491		syncdev if_pfsync \
492		maxupd 1 \
493		up
494	pft_set_rules gw_reply_to_master \
495		"set timeout { icmp.first 120, icmp.error 60 }" \
496		"block log all" \
497		"pass quick on if_pfsync proto pfsync keep state (no-sync)" \
498		"pass quick on { if_br1 if_br2 } proto carp keep state (no-sync)" \
499		"block drop in quick to 224.0.0.18/32" \
500		"pass out quick on if_br2 reply-to (if_br1 198.18.1.10) tagged auth_packet_reply_to keep state" \
501		"pass in quick log on if_br1 proto { icmp udp tcp } from 198.18.0.0/24 to 198.18.2.0/24 tag auth_packet_reply_to keep state"
502	jexec gw_reply_to_master pfctl -e
503
504	jexec gw_reply_to_backup ifconfig ${epair_sync_gw_reply_to}b \
505		inet 198.19.20.2/24 up
506	jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge1}a \
507		inet 198.18.1.19/24 up
508	jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge1}a \
509		alias 198.18.1.20/32 vhid 21 pass 3WjvVVw7 advskew 100
510	jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge2}a \
511		inet 198.18.2.19/24 up
512	jexec gw_reply_to_backup ifconfig ${epair_gw_reply_to_backup_bridge2}a \
513		alias 198.18.2.20/32 vhid 22 pass 3WjvVVw7 advskew 100
514	jexec gw_reply_to_backup sysctl net.inet.ip.forwarding=1
515	jexec gw_reply_to_backup sysctl net.inet.carp.preempt=1
516
517	vnet_ifrename_jail gw_reply_to_backup ${epair_sync_gw_reply_to}b if_pfsync
518	vnet_ifrename_jail gw_reply_to_backup ${epair_gw_reply_to_backup_bridge1}a if_br1
519	vnet_ifrename_jail gw_reply_to_backup ${epair_gw_reply_to_backup_bridge2}a if_br2
520
521	jexec gw_reply_to_backup ifconfig pfsync0 \
522		syncpeer 198.19.20.1 \
523		syncdev if_pfsync \
524		up
525	pft_set_rules gw_reply_to_backup \
526		"set timeout { icmp.first 120, icmp.error 60 }" \
527		"block log all" \
528		"pass quick on if_pfsync proto pfsync keep state (no-sync)" \
529		"pass quick on { if_br1 if_br2 } proto carp keep state (no-sync)" \
530		"block drop in quick to 224.0.0.18/32" \
531		"pass out quick on if_br2 reply-to (if_br1 198.18.1.10) tagged auth_packet_reply_to keep state" \
532		"pass in quick log on if_br1 proto { icmp udp tcp } from 198.18.0.0/24 to 198.18.2.0/24 tag auth_packet_reply_to keep state"
533	jexec gw_reply_to_backup pfctl -e
534
535	jexec server ifconfig ${epair_server_bridge2}a inet 198.18.2.1/24 up
536	jexec server route add 198.18.0.0/24 198.18.2.20
537
538	# Waiting for platform to settle
539	while ! jexec gw_route_to_backup ifconfig | grep 'carp: BACKUP'
540	do
541		sleep 1
542	done
543	while ! jexec gw_reply_to_backup ifconfig | grep 'carp: BACKUP'
544	do
545		sleep 1
546	done
547	while ! jexec client ping -c 10 198.18.2.1 | grep ', 0.0% packet loss'
548	do
549		sleep 1
550	done
551
552	# Checking cluster members pf.conf checksums match
553	gw_route_to_master_checksum=$(jexec gw_route_to_master pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2)
554	gw_route_to_backup_checksum=$(jexec gw_route_to_backup pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2)
555	gw_reply_to_master_checksum=$(jexec gw_reply_to_master pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2)
556	gw_reply_to_backup_checksum=$(jexec gw_reply_to_backup pfctl -si -v | grep 'Checksum:' | cut -d ' ' -f 2)
557	if [ "$gw_route_to_master_checksum" != "$gw_route_to_backup_checksum" ]
558	then
559		atf_fail "gw_route_to cluster members pf.conf do not match each others"
560	fi
561	if [ "$gw_reply_to_master_checksum" != "$gw_reply_to_backup_checksum" ]
562	then
563		atf_fail "gw_reply_to cluster members pf.conf do not match each others"
564	fi
565
566	# Creating state entries
567	(jexec client ping -c 10 198.18.2.1 >ping.stdout) &
568
569	if [ "$1" = "backup_promotion" ]
570	then
571		sleep 1
572		jexec gw_route_to_backup ifconfig if_br0 vhid 10 advskew 0
573		jexec gw_route_to_backup ifconfig if_br1 vhid 11 advskew 0
574		jexec gw_reply_to_backup ifconfig if_br1 vhid 21 advskew 0
575		jexec gw_reply_to_backup ifconfig if_br2 vhid 22 advskew 0
576	fi
577	while ! grep -q -e 'packet loss' ping.stdout
578	do
579		sleep 1
580	done
581
582	atf_check -s exit:0 -e ignore -o ignore grep ', 0.0% packet loss' ping.stdout
583}
584
585pbr_common_cleanup()
586{
587	pft_cleanup
588}
589
590atf_test_case "ipsec" "cleanup"
591ipsec_head()
592{
593	atf_set descr 'Transport pfsync over IPSec'
594	atf_set require.user root
595}
596
597ipsec_body()
598{
599	if ! sysctl -q kern.features.ipsec >/dev/null ; then
600		atf_skip "This test requires ipsec"
601	fi
602
603	# Run the common test, to set up pfsync
604	common_body
605
606	# But we want unicast pfsync
607	jexec one ifconfig pfsync0 syncpeer 192.0.2.2
608	jexec two ifconfig pfsync0 syncpeer 192.0.2.1
609
610	# Flush existing states
611	jexec one pfctl -Fs
612	jexec two pfctl -Fs
613
614	# Now define an ipsec policy to run over the epair_sync interfaces
615	echo "flush;
616	spdflush;
617	spdadd 192.0.2.1/32 192.0.2.2/32 any -P out ipsec esp/transport//require;
618	spdadd 192.0.2.2/32 192.0.2.1/32 any -P in ipsec esp/transport//require;
619	add 192.0.2.1 192.0.2.2 esp 0x1000 -E aes-gcm-16 \"12345678901234567890\";
620	add 192.0.2.2 192.0.2.1 esp 0x1001 -E aes-gcm-16 \"12345678901234567890\";" \
621	    | jexec one setkey -c
622
623	echo "flush;
624	spdflush;
625	spdadd 192.0.2.2/32 192.0.2.1/32 any -P out ipsec esp/transport//require;
626	spdadd 192.0.2.1/32 192.0.2.2/32 any -P in ipsec esp/transport//require;
627	add 192.0.2.1 192.0.2.2 esp 0x1000 -E aes-gcm-16 \"12345678901234567891\";
628	add 192.0.2.2 192.0.2.1 esp 0x1001 -E aes-gcm-16 \"12345678901234567891\";" \
629	    | jexec two setkey -c
630
631	# We've set incompatible keys, so pfsync will be broken.
632	ping -c 1 -S 198.51.100.254 198.51.100.1
633
634	# Give pfsync time to do its thing
635	sleep 2
636
637	if jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \
638	    grep 198.51.100.2 ; then
639		atf_fail "state synced although IPSec should have prevented it"
640	fi
641
642	# Flush existing states
643	jexec one pfctl -Fs
644	jexec two pfctl -Fs
645
646	# Fix the IPSec key to match
647	echo "flush;
648	spdflush;
649	spdadd 192.0.2.2/32 192.0.2.1/32 any -P out ipsec esp/transport//require;
650	spdadd 192.0.2.1/32 192.0.2.2/32 any -P in ipsec esp/transport//require;
651	add 192.0.2.1 192.0.2.2 esp 0x1000 -E aes-gcm-16 \"12345678901234567890\";
652	add 192.0.2.2 192.0.2.1 esp 0x1001 -E aes-gcm-16 \"12345678901234567890\";" \
653	    | jexec two setkey -c
654
655	ping -c 1 -S 198.51.100.254 198.51.100.1
656
657	# Give pfsync time to do its thing
658	sleep 2
659
660	if ! jexec two pfctl -s states | grep icmp | grep 198.51.100.1 | \
661	    grep 198.51.100.2 ; then
662		atf_fail "state not found on synced host"
663	fi
664}
665
666ipsec_cleanup()
667{
668	pft_cleanup
669}
670
671atf_test_case "timeout" "cleanup"
672timeout_head()
673{
674	atf_set descr 'Trigger pfsync_timeout()'
675	atf_set require.user root
676}
677
678timeout_body()
679{
680	pft_init
681
682	vnet_mkjail one
683
684	jexec one ifconfig lo0 127.0.0.1/8 up
685	jexec one ifconfig lo0 inet6 ::1/128 up
686
687	pft_set_rules one \
688		"pass all"
689	jexec one pfctl -e
690	jexec one ifconfig pfsync0 defer up
691
692	jexec one ping -c 1 ::1
693	jexec one ping -c 1 127.0.0.1
694
695	# Give pfsync_timeout() time to fire (a callout on a 1 second delay)
696	sleep 2
697}
698
699timeout_cleanup()
700{
701	pft_cleanup
702}
703
704atf_test_case "basic_ipv6_unicast" "cleanup"
705basic_ipv6_unicast_head()
706{
707	atf_set descr 'Basic pfsync test (IPv6)'
708	atf_set require.user root
709}
710
711basic_ipv6_unicast_body()
712{
713	pfsynct_init
714
715	epair_sync=$(vnet_mkepair)
716	epair_one=$(vnet_mkepair)
717	epair_two=$(vnet_mkepair)
718
719	vnet_mkjail one ${epair_one}a ${epair_sync}a
720	vnet_mkjail two ${epair_two}a ${epair_sync}b
721
722	# pfsync interface
723	jexec one ifconfig ${epair_sync}a inet6 fd2c::1/64 no_dad up
724	jexec one ifconfig ${epair_one}a inet6 fd2b::1/64 no_dad up
725	jexec one ifconfig pfsync0 \
726		syncdev ${epair_sync}a \
727		syncpeer fd2c::2 \
728		maxupd 1 \
729		up
730	jexec two ifconfig ${epair_two}a inet6 fd2b::2/64 no_dad up
731	jexec two ifconfig ${epair_sync}b inet6 fd2c::2/64 no_dad up
732	jexec two ifconfig pfsync0 \
733		syncdev ${epair_sync}b \
734		syncpeer fd2c::1 \
735		maxupd 1 \
736		up
737
738	# Enable pf!
739	jexec one pfctl -e
740	pft_set_rules one \
741		"block on ${epair_sync}a inet" \
742		"pass out keep state"
743	jexec two pfctl -e
744	pft_set_rules two \
745		"block on ${epair_sync}b inet" \
746		"pass out keep state"
747
748	ifconfig ${epair_one}b inet6 fd2b::f0/64 no_dad up
749
750	ping6 -c 1 -S fd2b::f0 fd2b::1
751
752	# Give pfsync time to do its thing
753	sleep 2
754
755	if ! jexec two pfctl -s states | grep icmp | grep fd2b::1 | \
756	    grep fd2b::f0 ; then
757		atf_fail "state not found on synced host"
758	fi
759}
760
761basic_ipv6_unicast_cleanup()
762{
763	pfsynct_cleanup
764}
765
766atf_test_case "basic_ipv6" "cleanup"
767basic_ipv6_head()
768{
769	atf_set descr 'Basic pfsync test (IPv6)'
770	atf_set require.user root
771}
772
773basic_ipv6_body()
774{
775	pfsynct_init
776
777	epair_sync=$(vnet_mkepair)
778	epair_one=$(vnet_mkepair)
779	epair_two=$(vnet_mkepair)
780
781	vnet_mkjail one ${epair_one}a ${epair_sync}a
782	vnet_mkjail two ${epair_two}a ${epair_sync}b
783
784	# pfsync interface
785	jexec one ifconfig ${epair_sync}a inet6 fd2c::1/64 no_dad up
786	jexec one ifconfig ${epair_one}a inet6 fd2b::1/64 no_dad up
787	jexec one ifconfig pfsync0 \
788		syncdev ${epair_sync}a \
789		syncpeer ff12::f0 \
790		maxupd 1 \
791		up
792	jexec two ifconfig ${epair_two}a inet6 fd2b::2/64 no_dad up
793	jexec two ifconfig ${epair_sync}b inet6 fd2c::2/64 no_dad up
794	jexec two ifconfig pfsync0 \
795		syncdev ${epair_sync}b \
796		syncpeer ff12::f0 \
797		maxupd 1 \
798		up
799
800	# Enable pf!
801	jexec one pfctl -e
802	pft_set_rules one \
803		"block on ${epair_sync}a inet" \
804		"pass out keep state"
805	jexec two pfctl -e
806	pft_set_rules two \
807		"block on ${epair_sync}b inet" \
808		"pass out keep state"
809
810	ifconfig ${epair_one}b inet6 fd2b::f0/64 no_dad up
811
812	ping6 -c 1 -S fd2b::f0 fd2b::1
813
814	# Give pfsync time to do its thing
815	sleep 2
816
817	if ! jexec two pfctl -s states | grep icmp | grep fd2b::1 | \
818	    grep fd2b::f0 ; then
819		atf_fail "state not found on synced host"
820	fi
821}
822
823basic_ipv6_cleanup()
824{
825	pfsynct_cleanup
826}
827
828atf_init_test_cases()
829{
830	atf_add_test_case "basic"
831	atf_add_test_case "basic_defer"
832	atf_add_test_case "defer"
833	atf_add_test_case "bulk"
834	atf_add_test_case "pbr"
835	atf_add_test_case "pfsync_pbr"
836	atf_add_test_case "ipsec"
837	atf_add_test_case "timeout"
838	atf_add_test_case "basic_ipv6_unicast"
839	atf_add_test_case "basic_ipv6"
840}
841