xref: /freebsd/tests/sys/netpfil/pf/mbuf.sh (revision 8829d4cb09d39801d3b6bcf8ab8c6b72dd757636)
109b7a038SIgor Ostapenko#
209b7a038SIgor Ostapenko# SPDX-License-Identifier: BSD-2-Clause
309b7a038SIgor Ostapenko#
409b7a038SIgor Ostapenko# Copyright (c) 2024 Igor Ostapenko <pm@igoro.pro>
509b7a038SIgor Ostapenko#
609b7a038SIgor Ostapenko# Redistribution and use in source and binary forms, with or without
709b7a038SIgor Ostapenko# modification, are permitted provided that the following conditions
809b7a038SIgor Ostapenko# are met:
909b7a038SIgor Ostapenko# 1. Redistributions of source code must retain the above copyright
1009b7a038SIgor Ostapenko#    notice, this list of conditions and the following disclaimer.
1109b7a038SIgor Ostapenko# 2. Redistributions in binary form must reproduce the above copyright
1209b7a038SIgor Ostapenko#    notice, this list of conditions and the following disclaimer in the
1309b7a038SIgor Ostapenko#    documentation and/or other materials provided with the distribution.
1409b7a038SIgor Ostapenko#
1509b7a038SIgor Ostapenko# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1609b7a038SIgor Ostapenko# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1709b7a038SIgor Ostapenko# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1809b7a038SIgor Ostapenko# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1909b7a038SIgor Ostapenko# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2009b7a038SIgor Ostapenko# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2109b7a038SIgor Ostapenko# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2209b7a038SIgor Ostapenko# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2309b7a038SIgor Ostapenko# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2409b7a038SIgor Ostapenko# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2509b7a038SIgor Ostapenko# SUCH DAMAGE.
2609b7a038SIgor Ostapenko
2709b7a038SIgor Ostapenko. $(atf_get_srcdir)/utils.subr
2809b7a038SIgor Ostapenko
2909b7a038SIgor Ostapenkodummymbuf_init()
3009b7a038SIgor Ostapenko{
3109b7a038SIgor Ostapenko	if ! kldstat -q -m dummymbuf; then
3209b7a038SIgor Ostapenko		atf_skip "This test requires dummymbuf"
3309b7a038SIgor Ostapenko	fi
3409b7a038SIgor Ostapenko}
3509b7a038SIgor Ostapenko
3609b7a038SIgor Ostapenkoatf_test_case "inet_in_mbuf_len" "cleanup"
3709b7a038SIgor Ostapenkoinet_in_mbuf_len_head()
3809b7a038SIgor Ostapenko{
3909b7a038SIgor Ostapenko	atf_set descr 'Test that pf can handle inbound with the first mbuf with m_len < sizeof(struct ip)'
4009b7a038SIgor Ostapenko	atf_set require.user root
4109b7a038SIgor Ostapenko}
4209b7a038SIgor Ostapenkoinet_in_mbuf_len_body()
4309b7a038SIgor Ostapenko{
4409b7a038SIgor Ostapenko	pft_init
4509b7a038SIgor Ostapenko	dummymbuf_init
4609b7a038SIgor Ostapenko
4709b7a038SIgor Ostapenko	epair=$(vnet_mkepair)
4809b7a038SIgor Ostapenko	ifconfig ${epair}a 192.0.2.1/24 up
4909b7a038SIgor Ostapenko
5009b7a038SIgor Ostapenko	# Set up a simple jail with one interface
5109b7a038SIgor Ostapenko	vnet_mkjail alcatraz ${epair}b
5209b7a038SIgor Ostapenko	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
5309b7a038SIgor Ostapenko
5409b7a038SIgor Ostapenko	# Sanity check
5509b7a038SIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 192.0.2.2
5609b7a038SIgor Ostapenko
5709b7a038SIgor Ostapenko	# Should be denied
5809b7a038SIgor Ostapenko	jexec alcatraz pfctl -e
5909b7a038SIgor Ostapenko	pft_set_rules alcatraz \
6009b7a038SIgor Ostapenko		"block"
6109b7a038SIgor Ostapenko	atf_check -s not-exit:0 -o ignore ping -c1 -t1 192.0.2.2
6209b7a038SIgor Ostapenko
6309b7a038SIgor Ostapenko	# Should be allowed by from/to addresses
6409b7a038SIgor Ostapenko	pft_set_rules alcatraz \
6509b7a038SIgor Ostapenko		"block" \
6609b7a038SIgor Ostapenko		"pass in from 192.0.2.1 to 192.0.2.2"
6709b7a038SIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 192.0.2.2
6809b7a038SIgor Ostapenko
6909b7a038SIgor Ostapenko	# Should still work for m_len=0
7009b7a038SIgor Ostapenko	jexec alcatraz pfilctl link -i dummymbuf:inet inet
7109b7a038SIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.rules="inet in ${epair}b pull-head 0;"
7209b7a038SIgor Ostapenko	atf_check_equal "0" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
7309b7a038SIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 192.0.2.2
7409b7a038SIgor Ostapenko	atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
7509b7a038SIgor Ostapenko
7609b7a038SIgor Ostapenko	# m_len=1
7709b7a038SIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.rules="inet in ${epair}b pull-head 1;"
7809b7a038SIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.hits=0
7909b7a038SIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 192.0.2.2
8009b7a038SIgor Ostapenko	atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
8109b7a038SIgor Ostapenko
8209b7a038SIgor Ostapenko	# m_len=19
8309b7a038SIgor Ostapenko	# provided IPv4 basic header is 20 bytes long, it should impact the dst addr
8409b7a038SIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.rules="inet in ${epair}b pull-head 19;"
8509b7a038SIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.hits=0
8609b7a038SIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 192.0.2.2
8709b7a038SIgor Ostapenko	atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
8809b7a038SIgor Ostapenko}
8909b7a038SIgor Ostapenkoinet_in_mbuf_len_cleanup()
9009b7a038SIgor Ostapenko{
9109b7a038SIgor Ostapenko	pft_cleanup
9209b7a038SIgor Ostapenko}
9309b7a038SIgor Ostapenko
9422a632c3SIgor Ostapenkoatf_test_case "inet6_in_mbuf_len" "cleanup"
9522a632c3SIgor Ostapenkoinet6_in_mbuf_len_head()
9622a632c3SIgor Ostapenko{
9722a632c3SIgor Ostapenko	atf_set descr 'Test that pf can handle inbound with the first mbuf with m_len < sizeof(struct ip6_hdr)'
9822a632c3SIgor Ostapenko	atf_set require.user root
9922a632c3SIgor Ostapenko}
10022a632c3SIgor Ostapenkoinet6_in_mbuf_len_body()
10122a632c3SIgor Ostapenko{
10222a632c3SIgor Ostapenko	pft_init
10322a632c3SIgor Ostapenko	dummymbuf_init
10422a632c3SIgor Ostapenko
10522a632c3SIgor Ostapenko	epair=$(vnet_mkepair)
10622a632c3SIgor Ostapenko	ifconfig ${epair}a inet6 2001:db8::1/64 up no_dad
10722a632c3SIgor Ostapenko
10822a632c3SIgor Ostapenko	# Set up a simple jail with one interface
10922a632c3SIgor Ostapenko	vnet_mkjail alcatraz ${epair}b
11022a632c3SIgor Ostapenko	jexec alcatraz ifconfig ${epair}b inet6 2001:db8::2/64 up no_dad
11122a632c3SIgor Ostapenko
11222a632c3SIgor Ostapenko	# Sanity check
11322a632c3SIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 2001:db8::2
11422a632c3SIgor Ostapenko
11522a632c3SIgor Ostapenko	# Should be denied
11622a632c3SIgor Ostapenko	jexec alcatraz pfctl -e
11722a632c3SIgor Ostapenko	pft_set_rules alcatraz \
11822a632c3SIgor Ostapenko		"block" \
11922a632c3SIgor Ostapenko		"pass quick inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }"
12022a632c3SIgor Ostapenko	atf_check -s not-exit:0 -o ignore ping -c1 -t1 2001:db8::2
12122a632c3SIgor Ostapenko
122*8829d4cbSIgor Ostapenko	# Avoid redundant ICMPv6 packets to avoid false positives during
123*8829d4cbSIgor Ostapenko	# counting of net.dummymbuf.hits.
124*8829d4cbSIgor Ostapenko	ndp -i ${epair}a -- -nud
125*8829d4cbSIgor Ostapenko	jexec alcatraz ndp -i ${epair}b -- -nud
126*8829d4cbSIgor Ostapenko
12722a632c3SIgor Ostapenko	# Should be allowed by from/to addresses
12822a632c3SIgor Ostapenko	pft_set_rules alcatraz \
12922a632c3SIgor Ostapenko		"block" \
13022a632c3SIgor Ostapenko		"pass quick inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
13122a632c3SIgor Ostapenko		"pass in inet6 from 2001:db8::1 to 2001:db8::2"
13222a632c3SIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 2001:db8::2
13322a632c3SIgor Ostapenko
13422a632c3SIgor Ostapenko	# Should still work for m_len=0
13522a632c3SIgor Ostapenko	jexec alcatraz pfilctl link -i dummymbuf:inet6 inet6
13622a632c3SIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.rules="inet6 in ${epair}b pull-head 0;"
13722a632c3SIgor Ostapenko	atf_check_equal "0" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
13822a632c3SIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 2001:db8::2
13922a632c3SIgor Ostapenko	atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
14022a632c3SIgor Ostapenko
14122a632c3SIgor Ostapenko	# m_len=1
14222a632c3SIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.rules="inet6 in ${epair}b pull-head 1;"
14322a632c3SIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.hits=0
14422a632c3SIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 2001:db8::2
14522a632c3SIgor Ostapenko	atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
14622a632c3SIgor Ostapenko
14722a632c3SIgor Ostapenko	# m_len=39
14822a632c3SIgor Ostapenko	# provided IPv6 basic header is 40 bytes long, it should impact the dst addr
14922a632c3SIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.rules="inet6 in ${epair}b pull-head 39;"
15022a632c3SIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.hits=0
15122a632c3SIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 2001:db8::2
15222a632c3SIgor Ostapenko	atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
15322a632c3SIgor Ostapenko}
15422a632c3SIgor Ostapenkoinet6_in_mbuf_len_cleanup()
15522a632c3SIgor Ostapenko{
15622a632c3SIgor Ostapenko	pft_cleanup
15722a632c3SIgor Ostapenko}
15822a632c3SIgor Ostapenko
159e7f9171bSIgor Ostapenkoatf_test_case "ethernet_in_mbuf_len" "cleanup"
160e7f9171bSIgor Ostapenkoethernet_in_mbuf_len_head()
161e7f9171bSIgor Ostapenko{
162e7f9171bSIgor Ostapenko	atf_set descr 'Test that pf can handle inbound with the first mbuf with m_len < sizeof(struct ether_header)'
163e7f9171bSIgor Ostapenko	atf_set require.user root
164e7f9171bSIgor Ostapenko}
165e7f9171bSIgor Ostapenkoethernet_in_mbuf_len_body()
166e7f9171bSIgor Ostapenko{
167e7f9171bSIgor Ostapenko	pft_init
168e7f9171bSIgor Ostapenko	dummymbuf_init
169e7f9171bSIgor Ostapenko
170e7f9171bSIgor Ostapenko	epair=$(vnet_mkepair)
171e7f9171bSIgor Ostapenko	epair_a_mac=$(ifconfig ${epair}a ether | awk '/ether/ { print $2; }')
172e7f9171bSIgor Ostapenko	ifconfig ${epair}a 192.0.2.1/24 up
173e7f9171bSIgor Ostapenko
174e7f9171bSIgor Ostapenko	# Set up a simple jail with one interface
175e7f9171bSIgor Ostapenko	vnet_mkjail alcatraz ${epair}b
176e7f9171bSIgor Ostapenko	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
177e7f9171bSIgor Ostapenko	epair_b_mac=$(jexec alcatraz ifconfig ${epair}b ether | awk '/ether/ { print $2; }')
178e7f9171bSIgor Ostapenko
179e7f9171bSIgor Ostapenko	# Sanity check
180e7f9171bSIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 192.0.2.2
181e7f9171bSIgor Ostapenko
182e7f9171bSIgor Ostapenko	# Should be denied
183e7f9171bSIgor Ostapenko	jexec alcatraz pfctl -e
184e7f9171bSIgor Ostapenko	pft_set_rules alcatraz \
185e7f9171bSIgor Ostapenko		"ether block" \
186e7f9171bSIgor Ostapenko		"pass"
187e7f9171bSIgor Ostapenko	atf_check -s not-exit:0 -o ignore ping -c1 -t1 192.0.2.2
188e7f9171bSIgor Ostapenko
189e7f9171bSIgor Ostapenko	# Should be allowed by from/to addresses
190e7f9171bSIgor Ostapenko	echo $epair_a_mac
191e7f9171bSIgor Ostapenko	echo $epair_b_mac
192e7f9171bSIgor Ostapenko	pft_set_rules alcatraz \
193e7f9171bSIgor Ostapenko		"ether block" \
194e7f9171bSIgor Ostapenko		"ether pass in  from ${epair_a_mac} to ${epair_b_mac}" \
195e7f9171bSIgor Ostapenko		"ether pass out from ${epair_b_mac} to ${epair_a_mac}" \
196e7f9171bSIgor Ostapenko		"pass"
197e7f9171bSIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 192.0.2.2
198e7f9171bSIgor Ostapenko
199e7f9171bSIgor Ostapenko	# Should still work for m_len=0
200e7f9171bSIgor Ostapenko	jexec alcatraz pfilctl link -i dummymbuf:ethernet ethernet
201e7f9171bSIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.rules="ethernet in ${epair}b pull-head 0;"
202e7f9171bSIgor Ostapenko	atf_check_equal "0" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
203e7f9171bSIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 192.0.2.2
204e7f9171bSIgor Ostapenko	atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
205e7f9171bSIgor Ostapenko
206e7f9171bSIgor Ostapenko	# m_len=1
207e7f9171bSIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.rules="ethernet in ${epair}b pull-head 1;"
208e7f9171bSIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.hits=0
209e7f9171bSIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 192.0.2.2
210e7f9171bSIgor Ostapenko	atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
211e7f9171bSIgor Ostapenko
212e7f9171bSIgor Ostapenko	# m_len=11
213e7f9171bSIgor Ostapenko	# for the simplest L2 Ethernet frame it should impact src field
214e7f9171bSIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.rules="ethernet in ${epair}b pull-head 11;"
215e7f9171bSIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.hits=0
216e7f9171bSIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 192.0.2.2
217e7f9171bSIgor Ostapenko	atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
218e7f9171bSIgor Ostapenko
219e7f9171bSIgor Ostapenko	# m_len=13
220e7f9171bSIgor Ostapenko	# provided L2 Ethernet simplest header is 14 bytes long, it should impact ethertype field
221e7f9171bSIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.rules="ethernet in ${epair}b pull-head 13;"
222e7f9171bSIgor Ostapenko	jexec alcatraz sysctl net.dummymbuf.hits=0
223e7f9171bSIgor Ostapenko	atf_check -s exit:0 -o ignore ping -c1 192.0.2.2
224e7f9171bSIgor Ostapenko	atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)"
225e7f9171bSIgor Ostapenko}
226e7f9171bSIgor Ostapenkoethernet_in_mbuf_len_cleanup()
227e7f9171bSIgor Ostapenko{
228e7f9171bSIgor Ostapenko	pft_cleanup
229e7f9171bSIgor Ostapenko}
230e7f9171bSIgor Ostapenko
23109b7a038SIgor Ostapenkoatf_init_test_cases()
23209b7a038SIgor Ostapenko{
23309b7a038SIgor Ostapenko	atf_add_test_case "inet_in_mbuf_len"
23422a632c3SIgor Ostapenko	atf_add_test_case "inet6_in_mbuf_len"
235e7f9171bSIgor Ostapenko	atf_add_test_case "ethernet_in_mbuf_len"
23609b7a038SIgor Ostapenko}
237