Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 14 Apr 2023 07:52:50 GMT
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: b800be978086 - main - pf tests: add tests for the new scrub syntax
Message-ID:  <202304140752.33E7qoNV080971@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=b800be978086396e4449525165096d188f4f3527

commit b800be978086396e4449525165096d188f4f3527
Author:     Kajetan Staszkiewicz <vegeta@tuxpowered.net>
AuthorDate: 2023-04-13 16:14:52 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2023-04-14 07:04:06 +0000

    pf tests: add tests for the new scrub syntax
    
    Add functions for testing new scrub option syntax and for packet
    fragmentation and route tables, because this was modified too. When
    testing of both the new and the compatible syntax is necessary, move
    original tests into _compat.sh file.
    
    Reviewed by:    kp
    Sponsored by:   InnoGames GmbH
    Differential Revision:  https://reviews.freebsd.org/D38129
---
 tests/sys/netpfil/pf/Makefile                      |   6 +-
 .../{fragmentation.sh => fragmentation_compat.sh}  |  31 +-
 tests/sys/netpfil/pf/fragmentation_pass.sh         | 438 +++++++++++++++++++++
 tests/sys/netpfil/pf/scrub_compat.sh               | 221 +++++++++++
 tests/sys/netpfil/pf/scrub_pass.sh                 | 173 ++++++++
 5 files changed, 856 insertions(+), 13 deletions(-)

diff --git a/tests/sys/netpfil/pf/Makefile b/tests/sys/netpfil/pf/Makefile
index 250299727697..1117f0dcc239 100644
--- a/tests/sys/netpfil/pf/Makefile
+++ b/tests/sys/netpfil/pf/Makefile
@@ -10,7 +10,8 @@ ATF_TESTS_SH+=	altq \
 		dup \
 		ether \
 		forward \
-		fragmentation \
+		fragmentation_compat \
+		fragmentation_pass \
 		get_state \
 		icmp \
 		killstate \
@@ -29,7 +30,8 @@ ATF_TESTS_SH+=	altq \
 		route_to \
 		rtable \
 		rules_counter \
-		scrub \
+		scrub_compat \
+		scrub_pass \
 		set_skip \
 		set_tos \
 		src_track \
diff --git a/tests/sys/netpfil/pf/fragmentation.sh b/tests/sys/netpfil/pf/fragmentation_compat.sh
similarity index 93%
rename from tests/sys/netpfil/pf/fragmentation.sh
rename to tests/sys/netpfil/pf/fragmentation_compat.sh
index 554a9fdecc09..ae1ba37310bf 100644
--- a/tests/sys/netpfil/pf/fragmentation.sh
+++ b/tests/sys/netpfil/pf/fragmentation_compat.sh
@@ -348,9 +348,6 @@ no_df_body()
 {
 	setup_router_server_ipv4
 
-	# Tester can send long packets which will get fragmented by the router.
-	# Replies from server will come in fragments which might get
-	# reassembled resulting in a long reply packet sent back to tester.
 	ifconfig ${epair_tester}a mtu 9000
 	jexec router ifconfig ${epair_tester}b mtu 9000
 	jexec router ifconfig ${epair_server}a mtu 1500
@@ -359,16 +356,29 @@ no_df_body()
 	# Sanity check.
 	ping_server_check_reply exit:0 --ping-type=icmp
 
-	# Enable packet reassembly with clearing of the no-df flag.
 	pft_set_rules router \
-		"scrub all fragment reassemble no-df" \
-		"block" \
-		"pass inet proto icmp all icmp-type echoreq"
-	# Ping with non-fragmentable packets.
-	# pf will strip the DF flag resulting in fragmentation and packets
-	# getting properly forwarded.
+		"scrub fragment reassemble" \
+		"pass out" \
+		"block in" \
+		"pass in inet proto icmp all icmp-type echoreq"
+
+	# Ping with normal, fragmentable packets.
+	ping_server_check_reply exit:0 --ping-type=icmp --send-length=2000
+
+	# Ping with non-fragmentable packets, this will fail.
+	ping_server_check_reply exit:1 --ping-type=icmp --send-length=2000 --send-flags DF
+
+	pft_set_rules router \
+		"scrub any reassemble" \
+		"pass out" \
+		"block in" \
+		"pass in inet proto icmp all icmp-type echoreq"
+
+	# Ping with non-fragmentable packets again.
+	# This time pf will strip the DF flag.
 	ping_server_check_reply exit:0 --ping-type=icmp --send-length=2000 --send-flags DF
 }
