xref: /src/tests/sys/netpfil/pf/killstate.sh (revision 301bc149b96e54af4ebfba2822f4b7b411bb76c1)
1#
2# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright (c) 2021 Rubicon Communications, LLC (Netgate)
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
31find_state()
32{
33	jail=${1:-alcatraz}
34	ip=${2:-192.0.2.2}
35
36	jexec ${jail} pfctl -ss | grep icmp | grep ${ip}
37}
38
39find_state_v6()
40{
41	jexec alcatraz pfctl -ss | grep icmp | grep 2001:db8::2
42}
43
44
45atf_test_case "v4" "cleanup"
46v4_head()
47{
48	atf_set descr 'Test killing states by IPv4 address'
49	atf_set require.user root
50	atf_set require.progs python3 scapy
51}
52
53v4_body()
54{
55	pft_init
56
57	epair=$(vnet_mkepair)
58	ifconfig ${epair}a 192.0.2.1/24 up
59
60	vnet_mkjail alcatraz ${epair}b
61	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
62	jexec alcatraz pfctl -e
63
64	pft_set_rules alcatraz "block all" \
65		"pass in proto icmp" \
66		"set skip on lo"
67
68	# Sanity check & establish state
69	atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
70		--sendif ${epair}a \
71		--to 192.0.2.2 \
72		--replyif ${epair}a
73
74	# Change rules to now deny the ICMP traffic
75	pft_set_rules noflush alcatraz "block all"
76	if ! find_state;
77	then
78		atf_fail "Setting new rules removed the state."
79	fi
80
81	# Killing with the wrong IP doesn't affect our state
82	jexec alcatraz pfctl -k 192.0.2.3
83	if ! find_state;
84	then
85		atf_fail "Killing with the wrong IP removed our state."
86	fi
87
88	# Killing with one correct address and one incorrect doesn't kill the state
89	jexec alcatraz pfctl -k 192.0.2.1 -k 192.0.2.3
90	if ! find_state;
91	then
92		atf_fail "Killing with one wrong IP removed our state."
93	fi
94
95	# Killing with correct address does remove the state
96	jexec alcatraz pfctl -k 192.0.2.1
97	if find_state;
98	then
99		atf_fail "Killing with the correct IP did not remove our state."
100	fi
101}
102
103v4_cleanup()
104{
105	pft_cleanup
106}
107
108atf_test_case "src_dst" "cleanup"
109src_dst_head()
110{
111	atf_set descr 'Test killing a state with source and destination specified'
112	atf_set require.user root
113	atf_set require.progs python3 scapy
114}
115
116src_dst_body()
117{
118	pft_init
119
120	epair=$(vnet_mkepair)
121	ifconfig ${epair}a 192.0.2.1/24 up
122
123	vnet_mkjail alcatraz ${epair}b
124	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
125	jexec alcatraz pfctl -e
126
127	pft_set_rules alcatraz "block all" \
128		"pass in proto icmp" \
129		"set skip on lo"
130
131	# Sanity check & establish state
132	atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
133		--sendif ${epair}a \
134		--to 192.0.2.2 \
135		--replyif ${epair}a
136
137	# Change rules to now deny the ICMP traffic
138	pft_set_rules noflush alcatraz "block all"
139	if ! find_state;
140	then
141		atf_fail "Setting new rules removed the state."
142	fi
143
144	# Killing with the wrong source IP doesn't affect our state
145	jexec alcatraz pfctl -k 192.0.2.3 -k 192.0.2.2
146	if ! find_state;
147	then
148		atf_fail "Killing with the wrong source IP removed our state."
149	fi
150
151	# Killing with the wrong destination IP doesn't affect our state
152	jexec alcatraz pfctl -k 192.0.2.1 -k 192.0.2.3
153	if ! find_state;
154	then
155		atf_fail "Killing with the wrong destination IP removed our state."
156	fi
157
158	# But it does with the correct one
159	jexec alcatraz pfctl -k 192.0.2.1 -k 192.0.2.2
160	if find_state;
161	then
162		atf_fail "Killing with the correct IPs did not remove our state."
163	fi
164}
165
166src_dst_cleanup()
167{
168	pft_cleanup
169}
170
171atf_test_case "v6" "cleanup"
172v6_head()
173{
174	atf_set descr 'Test killing states by IPv6 address'
175	atf_set require.user root
176	atf_set require.progs python3 scapy
177}
178
179v6_body()
180{
181	pft_init
182
183	epair=$(vnet_mkepair)
184	ifconfig ${epair}a inet6 2001:db8::1/64 up no_dad
185
186	vnet_mkjail alcatraz ${epair}b
187	jexec alcatraz ifconfig ${epair}b inet6 2001:db8::2/64 up no_dad
188	jexec alcatraz pfctl -e
189
190	pft_set_rules alcatraz "block all" \
191		"pass quick inet6 proto ipv6-icmp all icmp6-type { neighbrsol, neighbradv } no state" \
192		"pass in proto icmp6" \
193		"set skip on lo"
194
195	# Sanity check & establish state
196	atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
197		--sendif ${epair}a \
198		--fromaddr 2001:db8::1 \
199		--to 2001:db8::2 \
200		--replyif ${epair}a
201
202	# Change rules to now deny the ICMP traffic
203	pft_set_rules noflush alcatraz "block all"
204	if ! find_state_v6;
205	then
206		atf_fail "Setting new rules removed the state."
207	fi
208
209	# Killing with the wrong IP doesn't affect our state
210	jexec alcatraz pfctl -k 2001:db8::3
211	if ! find_state_v6;
212	then
213		atf_fail "Killing with the wrong IP removed our state."
214	fi
215
216	# Killing with one correct address and one incorrect doesn't kill the state
217	jexec alcatraz pfctl -k 2001:db8::1 -k 2001:db8::3
218	if ! find_state_v6;
219	then
220		atf_fail "Killing with one wrong IP removed our state."
221	fi
222
223	# Killing with correct address does remove the state
224	jexec alcatraz pfctl -k 2001:db8::1
225	if find_state_v6;
226	then
227		atf_fail "Killing with the correct IP did not remove our state."
228	fi
229}
230
231v6_cleanup()
232{
233	pft_cleanup
234}
235
236atf_test_case "label" "cleanup"
237label_head()
238{
239	atf_set descr 'Test killing states by label'
240	atf_set require.user root
241	atf_set require.progs python3 scapy
242}
243
244label_body()
245{
246	pft_init
247
248	epair=$(vnet_mkepair)
249	ifconfig ${epair}a 192.0.2.1/24 up
250
251	vnet_mkjail alcatraz ${epair}b
252	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
253	jexec alcatraz pfctl -e
254
255	pft_set_rules alcatraz "block all" \
256		"pass in proto tcp label bar" \
257		"pass in proto icmp label foo" \
258		"set skip on lo"
259
260	# Sanity check & establish state
261	atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
262		--sendif ${epair}a \
263		--to 192.0.2.2 \
264		--replyif ${epair}a
265
266	# Change rules to now deny the ICMP traffic
267	pft_set_rules noflush alcatraz "block all"
268	if ! find_state;
269	then
270		atf_fail "Setting new rules removed the state."
271	fi
272
273	# Killing a label on a different rules keeps the state
274	jexec alcatraz pfctl -k label -k bar
275	if ! find_state;
276	then
277		atf_fail "Killing a different label removed the state."
278	fi
279
280	# Killing a non-existing label keeps the state
281	jexec alcatraz pfctl -k label -k baz
282	if ! find_state;
283	then
284		atf_fail "Killing a non-existing label removed the state."
285	fi
286
287	# Killing the correct label kills the state
288	jexec alcatraz pfctl -k label -k foo
289	if find_state;
290	then
291		atf_fail "Killing the state did not remove it."
292	fi
293}
294
295label_cleanup()
296{
297	pft_cleanup
298}
299
300atf_test_case "multilabel" "cleanup"
301multilabel_head()
302{
303	atf_set descr 'Test killing states with multiple labels by label'
304	atf_set require.user root
305	atf_set require.progs python3 scapy
306}
307
308multilabel_body()
309{
310	pft_init
311
312	epair=$(vnet_mkepair)
313	ifconfig ${epair}a 192.0.2.1/24 up
314
315	vnet_mkjail alcatraz ${epair}b
316	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
317	jexec alcatraz pfctl -e
318
319	pft_set_rules alcatraz "block all" \
320		"pass in proto icmp label foo label bar" \
321		"set skip on lo"
322
323	# Sanity check & establish state
324	atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
325		--sendif ${epair}a \
326		--to 192.0.2.2 \
327		--replyif ${epair}a
328
329	# Change rules to now deny the ICMP traffic
330	pft_set_rules noflush alcatraz "block all"
331	if ! find_state;
332	then
333		atf_fail "Setting new rules removed the state."
334	fi
335
336	# Killing a label on a different rules keeps the state
337	jexec alcatraz pfctl -k label -k baz
338	if ! find_state;
339	then
340		atf_fail "Killing a different label removed the state."
341	fi
342
343	# Killing the state with the last label works
344	jexec alcatraz pfctl -k label -k bar
345	if find_state;
346	then
347		atf_fail "Killing with the last label did not remove the state."
348	fi
349
350	pft_set_rules alcatraz "block all" \
351		"pass in proto icmp label foo label bar" \
352		"set skip on lo"
353
354	# Reestablish state
355	atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
356		--sendif ${epair}a \
357		--to 192.0.2.2 \
358		--replyif ${epair}a
359
360	# Change rules to now deny the ICMP traffic
361	pft_set_rules noflush alcatraz "block all"
362	if ! find_state;
363	then
364		atf_fail "Setting new rules removed the state."
365	fi
366
367	# Killing with the first label works too
368	jexec alcatraz pfctl -k label -k foo
369	if find_state;
370	then
371		atf_fail "Killing with the first label did not remove the state."
372	fi
373}
374
375multilabel_cleanup()
376{
377	pft_cleanup
378}
379
380atf_test_case "gateway" "cleanup"
381gateway_head()
382{
383	atf_set descr 'Test killing states by route-to/reply-to address'
384	atf_set require.user root
385	atf_set require.progs python3 scapy
386}
387
388gateway_body()
389{
390	pft_init
391
392	epair=$(vnet_mkepair)
393	ifconfig ${epair}a 192.0.2.1/24 up
394
395	vnet_mkjail alcatraz ${epair}b
396	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
397	jexec alcatraz pfctl -e
398
399	pft_set_rules alcatraz "block all" \
400		"pass in reply-to (${epair}b 192.0.2.1) proto icmp" \
401		"set skip on lo"
402
403	# Sanity check & establish state
404	# Note: use pft_ping so we always use the same ID, so pf considers all
405	# echo requests part of the same flow.
406	atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
407		--sendif ${epair}a \
408		--to 192.0.2.2 \
409		--replyif ${epair}a
410
411	# Change rules to now deny the ICMP traffic
412	pft_set_rules noflush alcatraz "block all"
413	if ! find_state;
414	then
415		atf_fail "Setting new rules removed the state."
416	fi
417
418	# Killing with a different gateway does not affect our state
419	jexec alcatraz pfctl -k gateway -k 192.0.2.2
420	if ! find_state;
421	then
422		atf_fail "Killing with a different gateway removed the state."
423	fi
424
425	# Killing states with the relevant gateway does terminate our state
426	jexec alcatraz pfctl -k gateway -k 192.0.2.1
427	if find_state;
428	then
429		atf_fail "Killing with the gateway did not remove the state."
430	fi
431}
432
433gateway_cleanup()
434{
435	pft_cleanup
436}
437
438atf_test_case "match" "cleanup"
439match_head()
440{
441	atf_set descr 'Test killing matching states'
442	atf_set require.user root
443}
444
445wait_for_state()
446{
447	jail=$1
448	addr=$2
449
450	while ! jexec $jail pfctl -s s | grep $addr >/dev/null;
451	do
452		sleep .1
453	done
454}
455
456match_body()
457{
458	pft_init
459
460	epair_one=$(vnet_mkepair)
461	ifconfig ${epair_one}a 192.0.2.1/24 up
462
463	epair_two=$(vnet_mkepair)
464
465	vnet_mkjail alcatraz ${epair_one}b ${epair_two}a
466	jexec alcatraz ifconfig ${epair_one}b 192.0.2.2/24 up
467	jexec alcatraz ifconfig ${epair_two}a 198.51.100.1/24 up
468	jexec alcatraz sysctl net.inet.ip.forwarding=1
469	jexec alcatraz pfctl -e
470
471	vnet_mkjail singsing ${epair_two}b
472	jexec singsing ifconfig ${epair_two}b 198.51.100.2/24 up
473	jexec singsing route add default 198.51.100.1
474	jexec singsing /usr/sbin/inetd -p ${PWD}/inetd-echo.pid \
475	    $(atf_get_srcdir)/echo_inetd.conf
476
477	route add 198.51.100.0/24 192.0.2.2
478
479	pft_set_rules alcatraz \
480		"nat on ${epair_two}a from 192.0.2.0/24 -> (${epair_two}a)" \
481		"pass all"
482
483	nc 198.51.100.2 7 &
484	wait_for_state alcatraz 192.0.2.1
485
486	# Expect two states
487	states=$(jexec alcatraz pfctl -s s | grep 192.0.2.1 | wc -l)
488	if [ $states -ne 2 ] ;
489	then
490		atf_fail "Expected two states, found $states"
491	fi
492
493	# If we don't kill the matching NAT state one should be left
494	jexec alcatraz pfctl -k 192.0.2.1
495	states=$(jexec alcatraz pfctl -s s | grep 192.0.2.1 | wc -l)
496	if [ $states -ne 1 ] ;
497	then
498		atf_fail "Expected one states, found $states"
499	fi
500
501	# Flush
502	jexec alcatraz pfctl -F states
503
504	nc 198.51.100.2 7 &
505	wait_for_state alcatraz 192.0.2.1
506
507	# Kill matching states, expect all of them to be gone
508	jexec alcatraz pfctl -M -k 192.0.2.1
509	states=$(jexec alcatraz pfctl -s s | grep 192.0.2.1 | wc -l)
510	if [ $states -ne 0 ] ;
511	then
512		atf_fail "Expected zero states, found $states"
513	fi
514}
515
516match_cleanup()
517{
518	pft_cleanup
519}
520
521atf_test_case "interface" "cleanup"
522interface_head()
523{
524	atf_set descr 'Test killing states based on interface'
525	atf_set require.user root
526	atf_set require.progs python3 scapy
527}
528
529interface_body()
530{
531	pft_init
532
533	epair=$(vnet_mkepair)
534	ifconfig ${epair}a 192.0.2.1/24 up
535
536	vnet_mkjail alcatraz ${epair}b
537	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
538	jexec alcatraz pfctl -e
539
540	pft_set_rules alcatraz "block all" \
541		"pass in proto icmp" \
542		"set skip on lo"
543
544	# Sanity check & establish state
545	atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
546		--sendif ${epair}a \
547		--to 192.0.2.2 \
548		--replyif ${epair}a
549
550	# Change rules to now deny the ICMP traffic
551	pft_set_rules noflush alcatraz "block all"
552	if ! find_state;
553	then
554		atf_fail "Setting new rules removed the state."
555	fi
556
557	# Flushing states on a different interface doesn't affect our state
558	jexec alcatraz pfctl -i ${epair}a -Fs
559	if ! find_state;
560	then
561		atf_fail "Flushing on a different interface removed the state."
562	fi
563
564	# Flushing on the correct interface does (even with floating states)
565	jexec alcatraz pfctl -i ${epair}b -Fs
566	if find_state;
567	then
568		atf_fail "Flushing on a the interface did not remove the state."
569	fi
570}
571
572interface_cleanup()
573{
574	pft_cleanup
575}
576
577atf_test_case "id" "cleanup"
578id_head()
579{
580	atf_set descr 'Test killing states by id'
581	atf_set require.user root
582	atf_set require.progs python3 scapy
583}
584
585id_body()
586{
587	pft_init
588
589	epair=$(vnet_mkepair)
590	ifconfig ${epair}a 192.0.2.1/24 up
591
592	vnet_mkjail alcatraz ${epair}b
593	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
594	jexec alcatraz pfctl -e
595
596	pft_set_rules alcatraz "block all" \
597		"pass in proto tcp" \
598		"pass in proto icmp" \
599		"set skip on lo"
600
601	# Sanity check & establish state
602	atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
603		--sendif ${epair}a \
604		--to 192.0.2.2 \
605		--replyif ${epair}a
606
607	# Change rules to now deny the ICMP traffic
608	pft_set_rules noflush alcatraz "block all"
609	if ! find_state;
610	then
611		atf_fail "Setting new rules removed the state."
612	fi
613
614	# Get the state ID
615	id=$(jexec alcatraz pfctl -ss -vvv | grep -A 3 icmp |
616	    grep -A 3 192.0.2.2 | awk '/id:/ { printf("%s/%s", $2, $4); }')
617
618	# Kill the wrong ID
619	jexec alcatraz pfctl -k id -k 1
620	if ! find_state;
621	then
622		atf_fail "Killing a different ID removed the state."
623	fi
624
625	# Kill the correct ID
626	jexec alcatraz pfctl -k id -k ${id}
627	if find_state;
628	then
629		atf_fail "Killing the state did not remove it."
630	fi
631}
632
633id_cleanup()
634{
635	pft_cleanup
636}
637
638atf_test_case "key" "cleanup"
639key_head()
640{
641	atf_set descr 'Test killing states by their key'
642	atf_set require.user root
643	atf_set require.progs python3 scapy
644}
645
646key_body()
647{
648	pft_init
649
650	epair=$(vnet_mkepair)
651	ifconfig ${epair}a 192.0.2.1/24 up
652
653	vnet_mkjail alcatraz ${epair}b
654	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
655	jexec alcatraz pfctl -e
656
657	pft_set_rules alcatraz \
658		"block all" \
659		"pass in proto tcp" \
660		"pass in proto icmp"
661
662	# Sanity check & establish state
663	atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
664		--sendif ${epair}a \
665		--to 192.0.2.2 \
666		--replyif ${epair}a
667
668	# Get the state key
669	key=$(jexec alcatraz pfctl -ss -vvv | awk '/icmp/ { print($2 " " $3 " " $4 " " $5); }')
670	bad_key=$(echo ${key} | sed 's/icmp/tcp/')
671
672	# Kill the wrong key
673	atf_check -s exit:0 -e "match:killed 0 states" \
674	    jexec alcatraz pfctl -k key -k "${bad_key}"
675	if ! find_state;
676	then
677		atf_fail "Killing a different ID removed the state."
678	fi
679
680	# Kill the correct key
681	atf_check -s exit:0 -e "match:killed 1 states" \
682	    jexec alcatraz pfctl -k key -k "${key}"
683	if find_state;
684	then
685		atf_fail "Killing the state did not remove it."
686	fi
687}
688
689key_cleanup()
690{
691	pft_cleanup
692}
693
694atf_test_case "nat" "cleanup"
695nat_head()
696{
697	atf_set descr 'Test killing states by their NAT-ed IP address'
698	atf_set require.user root
699	atf_set require.progs python3 scapy
700}
701
702nat_body()
703{
704	pft_init
705	j="killstate:nat"
706
707	epair_c=$(vnet_mkepair)
708	epair_srv=$(vnet_mkepair)
709
710	vnet_mkjail ${j}c ${epair_c}a
711	ifconfig -j ${j}c ${epair_c}a inet 192.0.2.2/24 up
712	jexec ${j}c route add default 192.0.2.1
713
714	vnet_mkjail ${j}srv ${epair_srv}a
715	ifconfig -j ${j}srv ${epair_srv}a inet 198.51.100.2/24 up
716
717	vnet_mkjail ${j}r ${epair_c}b ${epair_srv}b
718	ifconfig -j ${j}r ${epair_c}b inet 192.0.2.1/24 up
719	ifconfig -j ${j}r ${epair_srv}b inet 198.51.100.1/24 up
720	jexec ${j}r sysctl net.inet.ip.forwarding=1
721
722	jexec ${j}r pfctl -e
723	pft_set_rules ${j}r \
724		"nat on ${epair_srv}b inet from 192.0.2.0/24 to any -> (${epair_srv}b)"
725
726	# Sanity check
727	atf_check -s exit:0 -o ignore \
728	    jexec ${j}c ping -c 1 192.0.2.1
729	atf_check -s exit:0 -o ignore \
730	    jexec ${j}srv ping -c 1 198.51.100.1
731	atf_check -s exit:0 -o ignore \
732	    jexec ${j}c ping -c 1 198.51.100.2
733
734	# Establish state
735	# Note: use pft_ping so we always use the same ID, so pf considers all
736	# echo requests part of the same flow.
737	atf_check -s exit:0 -o ignore jexec ${j}c ${common_dir}/pft_ping.py \
738		--sendif ${epair_c}a \
739		--to 198.51.100.1 \
740		--replyif ${epair_c}a
741
742	# There's NAT here, so the source IP will be 198.51.100.1
743	if ! find_state ${j}r 198.51.100.1;
744	then
745		atf_fail "Expected state not found"
746	fi
747
748	# By NAT-ed address?
749	jexec ${j}r pfctl -k nat -k 192.0.2.2
750
751	if find_state ${j}r 198.51.100.1;
752	then
753		jexec ${j}r pfctl -ss -v
754		atf_fail "Failed to remove state"
755	fi
756}
757
758nat_cleanup()
759{
760	pft_cleanup
761}
762
763atf_init_test_cases()
764{
765	atf_add_test_case "v4"
766	atf_add_test_case "src_dst"
767	atf_add_test_case "v6"
768	atf_add_test_case "label"
769	atf_add_test_case "multilabel"
770	atf_add_test_case "gateway"
771	atf_add_test_case "match"
772	atf_add_test_case "interface"
773	atf_add_test_case "id"
774	atf_add_test_case "key"
775	atf_add_test_case "nat"
776}
777