Changeset View
Changeset View
Standalone View
Standalone View
tests/sys/netpfil/pf/nat.sh
Show First 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | nested_anchor_body() | ||||
nat-anchor \"bar\" all { | nat-anchor \"bar\" all { | ||||
nat on ${epair}a all -> (${epair}a) round-robin | nat on ${epair}a all -> (${epair}a) round-robin | ||||
} | } | ||||
} | } | ||||
" jexec nat pfctl -sn -a "*" | " jexec nat pfctl -sn -a "*" | ||||
} | } | ||||
atf_test_case "endpoint_independent" "cleanup" | |||||
endpoint_independent_head() | |||||
{ | |||||
atf_set descr 'Test that a client behind NAT gets the same external IP:port for different servers' | |||||
atf_set require.user root | |||||
} | |||||
endpoint_independent_body() | |||||
{ | |||||
pft_init | |||||
epair_client=$(vnet_mkepair) | |||||
epair_nat=$(vnet_mkepair) | |||||
epair_server1=$(vnet_mkepair) | |||||
epair_server2=$(vnet_mkepair) | |||||
bridge=$(vnet_mkbridge) | |||||
vnet_mkjail nat ${epair_client}b ${epair_nat}a | |||||
vnet_mkjail client ${epair_client}a | |||||
vnet_mkjail server1 ${epair_server1}a | |||||
vnet_mkjail server2 ${epair_server2}a | |||||
ifconfig ${epair_server1}b up | |||||
ifconfig ${epair_server2}b up | |||||
ifconfig ${epair_nat}b up | |||||
ifconfig ${bridge} \ | |||||
addm ${epair_server1}b \ | |||||
addm ${epair_server2}b \ | |||||
addm ${epair_nat}b \ | |||||
up | |||||
jexec nat ifconfig ${epair_client}b 192.0.2.1/24 up | |||||
jexec nat ifconfig ${epair_nat}a 10.42.42.42/8 up | |||||
kp: Ideally use a documentation/test subnet here, so 198.51.100.0/24 or 203.0.113.0/24 | |||||
jexec nat sysctl net.inet.ip.forwarding=1 | |||||
Not Done Inline ActionsTEST-NET-2 is 198.51.100.0/24, not 192.51.100.0/24. kp: TEST-NET-2 is 198.51.100.0/24, not 192.51.100.0/24. | |||||
jexec client ifconfig ${epair_client}a 192.0.2.2/24 up | |||||
jexec client route add default 192.0.2.1 | |||||
jexec server1 ifconfig ${epair_server1}a 10.32.32.32/8 up | |||||
jexec server2 ifconfig ${epair_server2}a 10.22.22.22/8 up | |||||
# Enable pf! | |||||
jexec nat pfctl -e | |||||
# validate non-endpoint independent nat rule behaviour | |||||
pft_set_rules nat \ | |||||
"nat on ${epair_nat}a inet from ! (${epair_nat}a) to any -> (${epair_nat}a)" | |||||
jexec server1 nc -u -l 1234 -v 2> server1.out & | |||||
kpUnsubmitted Done Inline ActionsI've been poking the test failure a bit, and it looks like there's some buffering going on on the receive side, and that's causing the test to fail. I wonder if it wouldn't be better to just use tcpdump on the receive side. That'll also show us the port numbers. There are a few other test cases that use tcpdump with --immediate-mode to get immediate output, rather than have to deal with buffering. kp: I've been poking the test failure a bit, and it looks like there's some buffering going on on… | |||||
server1pid="$!" | |||||
jexec server2 nc -u -l 1234 -v 2> server2.out & | |||||
server2pid="$!" | |||||
# send out three packets because sometimes one fails to go through | |||||
for i in $(seq 1 3); do | |||||
echo "ping" | jexec client nc -u 10.32.32.32 1234 -p 4242 -w 0 | |||||
echo "ping" | jexec client nc -u 10.22.22.22 1234 -p 4242 -w 0 | |||||
done | |||||
ipport_server1=$(cat server1.out | grep Connection) | |||||
ipport_server2=$(cat server2.out | grep Connection) | |||||
if [ -z "$ipport_server1" ]; then | |||||
atf_fail "server1 did not receive connection from client (default)" | |||||
fi | |||||
if [ -z "$ipport_server2" ]; then | |||||
atf_fail "server2 did not receive connection from client (default)" | |||||
fi | |||||
if [ "$ipport_server1" = "$ipport_server2" ]; then | |||||
echo "server1: $ipport_server1" | |||||
echo "server2: $ipport_server2" | |||||
atf_fail "Received same IP:port on server1 and server2 (default)" | |||||
fi | |||||
kill $server1pid | |||||
kill $server2pid | |||||
# validate endpoint independent nat rule behaviour | |||||
pft_set_rules nat \ | |||||
"nat on ${epair_nat}a inet from ! (${epair_nat}a) to any -> (${epair_nat}a) endpoint-independent" | |||||
jexec server1 nc -u -l 1234 -v 2> server1.out & | |||||
server1pid="$!" | |||||
jexec server2 nc -u -l 1234 -v 2> server2.out & | |||||
server2pid="$!" | |||||
# send out three packets because sometimes one fails to go through | |||||
for i in $(seq 1 3); do | |||||
echo "ping" | jexec client nc -u 10.32.32.32 1234 -p 4242 -w 0 | |||||
echo "ping" | jexec client nc -u 10.22.22.22 1234 -p 4242 -w 0 | |||||
done | |||||
ipport_server1=$(cat server1.out | grep Connection) | |||||
ipport_server2=$(cat server2.out | grep Connection) | |||||
if [ -z "$ipport_server1" ]; then | |||||
atf_fail "server1 did not receive connection from client (endpoint-independent)" | |||||
fi | |||||
if [ -z "$ipport_server2" ]; then | |||||
atf_fail "server2 did not receive connection from client (endpoint-independent)" | |||||
fi | |||||
if [ ! "$ipport_server1" = "$ipport_server2" ]; then | |||||
echo "server1: $ipport_server1" | |||||
echo "server2: $ipport_server2" | |||||
atf_fail "Received different IP:port on server1 than server2 (endpoint-independent)" | |||||
fi | |||||
kill $server1pid | |||||
kill $server2pid | |||||
} | |||||
endpoint_independent_cleanup() | |||||
{ | |||||
pft_cleanup | |||||
rm -f server1.out | |||||
rm -f server2.out | |||||
} | |||||
nested_anchor_cleanup() | nested_anchor_cleanup() | ||||
{ | { | ||||
pft_cleanup | pft_cleanup | ||||
} | } | ||||
atf_init_test_cases() | atf_init_test_cases() | ||||
{ | { | ||||
atf_add_test_case "exhaust" | atf_add_test_case "exhaust" | ||||
atf_add_test_case "nested_anchor" | atf_add_test_case "nested_anchor" | ||||
atf_add_test_case "endpoint_independent" | |||||
} | } |
Ideally use a documentation/test subnet here, so 198.51.100.0/24 or 203.0.113.0/24