+
 no_df_cleanup()
 {
 	pft_cleanup
@@ -383,5 +393,4 @@ atf_init_test_cases()
 	atf_add_test_case "overindex"
 	atf_add_test_case "overlimit"
 	atf_add_test_case "reassemble"
-	atf_add_test_case "no_df"
 }
diff --git a/tests/sys/netpfil/pf/fragmentation_pass.sh b/tests/sys/netpfil/pf/fragmentation_pass.sh
new file mode 100644
index 000000000000..cd6b0f9059ce
--- /dev/null
+++ b/tests/sys/netpfil/pf/fragmentation_pass.sh
@@ -0,0 +1,438 @@
+# $FreeBSD$
+#
+# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+#
+# Copyright (c) 2017 Kristof Provost <kp@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+. $(atf_get_srcdir)/utils.subr
+
+common_dir=$(atf_get_srcdir)/../common
+
+atf_test_case "too_many_fragments" "cleanup"
+
+too_many_fragments_head()
+{
+	atf_set descr 'IPv4 fragment limitation test'
+	atf_set require.user root
+}
+
+too_many_fragments_body()
+{
+	pft_init
+
+	epair=$(vnet_mkepair)
+	vnet_mkjail alcatraz ${epair}a
+
+	ifconfig ${epair}b inet 192.0.2.1/24 up
+	jexec alcatraz ifconfig ${epair}a 192.0.2.2/24 up
+
+	ifconfig ${epair}b mtu 200
+	jexec alcatraz ifconfig ${epair}a mtu 200
+
+	jexec alcatraz pfctl -e
+	pft_set_rules alcatraz \
+		"set reassemble yes" \
+		"pass keep state"
+
+	# So we know pf is limiting things
+	jexec alcatraz sysctl net.inet.ip.maxfragsperpacket=1024
+
+	# Sanity check
+	atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2
+
+	# We can ping with < 64 fragments
+	atf_check -s exit:0 -o ignore ping -c 1 -s 800 192.0.2.2
+
+	# Too many fragments should fail
+	atf_check -s exit:2 -o ignore ping -c 1 -s 20000 192.0.2.2
+}
+
+too_many_fragments_cleanup()
+{
+	pft_cleanup
+}
+
+atf_test_case "v6" "cleanup"
+v6_head()
+{
+	atf_set descr 'IPv6 fragmentation test'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+v6_body()
+{
+	pft_init
+
+	epair_send=$(vnet_mkepair)
+	epair_link=$(vnet_mkepair)
+
+	vnet_mkjail alcatraz ${epair_send}b ${epair_link}a
+	vnet_mkjail singsing ${epair_link}b
+
+	ifconfig ${epair_send}a inet6 2001:db8:42::1/64 no_dad up
+
+	jexec alcatraz ifconfig ${epair_send}b inet6 2001:db8:42::2/64 no_dad up
+	jexec alcatraz ifconfig ${epair_link}a inet6 2001:db8:43::2/64 no_dad up
+	jexec alcatraz sysctl net.inet6.ip6.forwarding=1
+
+	jexec singsing ifconfig ${epair_link}b inet6 2001:db8:43::3/64 no_dad up
+	jexec singsing route add -6 2001:db8:42::/64 2001:db8:43::2
+	route add -6 2001:db8:43::/64 2001:db8:42::2
+
+	jexec alcatraz ifconfig ${epair_send}b inet6 -ifdisabled
+	jexec alcatraz ifconfig ${epair_link}a inet6 -ifdisabled
+	jexec singsing ifconfig ${epair_link}b inet6 -ifdisabled
+	ifconfig ${epair_send}a inet6 -ifdisabled
+
+	ifconfig ${epair_send}a
+	jexec alcatraz ifconfig ${epair_send}b
+	lladdr=$(jexec alcatraz ifconfig ${epair_send}b | awk '/ scopeid / { print($2); }' | cut -f 1 -d %)
+
+	jexec alcatraz pfctl -e
+	pft_set_rules alcatraz \
+		"set reassemble yes" \
+		"pass keep state" \
+		"block in" \
+		"pass in inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
+		"pass in inet6 proto icmp6 icmp6-type { echoreq, echorep }"
+
+	# Host test
+	atf_check -s exit:0 -o ignore \
+		ping -6 -c 1 2001:db8:42::2
+
+	atf_check -s exit:0 -o ignore \
+		ping -6 -c 1 -s 4500 2001:db8:42::2
+
+	atf_check -s exit:0 -o ignore\
+		ping -6 -c 1 -b 70000 -s 65000 2001:db8:42::2
+
+	# Force an NDP lookup
+	ping -6 -c 1 ${lladdr}%${epair_send}a
+
+	atf_check -s exit:0 -o ignore\
+		ping -6 -c 1 -b 70000 -s 65000 ${lladdr}%${epair_send}a
+
+	# Forwarding test
+	atf_check -s exit:0 -o ignore \
+		ping -6 -c 1 2001:db8:43::3
+
+	atf_check -s exit:0 -o ignore \
+		ping -6 -c 1 -s 4500 2001:db8:43::3
+
+	atf_check -s exit:0 -o ignore\
+		ping -6 -c 1 -b 70000 -s 65000 2001:db8:43::3
+
+	$(atf_get_srcdir)/CVE-2019-5597.py \
+		${epair_send}a \
+		2001:db8:42::1 \
+		2001:db8:43::3
+}
+
+v6_cleanup()
+{
+	pft_cleanup
+}
+
+atf_test_case "mtu_diff" "cleanup"
+mtu_diff_head()
+{
+	atf_set descr 'Test reassembly across different MTUs, PR #255432'
+	atf_set require.user root
+}
+
+mtu_diff_body()
+{
+	pft_init
+
+	epair_small=$(vnet_mkepair)
+	epair_large=$(vnet_mkepair)
+
+	vnet_mkjail first ${epair_small}b ${epair_large}a
+	vnet_mkjail second ${epair_large}b
+
+	ifconfig ${epair_small}a 192.0.2.1/25 up
+	jexec first ifconfig ${epair_small}b 192.0.2.2/25 up
+
+	jexec first sysctl net.inet.ip.forwarding=1
+	jexec first ifconfig ${epair_large}a 192.0.2.130/25 up
+	jexec first ifconfig ${epair_large}a mtu 9000
+	jexec second ifconfig ${epair_large}b 192.0.2.131/25 up
+	jexec second ifconfig ${epair_large}b mtu 9000
+	jexec second route add default 192.0.2.130
+
+	route add 192.0.2.128/25 192.0.2.2
+
+	jexec first pfctl -e
+	pft_set_rules first \
+		"set reassemble yes" \
+		"pass keep state"
+
+	# Sanity checks
+	atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2
+	atf_check -s exit:0 -o ignore ping -c 1 192.0.2.130
+	atf_check -s exit:0 -o ignore ping -c 1 192.0.2.131
+
+	# Large packet that'll get reassembled and sent out in one on the large
+	# epair
+	atf_check -s exit:0 -o ignore ping -c 1 -s 8000 192.0.2.131
+}
+
+mtu_diff_cleanup()
+{
+	pft_cleanup
+}
+
+frag_common()
+{
+	name=$1
+
+	pft_init
+
+	epair=$(vnet_mkepair)
+	vnet_mkjail alcatraz ${epair}a
+
+	ifconfig ${epair}b inet 192.0.2.1/24 up
+	jexec alcatraz ifconfig ${epair}a 192.0.2.2/24 up
+
+	jexec alcatraz pfctl -e
+	pft_set_rules alcatraz \
+		"set reassemble yes" \
+		"pass keep state"
+
+	# Sanity check
+	atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2
+
+	atf_check -s exit:0 -o ignore $(atf_get_srcdir)/frag-${1}.py \
+		--to 192.0.2.2 \
+		--fromaddr 192.0.2.1 \
+		--sendif ${epair}b \
+		--recvif ${epair}b
+}
+
+atf_test_case "overreplace" "cleanup"
+overreplace_head()
+{
+	atf_set descr 'ping fragment that overlaps fragment at index boundary and replace it'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+overreplace_body()
+{
+	frag_common overreplace
+}
+
+overreplace_cleanup()
+{
+	pft_cleanup
+}
+
+atf_test_case "overindex" "cleanup"
+overindex_head()
+{
+	atf_set descr 'ping fragment that overlaps the first fragment at index boundary'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+overindex_body()
+{
+	frag_common overindex
+}
+
+overindex_cleanup()
+{
+	pft_cleanup
+}
+
+atf_test_case "overlimit" "cleanup"
+overlimit_head()
+{
+	atf_set descr 'ping fragment at index boundary that cannot be requeued'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+overlimit_body()
+{
+	frag_common overlimit
+}
+
+overlimit_cleanup()
+{
+	pft_cleanup
+}
+
+atf_test_case "reassemble" "cleanup"
+reassemble_head()
+{
+	atf_set descr 'Test reassembly'
+	atf_set require.user root
+}
+
+reassemble_body()
+{
+	pft_init
+
+	epair=$(vnet_mkepair)
+	vnet_mkjail alcatraz ${epair}a
+
+	ifconfig ${epair}b inet 192.0.2.1/24 up
+	jexec alcatraz ifconfig ${epair}a 192.0.2.2/24 up
+
+	# Sanity check
+	atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2
+
+	jexec alcatraz pfctl -e
+	pft_set_rules alcatraz \
+		"pass out" \
+		"block in" \
+		"pass in inet proto icmp all icmp-type echoreq"
+
+	# Single fragment passes
+	atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2
+
+	# But a fragmented ping does not
+	atf_check -s exit:2 -o ignore ping -c 1 -s 2000 192.0.2.2
+
+	pft_set_rules alcatraz \
+		"set reassemble yes" \
+		"pass out" \
+		"block in" \
+		"pass in inet proto icmp all icmp-type echoreq"
+
+	# Both single packet & fragmented pass when we scrub
+	atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2
+	atf_check -s exit:0 -o ignore ping -c 1 -s 2000 192.0.2.2
+}
+
+reassemble_cleanup()
+{
+	pft_cleanup
+}
+
+atf_test_case "no_df" "cleanup"
+no_df_head()
+{
+	atf_set descr 'Test removing of DF flag'
+	atf_set require.user root
+}
+
+no_df_body()
+{
+	setup_router_server_ipv4
+
+	ifconfig ${epair_tester}a mtu 9000
+	jexec router ifconfig ${epair_tester}b mtu 9000
+	jexec router ifconfig ${epair_server}a mtu 1500
+	jexec server ifconfig ${epair_server}b mtu 1500
+
+	# Sanity check.
+	ping_server_check_reply exit:0 --ping-type=icmp
+
+	pft_set_rules router \
+		"set reassemble no" \
+		"pass out" \
+		"block in" \
+		"pass in inet proto icmp all icmp-type echoreq"
+
+	# Ping with normal, fragmentable packets.
+	ping_server_check_reply exit:1 --ping-type=icmp --send-length=2000
+
+	pft_set_rules router \
+		"set reassemble yes" \
+		"pass out" \
+		"block in" \
+		"pass in inet proto icmp all icmp-type echoreq"
+
+	# Ping with normal, fragmentable packets.
+	ping_server_check_reply exit:0 --ping-type=icmp --send-length=2000
+
+	# Ping with non-fragmentable packets.
+	ping_server_check_reply exit:1 --ping-type=icmp --send-length=2000 --send-flags DF
+
+	pft_set_rules router \
+		"set reassemble yes no-df" \
+		"pass out" \
+		"block in" \
+		"pass in inet proto icmp all icmp-type echoreq"
+
+	# Ping with non-fragmentable packets again.
+	# This time pf will strip the DF flag.
+	ping_server_check_reply exit:0 --ping-type=icmp --send-length=2000 --send-flags DF
+}
+no_df_cleanup()
+{
+	pft_cleanup
+}
+
+atf_test_case "no_df" "cleanup"
+no_df_head()
+{
+	atf_set descr 'Test removing of DF flag'
+	atf_set require.user root
+}
+
+no_df_body()
+{
+	setup_router_server_ipv4
+
+	# Tester can send long packets which will get fragmented by the router.
+	# Replies from server will come in fragments which might get
+	# reassembled resulting in a long reply packet sent back to tester.
+	ifconfig ${epair_tester}a mtu 9000
+	jexec router ifconfig ${epair_tester}b mtu 9000
+	jexec router ifconfig ${epair_server}a mtu 1500
+	jexec server ifconfig ${epair_server}b mtu 1500
+
+	# Sanity check.
+	ping_server_check_reply exit:0 --ping-type=icmp
+
+	# Enable packet reassembly with clearing of the no-df flag.
+	pft_set_rules router \
+		"scrub all fragment reassemble no-df" \
+		"block" \
+		"pass inet proto icmp all icmp-type echoreq"
+	# Ping with non-fragmentable packets.
+	# pf will strip the DF flag resulting in fragmentation and packets
+	# getting properly forwarded.
+	ping_server_check_reply exit:0 --ping-type=icmp --send-length=2000 --send-flags DF
+}
+no_df_cleanup()
+{
+	pft_cleanup
+}
+
+atf_init_test_cases()
+{
+	atf_add_test_case "too_many_fragments"
+	atf_add_test_case "v6"
+	atf_add_test_case "mtu_diff"
+	atf_add_test_case "overreplace"
+	atf_add_test_case "overindex"
+	atf_add_test_case "overlimit"
+	atf_add_test_case "reassemble"
+	atf_add_test_case "no_df"
+}
diff --git a/tests/sys/netpfil/pf/scrub_compat.sh b/tests/sys/netpfil/pf/scrub_compat.sh
new file mode 100644
index 000000000000..14065ba9bbeb
--- /dev/null
+++ b/tests/sys/netpfil/pf/scrub_compat.sh
@@ -0,0 +1,221 @@
+# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+#
+# Copyright (c) 2020 Kristof Provost <kp@FreeBSD.org>
+# Copyright (c) 2023 Kajetan Staszkiewicz <vegeta@tuxpowered.net>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+. $(atf_get_srcdir)/utils.subr
+
+common_dir=$(atf_get_srcdir)/../common
+
+atf_test_case "max_mss_v4" "cleanup"
+max_mss_v4_head()
+{
+	atf_set descr 'Test IPv4 scrub "mss" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+max_mss_v4_body()
+{
+	setup_router_dummy_ipv4
+	pft_set_rules router "scrub on ${epair_tester}b max-mss 1300"
+	# Check aligned
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-mss=1400 --expect-mss=1300
+	# And unaligned
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-mss=1400 --expect-mss=1300 \
+	    --send-tcpopt-unaligned
+}
+
+max_mss_v4_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_test_case "max_mss_v6" "cleanup"
+max_mss_v6_head()
+{
+	atf_set descr 'Test IPv6 scrub "mss" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+max_mss_v6_body()
+{
+	setup_router_dummy_ipv6
+	pft_set_rules router "scrub on ${epair_tester}b max-mss 1300"
+	# Check aligned
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-mss=1400 --expect-mss=1300
+	# And unaligned
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-mss=1400 --expect-mss=1300 \
+	    --send-tcpopt-unaligned
+}
+
+max_mss_v6_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_test_case "set_tos_v4" "cleanup"
+set_tos_v4_head()
+{
+	atf_set descr 'Test IPv4 scub "set-tos" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+set_tos_v4_body()
+{
+	setup_router_dummy_ipv4
+	pft_set_rules router "scrub on ${epair_tester}b set-tos 0x42"
+	ping_dummy_check_request exit:0 --send-tc=0 --expect-tc=66
+}
+
+set_tos_v4_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_test_case "set_tos_v6" "cleanup"
+set_tos_v6_head()
+{
+	atf_set descr 'Test IPv6 scub "set-tos" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+set_tos_v6_body()
+{
+	setup_router_dummy_ipv6
+	pft_set_rules router "scrub on ${epair_tester}b set-tos 0x42"
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-tc=0 --expect-tc=66
+}
+
+set_tos_v6_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_test_case "min_ttl_v4" "cleanup"
+min_ttl_v4_head()
+{
+	atf_set descr 'Test IPv4 scub "min-ttl" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+min_ttl_v4_body()
+{
+	setup_router_dummy_ipv4
+	pft_set_rules router "scrub on ${epair_tester}b min-ttl 50"
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-hlim=40 --expect-hlim=49
+}
+
+min_ttl_v4_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_test_case "min_ttl_v6" "cleanup"
+min_ttl_v6_head()
+{
+	atf_set descr 'Test IPv6 scub "min-ttl" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+min_ttl_v6_body()
+{
+	setup_router_dummy_ipv6
+	pft_set_rules router "scrub on ${epair_tester}b min-ttl 50"
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-hlim=40 --expect-hlim=49
+}
+
+min_ttl_v6_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_test_case "no_scrub_v4" "cleanup"
+no_scrub_v4_head()
+{
+	atf_set descr 'Test IPv4 "no scrub" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+no_scrub_v4_body()
+{
+	setup_router_dummy_ipv4
+	pft_set_rules router\
+		"no scrub on ${epair_tester}b to ${net_server_host_server}"
+		"scrub on ${epair_tester}b set-tos 0x42"
+	ping_dummy_check_request exit:0 --send-tc=0 --expect-tc=0
+}
+
+no_scrub_v4_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_test_case "no_scrub_v6" "cleanup"
+no_scrub_v6_head()
+{
+	atf_set descr 'Test IPv6 "no scrub" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+no_scrub_v6_body()
+{
+	setup_router_dummy_ipv6
+	pft_set_rules router \
+		"no scrub on ${epair_tester}b to ${net_server_host_server}"
+		"scrub on ${epair_tester}b set-tos 0x42"
+	ping_dummy_check_request exit:0 --send-tc=0 --expect-tc=0
+}
+
+no_scrub_v6_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_init_test_cases()
+{
+	atf_add_test_case "max_mss_v4"
+	atf_add_test_case "max_mss_v6"
+	atf_add_test_case "set_tos_v4"
+	atf_add_test_case "set_tos_v6"
+	atf_add_test_case "min_ttl_v4"
+	atf_add_test_case "min_ttl_v6"
+	atf_add_test_case "no_scrub_v4"
+	atf_add_test_case "no_scrub_v6"
+}
diff --git a/tests/sys/netpfil/pf/scrub_pass.sh b/tests/sys/netpfil/pf/scrub_pass.sh
new file mode 100644
index 000000000000..e6dd0ed018ad
--- /dev/null
+++ b/tests/sys/netpfil/pf/scrub_pass.sh
@@ -0,0 +1,173 @@
+# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+#
+# Copyright (c) 2020 Kristof Provost <kp@FreeBSD.org>
+# Copyright (c) 2023 Kajetan Staszkiewicz <vegeta@tuxpowered.net>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+. $(atf_get_srcdir)/utils.subr
+
+common_dir=$(atf_get_srcdir)/../common
+
+atf_test_case "max_mss_v4" "cleanup"
+max_mss_v4_head()
+{
+	atf_set descr 'Test IPv4 pass "mss" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+max_mss_v4_body()
+{
+	setup_router_dummy_ipv4
+	pft_set_rules router "pass on ${epair_tester}b scrub ( max-mss 1300 )"
+	# Check aligned
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-mss=1400 --expect-mss=1300
+	# And unaligned
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-mss=1400 --expect-mss=1300 \
+	    --send-tcpopt-unaligned
+}
+
+max_mss_v4_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_test_case "max_mss_v6" "cleanup"
+max_mss_v6_head()
+{
+	atf_set descr 'Test IPv6 pass "mss" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+max_mss_v6_body()
+{
+	setup_router_dummy_ipv6
+	pft_set_rules router "pass on ${epair_tester}b scrub ( max-mss 1300 )"
+	# Check aligned
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-mss=1400 --expect-mss=1300
+	# And unaligned
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-mss=1400 --expect-mss=1300 \
+	    --send-tcpopt-unaligned
+}
+
+max_mss_v6_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_test_case "set_tos_v4" "cleanup"
+set_tos_v4_head()
+{
+	atf_set descr 'Test IPv4 pass "set-tos" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+set_tos_v4_body()
+{
+	setup_router_dummy_ipv4
+	pft_set_rules router "pass on ${epair_tester}b set ( tos 0x42 )"
+	ping_dummy_check_request exit:0 --send-tc=66 --expect-tc=66
+}
+
+set_tos_v4_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_test_case "set_tos_v6" "cleanup"
+set_tos_v6_head()
+{
+	atf_set descr 'Test IPv6 pass "set-tos" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+set_tos_v6_body()
+{
+	setup_router_dummy_ipv4
+	pft_set_rules router "pass on ${epair_tester}b set ( tos 0x42 )"
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-tc=66 --expect-tc=66
+}
+
+set_tos_v6_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_test_case "min_ttl_v4" "cleanup"
+min_ttl_v4_head()
+{
+	atf_set descr 'Test IPv4 pass "min-ttl" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+min_ttl_v4_body()
+{
+	setup_router_dummy_ipv4
+	pft_set_rules router "pass on ${epair_tester}b scrub ( min-ttl 50 )"
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-hlim=40 --expect-hlim=49
+}
+
+min_ttl_v4_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_test_case "min_ttl_v6" "cleanup"
+min_ttl_v6_head()
+{
+	atf_set descr 'Test IPv6 pass "min-ttl" rule'
+	atf_set require.user root
+	atf_set require.progs scapy
+}
+
+min_ttl_v6_body()
+{
+	setup_router_dummy_ipv6
+	pft_set_rules router "pass on ${epair_tester}b scrub ( min-ttl 50 )"
+	ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-hlim=40 --expect-hlim=49
+}
+
+min_ttl_v6_cleanup()
+{
+	pft_cleanup
+}
+
+
+atf_init_test_cases()
+{
+	atf_add_test_case "max_mss_v4"
+	atf_add_test_case "max_mss_v6"
+	atf_add_test_case "set_tos_v4"
+	atf_add_test_case "set_tos_v6"
+	atf_add_test_case "min_ttl_v4"
+	atf_add_test_case "min_ttl_v6"
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202304140752.33E7qoNV080971>