Date: Tue, 11 Nov 2025 17:39:03 GMT From: Kajetan Staszkiewicz <ks@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 562648ad4145 - stable/15 - pf: Make nat-to and rdr-to work properly both on in and out rules Message-ID: <202511111739.5ABHd3fx058324@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch stable/15 has been updated by ks: URL: https://cgit.FreeBSD.org/src/commit/?id=562648ad414545bb4fb1f6da26273032c20875f3 commit 562648ad414545bb4fb1f6da26273032c20875f3 Author: Kajetan Staszkiewicz <ks@FreeBSD.org> AuthorDate: 2025-10-01 13:51:46 +0000 Commit: Kajetan Staszkiewicz <ks@FreeBSD.org> CommitDate: 2025-11-11 13:16:42 +0000 pf: Make nat-to and rdr-to work properly both on in and out rules New-style address translation is done by nat-to and rdr-to actions on normal match and pass rules. Those rules, when used without address translation, can be specified without direction. But that allows users to specify pre-routing nat and post-routing rdr. This case is not handled properly and causes pre-routing nat to modify destination address, as if it was a rdr rule, and post-routing rdr to modify source address, as if it was a nat rule. Ensure that nat-to action modifies source address and rdr-to destination address no matter in which direction the rule is applied. The man page for pf.conf already specifies that nat-to and rdr-to rules should be limited to respective directions. PR: 288577 Reviewed by: kp MFC after: 3 days Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D53216 (cherry picked from commit 646798b6783184fb194a2d97667e05895e00c358) --- sys/netpfil/pf/pf_lb.c | 16 +++++++++++++-- tests/sys/netpfil/pf/nat.sh | 47 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c index 29d7a32e0bdc..bee9f4637091 100644 --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -974,6 +974,7 @@ pf_get_transaddr(struct pf_test_ctx *ctx, struct pf_krule *r, { struct pf_pdesc *pd = ctx->pd; struct pf_addr *naddr; + int idx; uint16_t *nportp; uint16_t low, high; u_short reason; @@ -988,8 +989,19 @@ pf_get_transaddr(struct pf_test_ctx *ctx, struct pf_krule *r, return (PFRES_MEMORY); } - naddr = &ctx->nk->addr[1]; - nportp = &ctx->nk->port[1]; + switch (nat_action) { + case PF_NAT: + idx = pd->sidx; + break; + case PF_BINAT: + idx = 1; + break; + case PF_RDR: + idx = pd->didx; + break; + } + naddr = &ctx->nk->addr[idx]; + nportp = &ctx->nk->port[idx]; switch (nat_action) { case PF_NAT: diff --git a/tests/sys/netpfil/pf/nat.sh b/tests/sys/netpfil/pf/nat.sh index 5ea1dd6d8b2f..25cac1810349 100644 --- a/tests/sys/netpfil/pf/nat.sh +++ b/tests/sys/netpfil/pf/nat.sh @@ -474,14 +474,50 @@ no_addrs_random_cleanup() pft_cleanup } -nat_pass_head() +atf_test_case "nat_pass_in" "cleanup" +nat_pass_in_head() { - atf_set descr 'IPv4 NAT on pass rule' + atf_set descr 'IPv4 NAT on inbound pass rule' atf_set require.user root atf_set require.progs scapy } -nat_pass_body() +nat_pass_in_body() +{ + setup_router_server_ipv4 + # Delete the route back to make sure that the traffic has been NAT-ed + jexec server route del -net ${net_tester} ${net_server_host_router} + # Provide routing back to the NAT address + jexec server route add 203.0.113.0/24 ${net_server_host_router} + jexec router route add 203.0.113.0/24 -iface ${epair_tester}b + + pft_set_rules router \ + "block" \ + "pass in on ${epair_tester}b inet proto tcp nat-to 203.0.113.0 keep state" \ + "pass out on ${epair_server}a inet proto tcp keep state" + + ping_server_check_reply exit:0 --ping-type=tcp3way --send-sport=4201 + + jexec router pfctl -qvvsr + jexec router pfctl -qvvss + jexec router ifconfig + jexec router netstat -rn +} + +nat_pass_in_cleanup() +{ + pft_cleanup +} + +atf_test_case "nat_pass_out" "cleanup" +nat_pass_out_head() +{ + atf_set descr 'IPv4 NAT on outbound pass rule' + atf_set require.user root + atf_set require.progs scapy +} + +nat_pass_out_body() { setup_router_server_ipv4 # Delete the route back to make sure that the traffic has been NAT-ed @@ -500,7 +536,7 @@ nat_pass_body() jexec router netstat -rn } -nat_pass_cleanup() +nat_pass_out_cleanup() { pft_cleanup } @@ -823,7 +859,8 @@ atf_init_test_cases() atf_add_test_case "no_addrs_random" atf_add_test_case "map_e_compat" atf_add_test_case "map_e_pass" - atf_add_test_case "nat_pass" + atf_add_test_case "nat_pass_in" + atf_add_test_case "nat_pass_out" atf_add_test_case "nat_match" atf_add_test_case "binat_compat" atf_add_test_case "binat_match"home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202511111739.5ABHd3fx058324>
