diff options
author | Kristof Provost <kp@FreeBSD.org> | 2024-12-09 17:37:36 +0000 |
---|---|---|
committer | Kristof Provost <kp@FreeBSD.org> | 2024-12-17 10:07:17 +0000 |
commit | b0e3fb7e65c3a745177e52ec2f20a773b4d59c1e (patch) | |
tree | 76eae8fe7e79fa3a30f2c7d7bf2b87805619d835 | |
parent | 9e039875cb40e131dba4d5f00d0e44b619901e79 (diff) |
pf: fix nat64 round-robin addresses from a table
We do multiple lookups during the nat64 process, some of which will fail due
to address family mismatches. Do not reset the lookup offset so we actually use
different addresses from the table.
Sponsored by: Rubicon Communications, LLC ("Netgate")
-rw-r--r-- | sys/netpfil/pf/pf_lb.c | 1 | ||||
-rw-r--r-- | tests/sys/netpfil/pf/nat64.sh | 67 |
2 files changed, 67 insertions, 1 deletions
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c index 0f08226c1c0d..35896bdcf5b1 100644 --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -598,7 +598,6 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr, else rpool->cur = TAILQ_NEXT(rpool->cur, entries); if (rpool->cur->addr.type == PF_ADDR_TABLE) { - rpool->tblidx = -1; if (pfr_pool_get(rpool->cur->addr.p.tbl, &rpool->tblidx, &rpool->counter, af, NULL)) { /* table contains no address of type 'af' */ diff --git a/tests/sys/netpfil/pf/nat64.sh b/tests/sys/netpfil/pf/nat64.sh index b6b2b97a2f63..827891373903 100644 --- a/tests/sys/netpfil/pf/nat64.sh +++ b/tests/sys/netpfil/pf/nat64.sh @@ -341,6 +341,72 @@ pool_cleanup() pft_cleanup } +atf_test_case "table_round_robin" "cleanup" +table_round_robin_head() +{ + atf_set descr 'Use a table of IPv4 addresses in round-robin mode' + atf_set require.user root +} + +table_round_robin_body() +{ + pft_init + + epair_link=$(vnet_mkepair) + epair=$(vnet_mkepair) + + ifconfig ${epair}a inet6 2001:db8::2/64 up no_dad + route -6 add default 2001:db8::1 + + vnet_mkjail rtr ${epair}b ${epair_link}a + jexec rtr ifconfig ${epair}b inet6 2001:db8::1/64 up no_dad + jexec rtr ifconfig ${epair_link}a 192.0.2.1/24 up + jexec rtr ifconfig ${epair_link}a inet alias 192.0.2.3/24 up + jexec rtr ifconfig ${epair_link}a inet alias 192.0.2.4/24 up + + vnet_mkjail dst ${epair_link}b + jexec dst ifconfig ${epair_link}b 192.0.2.2/24 up + jexec dst route add default 192.0.2.1 + + # Sanity checks + atf_check -s exit:0 -o ignore \ + ping6 -c 1 2001:db8::1 + atf_check -s exit:0 -o ignore \ + jexec dst ping -c 1 192.0.2.1 + + jexec rtr pfctl -e + pft_set_rules rtr \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "table <wanaddrs> { 192.0.2.1, 192.0.2.3, 192.0.2.4 }" \ + "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from <wanaddrs> round-robin" + + # Use pf to count sources + jexec dst pfctl -e + pft_set_rules dst \ + "pass" + + atf_check -s exit:0 -o ignore \ + ping6 -c 1 64:ff9b::192.0.2.2 + atf_check -s exit:0 -o ignore \ + ping6 -c 1 64:ff9b::192.0.2.2 + atf_check -s exit:0 -o ignore \ + ping6 -c 1 64:ff9b::192.0.2.2 + + # Verify on dst that we saw different source addresses + atf_check -s exit:0 -o match:".*192.0.2.1.*" \ + jexec dst pfctl -ss + atf_check -s exit:0 -o match:".*192.0.2.3.*" \ + jexec dst pfctl -ss + atf_check -s exit:0 -o match:".*192.0.2.4.*" \ + jexec dst pfctl -ss +} + +table_round_robin_cleanup() +{ + pft_cleanup +} + atf_init_test_cases() { atf_add_test_case "icmp_echo" @@ -351,4 +417,5 @@ atf_init_test_cases() atf_add_test_case "tos" atf_add_test_case "no_v4" atf_add_test_case "pool" + atf_add_test_case "table_round_robin" } |