xref: /freebsd/tests/sys/netpfil/pf/route_to.sh (revision 04dcbb44340f3e42b130282112e9f741fccffc9f)
165d553b0SKristof Provost#
24d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause
365d553b0SKristof Provost#
465d553b0SKristof Provost# Copyright (c) 2018 Kristof Provost <kp@FreeBSD.org>
565d553b0SKristof Provost#
665d553b0SKristof Provost# Redistribution and use in source and binary forms, with or without
765d553b0SKristof Provost# modification, are permitted provided that the following conditions
865d553b0SKristof Provost# are met:
965d553b0SKristof Provost# 1. Redistributions of source code must retain the above copyright
1065d553b0SKristof Provost#    notice, this list of conditions and the following disclaimer.
1165d553b0SKristof Provost# 2. Redistributions in binary form must reproduce the above copyright
1265d553b0SKristof Provost#    notice, this list of conditions and the following disclaimer in the
1365d553b0SKristof Provost#    documentation and/or other materials provided with the distribution.
1465d553b0SKristof Provost#
1565d553b0SKristof Provost# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1665d553b0SKristof Provost# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1765d553b0SKristof Provost# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1865d553b0SKristof Provost# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1965d553b0SKristof Provost# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2065d553b0SKristof Provost# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2165d553b0SKristof Provost# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2265d553b0SKristof Provost# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2365d553b0SKristof Provost# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2465d553b0SKristof Provost# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2565d553b0SKristof Provost# SUCH DAMAGE.
26d850143eSKristof Provost
27d850143eSKristof Provost. $(atf_get_srcdir)/utils.subr
28d850143eSKristof Provost
2930276ef1SKristof Provostcommon_dir=$(atf_get_srcdir)/../common
3030276ef1SKristof Provost
31d850143eSKristof Provostatf_test_case "v4" "cleanup"
32d850143eSKristof Provostv4_head()
33d850143eSKristof Provost{
34d850143eSKristof Provost	atf_set descr 'Basic route-to test'
35d850143eSKristof Provost	atf_set require.user root
36d850143eSKristof Provost}
37d850143eSKristof Provost
38d850143eSKristof Provostv4_body()
39d850143eSKristof Provost{
40d850143eSKristof Provost	pft_init
41d850143eSKristof Provost
4206aac31aSKristof Provost	epair_send=$(vnet_mkepair)
43d850143eSKristof Provost	ifconfig ${epair_send}a 192.0.2.1/24 up
4406aac31aSKristof Provost	epair_route=$(vnet_mkepair)
45d850143eSKristof Provost	ifconfig ${epair_route}a 203.0.113.1/24 up
46d850143eSKristof Provost
4706aac31aSKristof Provost	vnet_mkjail alcatraz ${epair_send}b ${epair_route}b
48d850143eSKristof Provost	jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up
49d850143eSKristof Provost	jexec alcatraz ifconfig ${epair_route}b 203.0.113.2/24 up
50d850143eSKristof Provost	jexec alcatraz route add -net 198.51.100.0/24 192.0.2.1
51d850143eSKristof Provost	jexec alcatraz pfctl -e
52d850143eSKristof Provost
53d850143eSKristof Provost	# Attempt to provoke PR 228782
54d850143eSKristof Provost	pft_set_rules alcatraz "block all" "pass user 2" \
55d850143eSKristof Provost		"pass out route-to (${epair_route}b 203.0.113.1) from 192.0.2.2 to 198.51.100.1 no state"
56d850143eSKristof Provost	jexec alcatraz nc -w 3 -s 192.0.2.2 198.51.100.1 22
57d850143eSKristof Provost
58d850143eSKristof Provost	# atf wants us to not return an error, but our netcat will fail
59d850143eSKristof Provost	true
60d850143eSKristof Provost}
61d850143eSKristof Provost
62d850143eSKristof Provostv4_cleanup()
63d850143eSKristof Provost{
64d850143eSKristof Provost	pft_cleanup
65d850143eSKristof Provost}
66d850143eSKristof Provost
67d850143eSKristof Provostatf_test_case "v6" "cleanup"
68d850143eSKristof Provostv6_head()
69d850143eSKristof Provost{
70d850143eSKristof Provost	atf_set descr 'Basic route-to test (IPv6)'
71d850143eSKristof Provost	atf_set require.user root
72d850143eSKristof Provost}
73d850143eSKristof Provost
74d850143eSKristof Provostv6_body()
75d850143eSKristof Provost{
76d850143eSKristof Provost	pft_init
77d850143eSKristof Provost
7806aac31aSKristof Provost	epair_send=$(vnet_mkepair)
79d850143eSKristof Provost	ifconfig ${epair_send}a inet6 2001:db8:42::1/64 up no_dad -ifdisabled
8006aac31aSKristof Provost	epair_route=$(vnet_mkepair)
81d850143eSKristof Provost	ifconfig ${epair_route}a inet6 2001:db8:43::1/64 up no_dad -ifdisabled
82d850143eSKristof Provost
8306aac31aSKristof Provost	vnet_mkjail alcatraz ${epair_send}b ${epair_route}b
84d850143eSKristof Provost	jexec alcatraz ifconfig ${epair_send}b inet6 2001:db8:42::2/64 up no_dad
85d850143eSKristof Provost	jexec alcatraz ifconfig ${epair_route}b inet6 2001:db8:43::2/64 up no_dad
86d850143eSKristof Provost	jexec alcatraz route add -6 2001:db8:666::/64 2001:db8:42::2
87d850143eSKristof Provost	jexec alcatraz pfctl -e
88d850143eSKristof Provost
89d850143eSKristof Provost	# Attempt to provoke PR 228782
90d850143eSKristof Provost	pft_set_rules alcatraz "block all" "pass user 2" \
91d850143eSKristof Provost		"pass out route-to (${epair_route}b 2001:db8:43::1) from 2001:db8:42::2 to 2001:db8:666::1 no state"
92d850143eSKristof Provost	jexec alcatraz nc -6 -w 3 -s 2001:db8:42::2 2001:db8:666::1 22
93d850143eSKristof Provost
94d850143eSKristof Provost	# atf wants us to not return an error, but our netcat will fail
95d850143eSKristof Provost	true
96d850143eSKristof Provost}
97d850143eSKristof Provost
98d850143eSKristof Provostv6_cleanup()
99d850143eSKristof Provost{
100d850143eSKristof Provost	pft_cleanup
101d850143eSKristof Provost}
102d850143eSKristof Provost
103f37667e2SKristof Provostatf_test_case "multiwan" "cleanup"
104f37667e2SKristof Provostmultiwan_head()
105f37667e2SKristof Provost{
106f37667e2SKristof Provost	atf_set descr 'Multi-WAN redirection / reply-to test'
107f37667e2SKristof Provost	atf_set require.user root
108f37667e2SKristof Provost}
109f37667e2SKristof Provost
110f37667e2SKristof Provostmultiwan_body()
111f37667e2SKristof Provost{
112f37667e2SKristof Provost	pft_init
113f37667e2SKristof Provost
114f37667e2SKristof Provost	epair_one=$(vnet_mkepair)
115f37667e2SKristof Provost	epair_two=$(vnet_mkepair)
116f37667e2SKristof Provost	epair_cl_one=$(vnet_mkepair)
117f37667e2SKristof Provost	epair_cl_two=$(vnet_mkepair)
118f37667e2SKristof Provost
119f37667e2SKristof Provost	vnet_mkjail srv ${epair_one}b ${epair_two}b
120f37667e2SKristof Provost	vnet_mkjail wan_one ${epair_one}a ${epair_cl_one}b
121f37667e2SKristof Provost	vnet_mkjail wan_two ${epair_two}a ${epair_cl_two}b
122f37667e2SKristof Provost	vnet_mkjail client ${epair_cl_one}a ${epair_cl_two}a
123f37667e2SKristof Provost
124f37667e2SKristof Provost	jexec client ifconfig ${epair_cl_one}a 203.0.113.1/25
125f37667e2SKristof Provost	jexec wan_one ifconfig ${epair_cl_one}b 203.0.113.2/25
126f37667e2SKristof Provost	jexec wan_one ifconfig ${epair_one}a 192.0.2.1/24 up
127f37667e2SKristof Provost	jexec wan_one sysctl net.inet.ip.forwarding=1
128f37667e2SKristof Provost	jexec srv ifconfig ${epair_one}b 192.0.2.2/24 up
129f37667e2SKristof Provost	jexec client route add 192.0.2.0/24 203.0.113.2
130f37667e2SKristof Provost
131f37667e2SKristof Provost	jexec client ifconfig ${epair_cl_two}a 203.0.113.128/25
132f37667e2SKristof Provost	jexec wan_two ifconfig ${epair_cl_two}b 203.0.113.129/25
133f37667e2SKristof Provost	jexec wan_two ifconfig ${epair_two}a 198.51.100.1/24 up
134f37667e2SKristof Provost	jexec wan_two sysctl net.inet.ip.forwarding=1
135f37667e2SKristof Provost	jexec srv ifconfig ${epair_two}b 198.51.100.2/24 up
136f37667e2SKristof Provost	jexec client route add 198.51.100.0/24 203.0.113.129
137f37667e2SKristof Provost
138f37667e2SKristof Provost	jexec srv ifconfig lo0 127.0.0.1/8 up
139f37667e2SKristof Provost	jexec srv route add default 192.0.2.1
140f37667e2SKristof Provost	jexec srv sysctl net.inet.ip.forwarding=1
141f37667e2SKristof Provost
142f37667e2SKristof Provost	# Run echo server in srv jail
143b0fcf4d5SKristof Provost	jexec srv /usr/sbin/inetd -p ${PWD}/multiwan.pid $(atf_get_srcdir)/echo_inetd.conf
144f37667e2SKristof Provost
145f37667e2SKristof Provost	jexec srv pfctl -e
146f37667e2SKristof Provost	pft_set_rules srv \
147f37667e2SKristof Provost		"nat on ${epair_one}b inet from 127.0.0.0/8 to any -> (${epair_one}b)" \
148f37667e2SKristof Provost		"nat on ${epair_two}b inet from 127.0.0.0/8 to any -> (${epair_two}b)" \
149f37667e2SKristof Provost		"rdr on ${epair_one}b inet proto tcp from any to 192.0.2.2 port 7 -> 127.0.0.1 port 7" \
150f37667e2SKristof Provost		"rdr on ${epair_two}b inet proto tcp from any to 198.51.100.2 port 7 -> 127.0.0.1 port 7" \
151f37667e2SKristof Provost		"block in"	\
152f37667e2SKristof Provost		"block out"	\
153f37667e2SKristof Provost		"pass in quick on ${epair_one}b reply-to (${epair_one}b 192.0.2.1) inet proto tcp from any to 127.0.0.1 port 7" \
154f37667e2SKristof Provost		"pass in quick on ${epair_two}b reply-to (${epair_two}b 198.51.100.1) inet proto tcp from any to 127.0.0.1 port 7"
155f37667e2SKristof Provost
156f37667e2SKristof Provost	# These will always succeed, because we don't change interface to route
157f37667e2SKristof Provost	# correctly here.
158f37667e2SKristof Provost	result=$(echo "one" | jexec wan_one nc -N -w 3 192.0.2.2 7)
159f37667e2SKristof Provost	if [ "${result}" != "one" ]; then
160f37667e2SKristof Provost		atf_fail "Redirect on one failed"
161f37667e2SKristof Provost	fi
162f37667e2SKristof Provost	result=$(echo "two" | jexec wan_two nc -N -w 3 198.51.100.2 7)
163f37667e2SKristof Provost	if [ "${result}" != "two" ]; then
164f37667e2SKristof Provost		atf_fail "Redirect on two failed"
165f37667e2SKristof Provost	fi
166f37667e2SKristof Provost
167f37667e2SKristof Provost	result=$(echo "one" | jexec client nc -N -w 3 192.0.2.2 7)
168f37667e2SKristof Provost	if [ "${result}" != "one" ]; then
169f37667e2SKristof Provost		atf_fail "Redirect from client on one failed"
170f37667e2SKristof Provost	fi
171f37667e2SKristof Provost
172f37667e2SKristof Provost	# This should trigger the issue fixed in 829a69db855b48ff7e8242b95e193a0783c489d9
173f37667e2SKristof Provost	result=$(echo "two" | jexec client nc -N -w 3 198.51.100.2 7)
174f37667e2SKristof Provost	if [ "${result}" != "two" ]; then
175f37667e2SKristof Provost		atf_fail "Redirect from client on two failed"
176f37667e2SKristof Provost	fi
177f37667e2SKristof Provost}
178f37667e2SKristof Provost
179f37667e2SKristof Provostmultiwan_cleanup()
180f37667e2SKristof Provost{
181f37667e2SKristof Provost	pft_cleanup
182f37667e2SKristof Provost}
183f37667e2SKristof Provost
184f808bb9bSKristof Provostatf_test_case "multiwanlocal" "cleanup"
185f808bb9bSKristof Provostmultiwanlocal_head()
186f808bb9bSKristof Provost{
187f808bb9bSKristof Provost	atf_set descr 'Multi-WAN local origin source-based redirection / route-to test'
188f808bb9bSKristof Provost	atf_set require.user root
189f808bb9bSKristof Provost}
190f808bb9bSKristof Provost
191f808bb9bSKristof Provostmultiwanlocal_body()
192f808bb9bSKristof Provost{
193f808bb9bSKristof Provost	pft_init
194f808bb9bSKristof Provost
195f808bb9bSKristof Provost	epair_one=$(vnet_mkepair)
196f808bb9bSKristof Provost	epair_two=$(vnet_mkepair)
197f808bb9bSKristof Provost	epair_cl_one=$(vnet_mkepair)
198f808bb9bSKristof Provost	epair_cl_two=$(vnet_mkepair)
199f808bb9bSKristof Provost
200f808bb9bSKristof Provost	vnet_mkjail srv1 ${epair_one}b
201f808bb9bSKristof Provost	vnet_mkjail srv2 ${epair_two}b
202f808bb9bSKristof Provost	vnet_mkjail wan_one ${epair_one}a ${epair_cl_one}b
203f808bb9bSKristof Provost	vnet_mkjail wan_two ${epair_two}a ${epair_cl_two}b
204f808bb9bSKristof Provost	vnet_mkjail client ${epair_cl_one}a ${epair_cl_two}a
205f808bb9bSKristof Provost
206f808bb9bSKristof Provost	jexec client ifconfig ${epair_cl_one}a 203.0.113.1/25
207f808bb9bSKristof Provost	jexec wan_one ifconfig ${epair_cl_one}b 203.0.113.2/25
208f808bb9bSKristof Provost	jexec wan_one ifconfig ${epair_one}a 192.0.2.1/24 up
209f808bb9bSKristof Provost	jexec wan_one sysctl net.inet.ip.forwarding=1
210f808bb9bSKristof Provost	jexec srv1 ifconfig ${epair_one}b 192.0.2.2/24 up
211f808bb9bSKristof Provost
212f808bb9bSKristof Provost	jexec client ifconfig ${epair_cl_two}a 203.0.113.128/25
213f808bb9bSKristof Provost	jexec wan_two ifconfig ${epair_cl_two}b 203.0.113.129/25
214f808bb9bSKristof Provost	jexec wan_two ifconfig ${epair_two}a 198.51.100.1/24 up
215f808bb9bSKristof Provost	jexec wan_two sysctl net.inet.ip.forwarding=1
216f808bb9bSKristof Provost	jexec srv2 ifconfig ${epair_two}b 198.51.100.2/24 up
217f808bb9bSKristof Provost
218f808bb9bSKristof Provost	jexec client route add default 203.0.113.2
219f808bb9bSKristof Provost	jexec srv1 route add default 192.0.2.1
220f808bb9bSKristof Provost	jexec srv2 route add default 198.51.100.1
221f808bb9bSKristof Provost
222f808bb9bSKristof Provost	# Run data source in srv1 and srv2
223f808bb9bSKristof Provost	jexec srv1 sh -c 'dd if=/dev/zero bs=1024 count=100 | nc -l 7 -w 2 -N &'
224f808bb9bSKristof Provost	jexec srv2 sh -c 'dd if=/dev/zero bs=1024 count=100 | nc -l 7 -w 2 -N &'
225f808bb9bSKristof Provost
226f808bb9bSKristof Provost	jexec client pfctl -e
227f808bb9bSKristof Provost	pft_set_rules client \
228f808bb9bSKristof Provost		"block in"	\
229f808bb9bSKristof Provost		"block out"	\
230f808bb9bSKristof Provost		"pass out quick route-to (${epair_cl_two}a 203.0.113.129) inet proto tcp from 203.0.113.128 to any port 7" \
2313a1f834bSDoug Rabson		"pass out on ${epair_cl_one}a inet proto tcp from any to any port 7" \
2323a1f834bSDoug Rabson		"set skip on lo"
233f808bb9bSKristof Provost
234f808bb9bSKristof Provost	# This should work
235f808bb9bSKristof Provost	result=$(jexec client nc -N -w 1 192.0.2.2 7 | wc -c)
236f808bb9bSKristof Provost	if [ ${result} -ne 102400 ]; then
237f808bb9bSKristof Provost		jexec client pfctl -ss
238f808bb9bSKristof Provost		atf_fail "Redirect from client on one failed: ${result}"
239f808bb9bSKristof Provost	fi
240f808bb9bSKristof Provost
241f808bb9bSKristof Provost	# This should trigger the issue
242f808bb9bSKristof Provost	result=$(jexec client nc -N -w 1 -s 203.0.113.128 198.51.100.2 7 | wc -c)
243f808bb9bSKristof Provost	jexec client pfctl -ss
244f808bb9bSKristof Provost	if [ ${result} -ne 102400 ]; then
245f808bb9bSKristof Provost		atf_fail "Redirect from client on two failed: ${result}"
246f808bb9bSKristof Provost	fi
247f808bb9bSKristof Provost}
248f808bb9bSKristof Provost
249f808bb9bSKristof Provostmultiwanlocal_cleanup()
250f808bb9bSKristof Provost{
251f808bb9bSKristof Provost	pft_cleanup
252f808bb9bSKristof Provost}
253f808bb9bSKristof Provost
25430276ef1SKristof Provostatf_test_case "icmp_nat" "cleanup"
25530276ef1SKristof Provosticmp_nat_head()
25630276ef1SKristof Provost{
25730276ef1SKristof Provost	atf_set descr 'Test that ICMP packets are correct for route-to + NAT'
25830276ef1SKristof Provost	atf_set require.user root
259c46af893SJose Luis Duran	atf_set require.progs python3 scapy
26030276ef1SKristof Provost}
26130276ef1SKristof Provost
26230276ef1SKristof Provosticmp_nat_body()
26330276ef1SKristof Provost{
26430276ef1SKristof Provost	pft_init
26530276ef1SKristof Provost
26630276ef1SKristof Provost	epair_one=$(vnet_mkepair)
26730276ef1SKristof Provost	epair_two=$(vnet_mkepair)
26830276ef1SKristof Provost	epair_three=$(vnet_mkepair)
26930276ef1SKristof Provost
27030276ef1SKristof Provost	vnet_mkjail gw ${epair_one}b ${epair_two}a ${epair_three}a
27130276ef1SKristof Provost	vnet_mkjail srv ${epair_two}b
27230276ef1SKristof Provost	vnet_mkjail srv2 ${epair_three}b
27330276ef1SKristof Provost
27430276ef1SKristof Provost	ifconfig ${epair_one}a 192.0.2.2/24 up
27530276ef1SKristof Provost	route add -net 198.51.100.0/24 192.0.2.1
27630276ef1SKristof Provost	jexec gw sysctl net.inet.ip.forwarding=1
27730276ef1SKristof Provost	jexec gw ifconfig ${epair_one}b 192.0.2.1/24 up
27830276ef1SKristof Provost	jexec gw ifconfig ${epair_two}a 198.51.100.1/24 up
27930276ef1SKristof Provost	jexec gw ifconfig ${epair_three}a 203.0.113.1/24 up mtu 500
28030276ef1SKristof Provost	jexec srv ifconfig ${epair_two}b 198.51.100.2/24 up
28130276ef1SKristof Provost	jexec srv route add default 198.51.100.1
28230276ef1SKristof Provost	jexec srv2 ifconfig ${epair_three}b 203.0.113.2/24 up mtu 500
28330276ef1SKristof Provost	jexec srv2 route add default 203.0.113.1
28430276ef1SKristof Provost
28530276ef1SKristof Provost	# Sanity check
28630276ef1SKristof Provost	atf_check -s exit:0 -o ignore ping -c 1 198.51.100.2
28730276ef1SKristof Provost
28830276ef1SKristof Provost	jexec gw pfctl -e
28930276ef1SKristof Provost	pft_set_rules gw \
29030276ef1SKristof Provost		"nat on ${epair_two}a inet from 192.0.2.0/24 to any -> (${epair_two}a)" \
29130276ef1SKristof Provost		"nat on ${epair_three}a inet from 192.0.2.0/24 to any -> (${epair_three}a)" \
29230276ef1SKristof Provost		"pass out route-to (${epair_three}a 203.0.113.2) proto icmp icmp-type echoreq"
29330276ef1SKristof Provost
29430276ef1SKristof Provost	# Now ensure that we get an ICMP error with the correct IP addresses in it.
29530276ef1SKristof Provost	atf_check -s exit:0 ${common_dir}/pft_icmp_check.py \
29630276ef1SKristof Provost		--to 198.51.100.2 \
29730276ef1SKristof Provost		--fromaddr 192.0.2.2 \
29830276ef1SKristof Provost		--recvif ${epair_one}a \
29930276ef1SKristof Provost		--sendif ${epair_one}a
30030276ef1SKristof Provost
30130276ef1SKristof Provost	# ping reports the ICMP error, so check of that too.
30230276ef1SKristof Provost	atf_check -s exit:2 -o match:'frag needed and DF set' \
30330276ef1SKristof Provost		ping -D -c 1 -s 1000 198.51.100.2
30430276ef1SKristof Provost}
30530276ef1SKristof Provost
30630276ef1SKristof Provosticmp_nat_cleanup()
30730276ef1SKristof Provost{
30830276ef1SKristof Provost	pft_cleanup
30930276ef1SKristof Provost}
31030276ef1SKristof Provost
311920c3410SKristof Provostatf_test_case "dummynet" "cleanup"
312920c3410SKristof Provostdummynet_head()
313920c3410SKristof Provost{
314920c3410SKristof Provost	atf_set descr 'Test that dummynet applies to route-to packets'
315920c3410SKristof Provost	atf_set require.user root
316920c3410SKristof Provost}
317920c3410SKristof Provost
318920c3410SKristof Provostdummynet_body()
319920c3410SKristof Provost{
320920c3410SKristof Provost	dummynet_init
321920c3410SKristof Provost
322920c3410SKristof Provost	epair_srv=$(vnet_mkepair)
323920c3410SKristof Provost	epair_gw=$(vnet_mkepair)
324920c3410SKristof Provost
325920c3410SKristof Provost	vnet_mkjail srv ${epair_srv}a
326920c3410SKristof Provost	jexec srv ifconfig ${epair_srv}a 192.0.2.1/24 up
327920c3410SKristof Provost	jexec srv route add default 192.0.2.2
328920c3410SKristof Provost
329920c3410SKristof Provost	vnet_mkjail gw ${epair_srv}b ${epair_gw}a
330920c3410SKristof Provost	jexec gw ifconfig ${epair_srv}b 192.0.2.2/24 up
331920c3410SKristof Provost	jexec gw ifconfig ${epair_gw}a 198.51.100.1/24 up
332920c3410SKristof Provost	jexec gw sysctl net.inet.ip.forwarding=1
333920c3410SKristof Provost
334920c3410SKristof Provost	ifconfig ${epair_gw}b 198.51.100.2/24 up
335920c3410SKristof Provost	route add -net 192.0.2.0/24 198.51.100.1
336920c3410SKristof Provost
337920c3410SKristof Provost	# Sanity check
338920c3410SKristof Provost	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1
339920c3410SKristof Provost
340920c3410SKristof Provost	jexec gw dnctl pipe 1 config delay 1200
341920c3410SKristof Provost	pft_set_rules gw \
342920c3410SKristof Provost		"pass out route-to (${epair_srv}b 192.0.2.1) to 192.0.2.1 dnpipe 1"
343920c3410SKristof Provost	jexec gw pfctl -e
344920c3410SKristof Provost
345920c3410SKristof Provost	# The ping request will pass, but take 1.2 seconds
346920c3410SKristof Provost	# So this works:
347c6f11163SKristof Provost	atf_check -s exit:0 -o ignore ping -c 1 -t 2 192.0.2.1
348920c3410SKristof Provost	# But this times out:
349920c3410SKristof Provost	atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.1
350920c3410SKristof Provost
351920c3410SKristof Provost	# return path dummynet
352920c3410SKristof Provost	pft_set_rules gw \
353920c3410SKristof Provost		"pass out route-to (${epair_srv}b 192.0.2.1) to 192.0.2.1 dnpipe (0, 1)"
354920c3410SKristof Provost
355920c3410SKristof Provost	# The ping request will pass, but take 1.2 seconds
356920c3410SKristof Provost	# So this works:
357c6f11163SKristof Provost	atf_check -s exit:0 -o ignore ping -c 1 -t 2 192.0.2.1
358920c3410SKristof Provost	# But this times out:
359920c3410SKristof Provost	atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.1
360920c3410SKristof Provost}
361920c3410SKristof Provost
362920c3410SKristof Provostdummynet_cleanup()
363920c3410SKristof Provost{
364920c3410SKristof Provost	pft_cleanup
365920c3410SKristof Provost}
366920c3410SKristof Provost
367c6f11163SKristof Provostatf_test_case "dummynet_in" "cleanup"
368c6f11163SKristof Provostdummynet_in_head()
369c6f11163SKristof Provost{
370c6f11163SKristof Provost	atf_set descr 'Thest that dummynet works as expected on pass in route-to packets'
371c6f11163SKristof Provost	atf_set require.user root
372c6f11163SKristof Provost}
373c6f11163SKristof Provost
374c6f11163SKristof Provostdummynet_in_body()
375c6f11163SKristof Provost{
376c6f11163SKristof Provost	dummynet_init
377c6f11163SKristof Provost
378c6f11163SKristof Provost	epair_srv=$(vnet_mkepair)
379c6f11163SKristof Provost	epair_gw=$(vnet_mkepair)
380c6f11163SKristof Provost
381c6f11163SKristof Provost	vnet_mkjail srv ${epair_srv}a
382c6f11163SKristof Provost	jexec srv ifconfig ${epair_srv}a 192.0.2.1/24 up
383c6f11163SKristof Provost	jexec srv route add default 192.0.2.2
384c6f11163SKristof Provost
385c6f11163SKristof Provost	vnet_mkjail gw ${epair_srv}b ${epair_gw}a
386c6f11163SKristof Provost	jexec gw ifconfig ${epair_srv}b 192.0.2.2/24 up
387c6f11163SKristof Provost	jexec gw ifconfig ${epair_gw}a 198.51.100.1/24 up
388c6f11163SKristof Provost	jexec gw sysctl net.inet.ip.forwarding=1
389c6f11163SKristof Provost
390c6f11163SKristof Provost	ifconfig ${epair_gw}b 198.51.100.2/24 up
391c6f11163SKristof Provost	route add -net 192.0.2.0/24 198.51.100.1
392c6f11163SKristof Provost
393c6f11163SKristof Provost	# Sanity check
394c6f11163SKristof Provost	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1
395c6f11163SKristof Provost
396c6f11163SKristof Provost	jexec gw dnctl pipe 1 config delay 1200
397c6f11163SKristof Provost	pft_set_rules gw \
398c6f11163SKristof Provost		"pass in route-to (${epair_srv}b 192.0.2.1) to 192.0.2.1 dnpipe 1"
399c6f11163SKristof Provost	jexec gw pfctl -e
400c6f11163SKristof Provost
401c6f11163SKristof Provost	# The ping request will pass, but take 1.2 seconds
402c6f11163SKristof Provost	# So this works:
403c6f11163SKristof Provost	echo "Expect 1.2 s"
404c6f11163SKristof Provost	ping -c 1 192.0.2.1
405c6f11163SKristof Provost	atf_check -s exit:0 -o ignore ping -c 1 -t 2 192.0.2.1
406c6f11163SKristof Provost	# But this times out:
407c6f11163SKristof Provost	atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.1
408c6f11163SKristof Provost
409c6f11163SKristof Provost	# return path dummynet
410c6f11163SKristof Provost	pft_set_rules gw \
411c6f11163SKristof Provost		"pass in route-to (${epair_srv}b 192.0.2.1) to 192.0.2.1 dnpipe (0, 1)"
412c6f11163SKristof Provost
413c6f11163SKristof Provost	# The ping request will pass, but take 1.2 seconds
414c6f11163SKristof Provost	# So this works:
415c6f11163SKristof Provost	echo "Expect 1.2 s"
416c6f11163SKristof Provost	ping -c 1 192.0.2.1
417c6f11163SKristof Provost	atf_check -s exit:0 -o ignore ping -c 1 -t 2 192.0.2.1
418c6f11163SKristof Provost	# But this times out:
419c6f11163SKristof Provost	atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.1
420c6f11163SKristof Provost}
421c6f11163SKristof Provost
422c6f11163SKristof Provostdummynet_in_cleanup()
423c6f11163SKristof Provost{
424c6f11163SKristof Provost	pft_cleanup
425c6f11163SKristof Provost}
426c6f11163SKristof Provost
42731828075SKristof Provostatf_test_case "ifbound" "cleanup"
42831828075SKristof Provostifbound_head()
42931828075SKristof Provost{
43031828075SKristof Provost	atf_set descr 'Test that route-to states bind the expected interface'
43131828075SKristof Provost	atf_set require.user root
43231828075SKristof Provost}
43331828075SKristof Provost
43431828075SKristof Provostifbound_body()
43531828075SKristof Provost{
43631828075SKristof Provost	pft_init
43731828075SKristof Provost
43831828075SKristof Provost	j="route_to:ifbound"
43931828075SKristof Provost
44031828075SKristof Provost	epair_one=$(vnet_mkepair)
44131828075SKristof Provost	epair_two=$(vnet_mkepair)
44231828075SKristof Provost	ifconfig ${epair_one}b up
44331828075SKristof Provost
44431828075SKristof Provost	vnet_mkjail ${j}2 ${epair_two}b
44531828075SKristof Provost	jexec ${j}2 ifconfig ${epair_two}b inet 198.51.100.2/24 up
44631828075SKristof Provost	jexec ${j}2 ifconfig ${epair_two}b inet alias 203.0.113.1/24
44731828075SKristof Provost	jexec ${j}2 route add default 198.51.100.1
44831828075SKristof Provost
44931828075SKristof Provost	vnet_mkjail $j ${epair_one}a ${epair_two}a
45031828075SKristof Provost	jexec $j ifconfig ${epair_one}a 192.0.2.1/24 up
45131828075SKristof Provost	jexec $j ifconfig ${epair_two}a 198.51.100.1/24 up
45231828075SKristof Provost	jexec $j route add default 192.0.2.2
45331828075SKristof Provost
45431828075SKristof Provost	jexec $j pfctl -e
45531828075SKristof Provost	pft_set_rules $j \
45631828075SKristof Provost		"set state-policy if-bound" \
45731828075SKristof Provost		"block" \
45831828075SKristof Provost		"pass out route-to (${epair_two}a 198.51.100.2)"
45931828075SKristof Provost
46031828075SKristof Provost	atf_check -s exit:0 -o ignore \
46131828075SKristof Provost	    jexec $j ping -c 3 203.0.113.1
46231828075SKristof Provost}
46331828075SKristof Provost
46431828075SKristof Provostifbound_cleanup()
46531828075SKristof Provost{
46631828075SKristof Provost	pft_cleanup
46731828075SKristof Provost}
46831828075SKristof Provost
469fb995824SKristof Provostatf_test_case "ifbound_v6" "cleanup"
470fb995824SKristof Provostifbound_v6_head()
471fb995824SKristof Provost{
472fb995824SKristof Provost	atf_set descr 'Test that route-to states for IPv6 bind the expected interface'
473fb995824SKristof Provost	atf_set require.user root
474fb995824SKristof Provost}
475fb995824SKristof Provost
476fb995824SKristof Provostifbound_v6_body()
477fb995824SKristof Provost{
478fb995824SKristof Provost	pft_init
479fb995824SKristof Provost
480fb995824SKristof Provost	j="route_to:ifbound_v6"
481fb995824SKristof Provost
482fb995824SKristof Provost	epair_one=$(vnet_mkepair)
483fb995824SKristof Provost	epair_two=$(vnet_mkepair)
484fb995824SKristof Provost	ifconfig ${epair_one}b up
485fb995824SKristof Provost
486fb995824SKristof Provost	vnet_mkjail ${j}2 ${epair_two}b
487fb995824SKristof Provost	jexec ${j}2 ifconfig ${epair_two}b inet6 2001:db8:1::2/64 up no_dad
488fb995824SKristof Provost	jexec ${j}2 ifconfig ${epair_two}b inet6 alias 2001:db8:2::1/64 no_dad
489fb995824SKristof Provost	jexec ${j}2 route -6 add default 2001:db8:1::1
490fb995824SKristof Provost
491fb995824SKristof Provost	vnet_mkjail $j ${epair_one}a ${epair_two}a
492fb995824SKristof Provost	jexec $j ifconfig ${epair_one}a inet6 2001:db8::1/64 up no_dad
493fb995824SKristof Provost	jexec $j ifconfig ${epair_two}a inet6 2001:db8:1::1/64 up no_dad
494fb995824SKristof Provost	jexec $j route -6 add default 2001:db8::2
495fb995824SKristof Provost
496fb995824SKristof Provost	jexec $j ping6 -c 3 2001:db8:1::2
497fb995824SKristof Provost
498fb995824SKristof Provost	jexec $j pfctl -e
499fb995824SKristof Provost	pft_set_rules $j \
500fb995824SKristof Provost		"set state-policy if-bound" \
501fb995824SKristof Provost		"block" \
502fb995824SKristof Provost		"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
503fb995824SKristof Provost		"pass out route-to (${epair_two}a 2001:db8:1::2)"
504fb995824SKristof Provost
505fb995824SKristof Provost	atf_check -s exit:0 -o ignore \
506fb995824SKristof Provost	    jexec $j ping6 -c 3 2001:db8:2::1
507fb995824SKristof Provost}
508fb995824SKristof Provost
509fb995824SKristof Provostifbound_v6_cleanup()
510fb995824SKristof Provost{
511fb995824SKristof Provost	pft_cleanup
512fb995824SKristof Provost}
513fb995824SKristof Provost
5146460322aSKristof Provostatf_test_case "ifbound_reply_to" "cleanup"
5156460322aSKristof Provostifbound_reply_to_head()
5166460322aSKristof Provost{
5176460322aSKristof Provost	atf_set descr 'Test that reply-to states bind to the expected interface'
5186460322aSKristof Provost	atf_set require.user root
519c46af893SJose Luis Duran	atf_set require.progs python3 scapy
5206460322aSKristof Provost}
5216460322aSKristof Provost
5226460322aSKristof Provostifbound_reply_to_body()
5236460322aSKristof Provost{
5246460322aSKristof Provost	pft_init
5256460322aSKristof Provost
5266460322aSKristof Provost	j="route_to:ifbound_reply_to"
5276460322aSKristof Provost
5286460322aSKristof Provost	epair_one=$(vnet_mkepair)
5296460322aSKristof Provost	epair_two=$(vnet_mkepair)
5306460322aSKristof Provost	ifconfig ${epair_one}b inet 192.0.2.2/24 up
5316460322aSKristof Provost	ifconfig ${epair_two}b up
5326460322aSKristof Provost
5336460322aSKristof Provost	vnet_mkjail $j ${epair_one}a ${epair_two}a
5346460322aSKristof Provost	jexec $j ifconfig ${epair_one}a 192.0.2.1/24 up
5356460322aSKristof Provost	jexec $j ifconfig ${epair_two}a 198.51.100.1/24 up
5366460322aSKristof Provost	jexec $j route add default 198.51.100.254
5376460322aSKristof Provost
5386460322aSKristof Provost	jexec $j pfctl -e
5396460322aSKristof Provost	pft_set_rules $j \
5406460322aSKristof Provost		"set state-policy if-bound" \
5416460322aSKristof Provost		"block" \
5426460322aSKristof Provost		"pass in on ${epair_one}a reply-to (${epair_one}a 192.0.2.2) inet from any to 192.0.2.0/24 keep state"
5436460322aSKristof Provost
5446460322aSKristof Provost	atf_check -s exit:0 -o ignore \
5456460322aSKristof Provost	    ping -c 3 192.0.2.1
5466460322aSKristof Provost
5476460322aSKristof Provost	atf_check -s exit:0 \
5486460322aSKristof Provost	    ${common_dir}/pft_ping.py \
5496460322aSKristof Provost	    --to 192.0.2.1 \
5506460322aSKristof Provost	    --from 203.0.113.2 \
5516460322aSKristof Provost	    --sendif ${epair_one}b \
5526460322aSKristof Provost	    --replyif ${epair_one}b
5536460322aSKristof Provost
5546460322aSKristof Provost	# pft_ping uses the same ID every time, so this will look like more traffic in the same state
5556460322aSKristof Provost	atf_check -s exit:0 \
5566460322aSKristof Provost	    ${common_dir}/pft_ping.py \
5576460322aSKristof Provost	    --to 192.0.2.1 \
5586460322aSKristof Provost	    --from 203.0.113.2 \
5596460322aSKristof Provost	    --sendif ${epair_one}b \
5606460322aSKristof Provost	    --replyif ${epair_one}b
5616460322aSKristof Provost
5626460322aSKristof Provost	jexec $j pfctl -ss -vv
5636460322aSKristof Provost}
5646460322aSKristof Provost
5656460322aSKristof Provostifbound_reply_to_cleanup()
5666460322aSKristof Provost{
5676460322aSKristof Provost	pft_cleanup
5686460322aSKristof Provost}
5696460322aSKristof Provost
570fb995824SKristof Provostatf_test_case "ifbound_reply_to_v6" "cleanup"
571fb995824SKristof Provostifbound_reply_to_v6_head()
572fb995824SKristof Provost{
573fb995824SKristof Provost	atf_set descr 'Test that reply-to states bind to the expected interface for IPv6'
574fb995824SKristof Provost	atf_set require.user root
575c46af893SJose Luis Duran	atf_set require.progs python3 scapy
576fb995824SKristof Provost}
577fb995824SKristof Provost
578fb995824SKristof Provostifbound_reply_to_v6_body()
579fb995824SKristof Provost{
580fb995824SKristof Provost	pft_init
581fb995824SKristof Provost
582fb995824SKristof Provost	j="route_to:ifbound_reply_to_v6"
583fb995824SKristof Provost
584fb995824SKristof Provost	epair_one=$(vnet_mkepair)
585fb995824SKristof Provost	epair_two=$(vnet_mkepair)
586fb995824SKristof Provost
587fb995824SKristof Provost	vnet_mkjail ${j}s ${epair_one}b ${epair_two}b
588fb995824SKristof Provost	jexec ${j}s ifconfig ${epair_one}b inet6 2001:db8::2/64 up no_dad
589fb995824SKristof Provost	jexec ${j}s ifconfig ${epair_two}b up
590fb995824SKristof Provost	#jexec ${j}s route -6 add default 2001:db8::1
591fb995824SKristof Provost
592fb995824SKristof Provost	vnet_mkjail $j ${epair_one}a ${epair_two}a
593fb995824SKristof Provost	jexec $j ifconfig ${epair_one}a inet6 2001:db8::1/64 up no_dad
594fb995824SKristof Provost	jexec $j ifconfig ${epair_two}a inet6 2001:db8:1::1/64 up no_dad
595fb995824SKristof Provost	jexec $j route -6 add default 2001:db8:1::254
596fb995824SKristof Provost
597fb995824SKristof Provost	jexec $j pfctl -e
598fb995824SKristof Provost	pft_set_rules $j \
599fb995824SKristof Provost		"set state-policy if-bound" \
600fb995824SKristof Provost		"block" \
601fb995824SKristof Provost		"pass quick inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
602fb995824SKristof Provost		"pass in on ${epair_one}a reply-to (${epair_one}a 2001:db8::2) inet6 from any to 2001:db8::/64 keep state"
603fb995824SKristof Provost
604fb995824SKristof Provost	atf_check -s exit:0 -o ignore \
605fb995824SKristof Provost	    jexec ${j}s ping6 -c 3 2001:db8::1
606fb995824SKristof Provost
607fb995824SKristof Provost	atf_check -s exit:0 \
608fb995824SKristof Provost	    jexec ${j}s ${common_dir}/pft_ping.py \
609fb995824SKristof Provost	    --to 2001:db8::1 \
610fb995824SKristof Provost	    --from 2001:db8:2::2 \
611fb995824SKristof Provost	    --sendif ${epair_one}b \
612fb995824SKristof Provost	    --replyif ${epair_one}b
613fb995824SKristof Provost
614fb995824SKristof Provost	# pft_ping uses the same ID every time, so this will look like more traffic in the same state
615fb995824SKristof Provost	atf_check -s exit:0 \
616fb995824SKristof Provost	    jexec ${j}s ${common_dir}/pft_ping.py \
617fb995824SKristof Provost	    --to 2001:db8::1 \
618fb995824SKristof Provost	    --from 2001:db8:2::2 \
619fb995824SKristof Provost	    --sendif ${epair_one}b \
620fb995824SKristof Provost	    --replyif ${epair_one}b
621fb995824SKristof Provost
622fb995824SKristof Provost	jexec $j pfctl -ss -vv
623fb995824SKristof Provost}
624fb995824SKristof Provost
625fb995824SKristof Provostifbound_reply_to_v6_cleanup()
626fb995824SKristof Provost{
627fb995824SKristof Provost	pft_cleanup
628fb995824SKristof Provost}
629fb995824SKristof Provost
630a983cea4SKristof Provostatf_test_case "ifbound_reply_to_rdr_dummynet" "cleanup"
631a983cea4SKristof Provostifbound_reply_to_rdr_dummynet_head()
632a983cea4SKristof Provost{
633a983cea4SKristof Provost	atf_set descr 'Test that reply-to states bind to the expected non-default-route interface after rdr and dummynet'
634a983cea4SKristof Provost	atf_set require.user root
635c46af893SJose Luis Duran	atf_set require.progs python3 scapy
636a983cea4SKristof Provost}
637a983cea4SKristof Provost
638a983cea4SKristof Provostifbound_reply_to_rdr_dummynet_body()
639a983cea4SKristof Provost{
640a983cea4SKristof Provost	dummynet_init
641a983cea4SKristof Provost
642a983cea4SKristof Provost	j="route_to:ifbound_reply_to_rdr_dummynet"
643a983cea4SKristof Provost
644a983cea4SKristof Provost	epair_one=$(vnet_mkepair)
645a983cea4SKristof Provost	epair_two=$(vnet_mkepair)
646a983cea4SKristof Provost	ifconfig ${epair_one}b inet 192.0.2.2/24 up
647a983cea4SKristof Provost	ifconfig ${epair_two}b up
648a983cea4SKristof Provost
649a983cea4SKristof Provost	vnet_mkjail $j ${epair_one}a ${epair_two}a
650a983cea4SKristof Provost	jexec $j ifconfig lo0 inet 127.0.0.1/8 up
651a983cea4SKristof Provost	jexec $j ifconfig ${epair_one}a 192.0.2.1/24 up
652a983cea4SKristof Provost	jexec $j ifconfig ${epair_two}a 198.51.100.1/24 up
653a983cea4SKristof Provost	jexec $j route add default 198.51.100.254
654a983cea4SKristof Provost
655a983cea4SKristof Provost	jexec $j pfctl -e
656a983cea4SKristof Provost	jexec $j dnctl pipe 1 config delay 1
657a983cea4SKristof Provost	pft_set_rules $j \
658a983cea4SKristof Provost		"set state-policy if-bound" \
659a983cea4SKristof Provost		"rdr on ${epair_one}a proto icmp from any to 192.0.2.1 -> 127.0.0.1" \
660a983cea4SKristof Provost		"rdr on ${epair_two}a proto icmp from any to 198.51.100.1 -> 127.0.0.1" \
661a983cea4SKristof Provost		"match in on ${epair_one}a inet all dnpipe (1, 1)" \
662a983cea4SKristof Provost		"pass in on ${epair_one}a reply-to (${epair_one}a 192.0.2.2) inet from any to 127.0.0.1 keep state"
663a983cea4SKristof Provost
664a983cea4SKristof Provost	atf_check -s exit:0 -o ignore \
665a983cea4SKristof Provost	    ping -c 3 192.0.2.1
666a983cea4SKristof Provost
667a983cea4SKristof Provost	atf_check -s exit:0 \
668a983cea4SKristof Provost	    ${common_dir}/pft_ping.py \
669a983cea4SKristof Provost	    --to 192.0.2.1 \
670a983cea4SKristof Provost	    --from 203.0.113.2 \
671a983cea4SKristof Provost	    --sendif ${epair_one}b \
672a983cea4SKristof Provost	    --replyif ${epair_one}b
673a983cea4SKristof Provost
674a983cea4SKristof Provost	# pft_ping uses the same ID every time, so this will look like more traffic in the same state
675a983cea4SKristof Provost	atf_check -s exit:0 \
676a983cea4SKristof Provost	    ${common_dir}/pft_ping.py \
677a983cea4SKristof Provost	    --to 192.0.2.1 \
678a983cea4SKristof Provost	    --from 203.0.113.2 \
679a983cea4SKristof Provost	    --sendif ${epair_one}b \
680a983cea4SKristof Provost	    --replyif ${epair_one}b
681a983cea4SKristof Provost
682a983cea4SKristof Provost	jexec $j pfctl -sr -vv
683a983cea4SKristof Provost	jexec $j pfctl -ss -vv
684a983cea4SKristof Provost}
685a983cea4SKristof Provost
686a983cea4SKristof Provostifbound_reply_to_rdr_dummynet_cleanup()
687a983cea4SKristof Provost{
688a983cea4SKristof Provost	pft_cleanup
689a983cea4SKristof Provost}
690a983cea4SKristof Provost
691b8ef285fSKristof Provostatf_test_case "dummynet_frag" "cleanup"
692b8ef285fSKristof Provostdummynet_frag_head()
693b8ef285fSKristof Provost{
694b8ef285fSKristof Provost	atf_set descr 'Test fragmentation with route-to and dummynet'
695b8ef285fSKristof Provost	atf_set require.user root
696b8ef285fSKristof Provost}
697b8ef285fSKristof Provost
698b8ef285fSKristof Provostdummynet_frag_body()
699b8ef285fSKristof Provost{
700b8ef285fSKristof Provost	pft_init
701b8ef285fSKristof Provost	dummynet_init
702b8ef285fSKristof Provost
703b8ef285fSKristof Provost	epair_one=$(vnet_mkepair)
704b8ef285fSKristof Provost	epair_two=$(vnet_mkepair)
705b8ef285fSKristof Provost
706b8ef285fSKristof Provost	ifconfig ${epair_one}a 192.0.2.1/24 up
707b8ef285fSKristof Provost
708b8ef285fSKristof Provost	vnet_mkjail alcatraz ${epair_one}b ${epair_two}a
709b8ef285fSKristof Provost	jexec alcatraz ifconfig ${epair_one}b 192.0.2.2/24 up
710b8ef285fSKristof Provost	jexec alcatraz ifconfig ${epair_two}a 198.51.100.1/24 up
711b8ef285fSKristof Provost	jexec alcatraz sysctl net.inet.ip.forwarding=1
712b8ef285fSKristof Provost
713b8ef285fSKristof Provost	vnet_mkjail singsing ${epair_two}b
714b8ef285fSKristof Provost	jexec singsing ifconfig ${epair_two}b 198.51.100.2/24 up
715b8ef285fSKristof Provost	jexec singsing route add default 198.51.100.1
716b8ef285fSKristof Provost
717b8ef285fSKristof Provost	route add 198.51.100.0/24 192.0.2.2
718b8ef285fSKristof Provost
719b8ef285fSKristof Provost	jexec alcatraz dnctl pipe 1 config bw 1000Byte/s burst 4500
720b8ef285fSKristof Provost	jexec alcatraz dnctl pipe 2 config
721b8ef285fSKristof Provost	# This second pipe ensures that the pf_test(PF_OUT) call in pf_route() doesn't
722b8ef285fSKristof Provost	# delay packets in dummynet (by inheriting pipe 1 from the input rule).
723b8ef285fSKristof Provost
724b8ef285fSKristof Provost	jexec alcatraz pfctl -e
725b8ef285fSKristof Provost	pft_set_rules alcatraz \
726b8ef285fSKristof Provost		"set reassemble yes" \
727b8ef285fSKristof Provost		"pass in route-to (${epair_two}a 198.51.100.2) inet proto icmp all icmp-type echoreq dnpipe 1" \
728b8ef285fSKristof Provost		"pass out dnpipe 2"
729b8ef285fSKristof Provost
730b8ef285fSKristof Provost
731b8ef285fSKristof Provost	atf_check -s exit:0 -o ignore ping -c 1 198.51.100.2
732b8ef285fSKristof Provost	atf_check -s exit:0 -o ignore ping -c 1 -s 4000 198.51.100.2
733b8ef285fSKristof Provost}
734b8ef285fSKristof Provost
735b8ef285fSKristof Provostdummynet_frag_cleanup()
736b8ef285fSKristof Provost{
737b8ef285fSKristof Provost	pft_cleanup
738b8ef285fSKristof Provost}
739b8ef285fSKristof Provost
7400ea0c026SKristof Provostatf_test_case "dummynet_double" "cleanup"
7410ea0c026SKristof Provostdummynet_double_head()
7420ea0c026SKristof Provost{
7430ea0c026SKristof Provost	atf_set descr 'Ensure dummynet is not applied multiple times'
7440ea0c026SKristof Provost	atf_set require.user root
7450ea0c026SKristof Provost}
7460ea0c026SKristof Provost
7470ea0c026SKristof Provostdummynet_double_body()
7480ea0c026SKristof Provost{
7490ea0c026SKristof Provost	pft_init
7500ea0c026SKristof Provost	dummynet_init
7510ea0c026SKristof Provost
7520ea0c026SKristof Provost	epair_one=$(vnet_mkepair)
7530ea0c026SKristof Provost	epair_two=$(vnet_mkepair)
7540ea0c026SKristof Provost
7550ea0c026SKristof Provost	ifconfig ${epair_one}a 192.0.2.1/24 up
7560ea0c026SKristof Provost
7570ea0c026SKristof Provost	vnet_mkjail alcatraz ${epair_one}b ${epair_two}a
7580ea0c026SKristof Provost	jexec alcatraz ifconfig ${epair_one}b 192.0.2.2/24 up
7590ea0c026SKristof Provost	jexec alcatraz ifconfig ${epair_two}a 198.51.100.1/24 up
7600ea0c026SKristof Provost	jexec alcatraz sysctl net.inet.ip.forwarding=1
7610ea0c026SKristof Provost
7620ea0c026SKristof Provost	vnet_mkjail singsing ${epair_two}b
7630ea0c026SKristof Provost	jexec singsing ifconfig ${epair_two}b 198.51.100.2/24 up
7640ea0c026SKristof Provost	jexec singsing route add default 198.51.100.1
7650ea0c026SKristof Provost
7660ea0c026SKristof Provost	route add 198.51.100.0/24 192.0.2.2
7670ea0c026SKristof Provost
7680ea0c026SKristof Provost	jexec alcatraz dnctl pipe 1 config delay 800
7690ea0c026SKristof Provost
7700ea0c026SKristof Provost	jexec alcatraz pfctl -e
7710ea0c026SKristof Provost	pft_set_rules alcatraz \
7720ea0c026SKristof Provost		"set reassemble yes" \
7730ea0c026SKristof Provost		"nat on ${epair_two}a from 192.0.2.0/24 -> (${epair_two}a)" \
7740ea0c026SKristof Provost		"pass in route-to (${epair_two}a 198.51.100.2) inet proto icmp all icmp-type echoreq dnpipe (1, 1)" \
7750ea0c026SKristof Provost		"pass out route-to (${epair_two}a 198.51.100.2) inet proto icmp all icmp-type echoreq"
7760ea0c026SKristof Provost
7770ea0c026SKristof Provost	ping -c 1 198.51.100.2
7780ea0c026SKristof Provost	jexec alcatraz pfctl -sr -vv
7790ea0c026SKristof Provost	jexec alcatraz pfctl -ss -vv
7800ea0c026SKristof Provost
7810ea0c026SKristof Provost	# We expect to be delayed 1.6 seconds, so timeout of two seconds passes, but
7820ea0c026SKristof Provost	# timeout of 1 does not.
7830ea0c026SKristof Provost	atf_check -s exit:0 -o ignore ping -t 2 -c 1 198.51.100.2
7840ea0c026SKristof Provost	atf_check -s exit:2 -o ignore ping -t 1 -c 1 198.51.100.2
7850ea0c026SKristof Provost}
7860ea0c026SKristof Provost
7870ea0c026SKristof Provostdummynet_double_cleanup()
7880ea0c026SKristof Provost{
7890ea0c026SKristof Provost	pft_cleanup
7900ea0c026SKristof Provost}
7910ea0c026SKristof Provost
7929aeee948SKristof Provostatf_test_case "sticky" "cleanup"
7939aeee948SKristof Provoststicky_head()
7949aeee948SKristof Provost{
7959aeee948SKristof Provost	atf_set descr 'Set and retrieve a rule with sticky-address'
7969aeee948SKristof Provost	atf_set require.user root
7979aeee948SKristof Provost}
7989aeee948SKristof Provost
7999aeee948SKristof Provoststicky_body()
8009aeee948SKristof Provost{
8019aeee948SKristof Provost	pft_init
8029aeee948SKristof Provost
8039aeee948SKristof Provost	vnet_mkjail alcatraz
8049aeee948SKristof Provost
8059aeee948SKristof Provost	pft_set_rules alcatraz \
8069aeee948SKristof Provost	    "pass in quick log on n_test_h_rtr route-to (n_srv_h_rtr <change_dst>) sticky-address from any to <dst> keep state"
8079aeee948SKristof Provost
8089aeee948SKristof Provost	jexec alcatraz pfctl -qvvsr
8099aeee948SKristof Provost}
8109aeee948SKristof Provost
8119aeee948SKristof Provoststicky_cleanup()
8129aeee948SKristof Provost{
8139aeee948SKristof Provost	pft_cleanup
8149aeee948SKristof Provost}
8159aeee948SKristof Provost
816ad591cafSKristof Provostatf_test_case "ttl" "cleanup"
817ad591cafSKristof Provostttl_head()
818ad591cafSKristof Provost{
819ad591cafSKristof Provost	atf_set descr 'Ensure we decrement TTL on route-to'
820ad591cafSKristof Provost	atf_set require.user root
821ad591cafSKristof Provost}
822ad591cafSKristof Provost
823ad591cafSKristof Provostttl_body()
824ad591cafSKristof Provost{
825ad591cafSKristof Provost	pft_init
826ad591cafSKristof Provost
827ad591cafSKristof Provost	epair_one=$(vnet_mkepair)
828ad591cafSKristof Provost	epair_two=$(vnet_mkepair)
829ad591cafSKristof Provost	ifconfig ${epair_one}b 192.0.2.2/24 up
830ad591cafSKristof Provost	route add default 192.0.2.1
831ad591cafSKristof Provost
832ad591cafSKristof Provost	vnet_mkjail alcatraz ${epair_one}a ${epair_two}a
833ad591cafSKristof Provost	jexec alcatraz ifconfig ${epair_one}a 192.0.2.1/24 up
834ad591cafSKristof Provost	jexec alcatraz ifconfig ${epair_two}a 198.51.100.1/24 up
835ad591cafSKristof Provost	jexec alcatraz sysctl net.inet.ip.forwarding=1
836ad591cafSKristof Provost
837ad591cafSKristof Provost	vnet_mkjail singsing ${epair_two}b
838ad591cafSKristof Provost	jexec singsing ifconfig ${epair_two}b 198.51.100.2/24 up
839ad591cafSKristof Provost	jexec singsing route add default 198.51.100.1
840ad591cafSKristof Provost
841ad591cafSKristof Provost	# Sanity check
842ad591cafSKristof Provost	atf_check -s exit:0 -o ignore \
843ad591cafSKristof Provost	    ping -c 3 198.51.100.2
844ad591cafSKristof Provost
845ad591cafSKristof Provost	jexec alcatraz pfctl -e
846ad591cafSKristof Provost	pft_set_rules alcatraz \
847ad591cafSKristof Provost		"pass out" \
848ad591cafSKristof Provost		"pass in route-to (${epair_two}a 198.51.100.2)"
849ad591cafSKristof Provost
850ad591cafSKristof Provost	atf_check -s exit:0 -o ignore \
851ad591cafSKristof Provost	    ping -c 3 198.51.100.2
852ad591cafSKristof Provost
853ad591cafSKristof Provost	atf_check -s exit:2 -o ignore \
854ad591cafSKristof Provost	    ping -m 1 -c 3 198.51.100.2
855ad591cafSKristof Provost}
856ad591cafSKristof Provost
857ad591cafSKristof Provostttl_cleanup()
858ad591cafSKristof Provost{
859ad591cafSKristof Provost	pft_cleanup
860ad591cafSKristof Provost}
861ad591cafSKristof Provost
862cbd06dd2SKajetan Staszkiewicz
863cbd06dd2SKajetan Staszkiewiczatf_test_case "empty_pool" "cleanup"
864cbd06dd2SKajetan Staszkiewiczempty_pool_head()
865cbd06dd2SKajetan Staszkiewicz{
866cbd06dd2SKajetan Staszkiewicz	atf_set descr 'Route-to with empty pool'
867cbd06dd2SKajetan Staszkiewicz	atf_set require.user root
868cbd06dd2SKajetan Staszkiewicz}
869cbd06dd2SKajetan Staszkiewicz
870cbd06dd2SKajetan Staszkiewiczempty_pool_body()
871cbd06dd2SKajetan Staszkiewicz{
872cbd06dd2SKajetan Staszkiewicz	pft_init
873cbd06dd2SKajetan Staszkiewicz	setup_router_server_ipv6
874cbd06dd2SKajetan Staszkiewicz
875cbd06dd2SKajetan Staszkiewicz
876cbd06dd2SKajetan Staszkiewicz	pft_set_rules router \
877cbd06dd2SKajetan Staszkiewicz		"block" \
878cbd06dd2SKajetan Staszkiewicz		"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
879cbd06dd2SKajetan Staszkiewicz		"pass in  on ${epair_tester}b route-to (${epair_server}a <nonexistent>) inet6 from any to ${net_server_host_server}" \
880cbd06dd2SKajetan Staszkiewicz		"pass out on ${epair_server}a"
881cbd06dd2SKajetan Staszkiewicz
882cbd06dd2SKajetan Staszkiewicz	# pf_map_addr_sn() won't be able to pick a target address, because
883cbd06dd2SKajetan Staszkiewicz	# the table used in redireciton pool is empty. Packet will not be
884cbd06dd2SKajetan Staszkiewicz	# forwarded, error counter will be increased.
885cbd06dd2SKajetan Staszkiewicz	ping_server_check_reply exit:1
886cbd06dd2SKajetan Staszkiewicz	# Ignore warnings about not-loaded ALTQ
887cbd06dd2SKajetan Staszkiewicz	atf_check -o "match:map-failed +1 +" -x "jexec router pfctl -qvvsi 2> /dev/null"
888cbd06dd2SKajetan Staszkiewicz}
889cbd06dd2SKajetan Staszkiewicz
890cbd06dd2SKajetan Staszkiewiczempty_pool_cleanup()
891cbd06dd2SKajetan Staszkiewicz{
892cbd06dd2SKajetan Staszkiewicz	pft_cleanup
893cbd06dd2SKajetan Staszkiewicz}
894cbd06dd2SKajetan Staszkiewicz
895cbd06dd2SKajetan Staszkiewicz
896*04dcbb44SKajetan Staszkiewiczatf_test_case "table_loop" "cleanup"
897*04dcbb44SKajetan Staszkiewicz
898*04dcbb44SKajetan Staszkiewicztable_loop_head()
899*04dcbb44SKajetan Staszkiewicz{
900*04dcbb44SKajetan Staszkiewicz	atf_set descr 'Check that iterating over tables poperly loops'
901*04dcbb44SKajetan Staszkiewicz	atf_set require.user root
902*04dcbb44SKajetan Staszkiewicz}
903*04dcbb44SKajetan Staszkiewicz
904*04dcbb44SKajetan Staszkiewicztable_loop_body()
905*04dcbb44SKajetan Staszkiewicz{
906*04dcbb44SKajetan Staszkiewicz	setup_router_server_nat64
907*04dcbb44SKajetan Staszkiewicz
908*04dcbb44SKajetan Staszkiewicz	# Clients will connect from another network behind the router.
909*04dcbb44SKajetan Staszkiewicz	# This allows for using multiple source addresses.
910*04dcbb44SKajetan Staszkiewicz	jexec router route add -6 ${net_clients_6}::/${net_clients_6_mask} ${net_tester_6_host_tester}
911*04dcbb44SKajetan Staszkiewicz	jexec router route add    ${net_clients_4}.0/${net_clients_4_mask} ${net_tester_4_host_tester}
912*04dcbb44SKajetan Staszkiewicz
913*04dcbb44SKajetan Staszkiewicz	# The servers are reachable over additional IP addresses for
914*04dcbb44SKajetan Staszkiewicz	# testing of tables and subnets. The addresses are noncontinougnus
915*04dcbb44SKajetan Staszkiewicz	# for pf_map_addr() counter tests.
916*04dcbb44SKajetan Staszkiewicz	for i in 0 1 4 5; do
917*04dcbb44SKajetan Staszkiewicz		a1=$((24 + i))
918*04dcbb44SKajetan Staszkiewicz		jexec server1 ifconfig ${epair_server1}b inet  ${net_server1_4}.${a1}/32 alias
919*04dcbb44SKajetan Staszkiewicz		jexec server1 ifconfig ${epair_server1}b inet6 ${net_server1_6}::42:${i}/128 alias
920*04dcbb44SKajetan Staszkiewicz		a2=$((40 + i))
921*04dcbb44SKajetan Staszkiewicz		jexec server2 ifconfig ${epair_server2}b inet  ${net_server2_4}.${a2}/32 alias
922*04dcbb44SKajetan Staszkiewicz		jexec server2 ifconfig ${epair_server2}b inet6 ${net_server2_6}::42:${i}/128 alias
923*04dcbb44SKajetan Staszkiewicz	done
924*04dcbb44SKajetan Staszkiewicz
925*04dcbb44SKajetan Staszkiewicz	jexec router pfctl -e
926*04dcbb44SKajetan Staszkiewicz	pft_set_rules router \
927*04dcbb44SKajetan Staszkiewicz		"set debug loud" \
928*04dcbb44SKajetan Staszkiewicz		"set reassemble yes" \
929*04dcbb44SKajetan Staszkiewicz		"set state-policy if-bound" \
930*04dcbb44SKajetan Staszkiewicz		"table <rt_targets_1> { ${net_server1_6}::42:4/127 ${net_server1_6}::42:0/127 }" \
931*04dcbb44SKajetan Staszkiewicz		"table <rt_targets_2> { ${net_server2_6}::42:4/127 }" \
932*04dcbb44SKajetan Staszkiewicz		"pass in on ${epair_tester}b \
933*04dcbb44SKajetan Staszkiewicz			route-to { \
934*04dcbb44SKajetan Staszkiewicz			(${epair_server1}a <rt_targets_1>) \
935*04dcbb44SKajetan Staszkiewicz			(${epair_server2}a <rt_targets_2_empty>) \
936*04dcbb44SKajetan Staszkiewicz			(${epair_server2}a <rt_targets_2>) \
937*04dcbb44SKajetan Staszkiewicz			} \
938*04dcbb44SKajetan Staszkiewicz		inet6 proto tcp \
939*04dcbb44SKajetan Staszkiewicz		keep state"
940*04dcbb44SKajetan Staszkiewicz
941*04dcbb44SKajetan Staszkiewicz	# Both hosts of the pool are tables. Each table gets iterated over once,
942*04dcbb44SKajetan Staszkiewicz	# then the pool iterates to the next host, which is also iterated,
943*04dcbb44SKajetan Staszkiewicz	# then the pool loops back to the 1st host. If an empty table is found,
944*04dcbb44SKajetan Staszkiewicz	# it is skipped. Unless that's the only table, that is tested by
945*04dcbb44SKajetan Staszkiewicz	# the "empty_pool" test.
946*04dcbb44SKajetan Staszkiewicz	for port in $(seq 1 7); do
947*04dcbb44SKajetan Staszkiewicz	port=$((4200 + port))
948*04dcbb44SKajetan Staszkiewicz		atf_check -s exit:0 ${common_dir}/pft_ping.py \
949*04dcbb44SKajetan Staszkiewicz			--sendif ${epair_tester}a --replyif ${epair_tester}a \
950*04dcbb44SKajetan Staszkiewicz			--fromaddr ${net_clients_6}::1 --to ${host_server_6} \
951*04dcbb44SKajetan Staszkiewicz			--ping-type=tcp3way --send-sport=${port}
952*04dcbb44SKajetan Staszkiewicz	done
953*04dcbb44SKajetan Staszkiewicz
954*04dcbb44SKajetan Staszkiewicz	states=$(mktemp) || exit 1
955*04dcbb44SKajetan Staszkiewicz	jexec router pfctl -qvvss | normalize_pfctl_s > $states
956*04dcbb44SKajetan Staszkiewicz	cat $states
957*04dcbb44SKajetan Staszkiewicz
958*04dcbb44SKajetan Staszkiewicz	for state_regexp in \
959*04dcbb44SKajetan Staszkiewicz		"${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4201\] .* route-to: ${net_server1_6}::42:0@${epair_server1}a" \
960*04dcbb44SKajetan Staszkiewicz		"${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4202\] .* route-to: ${net_server1_6}::42:1@${epair_server1}a" \
961*04dcbb44SKajetan Staszkiewicz		"${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4203\] .* route-to: ${net_server1_6}::42:4@${epair_server1}a" \
962*04dcbb44SKajetan Staszkiewicz		"${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4204\] .* route-to: ${net_server1_6}::42:5@${epair_server1}a" \
963*04dcbb44SKajetan Staszkiewicz		"${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4205\] .* route-to: ${net_server2_6}::42:4@${epair_server2}a" \
964*04dcbb44SKajetan Staszkiewicz		"${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4206\] .* route-to: ${net_server2_6}::42:5@${epair_server2}a" \
965*04dcbb44SKajetan Staszkiewicz		"${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4207\] .* route-to: ${net_server1_6}::42:0@${epair_server1}a" \
966*04dcbb44SKajetan Staszkiewicz	; do
967*04dcbb44SKajetan Staszkiewicz		grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'"
968*04dcbb44SKajetan Staszkiewicz	done
969*04dcbb44SKajetan Staszkiewicz}
970*04dcbb44SKajetan Staszkiewicz
971*04dcbb44SKajetan Staszkiewicztable_loop_cleanup()
972*04dcbb44SKajetan Staszkiewicz{
973*04dcbb44SKajetan Staszkiewicz	pft_cleanup
974*04dcbb44SKajetan Staszkiewicz}
975*04dcbb44SKajetan Staszkiewicz
976*04dcbb44SKajetan Staszkiewicz
977d850143eSKristof Provostatf_init_test_cases()
978d850143eSKristof Provost{
979d850143eSKristof Provost	atf_add_test_case "v4"
980d850143eSKristof Provost	atf_add_test_case "v6"
981f37667e2SKristof Provost	atf_add_test_case "multiwan"
982f808bb9bSKristof Provost	atf_add_test_case "multiwanlocal"
98330276ef1SKristof Provost	atf_add_test_case "icmp_nat"
984920c3410SKristof Provost	atf_add_test_case "dummynet"
985c6f11163SKristof Provost	atf_add_test_case "dummynet_in"
98631828075SKristof Provost	atf_add_test_case "ifbound"
987fb995824SKristof Provost	atf_add_test_case "ifbound_v6"
9886460322aSKristof Provost	atf_add_test_case "ifbound_reply_to"
989fb995824SKristof Provost	atf_add_test_case "ifbound_reply_to_v6"
990a983cea4SKristof Provost	atf_add_test_case "ifbound_reply_to_rdr_dummynet"
991b8ef285fSKristof Provost	atf_add_test_case "dummynet_frag"
9920ea0c026SKristof Provost	atf_add_test_case "dummynet_double"
9939aeee948SKristof Provost	atf_add_test_case "sticky"
994ad591cafSKristof Provost	atf_add_test_case "ttl"
995cbd06dd2SKajetan Staszkiewicz	atf_add_test_case "empty_pool"
996*04dcbb44SKajetan Staszkiewicz	atf_add_test_case "table_loop"
997d850143eSKristof Provost}
998