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,