commit 6d2336f9b5fe6a8c2da9e98cb1d5ec6a2dfbf646 Author: Kristof Provost Date: Wed Dec 5 22:35:01 2018 +0100 pf tests: NAT exhaustion test It's been reported that pf doesn't handle running out of available ports for NAT correctly. It freezes until a state expires and it can find a free port. Test for this, by setting up a situation where only two ports are available for NAT and then attempting to create three connections. If successful the third connection will fail immediately. In an incorrect case the connection attempt will freeze, and trigger timeout. diff --git a/tests/sys/netpfil/pf/Makefile b/tests/sys/netpfil/pf/Makefile index 3d0f861f0a1..cab2cb35d3b 100644 --- a/tests/sys/netpfil/pf/Makefile +++ b/tests/sys/netpfil/pf/Makefile @@ -10,6 +10,7 @@ ATF_TESTS_SH+= anchor \ forward \ fragmentation \ names \ + nat \ set_tos \ route_to \ synproxy \ diff --git a/tests/sys/netpfil/pf/nat.sh b/tests/sys/netpfil/pf/nat.sh new file mode 100755 index 00000000000..57ea1c96ff2 --- /dev/null +++ b/tests/sys/netpfil/pf/nat.sh @@ -0,0 +1,64 @@ +# $FreeBSD$ + +. $(atf_get_srcdir)/utils.subr + +atf_test_case "exhaust" "cleanup" +exhaust_head() +{ + atf_set descr 'Test exhausting the NAT pool' + atf_set require.user root +} + +exhaust_body() +{ + pft_init + + epair_nat=$(pft_mkepair) + epair_echo=$(pft_mkepair) + + pft_mkjail nat ${epair_nat}b ${epair_echo}a + pft_mkjail echo ${epair_echo}b + + ifconfig ${epair_nat}a 192.0.2.2/24 up + route add -net 198.51.100.0/24 192.0.2.1 + + jexec nat ifconfig ${epair_nat}b 192.0.2.1/24 up + jexec nat ifconfig ${epair_echo}a 198.51.100.1/24 up + jexec nat sysctl net.inet.ip.forwarding=1 + + jexec echo ifconfig ${epair_echo}b 198.51.100.2/24 up + jexec echo /usr/sbin/inetd $(atf_get_srcdir)/echo_inetd.conf + + # Enable pf! + jexec nat pfctl -e + pft_set_rules nat \ + "nat pass on ${epair_echo}a inet from 192.0.2.0/24 to any -> (${epair_echo}a) port 30000:30001 sticky-address" + + # Sanity check + atf_check -s exit:0 -o ignore ping -c 3 198.51.100.2 + + echo "foo" | nc -N 198.51.100.2 7 + echo "foo" | nc -N 198.51.100.2 7 + + # This one will fail, but that's expected + echo "foo" | nc -N 198.51.100.2 7 & + + sleep 1 + + # If the kernel is stuck in pf_get_sport() this will not succeed either. + timeout 2 jexec nat pfctl -sa + if [ $? -eq 124 ]; then + # Timed out + atf_fail "pfctl timeout" + fi +} + +exhaust_cleanup() +{ + pft_cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case "exhaust" +}