3 # SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5 # Copyright (c) 2021 Rubicon Communications, LLC (Netgate)
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
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.
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
28 . $(atf_get_srcdir)/utils.subr
30 common_dir=$(atf_get_srcdir)/../common
32 atf_test_case "v4" "cleanup"
35 atf_set descr 'Test killing states by IPv4 address'
36 atf_set require.user root
37 atf_set require.progs scapy
45 ifconfig ${epair}a 192.0.2.1/24 up
47 vnet_mkjail alcatraz ${epair}b
48 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
49 jexec alcatraz pfctl -e
51 pft_set_rules alcatraz "block all" \
54 # Sanity check & establish state
55 # Note: use pft_ping so we always use the same ID, so pf considers all
56 # echo requests part of the same flow.
57 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
62 # Change rules to now deny the ICMP traffic
63 pft_set_rules noflush alcatraz "block all"
65 # Established state means we can still ping alcatraz
66 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
71 # Killing with the wrong IP doesn't affect our state
72 jexec alcatraz pfctl -k 192.0.2.3
74 # So we can still ping
75 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
80 # Killing with one correct address and one incorrect doesn't kill the state
81 jexec alcatraz pfctl -k 192.0.2.1 -k 192.0.2.3
83 # So we can still ping
84 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
89 # Killing with correct address does remove the state
90 jexec alcatraz pfctl -k 192.0.2.1
93 atf_check -s exit:1 -o ignore ${common_dir}/pft_ping.py \
104 atf_test_case "label" "cleanup"
107 atf_set descr 'Test killing states by label'
108 atf_set require.user root
109 atf_set require.progs scapy
116 epair=$(vnet_mkepair)
117 ifconfig ${epair}a 192.0.2.1/24 up
119 vnet_mkjail alcatraz ${epair}b
120 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
121 jexec alcatraz pfctl -e
123 pft_set_rules alcatraz "block all" \
124 "pass in proto tcp label bar" \
125 "pass in proto icmp label foo"
127 # Sanity check & establish state
128 # Note: use pft_ping so we always use the same ID, so pf considers all
129 # echo requests part of the same flow.
130 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
135 # Change rules to now deny the ICMP traffic
136 pft_set_rules noflush alcatraz "block all"
138 # Established state means we can still ping alcatraz
139 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
144 # Killing a label on a different rules keeps the state
145 jexec alcatraz pfctl -k label -k bar
146 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
151 # Killing a non-existing label keeps the state
152 jexec alcatraz pfctl -k label -k baz
153 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
158 # Killing the correct label kills the state
159 jexec alcatraz pfctl -k label -k foo
160 atf_check -s exit:1 -o ignore ${common_dir}/pft_ping.py \
171 atf_test_case "multilabel" "cleanup"
174 atf_set descr 'Test killing states with multiple labels by label'
175 atf_set require.user root
176 atf_set require.progs scapy
183 epair=$(vnet_mkepair)
184 ifconfig ${epair}a 192.0.2.1/24 up
186 vnet_mkjail alcatraz ${epair}b
187 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
188 jexec alcatraz pfctl -e
190 pft_set_rules alcatraz "block all" \
191 "pass in proto icmp label foo label bar"
193 # Sanity check & establish state
194 # Note: use pft_ping so we always use the same ID, so pf considers all
195 # echo requests part of the same flow.
196 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
201 # Change rules to now deny the ICMP traffic
202 pft_set_rules noflush alcatraz "block all"
204 # Established state means we can still ping alcatraz
205 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
210 # Killing a label on a different rules keeps the state
211 jexec alcatraz pfctl -k label -k baz
212 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
217 # Killing the state with the last label works
218 jexec alcatraz pfctl -k label -k bar
219 atf_check -s exit:1 -o ignore ${common_dir}/pft_ping.py \
224 pft_set_rules alcatraz "block all" \
225 "pass in proto icmp label foo label bar"
228 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
233 # Change rules to now deny the ICMP traffic
234 pft_set_rules noflush alcatraz "block all"
236 # Killing with the first label works too
237 jexec alcatraz pfctl -k label -k foo
238 atf_check -s exit:1 -o ignore ${common_dir}/pft_ping.py \
249 atf_test_case "gateway" "cleanup"
252 atf_set descr 'Test killing states by route-to/reply-to address'
253 atf_set require.user root
254 atf_set require.progs scapy
261 epair=$(vnet_mkepair)
262 ifconfig ${epair}a 192.0.2.1/24 up
264 vnet_mkjail alcatraz ${epair}b
265 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
266 jexec alcatraz pfctl -e
268 pft_set_rules alcatraz "block all" \
269 "pass in reply-to (${epair}b 192.0.2.1) proto icmp"
271 # Sanity check & establish state
272 # Note: use pft_ping so we always use the same ID, so pf considers all
273 # echo requests part of the same flow.
274 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
279 # Change rules to now deny the ICMP traffic
280 pft_set_rules noflush alcatraz "block all"
282 # Established state means we can still ping alcatraz
283 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
288 # Killing with a different gateway does not affect our state
289 jexec alcatraz pfctl -k gateway -k 192.0.2.2
290 atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
295 # Killing states with the relevant gateway does terminate our state
296 jexec alcatraz pfctl -k gateway -k 192.0.2.1
297 atf_check -s exit:1 -o ignore ${common_dir}/pft_ping.py \
308 atf_init_test_cases()
310 atf_add_test_case "v4"
311 atf_add_test_case "label"
312 atf_add_test_case "multilabel"
313 atf_add_test_case "gateway"