From nobody Wed Sep 24 11:45:20 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4cWw5D2zfKz67jG9; Wed, 24 Sep 2025 11:45:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4cWw5D1kmQz3L9q; Wed, 24 Sep 2025 11:45:20 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1758714320; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=L11JfRoCnrM34pUvNqnABs9NzOfShlw0gprq9hEEFrE=; b=azfD39R1E//XI4FFq6SdJ7KhjzSlG7MiP6pjvbPkIfk5pWD1aoPYQEM5CBtuCZU4wtOqSY b9+tmpXnvcFfbJacpqNPTQ1KNT5lwVJvcKa+XlbhTUg3p2RmgGx/pWzEiPvkPvIoguzsvl Uwa2gAFc+HPPCs/3vbbuMhfh1IxuXXWclOIUA/55dSdyLQ6RGtWqZeYulz0ID5WqO8ZuaZ DJ7c7Ti9mXnKgccWqssEO/8xV+ROx9UJzB2CssKVN6QhRaY/aEFjOaC9zdgh9qvfc3e00c 1wf/uoz/sswWxExgv9mZwIf3KFPqdqXbjhjdcdHkENMTyc1nh/Q6Rt0C5FnkiQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1758714320; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=L11JfRoCnrM34pUvNqnABs9NzOfShlw0gprq9hEEFrE=; b=JsMYioX8HA2a3jfoj3FWSJda3qqVUavJLPpy+9g1PbYiWZh4fvhNBPXVk9rMCGJYofdno1 QTlchgEYAUq4Os5Q+JBa1pDk4/t+hEJAPB+TxpBY2EQUYjWF5RnBxJJFtcNe8kBkAMmikN pWTozoE52gc1ZTMwW6Re1XupckbsnELz6dBtN0RN/a1deITZPngD7BSmTAH1D6BMhORu60 skTGBJVUW3tMdjRD494fLGUh/sPwLtiB93jR5LXYMr9R0lhqFNEb7uQ0yDizQTKucCPUFM oC5TCoTvpAEHlvazDK4vdi2VbFH+qsq8SQmD2V9uDTvugh7ypi4bZV024is3CQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1758714320; a=rsa-sha256; cv=none; b=k0Hc1CpxfTGXQ31/klh9seBd/nYlPxD9JHgcYhDiFUhrTgOS1O11Af6JCL3QLYi+evsIMf skWxh8Q/qeQzuuE5uXhTGRrxmBGCkK0cu7s6LxLTLZVMhbvqgd2824ycFaIAqyQpC1Md5P 1r+P2jfEdMoi7LzlviAKm+AK2dW42TKETKYqeSOGq7ZhnCJ7Xf5Xi8Ijt4kjrbWbAR4t8Z QdlCm19PzdT6sSlrjxbMUf9PuB6qivWE+sHHnZbi86V4Ebaj7myUKHts1Rny7HIIL8OnAr w9aWsOmYIYgcMNJWQzZZ7gQw4/ADIeTkRTjIZFGO/hPweFJJRPizj8p0Fv27TA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4cWw5D19DjzVZx; Wed, 24 Sep 2025 11:45:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 58OBjKRO083153; Wed, 24 Sep 2025 11:45:20 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 58OBjKI8083150; Wed, 24 Sep 2025 11:45:20 GMT (envelope-from git) Date: Wed, 24 Sep 2025 11:45:20 GMT Message-Id: <202509241145.58OBjKI8083150@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: 7ec06143964a - main - pf: pass pre-NAT addresses to dummynet List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7ec06143964a949ebf6885ac120fdf839ad29eab Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=7ec06143964a949ebf6885ac120fdf839ad29eab commit 7ec06143964a949ebf6885ac120fdf839ad29eab Author: Kristof Provost AuthorDate: 2025-09-04 12:49:00 +0000 Commit: Kristof Provost CommitDate: 2025-09-24 11:44:54 +0000 pf: pass pre-NAT addresses to dummynet When we're NAT-ing give dummynet (via its struct ip_fw_args) the pre-NAT source and destination addresses. That's what we used to do, but that got unintentionally changed during the nat64 work. The pre-NAT addresses make somewhat more sense, in that it enables limiting based on specific LAN clients. See also: https://redmine.pfsense.org/issues/15770 Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/netpfil/pf/pf.c | 39 +++++++++++++++++++++++++++++++++------ tests/sys/netpfil/pf/nat.sh | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 6 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index a57905df0c69..be00aff1f5cb 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -9760,6 +9760,7 @@ pf_pdesc_to_dnflow(const struct pf_pdesc *pd, const struct pf_krule *r, const struct pf_kstate *s, struct ip_fw_args *dnflow) { int dndir = r->direction; + sa_family_t af = pd->naf; if (s && dndir == PF_INOUT) { dndir = s->direction; @@ -9800,20 +9801,46 @@ pf_pdesc_to_dnflow(const struct pf_pdesc *pd, const struct pf_krule *r, dnflow->f_id.proto = pd->proto; dnflow->f_id.extra = dnflow->rule.info; - switch (pd->naf) { + if (s) + af = s->key[PF_SK_STACK]->af; + + switch (af) { case AF_INET: dnflow->f_id.addr_type = 4; - dnflow->f_id.src_ip = ntohl(pd->src->v4.s_addr); - dnflow->f_id.dst_ip = ntohl(pd->dst->v4.s_addr); + if (s) { + dnflow->f_id.src_ip = htonl( + s->key[PF_SK_STACK]->addr[pd->sidx].v4.s_addr); + dnflow->f_id.dst_ip = htonl( + s->key[PF_SK_STACK]->addr[pd->didx].v4.s_addr); + } else { + dnflow->f_id.src_ip = ntohl(pd->src->v4.s_addr); + dnflow->f_id.dst_ip = ntohl(pd->dst->v4.s_addr); + } break; case AF_INET6: - dnflow->flags |= IPFW_ARGS_IP6; dnflow->f_id.addr_type = 6; - dnflow->f_id.src_ip6 = pd->src->v6; - dnflow->f_id.dst_ip6 = pd->dst->v6; + + if (s) { + dnflow->f_id.src_ip6 = + s->key[PF_SK_STACK]->addr[pd->sidx].v6; + dnflow->f_id.dst_ip6 = + s->key[PF_SK_STACK]->addr[pd->didx].v6; + } else { + dnflow->f_id.src_ip6 = pd->src->v6; + dnflow->f_id.dst_ip6 = pd->dst->v6; + } break; } + /* + * Separate this out, because while we pass the pre-NAT addresses to + * dummynet we want the post-nat address family in case of nat64. + * Dummynet may call ip_output/ip6_output itself, and we need it to + * call the correct one. + */ + if (pd->naf == AF_INET6) + dnflow->flags |= IPFW_ARGS_IP6; + return (true); } diff --git a/tests/sys/netpfil/pf/nat.sh b/tests/sys/netpfil/pf/nat.sh index 5ea1dd6d8b2f..170d813d57fe 100644 --- a/tests/sys/netpfil/pf/nat.sh +++ b/tests/sys/netpfil/pf/nat.sh @@ -810,6 +810,50 @@ empty_pool_cleanup() pft_cleanup } +atf_test_case "dummynet_mask" "cleanup" +dummynet_mask_head() +{ + atf_set descr 'Verify that dummynet uses the pre-nat address for masking' + atf_set require.user root +} + +dummynet_mask_body() +{ + dummynet_init + + epair_srv=$(vnet_mkepair) + epair_cl=$(vnet_mkepair) + + ifconfig ${epair_cl}b 192.0.2.2/24 up + route add default 192.0.2.1 + + vnet_mkjail srv ${epair_srv}a + jexec srv ifconfig ${epair_srv}a 198.51.100.2/24 up + + vnet_mkjail gw ${epair_srv}b ${epair_cl}a + jexec gw ifconfig ${epair_srv}b 198.51.100.1/24 up + jexec gw ifconfig ${epair_cl}a 192.0.2.1/24 up + jexec gw sysctl net.inet.ip.forwarding=1 + + jexec gw dnctl pipe 1 config delay 100 mask src-ip 0xffffff00 + jexec gw pfctl -e + pft_set_rules gw \ + "nat pass on ${epair_srv}b inet from 192.0.2.0/24 to any -> (${epair_srv}b)" \ + "pass out dnpipe 1" + + atf_check -s exit:0 -o ignore \ + ping -c 3 198.51.100.2 + + # Now check that dummynet looked at the correct address + atf_check -s exit:0 -o match:"ip.*192.0.2.0/0" \ + jexec gw dnctl pipe show +} + +dummynet_mask_cleanup() +{ + pft_cleanup +} + atf_init_test_cases() { atf_add_test_case "exhaust" @@ -828,4 +872,5 @@ atf_init_test_cases() atf_add_test_case "binat_compat" atf_add_test_case "binat_match" atf_add_test_case "empty_pool" + atf_add_test_case "dummynet_mask" }