xref: /freebsd/tests/sys/netpfil/pf/counters.sh (revision 7cd3854f827faaad1ecf414d20bdf6802cfa60f8)
16353f5d9SKajetan Staszkiewicz#
26353f5d9SKajetan Staszkiewicz# SPDX-License-Identifier: BSD-2-Clause
36353f5d9SKajetan Staszkiewicz#
46353f5d9SKajetan Staszkiewicz# Copyright (c) 2025 Kajetan Staszkiewicz
56353f5d9SKajetan Staszkiewicz#
66353f5d9SKajetan Staszkiewicz# Redistribution and use in source and binary forms, with or without
76353f5d9SKajetan Staszkiewicz# modification, are permitted provided that the following conditions
86353f5d9SKajetan Staszkiewicz# are met:
96353f5d9SKajetan Staszkiewicz# 1. Redistributions of source code must retain the above copyright
106353f5d9SKajetan Staszkiewicz#    notice, this list of conditions and the following disclaimer.
116353f5d9SKajetan Staszkiewicz# 2. Redistributions in binary form must reproduce the above copyright
126353f5d9SKajetan Staszkiewicz#    notice, this list of conditions and the following disclaimer in the
136353f5d9SKajetan Staszkiewicz#    documentation and/or other materials provided with the distribution.
146353f5d9SKajetan Staszkiewicz#
156353f5d9SKajetan Staszkiewicz# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
166353f5d9SKajetan Staszkiewicz# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
176353f5d9SKajetan Staszkiewicz# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
186353f5d9SKajetan Staszkiewicz# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
196353f5d9SKajetan Staszkiewicz# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
206353f5d9SKajetan Staszkiewicz# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
216353f5d9SKajetan Staszkiewicz# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
226353f5d9SKajetan Staszkiewicz# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
236353f5d9SKajetan Staszkiewicz# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
246353f5d9SKajetan Staszkiewicz# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
256353f5d9SKajetan Staszkiewicz# SUCH DAMAGE.
266353f5d9SKajetan Staszkiewicz
276353f5d9SKajetan Staszkiewicz. $(atf_get_srcdir)/utils.subr
286353f5d9SKajetan Staszkiewicz
296353f5d9SKajetan Staszkiewiczget_counters()
306353f5d9SKajetan Staszkiewicz{
316353f5d9SKajetan Staszkiewicz	echo " === rules ==="
326353f5d9SKajetan Staszkiewicz	rules=$(mktemp) || exit
336353f5d9SKajetan Staszkiewicz	(jexec router pfctl -qvvsn ; jexec router pfctl -qvvsr) | normalize_pfctl_s > $rules
346353f5d9SKajetan Staszkiewicz	cat $rules
356353f5d9SKajetan Staszkiewicz
366353f5d9SKajetan Staszkiewicz	echo " === tables ==="
376353f5d9SKajetan Staszkiewicz	tables=$(mktemp) || exit 1
386353f5d9SKajetan Staszkiewicz	jexec router pfctl -qvvsT > $tables
396353f5d9SKajetan Staszkiewicz	cat $tables
406353f5d9SKajetan Staszkiewicz
416353f5d9SKajetan Staszkiewicz	echo " === states ==="
426353f5d9SKajetan Staszkiewicz	states=$(mktemp) || exit 1
436353f5d9SKajetan Staszkiewicz	jexec router pfctl -qvvss | normalize_pfctl_s > $states
446353f5d9SKajetan Staszkiewicz	cat $states
456353f5d9SKajetan Staszkiewicz
466353f5d9SKajetan Staszkiewicz	echo " === nodes ==="
476353f5d9SKajetan Staszkiewicz	nodes=$(mktemp) || exit 1
486353f5d9SKajetan Staszkiewicz	jexec router pfctl -qvvsS | normalize_pfctl_s > $nodes
496353f5d9SKajetan Staszkiewicz	cat $nodes
506353f5d9SKajetan Staszkiewicz}
516353f5d9SKajetan Staszkiewicz
526353f5d9SKajetan Staszkiewiczatf_test_case "match_pass_state" "cleanup"
536353f5d9SKajetan Staszkiewiczmatch_pass_state_head()
546353f5d9SKajetan Staszkiewicz{
556353f5d9SKajetan Staszkiewicz	atf_set descr 'Counters on match and pass rules'
566353f5d9SKajetan Staszkiewicz	atf_set require.user root
576353f5d9SKajetan Staszkiewicz}
586353f5d9SKajetan Staszkiewicz
596353f5d9SKajetan Staszkiewiczmatch_pass_state_body()
606353f5d9SKajetan Staszkiewicz{
616353f5d9SKajetan Staszkiewicz	setup_router_server_ipv6
626353f5d9SKajetan Staszkiewicz
636353f5d9SKajetan Staszkiewicz	# Thest counters for a statefull firewall. Expose the behaviour of
646353f5d9SKajetan Staszkiewicz	# increasing table counters if a table is used multiple times.
656353f5d9SKajetan Staszkiewicz	# The table "tbl_in" is used both in match and pass rule. It's counters
666353f5d9SKajetan Staszkiewicz	# are incremented twice. The tables "tbl_out_match" and "tbl_out_pass"
676353f5d9SKajetan Staszkiewicz	# are used only once and have their countes increased only once.
686353f5d9SKajetan Staszkiewicz	# Test source node counters for this simple scenario too.
696353f5d9SKajetan Staszkiewicz	pft_set_rules router \
706353f5d9SKajetan Staszkiewicz		"set state-policy if-bound" \
716353f5d9SKajetan Staszkiewicz		"table <tbl_in>  { ${net_tester_host_tester} }" \
726353f5d9SKajetan Staszkiewicz		"table <tbl_out_pass> { ${net_server_host_server} }" \
736353f5d9SKajetan Staszkiewicz		"table <tbl_out_match> { ${net_server_host_server} }" \
746353f5d9SKajetan Staszkiewicz		"block" \
756353f5d9SKajetan Staszkiewicz		"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
766353f5d9SKajetan Staszkiewicz		"match in  on ${epair_tester}b inet6 proto tcp from <tbl_in>  scrub (random-id)" \
776353f5d9SKajetan Staszkiewicz		"pass  in  on ${epair_tester}b inet6 proto tcp from <tbl_in>  keep state (max-src-states 3 source-track rule)" \
786353f5d9SKajetan Staszkiewicz		"match out on ${epair_server}a inet6 proto tcp to   <tbl_out_match> scrub (random-id)" \
796353f5d9SKajetan Staszkiewicz		"pass  out on ${epair_server}a inet6 proto tcp to   <tbl_out_pass> keep state"
806353f5d9SKajetan Staszkiewicz
816353f5d9SKajetan Staszkiewicz	# Use a real TCP connection so that it will be properly closed, guaranteeing the amount of packets.
826353f5d9SKajetan Staszkiewicz	atf_check -s exit:0 -o match:"This is a test" -x \
836353f5d9SKajetan Staszkiewicz		"echo 'This is a test' | nc -w3 ${net_server_host_server} echo"
846353f5d9SKajetan Staszkiewicz	# Let FINs pass through.
856353f5d9SKajetan Staszkiewicz	sleep 1
866353f5d9SKajetan Staszkiewicz	get_counters
876353f5d9SKajetan Staszkiewicz
886353f5d9SKajetan Staszkiewicz	for rule_regexp in \
896353f5d9SKajetan Staszkiewicz		"@3 match in on ${epair_tester}b .* Packets: 10 Bytes: 766 States: 1 " \
906353f5d9SKajetan Staszkiewicz		"@4 pass in on ${epair_tester}b .* Packets: 10 Bytes: 766 States: 1 " \
916353f5d9SKajetan Staszkiewicz		"@5 match out on ${epair_server}a .* Packets: 10 Bytes: 766 States: 1 " \
926353f5d9SKajetan Staszkiewicz		"@6 pass out on ${epair_server}a .* Packets: 10 Bytes: 766 States: 1 " \
936353f5d9SKajetan Staszkiewicz	; do
946353f5d9SKajetan Staszkiewicz		grep -qE "${rule_regexp}" $rules || atf_fail "Rule regexp not found for '${rule_regexp}'"
956353f5d9SKajetan Staszkiewicz	done
966353f5d9SKajetan Staszkiewicz
976353f5d9SKajetan Staszkiewicz	table_counters_single="Evaluations: NoMatch: 0 Match: 1 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 4 Bytes: 311 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 6 Bytes: 455 Out/XPass: Packets: 0 Bytes: 0"
986353f5d9SKajetan Staszkiewicz	table_counters_double="Evaluations: NoMatch: 0 Match: 2 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 12 Bytes: 910 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 8 Bytes: 622 Out/XPass: Packets: 0 Bytes: 0"
996353f5d9SKajetan Staszkiewicz	for table_test in \
1006353f5d9SKajetan Staszkiewicz		"tbl_in___${table_counters_double}" \
1016353f5d9SKajetan Staszkiewicz		"tbl_out_match___${table_counters_single}" \
1026353f5d9SKajetan Staszkiewicz		"tbl_out_pass___${table_counters_single}" \
1036353f5d9SKajetan Staszkiewicz	; do
1046353f5d9SKajetan Staszkiewicz		table_name=${table_test%%___*}
1056353f5d9SKajetan Staszkiewicz		table_regexp=${table_test##*___}
1066353f5d9SKajetan Staszkiewicz		table=$(mktemp) || exit 1
1076353f5d9SKajetan Staszkiewicz		cat $tables | grep -A10 $table_name | tr '\n' ' ' | awk '{gsub("[\\[\\]]", " ", $0); gsub("[[:blank:]]+"," ",$0); print $0}' > ${table}
1086353f5d9SKajetan Staszkiewicz		grep -qE "${table_regexp}" ${table} || atf_fail "Bad counters for table ${table_name}"
1096353f5d9SKajetan Staszkiewicz	done;
1106353f5d9SKajetan Staszkiewicz
1116353f5d9SKajetan Staszkiewicz	for state_regexp in \
1126353f5d9SKajetan Staszkiewicz		"${epair_tester}b tcp ${net_server_host_server}.* <- ${net_tester_host_tester}.* 6:4 pkts, 455:311 bytes, rule 4," \
1136353f5d9SKajetan Staszkiewicz		"${epair_server}a tcp ${net_server_host_tester}.* -> ${net_server_host_server}.* 6:4 pkts, 455:311 bytes, rule 6," \
1146353f5d9SKajetan Staszkiewicz	; do
1156353f5d9SKajetan Staszkiewicz		grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'"
1166353f5d9SKajetan Staszkiewicz	done
1176353f5d9SKajetan Staszkiewicz
1186353f5d9SKajetan Staszkiewicz	for node_regexp in \
1196353f5d9SKajetan Staszkiewicz		"${net_tester_host_tester} -> :: .* 10 pkts, 766 bytes, filter rule 4, limit source-track"\
1206353f5d9SKajetan Staszkiewicz	; do
1216353f5d9SKajetan Staszkiewicz		grep -qE "${node_regexp}" $nodes || atf_fail "Source node not found for '${node_regexp}'"
1226353f5d9SKajetan Staszkiewicz	done
1236353f5d9SKajetan Staszkiewicz}
1246353f5d9SKajetan Staszkiewicz
1256353f5d9SKajetan Staszkiewiczmatch_pass_state_cleanup()
1266353f5d9SKajetan Staszkiewicz{
1276353f5d9SKajetan Staszkiewicz	pft_cleanup
1286353f5d9SKajetan Staszkiewicz}
1296353f5d9SKajetan Staszkiewicz
1306353f5d9SKajetan Staszkiewiczatf_test_case "match_pass_no_state" "cleanup"
1316353f5d9SKajetan Staszkiewiczmatch_pass_no_state_head()
1326353f5d9SKajetan Staszkiewicz{
1336353f5d9SKajetan Staszkiewicz	atf_set descr 'Counters on match and pass rules without keep state'
1346353f5d9SKajetan Staszkiewicz	atf_set require.user root
1356353f5d9SKajetan Staszkiewicz}
1366353f5d9SKajetan Staszkiewicz
1376353f5d9SKajetan Staszkiewiczmatch_pass_no_state_body()
1386353f5d9SKajetan Staszkiewicz{
1396353f5d9SKajetan Staszkiewicz	setup_router_server_ipv6
1406353f5d9SKajetan Staszkiewicz
1416353f5d9SKajetan Staszkiewicz	# Test counters for a stateless firewall.
1426353f5d9SKajetan Staszkiewicz	# The table "tbl_in" is used both in match and pass rule in the inbound
1436353f5d9SKajetan Staszkiewicz	# direction. The "In/Pass" counter is incremented twice. The table
1446353f5d9SKajetan Staszkiewicz	# "tbl_inout" matches the same host on inbound and outbound direction.
1456353f5d9SKajetan Staszkiewicz	# It will also be incremented twice. The tables "tbl_out_match" and
1466353f5d9SKajetan Staszkiewicz	# "tbl_out_pass" will have their counters increased only once.
1476353f5d9SKajetan Staszkiewicz	pft_set_rules router \
1486353f5d9SKajetan Staszkiewicz		"table <tbl_in>        { ${net_tester_host_tester} }" \
1496353f5d9SKajetan Staszkiewicz		"table <tbl_inout>     { ${net_tester_host_tester} }" \
1506353f5d9SKajetan Staszkiewicz		"table <tbl_out_match> { ${net_server_host_server} }" \
1516353f5d9SKajetan Staszkiewicz		"table <tbl_out_pass>  { ${net_server_host_server} }" \
1526353f5d9SKajetan Staszkiewicz		"block" \
1536353f5d9SKajetan Staszkiewicz		"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
1546353f5d9SKajetan Staszkiewicz		"match in  on ${epair_tester}b inet6 proto tcp from <tbl_inout>" \
1556353f5d9SKajetan Staszkiewicz		"match in  on ${epair_tester}b inet6 proto tcp from <tbl_in>" \
1566353f5d9SKajetan Staszkiewicz		"pass  in  on ${epair_tester}b inet6 proto tcp from <tbl_in> no state" \
1576353f5d9SKajetan Staszkiewicz		"pass  out on ${epair_tester}b inet6 proto tcp to   <tbl_in> no state" \
1586353f5d9SKajetan Staszkiewicz		"match in  on ${epair_server}a inet6 proto tcp from <tbl_out_match>" \
1596353f5d9SKajetan Staszkiewicz		"pass  in  on ${epair_server}a inet6 proto tcp from <tbl_out_pass>  no state" \
1606353f5d9SKajetan Staszkiewicz		"match out on ${epair_server}a inet6 proto tcp from <tbl_inout> no state" \
1616353f5d9SKajetan Staszkiewicz		"pass  out on ${epair_server}a inet6 proto tcp to   <tbl_out_pass>  no state"
1626353f5d9SKajetan Staszkiewicz
1636353f5d9SKajetan Staszkiewicz	# Use a real TCP connection so that it will be properly closed, guaranteeing the amount of packets.
1646353f5d9SKajetan Staszkiewicz	atf_check -s exit:0 -o match:"This is a test" -x \
1656353f5d9SKajetan Staszkiewicz		"echo 'This is a test' | nc -w3 ${net_server_host_server} echo"
1666353f5d9SKajetan Staszkiewicz	sleep 1
1676353f5d9SKajetan Staszkiewicz	get_counters
1686353f5d9SKajetan Staszkiewicz
1696353f5d9SKajetan Staszkiewicz	for rule_regexp in \
1706353f5d9SKajetan Staszkiewicz		"@3 match in on ${epair_tester}b .* Packets: 6 Bytes: 455 " \
1716353f5d9SKajetan Staszkiewicz		"@4 match in on ${epair_tester}b .* Packets: 6 Bytes: 455 " \
1726353f5d9SKajetan Staszkiewicz		"@5 pass in on ${epair_tester}b .* Packets: 6 Bytes: 455 " \
1736353f5d9SKajetan Staszkiewicz		"@6 pass out on ${epair_tester}b .* Packets: 4 Bytes: 311 " \
1746353f5d9SKajetan Staszkiewicz		"@7 match in on ${epair_server}a .* Packets: 4 Bytes: 311 " \
1756353f5d9SKajetan Staszkiewicz		"@8 pass in on ${epair_server}a .* Packets: 4 Bytes: 311 " \
1766353f5d9SKajetan Staszkiewicz		"@10 pass out on ${epair_server}a .* Packets: 6 Bytes: 455 " \
1776353f5d9SKajetan Staszkiewicz	; do
1786353f5d9SKajetan Staszkiewicz		grep -qE "${rule_regexp}" $rules || atf_fail "Rule regexp not found for '${rule_regexp}'"
1796353f5d9SKajetan Staszkiewicz	done
1806353f5d9SKajetan Staszkiewicz
1816353f5d9SKajetan Staszkiewicz	for table_test in \
1826353f5d9SKajetan Staszkiewicz		"tbl_in___Evaluations: NoMatch: 0 Match: 16 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 12 Bytes: 910 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 4 Bytes: 311 Out/XPass: Packets: 0 Bytes: 0" \
1836353f5d9SKajetan Staszkiewicz		"tbl_out_match___Evaluations: NoMatch: 0 Match: 4 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 4 Bytes: 311 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 0 Bytes: 0 Out/XPass: Packets: 0 Bytes: 0" \
1846353f5d9SKajetan Staszkiewicz		"tbl_out_pass___Evaluations: NoMatch: 0 Match: 10 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 4 Bytes: 311 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 6 Bytes: 455 Out/XPass: Packets: 0 Bytes: 0" \
1856353f5d9SKajetan Staszkiewicz		"tbl_inout___Evaluations: NoMatch: 0 Match: 12 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 6 Bytes: 455 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 6 Bytes: 455 Out/XPass: Packets: 0 Bytes: 0" \
1866353f5d9SKajetan Staszkiewicz	; do
1876353f5d9SKajetan Staszkiewicz		table_name=${table_test%%___*}
1886353f5d9SKajetan Staszkiewicz		table_regexp=${table_test##*___}
1896353f5d9SKajetan Staszkiewicz		table=$(mktemp) || exit 1
1906353f5d9SKajetan Staszkiewicz		cat $tables | grep -A10 $table_name | tr '\n' ' ' | awk '{gsub("[\\[\\]]", " ", $0); gsub("[[:blank:]]+"," ",$0); print $0}' > ${table}
1916353f5d9SKajetan Staszkiewicz		grep -qE "${table_regexp}" ${table} || atf_fail "Bad counters for table ${table_name}"
1926353f5d9SKajetan Staszkiewicz	done;
1936353f5d9SKajetan Staszkiewicz}
1946353f5d9SKajetan Staszkiewicz
1956353f5d9SKajetan Staszkiewiczmatch_pass_no_state_cleanup()
1966353f5d9SKajetan Staszkiewicz{
1976353f5d9SKajetan Staszkiewicz	pft_cleanup
1986353f5d9SKajetan Staszkiewicz}
1996353f5d9SKajetan Staszkiewicz
2006353f5d9SKajetan Staszkiewiczatf_test_case "match_block" "cleanup"
2016353f5d9SKajetan Staszkiewiczmatch_block_head()
2026353f5d9SKajetan Staszkiewicz{
2036353f5d9SKajetan Staszkiewicz	atf_set descr 'Counters on match and block rules'
2046353f5d9SKajetan Staszkiewicz	atf_set require.user root
2056353f5d9SKajetan Staszkiewicz}
2066353f5d9SKajetan Staszkiewicz
2076353f5d9SKajetan Staszkiewiczmatch_block_body()
2086353f5d9SKajetan Staszkiewicz{
2096353f5d9SKajetan Staszkiewicz	setup_router_server_ipv6
2106353f5d9SKajetan Staszkiewicz
2116353f5d9SKajetan Staszkiewicz	# Stateful firewall with a blocking rule. The rule will have its
2126353f5d9SKajetan Staszkiewicz	# counters increased because it matches and applies correctly.
2136353f5d9SKajetan Staszkiewicz	# The "match" rule before the "pass" rule will have its counters
2146353f5d9SKajetan Staszkiewicz	# increased for blocked traffic too.
2156353f5d9SKajetan Staszkiewicz	pft_set_rules router \
2166353f5d9SKajetan Staszkiewicz		"set state-policy if-bound" \
2176353f5d9SKajetan Staszkiewicz		"table <tbl_in_match> { ${net_server_host_server} }" \
2186353f5d9SKajetan Staszkiewicz		"table <tbl_in_block> { ${net_server_host_server} }" \
2196353f5d9SKajetan Staszkiewicz		"block" \
2206353f5d9SKajetan Staszkiewicz		"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
2216353f5d9SKajetan Staszkiewicz		"match  in on ${epair_tester}b inet6 proto tcp to   <tbl_in_match> scrub (random-id)" \
2226353f5d9SKajetan Staszkiewicz		"block  in on ${epair_tester}b inet6 proto tcp to   <tbl_in_block>" \
2236353f5d9SKajetan Staszkiewicz		"pass  out on ${epair_server}a inet6 proto tcp keep state"
2246353f5d9SKajetan Staszkiewicz
2256353f5d9SKajetan Staszkiewicz	# Wait 3 seconds, that will cause 2 SYNs to be sent out.
2266353f5d9SKajetan Staszkiewicz	echo 'This is a test' | nc -w3 ${net_server_host_server} echo
2276353f5d9SKajetan Staszkiewicz	sleep 1
2286353f5d9SKajetan Staszkiewicz	get_counters
2296353f5d9SKajetan Staszkiewicz
2306353f5d9SKajetan Staszkiewicz	for rule_regexp in \
2316353f5d9SKajetan Staszkiewicz		"@3 match in on ${epair_tester}b .* Packets: 2 Bytes: 160 States: 0 " \
2326353f5d9SKajetan Staszkiewicz		"@4 block drop in on ${epair_tester}b .* Packets: 2 Bytes: 160 States: 0 " \
2336353f5d9SKajetan Staszkiewicz	; do
2346353f5d9SKajetan Staszkiewicz		grep -qE "${rule_regexp}" $rules || atf_fail "Rule regexp not found for '${rule_regexp}'"
2356353f5d9SKajetan Staszkiewicz	done
2366353f5d9SKajetan Staszkiewicz
2376353f5d9SKajetan Staszkiewicz	# OpenBSD has (In|Out)/Match. We don't (yet) have it in FreeBSD
2386353f5d9SKajetan Staszkiewicz	# so we follow the action of the "pass" rule ("block" for this test)
2396353f5d9SKajetan Staszkiewicz	# in "match" rules.
2406353f5d9SKajetan Staszkiewicz	for table_test in \
2416353f5d9SKajetan Staszkiewicz		"tbl_in_match___Evaluations: NoMatch: 0 Match: 2 In/Block: Packets: 2 Bytes: 160 In/Pass: Packets: 0 Bytes: 0 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 0 Bytes: 0 Out/XPass: Packets: 0 Bytes: 0" \
2426353f5d9SKajetan Staszkiewicz		"tbl_in_block___Evaluations: NoMatch: 0 Match: 2 In/Block: Packets: 2 Bytes: 160 In/Pass: Packets: 0 Bytes: 0 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 0 Bytes: 0 Out/XPass: Packets: 0 Bytes: 0" \
2436353f5d9SKajetan Staszkiewicz	; do
2446353f5d9SKajetan Staszkiewicz		table_name=${table_test%%___*}
2456353f5d9SKajetan Staszkiewicz		table_regexp=${table_test##*___}
2466353f5d9SKajetan Staszkiewicz		table=$(mktemp) || exit 1
2476353f5d9SKajetan Staszkiewicz		cat $tables | grep -A10 $table_name | tr '\n' ' ' | awk '{gsub("[\\[\\]]", " ", $0); gsub("[[:blank:]]+"," ",$0); print $0}' > ${table}
2486353f5d9SKajetan Staszkiewicz		grep -qE "${table_regexp}" ${table} || atf_fail "Bad counters for table ${table_name}"
2496353f5d9SKajetan Staszkiewicz	done;
2506353f5d9SKajetan Staszkiewicz}
2516353f5d9SKajetan Staszkiewicz
2526353f5d9SKajetan Staszkiewiczmatch_block_cleanup()
2536353f5d9SKajetan Staszkiewicz{
2546353f5d9SKajetan Staszkiewicz	pft_cleanup
2556353f5d9SKajetan Staszkiewicz}
2566353f5d9SKajetan Staszkiewicz
2576353f5d9SKajetan Staszkiewiczatf_test_case "match_fail" "cleanup"
2586353f5d9SKajetan Staszkiewiczmatch_fail_head()
2596353f5d9SKajetan Staszkiewicz{
2606353f5d9SKajetan Staszkiewicz	atf_set descr 'Counters on match and failing pass rules'
2616353f5d9SKajetan Staszkiewicz	atf_set require.user root
2626353f5d9SKajetan Staszkiewicz}
2636353f5d9SKajetan Staszkiewicz
2646353f5d9SKajetan Staszkiewiczmatch_fail_body()
2656353f5d9SKajetan Staszkiewicz{
2666353f5d9SKajetan Staszkiewicz	setup_router_server_ipv6
2676353f5d9SKajetan Staszkiewicz
2686353f5d9SKajetan Staszkiewicz	# Statefull firewall with a failing "pass" rule.
2696353f5d9SKajetan Staszkiewicz	# When the rule can't apply it will not have its counters increased.
2706353f5d9SKajetan Staszkiewicz	pft_set_rules router \
2716353f5d9SKajetan Staszkiewicz		"set state-policy if-bound" \
2726353f5d9SKajetan Staszkiewicz		"table <tbl_in_match> { ${net_server_host_server} }" \
2736353f5d9SKajetan Staszkiewicz		"table <tbl_in_fail> { ${net_server_host_server} }" \
2746353f5d9SKajetan Staszkiewicz		"block" \
2756353f5d9SKajetan Staszkiewicz		"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
2766353f5d9SKajetan Staszkiewicz		"match  in on ${epair_tester}b inet6 proto tcp to <tbl_in_match> scrub (random-id)" \
2776353f5d9SKajetan Staszkiewicz		"pass   in on ${epair_tester}b inet6 proto tcp to <tbl_in_fail> keep state (max 1)" \
2786353f5d9SKajetan Staszkiewicz		"pass  out on ${epair_server}a inet6 proto tcp keep state"
2796353f5d9SKajetan Staszkiewicz
2806353f5d9SKajetan Staszkiewicz	# The first test will pass and increase the counters for all rules.
2816353f5d9SKajetan Staszkiewicz	echo 'This is a test' | nc -w3 ${net_server_host_server} echo
2826353f5d9SKajetan Staszkiewicz	# The second test will go through the "match" rules but fail
2836353f5d9SKajetan Staszkiewicz	# on the "pass" rule due to 'keep state (max 1)'.
2846353f5d9SKajetan Staszkiewicz	# Wait 3 seconds, that will cause 2 SYNs to be sent out.
2856353f5d9SKajetan Staszkiewicz	echo 'This is a test' | nc -w3 ${net_server_host_server} echo
2866353f5d9SKajetan Staszkiewicz	sleep 1
2876353f5d9SKajetan Staszkiewicz	get_counters
2886353f5d9SKajetan Staszkiewicz
2896353f5d9SKajetan Staszkiewicz	for rule_regexp in \
2906353f5d9SKajetan Staszkiewicz		"@3 match in on ${epair_tester}b .* Packets: 10 Bytes: 766 States: 1 " \
2916353f5d9SKajetan Staszkiewicz		"@4 pass in on ${epair_tester}b .* Packets: 10 Bytes: 766 States: 1 " \
2926353f5d9SKajetan Staszkiewicz	; do
2936353f5d9SKajetan Staszkiewicz		grep -qE "${rule_regexp}" $rules || atf_fail "Rule regexp not found for '${rule_regexp}'"
2946353f5d9SKajetan Staszkiewicz	done
2956353f5d9SKajetan Staszkiewicz
2966353f5d9SKajetan Staszkiewicz	$table_counters_single="Evaluations: NoMatch: 0 Match: 3 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 6 Bytes: 455 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 4 Bytes: 311 Out/XPass: Packets: 0 Bytes: 0"
2976353f5d9SKajetan Staszkiewicz	for table_test in \
2986353f5d9SKajetan Staszkiewicz		"tbl_in_match___${table_counters_single}" \
2996353f5d9SKajetan Staszkiewicz		"tbl_in_fail___${table_counters_single}" \
3006353f5d9SKajetan Staszkiewicz	; do
3016353f5d9SKajetan Staszkiewicz		table_name=${table_test%%___*}
3026353f5d9SKajetan Staszkiewicz		table_regexp=${table_test##*___}
3036353f5d9SKajetan Staszkiewicz		table=$(mktemp) || exit 1
3046353f5d9SKajetan Staszkiewicz		cat $tables | grep -A10 $table_name | tr '\n' ' ' | awk '{gsub("[\\[\\]]", " ", $0); gsub("[[:blank:]]+"," ",$0); print $0}' > ${table}
3056353f5d9SKajetan Staszkiewicz		grep -qE "${table_regexp}" ${table} || atf_fail "Bad counters for table ${table_name}"
3066353f5d9SKajetan Staszkiewicz	done;
3076353f5d9SKajetan Staszkiewicz}
3086353f5d9SKajetan Staszkiewicz
3096353f5d9SKajetan Staszkiewiczmatch_fail_cleanup()
3106353f5d9SKajetan Staszkiewicz{
3116353f5d9SKajetan Staszkiewicz	pft_cleanup
3126353f5d9SKajetan Staszkiewicz}
3136353f5d9SKajetan Staszkiewicz
3146353f5d9SKajetan Staszkiewiczatf_test_case "nat_natonly" "cleanup"
3156353f5d9SKajetan Staszkiewicznat_natonly_head()
3166353f5d9SKajetan Staszkiewicz{
3176353f5d9SKajetan Staszkiewicz	atf_set descr 'Counters on only a NAT rule creating state'
3186353f5d9SKajetan Staszkiewicz	atf_set require.user root
3196353f5d9SKajetan Staszkiewicz}
3206353f5d9SKajetan Staszkiewicz
3216353f5d9SKajetan Staszkiewicznat_natonly_body()
3226353f5d9SKajetan Staszkiewicz{
3236353f5d9SKajetan Staszkiewicz	setup_router_server_ipv6
3246353f5d9SKajetan Staszkiewicz
3256353f5d9SKajetan Staszkiewicz	# NAT is applied on the "nat" rule.
3266353f5d9SKajetan Staszkiewicz	# The "nat" rule matches on pre-NAT addresses. There is no separate
3276353f5d9SKajetan Staszkiewicz	# "pass" rule so the "nat" rule creates the state.
3286353f5d9SKajetan Staszkiewicz	pft_set_rules router \
3296353f5d9SKajetan Staszkiewicz		"set state-policy if-bound" \
3306353f5d9SKajetan Staszkiewicz		"table <tbl_src_nat> { ${net_tester_host_tester} }" \
3316353f5d9SKajetan Staszkiewicz		"table <tbl_dst_nat> { ${net_server_host_server} }" \
3326353f5d9SKajetan Staszkiewicz		"nat on ${epair_server}a inet6 proto tcp from <tbl_src_nat> to <tbl_dst_nat> -> ${net_server_host_router}"
3336353f5d9SKajetan Staszkiewicz
3346353f5d9SKajetan Staszkiewicz	# Use a real TCP connection so that it will be properly closed, guaranteeing the amount of packets.
3356353f5d9SKajetan Staszkiewicz	atf_check -s exit:0 -o match:"This is a test" -x \
3366353f5d9SKajetan Staszkiewicz		"echo 'This is a test' | nc -w3 ${net_server_host_server} echo"
3376353f5d9SKajetan Staszkiewicz	sleep 1
3386353f5d9SKajetan Staszkiewicz	get_counters
3396353f5d9SKajetan Staszkiewicz
3406353f5d9SKajetan Staszkiewicz	for rule_regexp in \
3416353f5d9SKajetan Staszkiewicz		"@0 nat on ${epair_server}a .* Packets: 10 Bytes: 766 States: 1 " \
3426353f5d9SKajetan Staszkiewicz	; do
3436353f5d9SKajetan Staszkiewicz		grep -qE "${rule_regexp}" $rules || atf_fail "Rule regexp not found for '${rule_regexp}'"
3446353f5d9SKajetan Staszkiewicz	done
3456353f5d9SKajetan Staszkiewicz
3466353f5d9SKajetan Staszkiewicz	# All tables have counters increased for In/Pass and Out/Pass, not XPass.
3476353f5d9SKajetan Staszkiewicz	table_counters="Evaluations: NoMatch: 0 Match: 1 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 4 Bytes: 311 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 6 Bytes: 455 Out/XPass: Packets: 0 Bytes: 0"
3486353f5d9SKajetan Staszkiewicz	for table_test in \
3496353f5d9SKajetan Staszkiewicz		"tbl_src_nat___${table_counters}" \
3506353f5d9SKajetan Staszkiewicz		"tbl_dst_nat___${table_counters}" \
3516353f5d9SKajetan Staszkiewicz	; do
3526353f5d9SKajetan Staszkiewicz		table_name=${table_test%%___*}
3536353f5d9SKajetan Staszkiewicz		table_regexp=${table_test##*___}
3546353f5d9SKajetan Staszkiewicz		table=$(mktemp) || exit 1
3556353f5d9SKajetan Staszkiewicz		cat $tables | grep -A10 $table_name | tr '\n' ' ' | awk '{gsub("[\\[\\]]", " ", $0); gsub("[[:blank:]]+"," ",$0); print $0}' > ${table}
3566353f5d9SKajetan Staszkiewicz		grep -qE "${table_regexp}" ${table} || atf_fail "Bad counters for table ${table_name}"
3576353f5d9SKajetan Staszkiewicz	done;
3586353f5d9SKajetan Staszkiewicz
3596353f5d9SKajetan Staszkiewicz	for state_regexp in \
3606353f5d9SKajetan Staszkiewicz		"all tcp ${net_server_host_router}.* -> ${net_server_host_server}.* 6:4 pkts, 455:311 bytes" \
3616353f5d9SKajetan Staszkiewicz	; do
3626353f5d9SKajetan Staszkiewicz		grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'"
3636353f5d9SKajetan Staszkiewicz	done
3646353f5d9SKajetan Staszkiewicz}
3656353f5d9SKajetan Staszkiewicz
3666353f5d9SKajetan Staszkiewicznat_natonly_cleanup()
3676353f5d9SKajetan Staszkiewicz{
3686353f5d9SKajetan Staszkiewicz	pft_cleanup
3696353f5d9SKajetan Staszkiewicz}
3706353f5d9SKajetan Staszkiewicz
3716353f5d9SKajetan Staszkiewiczatf_test_case "nat_nat" "cleanup"
3726353f5d9SKajetan Staszkiewicznat_nat_head()
3736353f5d9SKajetan Staszkiewicz{
3746353f5d9SKajetan Staszkiewicz	atf_set descr 'Counters on NAT, match and pass rules with keep state'
3756353f5d9SKajetan Staszkiewicz	atf_set require.user root
3766353f5d9SKajetan Staszkiewicz}
3776353f5d9SKajetan Staszkiewicz
3786353f5d9SKajetan Staszkiewicznat_nat_body()
3796353f5d9SKajetan Staszkiewicz{
3806353f5d9SKajetan Staszkiewicz	setup_router_server_ipv6
3816353f5d9SKajetan Staszkiewicz
3826353f5d9SKajetan Staszkiewicz	# NAT is applied in the NAT ruleset.
3836353f5d9SKajetan Staszkiewicz	# The "nat" rule matches on pre-NAT addresses.
3846353f5d9SKajetan Staszkiewicz	# The "match" rule matches on post-NAT addresses.
3856353f5d9SKajetan Staszkiewicz	# The "pass" rule matches on post-NAT addresses and creates the state.
3866353f5d9SKajetan Staszkiewicz	pft_set_rules router \
3876353f5d9SKajetan Staszkiewicz		"set state-policy if-bound" \
3886353f5d9SKajetan Staszkiewicz		"table <tbl_src_nat> { ${net_tester_host_tester} }" \
3896353f5d9SKajetan Staszkiewicz		"table <tbl_dst_nat> { ${net_server_host_server} }" \
3906353f5d9SKajetan Staszkiewicz		"table <tbl_src_match> { ${net_server_host_router} }" \
3916353f5d9SKajetan Staszkiewicz		"table <tbl_dst_match> { ${net_server_host_server} }" \
3926353f5d9SKajetan Staszkiewicz		"table <tbl_src_pass> { ${net_server_host_router} }" \
3936353f5d9SKajetan Staszkiewicz		"table <tbl_dst_pass> { ${net_server_host_server} }" \
3946353f5d9SKajetan Staszkiewicz		"nat on ${epair_server}a inet6 proto tcp from <tbl_src_nat> to <tbl_dst_nat> -> ${net_server_host_router}" \
3956353f5d9SKajetan Staszkiewicz		"block" \
3966353f5d9SKajetan Staszkiewicz		"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
3976353f5d9SKajetan Staszkiewicz		"pass  in  on ${epair_tester}b inet6 proto tcp keep state" \
3986353f5d9SKajetan Staszkiewicz		"match out on ${epair_server}a inet6 proto tcp from <tbl_src_match> to <tbl_dst_match> scrub (random-id)" \
3996353f5d9SKajetan Staszkiewicz		"pass  out on ${epair_server}a inet6 proto tcp from <tbl_src_pass>  to <tbl_dst_pass>  keep state"
4006353f5d9SKajetan Staszkiewicz
4016353f5d9SKajetan Staszkiewicz	# Use a real TCP connection so that it will be properly closed, guaranteeing the amount of packets.
4026353f5d9SKajetan Staszkiewicz	atf_check -s exit:0 -o match:"This is a test" -x \
4036353f5d9SKajetan Staszkiewicz		"echo 'This is a test' | nc -w3 ${net_server_host_server} echo"
4046353f5d9SKajetan Staszkiewicz	sleep 1
4056353f5d9SKajetan Staszkiewicz	get_counters
4066353f5d9SKajetan Staszkiewicz
4076353f5d9SKajetan Staszkiewicz	for rule_regexp in \
4086353f5d9SKajetan Staszkiewicz		"@0 nat on ${epair_server}a .* Packets: 10 Bytes: 766 States: 1 " \
4096353f5d9SKajetan Staszkiewicz		"@4 match out on ${epair_server}a .* Packets: 10 Bytes: 766 States: 1 " \
4106353f5d9SKajetan Staszkiewicz		"@5 pass out on ${epair_server}a .* Packets: 10 Bytes: 766 States: 1 " \
4116353f5d9SKajetan Staszkiewicz	; do
4126353f5d9SKajetan Staszkiewicz		grep -qE "${rule_regexp}" $rules || atf_fail "Rule regexp not found for '${rule_regexp}'"
4136353f5d9SKajetan Staszkiewicz	done
4146353f5d9SKajetan Staszkiewicz
4156353f5d9SKajetan Staszkiewicz	# All tables have counters increased for In/Pass and Out/Pass, not XPass nor Block.
4166353f5d9SKajetan Staszkiewicz	table_counters="Evaluations: NoMatch: 0 Match: 1 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 4 Bytes: 311 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 6 Bytes: 455 Out/XPass: Packets: 0 Bytes: 0"
4176353f5d9SKajetan Staszkiewicz	for table_test in \
4186353f5d9SKajetan Staszkiewicz		"tbl_src_nat___${table_counters}" \
4196353f5d9SKajetan Staszkiewicz		"tbl_dst_nat___${table_counters}" \
4206353f5d9SKajetan Staszkiewicz		"tbl_src_match___${table_counters}" \
4216353f5d9SKajetan Staszkiewicz		"tbl_dst_match___${table_counters}" \
4226353f5d9SKajetan Staszkiewicz		"tbl_src_pass___${table_counters}" \
4236353f5d9SKajetan Staszkiewicz		"tbl_dst_pass___${table_counters}" \
4246353f5d9SKajetan Staszkiewicz	; do
4256353f5d9SKajetan Staszkiewicz		table_name=${table_test%%___*}
4266353f5d9SKajetan Staszkiewicz		table_regexp=${table_test##*___}
4276353f5d9SKajetan Staszkiewicz		table=$(mktemp) || exit 1
4286353f5d9SKajetan Staszkiewicz		cat $tables | grep -A10 $table_name | tr '\n' ' ' | awk '{gsub("[\\[\\]]", " ", $0); gsub("[[:blank:]]+"," ",$0); print $0}' > ${table}
4296353f5d9SKajetan Staszkiewicz		grep -qE "${table_regexp}" ${table} || atf_fail "Bad counters for table ${table_name}"
4306353f5d9SKajetan Staszkiewicz	done;
4316353f5d9SKajetan Staszkiewicz
4326353f5d9SKajetan Staszkiewicz	for state_regexp in \
4336353f5d9SKajetan Staszkiewicz		"${epair_server}a tcp ${net_server_host_router}.* -> ${net_server_host_server}.* 6:4 pkts, 455:311 bytes, rule 5," \
4346353f5d9SKajetan Staszkiewicz	; do
4356353f5d9SKajetan Staszkiewicz		grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'"
4366353f5d9SKajetan Staszkiewicz	done
4376353f5d9SKajetan Staszkiewicz}
4386353f5d9SKajetan Staszkiewicz
4396353f5d9SKajetan Staszkiewicznat_nat_cleanup()
4406353f5d9SKajetan Staszkiewicz{
4416353f5d9SKajetan Staszkiewicz	pft_cleanup
4426353f5d9SKajetan Staszkiewicz}
4436353f5d9SKajetan Staszkiewicz
4446353f5d9SKajetan Staszkiewiczatf_test_case "nat_match" "cleanup"
4456353f5d9SKajetan Staszkiewicznat_match_head()
4466353f5d9SKajetan Staszkiewicz{
4476353f5d9SKajetan Staszkiewicz	atf_set descr 'Counters on match with NAT and pass rules'
4486353f5d9SKajetan Staszkiewicz	atf_set require.user root
4496353f5d9SKajetan Staszkiewicz}
4506353f5d9SKajetan Staszkiewicz
4516353f5d9SKajetan Staszkiewicznat_match_body()
4526353f5d9SKajetan Staszkiewicz{
4536353f5d9SKajetan Staszkiewicz	setup_router_server_ipv6
4546353f5d9SKajetan Staszkiewicz
4556353f5d9SKajetan Staszkiewicz	# NAT is applied on the "match" rule.
4566353f5d9SKajetan Staszkiewicz	# The "match" rule up to and including the NAT rule match on pre-NAT addresses.
4576353f5d9SKajetan Staszkiewicz	# The "match" rule after NAT matches on post-NAT addresses.
4586353f5d9SKajetan Staszkiewicz	# The "pass" rule matches on post-NAT addresses and creates the state.
4596353f5d9SKajetan Staszkiewicz	pft_set_rules router \
4606353f5d9SKajetan Staszkiewicz		"set state-policy if-bound" \
4616353f5d9SKajetan Staszkiewicz		"table <tbl_src_match1> { ${net_tester_host_tester} }" \
4626353f5d9SKajetan Staszkiewicz		"table <tbl_dst_match1> { ${net_server_host_server} }" \
4636353f5d9SKajetan Staszkiewicz		"table <tbl_src_match2> { ${net_tester_host_tester} }" \
4646353f5d9SKajetan Staszkiewicz		"table <tbl_dst_match2> { ${net_server_host_server} }" \
4656353f5d9SKajetan Staszkiewicz		"table <tbl_src_match3> { ${net_server_host_router} }" \
4666353f5d9SKajetan Staszkiewicz		"table <tbl_dst_match3> { ${net_server_host_server} }" \
4676353f5d9SKajetan Staszkiewicz		"table <tbl_src_pass> { ${net_server_host_router} }" \
4686353f5d9SKajetan Staszkiewicz		"table <tbl_dst_pass> { ${net_server_host_server} }" \
4696353f5d9SKajetan Staszkiewicz		"block" \
4706353f5d9SKajetan Staszkiewicz		"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
4716353f5d9SKajetan Staszkiewicz		"pass  in  on ${epair_tester}b inet6 proto tcp keep state" \
4726353f5d9SKajetan Staszkiewicz		"match out on ${epair_server}a inet6 proto tcp from <tbl_src_match1> to <tbl_dst_match1> scrub (random-id)" \
4736353f5d9SKajetan Staszkiewicz		"match out on ${epair_server}a inet6 proto tcp from <tbl_src_match2> to <tbl_dst_match2> nat-to ${net_server_host_router}" \
4746353f5d9SKajetan Staszkiewicz		"match out on ${epair_server}a inet6 proto tcp from <tbl_src_match3> to <tbl_dst_match3> scrub (random-id)" \
4756353f5d9SKajetan Staszkiewicz		"pass  out on ${epair_server}a inet6 proto tcp from <tbl_src_pass>  to <tbl_dst_pass>  keep state"
4766353f5d9SKajetan Staszkiewicz
4776353f5d9SKajetan Staszkiewicz	# Use a real TCP connection so that it will be properly closed, guaranteeing the amount of packets.
4786353f5d9SKajetan Staszkiewicz	atf_check -s exit:0 -o match:"This is a test" -x \
4796353f5d9SKajetan Staszkiewicz		"echo 'This is a test' | nc -w3 ${net_server_host_server} echo"
4806353f5d9SKajetan Staszkiewicz	sleep 1
4816353f5d9SKajetan Staszkiewicz	get_counters
4826353f5d9SKajetan Staszkiewicz
4836353f5d9SKajetan Staszkiewicz	for rule_regexp in \
4846353f5d9SKajetan Staszkiewicz		"@4 match out on ${epair_server}a .* Packets: 10 Bytes: 766 States: 1 " \
4856353f5d9SKajetan Staszkiewicz		"@5 match out on ${epair_server}a .* Packets: 10 Bytes: 766 States: 1 " \
4866353f5d9SKajetan Staszkiewicz		"@6 match out on ${epair_server}a .* Packets: 10 Bytes: 766 States: 1 " \
4876353f5d9SKajetan Staszkiewicz		"@7 pass out on ${epair_server}a .* Packets: 10 Bytes: 766 States: 1 " \
4886353f5d9SKajetan Staszkiewicz	; do
4896353f5d9SKajetan Staszkiewicz		grep -qE "${rule_regexp}" $rules || atf_fail "Rule regexp not found for '${rule_regexp}'"
4906353f5d9SKajetan Staszkiewicz	done
4916353f5d9SKajetan Staszkiewicz
4926353f5d9SKajetan Staszkiewicz	# All tables have counters increased for In/Pass and Out/Pass, not XPass nor Block.
4936353f5d9SKajetan Staszkiewicz	table_counters="Evaluations: NoMatch: 0 Match: 1 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 4 Bytes: 311 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 6 Bytes: 455 Out/XPass: Packets: 0 Bytes: 0"
4946353f5d9SKajetan Staszkiewicz	for table_test in \
4956353f5d9SKajetan Staszkiewicz		"tbl_src_match1___${table_counters}" \
4966353f5d9SKajetan Staszkiewicz		"tbl_dst_match1___${table_counters}" \
4976353f5d9SKajetan Staszkiewicz		"tbl_src_match2___${table_counters}" \
4986353f5d9SKajetan Staszkiewicz		"tbl_dst_match2___${table_counters}" \
4996353f5d9SKajetan Staszkiewicz		"tbl_src_match3___${table_counters}" \
5006353f5d9SKajetan Staszkiewicz		"tbl_dst_match3___${table_counters}" \
5016353f5d9SKajetan Staszkiewicz		"tbl_src_pass___${table_counters}" \
5026353f5d9SKajetan Staszkiewicz		"tbl_dst_pass___${table_counters}" \
5036353f5d9SKajetan Staszkiewicz	; do
5046353f5d9SKajetan Staszkiewicz		table_name=${table_test%%___*}
5056353f5d9SKajetan Staszkiewicz		table_regexp=${table_test##*___}
5066353f5d9SKajetan Staszkiewicz		table=$(mktemp) || exit 1
5076353f5d9SKajetan Staszkiewicz		cat $tables | grep -A10 $table_name | tr '\n' ' ' | awk '{gsub("[\\[\\]]", " ", $0); gsub("[[:blank:]]+"," ",$0); print $0}' > ${table}
5086353f5d9SKajetan Staszkiewicz		grep -qE "${table_regexp}" ${table} || atf_fail "Bad counters for table ${table_name}"
5096353f5d9SKajetan Staszkiewicz	done;
5106353f5d9SKajetan Staszkiewicz
5116353f5d9SKajetan Staszkiewicz	for state_regexp in \
5126353f5d9SKajetan Staszkiewicz		"${epair_server}a tcp ${net_server_host_tester}.* -> ${net_server_host_server}.* 6:4 pkts, 455:311 bytes, rule 7, " \
5136353f5d9SKajetan Staszkiewicz	; do
5146353f5d9SKajetan Staszkiewicz		grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'"
5156353f5d9SKajetan Staszkiewicz	done
5166353f5d9SKajetan Staszkiewicz}
5176353f5d9SKajetan Staszkiewicz
5186353f5d9SKajetan Staszkiewicznat_match_cleanup()
5196353f5d9SKajetan Staszkiewicz{
5206353f5d9SKajetan Staszkiewicz	pft_cleanup
5216353f5d9SKajetan Staszkiewicz}
5226353f5d9SKajetan Staszkiewicz
5236353f5d9SKajetan Staszkiewiczatf_test_case "nat_pass" "cleanup"
5246353f5d9SKajetan Staszkiewicznat_pass_head()
5256353f5d9SKajetan Staszkiewicz{
5266353f5d9SKajetan Staszkiewicz	atf_set descr 'Counters on match, and pass with NAT rules'
5276353f5d9SKajetan Staszkiewicz	atf_set require.user root
5286353f5d9SKajetan Staszkiewicz}
5296353f5d9SKajetan Staszkiewicz
5306353f5d9SKajetan Staszkiewicznat_pass_body()
5316353f5d9SKajetan Staszkiewicz{
5326353f5d9SKajetan Staszkiewicz	setup_router_server_ipv6
5336353f5d9SKajetan Staszkiewicz
5346353f5d9SKajetan Staszkiewicz	# NAT is applied on the "pass" rule which also creates the state.
5356353f5d9SKajetan Staszkiewicz	# All rules match on pre-NAT addresses.
5366353f5d9SKajetan Staszkiewicz	pft_set_rules router \
5376353f5d9SKajetan Staszkiewicz		"set state-policy if-bound" \
5386353f5d9SKajetan Staszkiewicz		"table <tbl_src_match> { ${net_tester_host_tester} }" \
5396353f5d9SKajetan Staszkiewicz		"table <tbl_dst_match> { ${net_server_host_server} }" \
5406353f5d9SKajetan Staszkiewicz		"table <tbl_src_pass> { ${net_tester_host_tester} }" \
5416353f5d9SKajetan Staszkiewicz		"table <tbl_dst_pass> { ${net_server_host_server} }" \
5426353f5d9SKajetan Staszkiewicz		"block" \
5436353f5d9SKajetan Staszkiewicz		"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
5446353f5d9SKajetan Staszkiewicz		"pass  in  on ${epair_tester}b inet6 proto tcp keep state" \
5456353f5d9SKajetan Staszkiewicz		"match out on ${epair_server}a inet6 proto tcp from <tbl_src_match> to <tbl_dst_match> scrub (random-id)" \
5466353f5d9SKajetan Staszkiewicz		"pass  out on ${epair_server}a inet6 proto tcp from <tbl_src_pass>  to <tbl_dst_pass>  nat-to ${net_server_host_router} keep state"
5476353f5d9SKajetan Staszkiewicz
5486353f5d9SKajetan Staszkiewicz	# Use a real TCP connection so that it will be properly closed, guaranteeing the amount of packets.
5496353f5d9SKajetan Staszkiewicz	atf_check -s exit:0 -o match:"This is a test" -x \
5506353f5d9SKajetan Staszkiewicz		"echo 'This is a test' | nc -w3 ${net_server_host_server} echo"
5516353f5d9SKajetan Staszkiewicz	sleep 1
5526353f5d9SKajetan Staszkiewicz	get_counters
5536353f5d9SKajetan Staszkiewicz
5546353f5d9SKajetan Staszkiewicz	for rule_regexp in \
5556353f5d9SKajetan Staszkiewicz		"@4 match out on ${epair_server}a .* Packets: 10 Bytes: 766 States: 1 " \
5566353f5d9SKajetan Staszkiewicz		"@5 pass out on ${epair_server}a .* Packets: 10 Bytes: 766 States: 1 " \
5576353f5d9SKajetan Staszkiewicz	; do
5586353f5d9SKajetan Staszkiewicz		grep -qE "${rule_regexp}" $rules || atf_fail "Rule regexp not found for '${rule_regexp}'"
5596353f5d9SKajetan Staszkiewicz	done
5606353f5d9SKajetan Staszkiewicz
5616353f5d9SKajetan Staszkiewicz	table_counters="Evaluations: NoMatch: 0 Match: 1 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 4 Bytes: 311 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 6 Bytes: 455 Out/XPass: Packets: 0 Bytes: 0"
5626353f5d9SKajetan Staszkiewicz	for table_test in \
5636353f5d9SKajetan Staszkiewicz		"tbl_src_match___${table_counters}" \
5646353f5d9SKajetan Staszkiewicz		"tbl_dst_match___${table_counters}" \
5656353f5d9SKajetan Staszkiewicz		"tbl_src_pass___${table_counters}" \
5666353f5d9SKajetan Staszkiewicz		"tbl_dst_pass___${table_counters}" \
5676353f5d9SKajetan Staszkiewicz	; do
5686353f5d9SKajetan Staszkiewicz		table_name=${table_test%%___*}
5696353f5d9SKajetan Staszkiewicz		table_regexp=${table_test##*___}
5706353f5d9SKajetan Staszkiewicz		table=$(mktemp) || exit 1
5716353f5d9SKajetan Staszkiewicz		cat $tables | grep -A10 $table_name | tr '\n' ' ' | awk '{gsub("[\\[\\]]", " ", $0); gsub("[[:blank:]]+"," ",$0); print $0}' > ${table}
5726353f5d9SKajetan Staszkiewicz		grep -qE "${table_regexp}" ${table} || atf_fail "Bad counters for table ${table_name}"
5736353f5d9SKajetan Staszkiewicz	done;
5746353f5d9SKajetan Staszkiewicz
5756353f5d9SKajetan Staszkiewicz	for state_regexp in \
5766353f5d9SKajetan Staszkiewicz		"${epair_server}a tcp ${net_server_host_router}.* -> ${net_server_host_server}.* 6:4 pkts, 455:311 bytes, rule 5," \
5776353f5d9SKajetan Staszkiewicz	; do
5786353f5d9SKajetan Staszkiewicz		grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'"
5796353f5d9SKajetan Staszkiewicz	done
5806353f5d9SKajetan Staszkiewicz}
5816353f5d9SKajetan Staszkiewicz
5826353f5d9SKajetan Staszkiewicznat_pass_cleanup()
5836353f5d9SKajetan Staszkiewicz{
5846353f5d9SKajetan Staszkiewicz	pft_cleanup
5856353f5d9SKajetan Staszkiewicz}
5866353f5d9SKajetan Staszkiewicz
5876353f5d9SKajetan Staszkiewiczatf_test_case "rdr_match" "cleanup"
5886353f5d9SKajetan Staszkiewiczrdr_match_head()
5896353f5d9SKajetan Staszkiewicz{
5906353f5d9SKajetan Staszkiewicz	atf_set descr 'Counters on match with RDR and pass rules'
5916353f5d9SKajetan Staszkiewicz	atf_set require.user root
5926353f5d9SKajetan Staszkiewicz}
5936353f5d9SKajetan Staszkiewicz
5946353f5d9SKajetan Staszkiewiczrdr_match_body()
5956353f5d9SKajetan Staszkiewicz{
5966353f5d9SKajetan Staszkiewicz	setup_router_server_ipv6
5976353f5d9SKajetan Staszkiewicz
5986353f5d9SKajetan Staszkiewicz	# Similar to the nat_match test but for the RDR action.
5996353f5d9SKajetan Staszkiewicz	# Hopefully we don't need all other tests duplicated for RDR.
6006353f5d9SKajetan Staszkiewicz	# Send traffic to a non-existing host, RDR it to the server.
6016353f5d9SKajetan Staszkiewicz	#
6026353f5d9SKajetan Staszkiewicz	# The "match" rule up to and including the RDR rule match on pre-RDR dst address.
6036353f5d9SKajetan Staszkiewicz	# The "match" rule after NAT matches on post-RDR dst address.
6046353f5d9SKajetan Staszkiewicz	# The "pass" rule matches on post-RDR dst address.
6056353f5d9SKajetan Staszkiewicz	net_server_host_notserver=${net_server_host_server%%::*}::3
6066353f5d9SKajetan Staszkiewicz	pft_set_rules router \
6076353f5d9SKajetan Staszkiewicz		"set state-policy if-bound" \
6086353f5d9SKajetan Staszkiewicz		"table <tbl_src_match1> { ${net_tester_host_tester} }" \
6096353f5d9SKajetan Staszkiewicz		"table <tbl_dst_match1> { ${net_server_host_notserver} }" \
6106353f5d9SKajetan Staszkiewicz		"table <tbl_src_match2> { ${net_tester_host_tester} }" \
6116353f5d9SKajetan Staszkiewicz		"table <tbl_dst_match2> { ${net_server_host_notserver} }" \
6126353f5d9SKajetan Staszkiewicz		"table <tbl_src_match3> { ${net_tester_host_tester} }" \
6136353f5d9SKajetan Staszkiewicz		"table <tbl_dst_match3> { ${net_server_host_server} }" \
6146353f5d9SKajetan Staszkiewicz		"table <tbl_src_pass> { ${net_tester_host_tester} }" \
6156353f5d9SKajetan Staszkiewicz		"table <tbl_dst_pass> { ${net_server_host_server} }" \
6166353f5d9SKajetan Staszkiewicz		"block" \
6176353f5d9SKajetan Staszkiewicz		"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
6186353f5d9SKajetan Staszkiewicz		"pass  out on ${epair_server}a inet6 proto tcp keep state" \
6196353f5d9SKajetan Staszkiewicz		"match  in on ${epair_tester}b inet6 proto tcp from <tbl_src_match1> to <tbl_dst_match1> scrub (random-id)" \
6206353f5d9SKajetan Staszkiewicz		"match  in on ${epair_tester}b inet6 proto tcp from <tbl_src_match2> to <tbl_dst_match2> rdr-to ${net_server_host_server}" \
6216353f5d9SKajetan Staszkiewicz		"match  in on ${epair_tester}b inet6 proto tcp from <tbl_src_match3> to <tbl_dst_match3> scrub (random-id)" \
6226353f5d9SKajetan Staszkiewicz		"pass   in on ${epair_tester}b inet6 proto tcp from <tbl_src_pass>  to <tbl_dst_pass>  keep state"
6236353f5d9SKajetan Staszkiewicz
6246353f5d9SKajetan Staszkiewicz	# Use a real TCP connection so that it will be properly closed, guaranteeing the amount of packets.
6256353f5d9SKajetan Staszkiewicz	atf_check -s exit:0 -o match:"This is a test" -x \
6266353f5d9SKajetan Staszkiewicz		"echo 'This is a test' | nc -w3 ${net_server_host_notserver} echo"
6276353f5d9SKajetan Staszkiewicz	sleep 1
6286353f5d9SKajetan Staszkiewicz	get_counters
6296353f5d9SKajetan Staszkiewicz
6306353f5d9SKajetan Staszkiewicz	for rule_regexp in \
6316353f5d9SKajetan Staszkiewicz		"@4 match in on ${epair_tester}b .* Packets: 10 Bytes: 766 States: 1 " \
6326353f5d9SKajetan Staszkiewicz		"@5 match in on ${epair_tester}b .* Packets: 10 Bytes: 766 States: 1 " \
6336353f5d9SKajetan Staszkiewicz		"@6 match in on ${epair_tester}b .* Packets: 10 Bytes: 766 States: 1 " \
6346353f5d9SKajetan Staszkiewicz		"@7 pass in on ${epair_tester}b .* Packets: 10 Bytes: 766 States: 1 " \
6356353f5d9SKajetan Staszkiewicz	; do
6366353f5d9SKajetan Staszkiewicz		grep -qE "${rule_regexp}" $rules || atf_fail "Rule regexp not found for '${rule_regexp}'"
6376353f5d9SKajetan Staszkiewicz	done
6386353f5d9SKajetan Staszkiewicz
6396353f5d9SKajetan Staszkiewicz	# All tables have counters increased for In/Pass and Out/Pass, not XPass nor Block.
6406353f5d9SKajetan Staszkiewicz	table_counters="Evaluations: NoMatch: 0 Match: 1 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 6 Bytes: 455 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 4 Bytes: 311 Out/XPass: Packets: 0 Bytes: 0"
6416353f5d9SKajetan Staszkiewicz	for table_test in \
6426353f5d9SKajetan Staszkiewicz		"tbl_src_match1___${table_counters}" \
6436353f5d9SKajetan Staszkiewicz		"tbl_dst_match1___${table_counters}" \
6446353f5d9SKajetan Staszkiewicz		"tbl_src_match2___${table_counters}" \
6456353f5d9SKajetan Staszkiewicz		"tbl_dst_match2___${table_counters}" \
6466353f5d9SKajetan Staszkiewicz		"tbl_src_match3___${table_counters}" \
6476353f5d9SKajetan Staszkiewicz		"tbl_dst_match3___${table_counters}" \
6486353f5d9SKajetan Staszkiewicz		"tbl_src_pass___${table_counters}" \
6496353f5d9SKajetan Staszkiewicz		"tbl_dst_pass___${table_counters}" \
6506353f5d9SKajetan Staszkiewicz	; do
6516353f5d9SKajetan Staszkiewicz		table_name=${table_test%%___*}
6526353f5d9SKajetan Staszkiewicz		table_regexp=${table_test##*___}
6536353f5d9SKajetan Staszkiewicz		table=$(mktemp) || exit 1
6546353f5d9SKajetan Staszkiewicz		cat $tables | grep -A10 $table_name | tr '\n' ' ' | awk '{gsub("[\\[\\]]", " ", $0); gsub("[[:blank:]]+"," ",$0); print $0}' > ${table}
6556353f5d9SKajetan Staszkiewicz		grep -qE "${table_regexp}" ${table} || atf_fail "Bad counters for table ${table_name}"
6566353f5d9SKajetan Staszkiewicz	done;
6576353f5d9SKajetan Staszkiewicz
6586353f5d9SKajetan Staszkiewicz	for state_regexp in \
6596353f5d9SKajetan Staszkiewicz		"${epair_tester}b tcp ${net_server_host_server}.* 6:4 pkts, 455:311 bytes, rule 7, " \
6606353f5d9SKajetan Staszkiewicz	; do
6616353f5d9SKajetan Staszkiewicz		grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'"
6626353f5d9SKajetan Staszkiewicz	done
6636353f5d9SKajetan Staszkiewicz}
6646353f5d9SKajetan Staszkiewicz
6656353f5d9SKajetan Staszkiewiczrdr_match_cleanup()
6666353f5d9SKajetan Staszkiewicz{
6676353f5d9SKajetan Staszkiewicz	pft_cleanup
6686353f5d9SKajetan Staszkiewicz}
6696353f5d9SKajetan Staszkiewicz
6706353f5d9SKajetan Staszkiewiczatf_test_case "nat64_in" "cleanup"
6716353f5d9SKajetan Staszkiewicznat64_in_head()
6726353f5d9SKajetan Staszkiewicz{
6736353f5d9SKajetan Staszkiewicz	atf_set descr 'Counters on match and inbound af-to rules'
6746353f5d9SKajetan Staszkiewicz	atf_set require.user root
6756353f5d9SKajetan Staszkiewicz}
6766353f5d9SKajetan Staszkiewicz
6776353f5d9SKajetan Staszkiewicznat64_in_body()
6786353f5d9SKajetan Staszkiewicz{
6796353f5d9SKajetan Staszkiewicz	setup_router_server_nat64
6806353f5d9SKajetan Staszkiewicz
6816353f5d9SKajetan Staszkiewicz	pft_set_rules router \
6826353f5d9SKajetan Staszkiewicz		"set state-policy if-bound" \
6836353f5d9SKajetan Staszkiewicz		"table <tbl_src_match> { ${net_tester_6_host_tester} }" \
6846353f5d9SKajetan Staszkiewicz		"table <tbl_dst_match> { 64:ff9b::${net_server1_4_host_server} }" \
6856353f5d9SKajetan Staszkiewicz		"table <tbl_src_pass>  { ${net_tester_6_host_tester} }" \
6866353f5d9SKajetan Staszkiewicz		"table <tbl_dst_pass>  { 64:ff9b::${net_server1_4_host_server} }" \
687*7cd3854fSKajetan Staszkiewicz		"block log" \
6886353f5d9SKajetan Staszkiewicz		"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
6896353f5d9SKajetan Staszkiewicz		"match  in on ${epair_tester}b inet6 proto tcp from <tbl_src_match> to <tbl_dst_match> scrub (random-id)" \
6906353f5d9SKajetan Staszkiewicz		"pass   in on ${epair_tester}b inet6 proto tcp from <tbl_src_pass>  to <tbl_dst_pass> \
6916353f5d9SKajetan Staszkiewicz			af-to inet from (${epair_server1}a) \
6926353f5d9SKajetan Staszkiewicz			keep state"
6936353f5d9SKajetan Staszkiewicz
6946353f5d9SKajetan Staszkiewicz	# Use a real TCP connection so that it will be properly closed, guaranteeing the amount of packets.
6956353f5d9SKajetan Staszkiewicz	atf_check -s exit:0 -o match:"This is a test" -x \
6966353f5d9SKajetan Staszkiewicz		"echo 'This is a test' | nc -w3 64:ff9b::${net_server1_4_host_server} echo"
6976353f5d9SKajetan Staszkiewicz	sleep 1
6986353f5d9SKajetan Staszkiewicz	get_counters
6996353f5d9SKajetan Staszkiewicz
7006353f5d9SKajetan Staszkiewicz	# The amount of packets is counted properly but sizes are not because
7016353f5d9SKajetan Staszkiewicz	# pd->tot_len is always post-nat, even when updating pre-nat counters.
7026353f5d9SKajetan Staszkiewicz	for rule_regexp in \
7036353f5d9SKajetan Staszkiewicz		"@3 match in on ${epair_tester}b .* Packets: 10 Bytes: 686 States: 1 " \
7046353f5d9SKajetan Staszkiewicz		"@4 pass in on ${epair_tester}b .* Packets: 10 Bytes: 686 States: 1 " \
7056353f5d9SKajetan Staszkiewicz	; do
7066353f5d9SKajetan Staszkiewicz		grep -qE "${rule_regexp}" $rules || atf_fail "Rule regexp not found for '${rule_regexp}'"
7076353f5d9SKajetan Staszkiewicz	done
7086353f5d9SKajetan Staszkiewicz
7096353f5d9SKajetan Staszkiewicz	# All tables have counters increased for In/Pass and Out/Pass, not XPass nor Block.
7106353f5d9SKajetan Staszkiewicz	table_counters="Evaluations: NoMatch: 0 Match: 1 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 4 Bytes: 231 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 6 Bytes: 455 Out/XPass: Packets: 0 Bytes: 0"
7116353f5d9SKajetan Staszkiewicz	for table_test in \
7126353f5d9SKajetan Staszkiewicz		"tbl_src_match___${table_counters}" \
7136353f5d9SKajetan Staszkiewicz		"tbl_dst_match___${table_counters}" \
7146353f5d9SKajetan Staszkiewicz		"tbl_src_pass___${table_counters}" \
7156353f5d9SKajetan Staszkiewicz		"tbl_dst_pass___${table_counters}" \
7166353f5d9SKajetan Staszkiewicz	; do
7176353f5d9SKajetan Staszkiewicz		table_name=${table_test%%___*}
7186353f5d9SKajetan Staszkiewicz		table_regexp=${table_test##*___}
7196353f5d9SKajetan Staszkiewicz		table=$(mktemp) || exit 1
7206353f5d9SKajetan Staszkiewicz		cat $tables | grep -A10 $table_name | tr '\n' ' ' | awk '{gsub("[\\[\\]]", " ", $0); gsub("[[:blank:]]+"," ",$0); print $0}' > ${table}
7216353f5d9SKajetan Staszkiewicz		grep -qE "${table_regexp}" ${table} || atf_fail "Bad counters for table ${table_name}"
7226353f5d9SKajetan Staszkiewicz	done;
7236353f5d9SKajetan Staszkiewicz
7246353f5d9SKajetan Staszkiewicz	for state_regexp in \
7256353f5d9SKajetan Staszkiewicz		"${epair_server1}a tcp ${net_server_host_tester}.* 6:4 pkts, 455:231 bytes, rule 4, " \
7266353f5d9SKajetan Staszkiewicz	; do
7276353f5d9SKajetan Staszkiewicz		grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'"
7286353f5d9SKajetan Staszkiewicz	done
729*7cd3854fSKajetan Staszkiewicz
730*7cd3854fSKajetan Staszkiewicz	echo " === interfaces === "
731*7cd3854fSKajetan Staszkiewicz	echo " === tester === "
732*7cd3854fSKajetan Staszkiewicz	jexec router pfctl -qvvsI -i ${epair_tester}b
733*7cd3854fSKajetan Staszkiewicz	echo " === server === "
734*7cd3854fSKajetan Staszkiewicz	jexec router pfctl -qvvsI -i ${epair_server1}a
735*7cd3854fSKajetan Staszkiewicz	echo " === "
7366353f5d9SKajetan Staszkiewicz}
7376353f5d9SKajetan Staszkiewicz
7386353f5d9SKajetan Staszkiewicznat64_in_cleanup()
7396353f5d9SKajetan Staszkiewicz{
7406353f5d9SKajetan Staszkiewicz	pft_cleanup
7416353f5d9SKajetan Staszkiewicz}
7426353f5d9SKajetan Staszkiewicz
7436353f5d9SKajetan Staszkiewiczatf_test_case "nat64_out" "cleanup"
7446353f5d9SKajetan Staszkiewicznat64_out_head()
7456353f5d9SKajetan Staszkiewicz{
7466353f5d9SKajetan Staszkiewicz	atf_set descr 'Counters on match and outbound af-to rules'
7476353f5d9SKajetan Staszkiewicz	atf_set require.user root
7486353f5d9SKajetan Staszkiewicz}
7496353f5d9SKajetan Staszkiewicz
7506353f5d9SKajetan Staszkiewicznat64_out_body()
7516353f5d9SKajetan Staszkiewicz{
7526353f5d9SKajetan Staszkiewicz	setup_router_server_nat64
7536353f5d9SKajetan Staszkiewicz
7546353f5d9SKajetan Staszkiewicz	# af-to in outbound path requires routes for the pre-af-to traffic.
7556353f5d9SKajetan Staszkiewicz	jexec router route add -inet6 64:ff9b::/96 -iface ${epair_server1}a
7566353f5d9SKajetan Staszkiewicz
7576353f5d9SKajetan Staszkiewicz	pft_set_rules router \
7586353f5d9SKajetan Staszkiewicz		"set state-policy if-bound" \
7596353f5d9SKajetan Staszkiewicz		"table <tbl_src_match> { ${net_tester_6_host_tester} }" \
7606353f5d9SKajetan Staszkiewicz		"table <tbl_dst_match> { 64:ff9b::${net_server1_4_host_server} }" \
7616353f5d9SKajetan Staszkiewicz		"table <tbl_src_pass>  { ${net_tester_6_host_tester} }" \
7626353f5d9SKajetan Staszkiewicz		"table <tbl_dst_pass>  { 64:ff9b::${net_server1_4_host_server} }" \
763*7cd3854fSKajetan Staszkiewicz		"block log " \
7646353f5d9SKajetan Staszkiewicz		"pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
7656353f5d9SKajetan Staszkiewicz		"pass  in  on ${epair_tester}b inet6 proto tcp keep state" \
7666353f5d9SKajetan Staszkiewicz		"match out on ${epair_server1}a inet6 proto tcp from <tbl_src_match> to <tbl_dst_match> scrub (random-id)" \
7676353f5d9SKajetan Staszkiewicz		"pass  out on ${epair_server1}a inet6 proto tcp from <tbl_src_pass>  to <tbl_dst_pass> \
7686353f5d9SKajetan Staszkiewicz			af-to inet from (${epair_server1}a) \
7696353f5d9SKajetan Staszkiewicz			keep state"
7706353f5d9SKajetan Staszkiewicz
7716353f5d9SKajetan Staszkiewicz	# Use a real TCP connection so that it will be properly closed, guaranteeing the amount of packets.
7726353f5d9SKajetan Staszkiewicz	atf_check -s exit:0 -o match:"This is a test" -x \
7736353f5d9SKajetan Staszkiewicz		"echo 'This is a test' | nc -w3 64:ff9b::${net_server1_4_host_server} echo"
7746353f5d9SKajetan Staszkiewicz	sleep 1
7756353f5d9SKajetan Staszkiewicz	get_counters
7766353f5d9SKajetan Staszkiewicz
7776353f5d9SKajetan Staszkiewicz	for rule_regexp in \
7786353f5d9SKajetan Staszkiewicz		"@4 match out on ${epair_server1}a .* Packets: 10 Bytes: 686 States: 1 " \
7796353f5d9SKajetan Staszkiewicz		"@5 pass out on ${epair_server1}a .* Packets: 10 Bytes: 686 States: 1 " \
7806353f5d9SKajetan Staszkiewicz	; do
7816353f5d9SKajetan Staszkiewicz		grep -qE "${rule_regexp}" $rules || atf_fail "Rule regexp not found for '${rule_regexp}'"
7826353f5d9SKajetan Staszkiewicz	done
7836353f5d9SKajetan Staszkiewicz
7846353f5d9SKajetan Staszkiewicz	# All tables have counters increased for In/Pass and Out/Pass, not XPass nor Block.
7856353f5d9SKajetan Staszkiewicz	table_counters="Evaluations: NoMatch: 0 Match: 1 In/Block: Packets: 0 Bytes: 0 In/Pass: Packets: 4 Bytes: 231 In/XPass: Packets: 0 Bytes: 0 Out/Block: Packets: 0 Bytes: 0 Out/Pass: Packets: 6 Bytes: 455 Out/XPass: Packets: 0 Bytes: 0"
7866353f5d9SKajetan Staszkiewicz	for table_test in \
7876353f5d9SKajetan Staszkiewicz		"tbl_src_match___${table_counters}" \
7886353f5d9SKajetan Staszkiewicz		"tbl_dst_match___${table_counters}" \
7896353f5d9SKajetan Staszkiewicz		"tbl_src_pass___${table_counters}" \
7906353f5d9SKajetan Staszkiewicz		"tbl_dst_pass___${table_counters}" \
7916353f5d9SKajetan Staszkiewicz	; do
7926353f5d9SKajetan Staszkiewicz		table_name=${table_test%%___*}
7936353f5d9SKajetan Staszkiewicz		table_regexp=${table_test##*___}
7946353f5d9SKajetan Staszkiewicz		table=$(mktemp) || exit 1
7956353f5d9SKajetan Staszkiewicz		cat $tables | grep -A10 $table_name | tr '\n' ' ' | awk '{gsub("[\\[\\]]", " ", $0); gsub("[[:blank:]]+"," ",$0); print $0}' > ${table}
7966353f5d9SKajetan Staszkiewicz		grep -qE "${table_regexp}" ${table} || atf_fail "Bad counters for table ${table_name}"
7976353f5d9SKajetan Staszkiewicz	done;
7986353f5d9SKajetan Staszkiewicz
7996353f5d9SKajetan Staszkiewicz	for state_regexp in \
8006353f5d9SKajetan Staszkiewicz		"${epair_server1}a tcp 198.51.100.17:[0-9]+ \(64:ff9b::c633:6412\[7\]\) -> 198.51.100.18:7 \(2001:db8:4200::2\[[0-9]+\]\) .* 6:4 pkts, 455:231 bytes, rule 5," \
8016353f5d9SKajetan Staszkiewicz	; do
8026353f5d9SKajetan Staszkiewicz		grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'"
8036353f5d9SKajetan Staszkiewicz	done
804*7cd3854fSKajetan Staszkiewicz
805*7cd3854fSKajetan Staszkiewicz	echo " === interfaces === "
806*7cd3854fSKajetan Staszkiewicz	echo " === tester === "
807*7cd3854fSKajetan Staszkiewicz	jexec router pfctl -qvvsI -i ${epair_tester}b
808*7cd3854fSKajetan Staszkiewicz	echo " === server === "
809*7cd3854fSKajetan Staszkiewicz	jexec router pfctl -qvvsI -i ${epair_server1}a
810*7cd3854fSKajetan Staszkiewicz	echo " === "
8116353f5d9SKajetan Staszkiewicz}
8126353f5d9SKajetan Staszkiewicz
8136353f5d9SKajetan Staszkiewicznat64_out_cleanup()
8146353f5d9SKajetan Staszkiewicz{
8156353f5d9SKajetan Staszkiewicz	pft_cleanup
8166353f5d9SKajetan Staszkiewicz}
8176353f5d9SKajetan Staszkiewicz
8186353f5d9SKajetan Staszkiewiczatf_init_test_cases()
8196353f5d9SKajetan Staszkiewicz{
8206353f5d9SKajetan Staszkiewicz	atf_add_test_case "match_pass_state"
8216353f5d9SKajetan Staszkiewicz	atf_add_test_case "match_pass_no_state"
8226353f5d9SKajetan Staszkiewicz	atf_add_test_case "match_block"
8236353f5d9SKajetan Staszkiewicz	atf_add_test_case "match_fail"
8246353f5d9SKajetan Staszkiewicz	atf_add_test_case "nat_natonly"
8256353f5d9SKajetan Staszkiewicz	atf_add_test_case "nat_nat"
8266353f5d9SKajetan Staszkiewicz	atf_add_test_case "nat_match"
8276353f5d9SKajetan Staszkiewicz	atf_add_test_case "nat_pass"
8286353f5d9SKajetan Staszkiewicz	atf_add_test_case "rdr_match"
8296353f5d9SKajetan Staszkiewicz	atf_add_test_case "nat64_in"
8306353f5d9SKajetan Staszkiewicz	atf_add_test_case "nat64_out"
8316353f5d9SKajetan Staszkiewicz}
832