git: fa6330030b93 - main - pf: move pf_change_icmp_af() call for TCP/UDP in ICMP
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 23 Apr 2025 11:56:56 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=fa6330030b935c6a8505890fb019a963fa6f0036
commit fa6330030b935c6a8505890fb019a963fa6f0036
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-04-22 14:34:40 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-04-23 08:15:09 +0000
pf: move pf_change_icmp_af() call for TCP/UDP in ICMP
The checksum of a ICMP "need to frag" packet for TCP was wrong when
created from a ICMP6 "too big" packet. The function pf_change_icmp_af()
has code to adjust the pseudo-header checksum in the ICMP6 case,
but pf_test_state_icmp() changed the proto before the case was
entered.
So call pf_change_icmp_af() before the pd->proto is converted in
the TCP and UDP payload case like it was already done for ICMP and
ICMP6 payload.
Found by sys/net/pf_forward regress test; OK henning@
Note that we fully recalculate ICMP checksums in pf_translate_af(), so this does
not result in any functional changes on FreeBSD. It is imported to reduce the
diff with OpenBSD.
Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 50188ace62
Sponsored by: Rubicon Communications, LLC ("Netgate")
---
sys/netpfil/pf/pf.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index a154e0c7b446..06ced7b055b3 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -7987,6 +7987,11 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
m_copyback(pd->m, pd->off,
sizeof(struct icmp6_hdr),
(c_caddr_t)&pd->hdr.icmp6);
+ if (pf_change_icmp_af(pd->m, ipoff2, pd,
+ &pd2, &nk->addr[sidx],
+ &nk->addr[didx], pd->af,
+ nk->af))
+ return (PF_DROP);
PF_ACPY(&pd->nsaddr, &nk->addr[pd2.sidx],
nk->af);
PF_ACPY(&pd->ndaddr,
@@ -8006,11 +8011,6 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
pd->src->addr32[0];
}
pd->naf = pd2.naf = nk->af;
- if (pf_change_icmp_af(pd->m, ipoff2, pd,
- &pd2, &nk->addr[sidx],
- &nk->addr[didx], pd->af,
- nk->af))
- return (PF_DROP);
pf_change_ap(&pd2, pd2.src, &th->th_sport,
&nk->addr[pd2.sidx], nk->port[sidx]);
pf_change_ap(&pd2, pd2.dst, &th->th_dport,
@@ -8119,6 +8119,11 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
m_copyback(pd->m, pd->off,
sizeof(struct icmp6_hdr),
(c_caddr_t)&pd->hdr.icmp6);
+ if (pf_change_icmp_af(pd->m, ipoff2, pd,
+ &pd2, &nk->addr[sidx],
+ &nk->addr[didx], pd->af,
+ nk->af))
+ return (PF_DROP);
PF_ACPY(&pd->nsaddr,
&nk->addr[pd2.sidx], nk->af);
PF_ACPY(&pd->ndaddr,
@@ -8138,11 +8143,6 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
pd->src->addr32[0];
}
pd->naf = pd2.naf = nk->af;
- if (pf_change_icmp_af(pd->m, ipoff2, pd,
- &pd2, &nk->addr[sidx],
- &nk->addr[didx], pd->af,
- nk->af))
- return (PF_DROP);
pf_change_ap(&pd2, pd2.src, &uh->uh_sport,
&nk->addr[pd2.sidx], nk->port[sidx]);
pf_change_ap(&pd2, pd2.dst, &uh->uh_dport,