From nobody Wed Mar 05 09:38:11 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 4Z76tC3yKjz5pWnG; Wed, 05 Mar 2025 09:38:11 +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 "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Z76tC3Hcgz411S; Wed, 05 Mar 2025 09:38:11 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1741167491; 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=j6g9l5peouzpLUS7X/m1h78YzDf+zJsbJCyh683BK64=; b=WfTLCtxvw/xKe6sXWf6n66DehfefZVhJnTZ8FvvF7+tACizQ4HShTVqd356gsxTMUnaTHO gZC8kNJSi5BQvudvOS9cj3LOa+Tb1xUyI7iYY32/W41E5B25h3x7tmEBLmn2pRZB9IOkpT lj/X7zpBN+InYKStdVADYGCdSMHilGocdhC0KTBuvZ+Rt21L2vhLjBAbz0GeWEzDApRaHo YRFqu4Xu3bvy5BV+zT9q6ZOWhSe2zhoxn+Bx9euS82ouigSbliseHwd+3ef5dIe3gTBVOk HpUeFSUqS45NI1nWZrl2YQuYoi6edPiJcLlzgX2/brXb/8+IjP370eMq6LRCrw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1741167491; a=rsa-sha256; cv=none; b=foizuar4utMzCz4VW7pwgbHpowA9NwIfD1MGeMNBsw7HoUC+rFwgI5JKiJLmyqvlFQWg3+ tv6R+9nw1E+b00EOduNsY5KubxmBismQOKNR3baaNhaCk897VdYuS/LN3z3axNqireKNCS AH16NpdRQx8IPDDbM8Y3+vJNWGIyfDmg7uAHdGc8Jz3zlYDrm0XxRAy+W1ziTTJytJH/nA Uh6JanIP7uvMnent3C7A/QKR+CZxG/p9AE5UEnbeGKUXEnZk8ZJzAS5DTTRjZV2gDaGIFY sHwc86i172+YPmTaGuvVCPPUYFqwd+mT9aD50cwmGP3TKzgzKDz2+osR2RPn7w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1741167491; 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=j6g9l5peouzpLUS7X/m1h78YzDf+zJsbJCyh683BK64=; b=RSFNcpAUGKoiePgH1Jx+2vgqEWXUSoi7q88XOFmALhb+X9QnpSWBDOeAz/S1tyIvjZtpPO Mu9r1DeZ9hlN34L0wOWYCLUQyKLf6msUxHILAKAo+PyLl4jSWmHn9z+G+KZQlaSLg9o/r6 hfGL5Pr/nMlsDGo+G1SKcMS4Qnlt4GPtOIHMmvR9LbDYvc8WaQi4Fmy4tfGkf/voKmB2ZH ON3F8yVLVbSYNaAYTDY5hYjzbPDtexwWYXa7yfVdyBYuPX2DSrGn0NX8asPcy7+9hBq1o1 6NZwMjYqXua56wVHMa6IYNumdhwB7AsOd3Al48kg+ONa2eb1Jwin6/J04zXTsA== 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 4Z76tC2c7WzypH; Wed, 05 Mar 2025 09:38:11 +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 5259cBrj053554; Wed, 5 Mar 2025 09:38:11 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 5259cB6d053551; Wed, 5 Mar 2025 09:38:11 GMT (envelope-from git) Date: Wed, 5 Mar 2025 09:38:11 GMT Message-Id: <202503050938.5259cB6d053551@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: e9a490b10d6c - main - pf: fix ICMP source address translation for nat64 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: e9a490b10d6cf2006bc2442648f8b2de39aacc5f Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=e9a490b10d6cf2006bc2442648f8b2de39aacc5f commit e9a490b10d6cf2006bc2442648f8b2de39aacc5f Author: Kristof Provost AuthorDate: 2025-03-04 16:13:38 +0000 Commit: Kristof Provost CommitDate: 2025-03-05 09:37:56 +0000 pf: fix ICMP source address translation for nat64 While handling an ICMP error related to another state (e.g. TTL expired, port closed, fragmentation needed, ...) we can't just use the state's source address as the ICMP source address. We have to translate the IPv4 address back to an IPv6 nat64 address. Failing to do so breaks things like traceroute, where the intermediate router generates an ICMP error message, and the traceroute tool uses the source address to build the path. Use the state's source address to figure out the prefix, and copy the IPv4 IP address to the last bytes to construct the mapped IPv6 address. PR: 284944 Sponsored by: Rubicon Communications, LLC ("Netgate") In collaboration with: sashan , dac07517c7 Differential Revision: https://reviews.freebsd.org/D49143 --- sys/netpfil/pf/pf.c | 72 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index e0b664772544..2b28474f36c6 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -8025,10 +8025,6 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd, &nk->addr[didx], pd->af, nk->af)) return (PF_DROP); - if (nk->af == AF_INET) - pd->proto = IPPROTO_ICMP; - else - pd->proto = IPPROTO_ICMPV6; pf_change_ap(pd->m, pd2.src, &th.th_sport, pd->ip_sum, &th.th_sum, &nk->addr[pd2.sidx], nk->port[sidx], 1, pd->af, nk->af); @@ -8036,10 +8032,24 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd, pd->ip_sum, &th.th_sum, &nk->addr[pd2.didx], nk->port[didx], 1, pd->af, nk->af); m_copyback(pd2.m, pd2.off, 8, (c_caddr_t)&th); - PF_ACPY(pd->src, - &nk->addr[pd2.sidx], nk->af); - PF_ACPY(pd->dst, + PF_ACPY(&pd->nsaddr, &nk->addr[pd2.sidx], + nk->af); + PF_ACPY(&pd->ndaddr, &nk->addr[pd2.didx], nk->af); + if (nk->af == AF_INET) { + pd->proto = IPPROTO_ICMP; + } else { + pd->proto = IPPROTO_ICMPV6; + /* + * IPv4 becomes IPv6 so we must + * copy IPv4 src addr to least + * 32bits in IPv6 address to + * keep traceroute/icmp + * working. + */ + pd->nsaddr.addr32[3] = + pd->src->addr32[0]; + } pd->naf = nk->af; return (PF_AFRT); } @@ -8148,10 +8158,6 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd, &nk->addr[didx], pd->af, nk->af)) return (PF_DROP); - if (nk->af == AF_INET) - pd->proto = IPPROTO_ICMP; - else - pd->proto = IPPROTO_ICMPV6; pf_change_ap(pd->m, pd2.src, &uh.uh_sport, pd->ip_sum, &uh.uh_sum, &nk->addr[pd2.sidx], nk->port[sidx], 1, pd->af, nk->af); @@ -8164,6 +8170,20 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd, &nk->addr[pd2.sidx], nk->af); PF_ACPY(&pd->ndaddr, &nk->addr[pd2.didx], nk->af); + if (nk->af == AF_INET) { + pd->proto = IPPROTO_ICMP; + } else { + pd->proto = IPPROTO_ICMPV6; + /* + * IPv4 becomes IPv6 so we must + * copy IPv4 src addr to least + * 32bits in IPv6 address to + * keep traceroute/icmp + * working. + */ + pd->nsaddr.addr32[3] = + pd->src->addr32[0]; + } pd->naf = nk->af; return (PF_AFRT); } @@ -8288,17 +8308,27 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd, &nk->addr[didx], pd->af, nk->af)) return (PF_DROP); - if (nk->af == AF_INET) - pd->proto = IPPROTO_ICMP; - else - pd->proto = IPPROTO_ICMPV6; sh.src_port = nk->port[sidx]; sh.dest_port = nk->port[didx]; m_copyback(pd2.m, pd2.off, sizeof(sh), (c_caddr_t)&sh); - PF_ACPY(pd->src, + PF_ACPY(&pd->nsaddr, &nk->addr[pd2.sidx], nk->af); - PF_ACPY(pd->dst, + PF_ACPY(&pd->ndaddr, &nk->addr[pd2.didx], nk->af); + if (nk->af == AF_INET) { + pd->proto = IPPROTO_ICMP; + } else { + pd->proto = IPPROTO_ICMPV6; + /* + * IPv4 becomes IPv6 so we must + * copy IPv4 src addr to least + * 32bits in IPv6 address to + * keep traceroute/icmp + * working. + */ + pd->nsaddr.addr32[3] = + pd->src->addr32[0]; + } pd->naf = nk->af; return (PF_AFRT); } @@ -8427,6 +8457,14 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd, &nk->addr[pd2.sidx], nk->af); PF_ACPY(&pd->ndaddr, &nk->addr[pd2.didx], nk->af); + /* + * IPv4 becomes IPv6 so we must copy + * IPv4 src addr to least 32bits in + * IPv6 address to keep traceroute + * working. + */ + pd->nsaddr.addr32[3] = + pd->src->addr32[0]; pd->naf = nk->af; return (PF_AFRT); }