git: 04ed606def89 - main - pf: pull icmp-nested headers into struct pf_pdesc
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 21 Apr 2025 12:49:09 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=04ed606def89081f9309fc498f3e333da2bb561a
commit 04ed606def89081f9309fc498f3e333da2bb561a
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-04-17 07:46:42 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-04-21 08:43:31 +0000
pf: pull icmp-nested headers into struct pf_pdesc
Rather than copying headers nested in an ICMP message into separate stack
variables copy them into struct pf_pdesc (pd2). That's one of the things the
struct is for.
This saves a trivial amount of stack space, but also makes future refactoring
easier.
Sponsored by: Rubicon Communications, LLC ("Netgate")
---
sys/netpfil/pf/pf.c | 95 ++++++++++++++++++++++++++++-------------------------
1 file changed, 51 insertions(+), 44 deletions(-)
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 463504bebcbc..8b947a26ab6a 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -7906,7 +7906,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
switch (pd2.proto) {
case IPPROTO_TCP: {
- struct tcphdr th;
+ struct tcphdr *th = &pd2.hdr.tcp;
u_int32_t seq;
struct pf_state_peer *src, *dst;
u_int8_t dws;
@@ -7917,7 +7917,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
* expected. Don't access any TCP header fields after
* th_seq, an ackskew test is not possible.
*/
- if (!pf_pull_hdr(pd->m, pd2.off, &th, 8, NULL, reason,
+ if (!pf_pull_hdr(pd->m, pd2.off, th, 8, NULL, reason,
pd2.af)) {
DPFPRINTF(PF_DEBUG_MISC,
("pf: ICMP error message too short "
@@ -7929,8 +7929,8 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
key.proto = IPPROTO_TCP;
PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
- key.port[pd2.sidx] = th.th_sport;
- key.port[pd2.didx] = th.th_dport;
+ key.port[pd2.sidx] = th->th_sport;
+ key.port[pd2.didx] = th->th_dport;
STATE_LOOKUP(&key, *state, pd);
@@ -7958,9 +7958,9 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
dws = 0;
/* Demodulate sequence number */
- seq = ntohl(th.th_seq) - src->seqdiff;
+ seq = ntohl(th->th_seq) - src->seqdiff;
if (src->seqdiff) {
- pf_change_a(&th.th_seq, icmpsum,
+ pf_change_a(&th->th_seq, icmpsum,
htonl(seq), 0);
copyback = 1;
}
@@ -8049,21 +8049,28 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
&nk->addr[didx], pd->af,
nk->af))
return (PF_DROP);
- pf_change_ap(pd, pd2.src, &th.th_sport,
+ pf_change_ap(pd, pd2.src, &th->th_sport,
pd->ip_sum, &dummy_cksum, &nk->addr[pd2.sidx],
nk->port[sidx], 1);
- pf_change_ap(pd, pd2.dst, &th.th_dport,
+ pf_change_ap(pd, pd2.dst, &th->th_dport,
pd->ip_sum, &dummy_cksum, &nk->addr[pd2.didx],
nk->port[didx], 1);
- m_copyback(pd2.m, pd2.off, 8, (c_caddr_t)&th);
+ m_copyback(pd2.m, pd2.off, 8, (c_caddr_t)th);
+ pf_change_ap(pd, pd2.src, &th->th_sport,
+ pd->ip_sum, &dummy_cksum, &nk->addr[pd2.sidx],
+ nk->port[sidx], 1);
+ pf_change_ap(pd, pd2.dst, &th->th_dport,
+ pd->ip_sum, &dummy_cksum, &nk->addr[pd2.didx],
+ nk->port[didx], 1);
+ m_copyback(pd2.m, pd2.off, 8, (c_caddr_t)th);
return (PF_AFRT);
}
#endif /* INET && INET6 */
if (PF_ANEQ(pd2.src,
&nk->addr[pd2.sidx], pd2.af) ||
- nk->port[pd2.sidx] != th.th_sport)
- pf_change_icmp(pd2.src, &th.th_sport,
+ nk->port[pd2.sidx] != th->th_sport)
+ pf_change_icmp(pd2.src, &th->th_sport,
daddr, &nk->addr[pd2.sidx],
nk->port[pd2.sidx], NULL,
pd2.ip_sum, icmpsum,
@@ -8071,8 +8078,8 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
if (PF_ANEQ(pd2.dst,
&nk->addr[pd2.didx], pd2.af) ||
- nk->port[pd2.didx] != th.th_dport)
- pf_change_icmp(pd2.dst, &th.th_dport,
+ nk->port[pd2.didx] != th->th_dport)
+ pf_change_icmp(pd2.dst, &th->th_dport,
saddr, &nk->addr[pd2.didx],
nk->port[pd2.didx], NULL,
pd2.ip_sum, icmpsum,
@@ -8102,16 +8109,16 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
default:
unhandled_af(pd->af);
}
- m_copyback(pd->m, pd2.off, 8, (caddr_t)&th);
+ m_copyback(pd->m, pd2.off, 8, (caddr_t)th);
}
return (PF_PASS);
break;
}
case IPPROTO_UDP: {
- struct udphdr uh;
+ struct udphdr *uh = &pd2.hdr.udp;
- if (!pf_pull_hdr(pd->m, pd2.off, &uh, sizeof(uh),
+ if (!pf_pull_hdr(pd->m, pd2.off, uh, sizeof(*uh),
NULL, reason, pd2.af)) {
DPFPRINTF(PF_DEBUG_MISC,
("pf: ICMP error message too short "
@@ -8123,8 +8130,8 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
key.proto = IPPROTO_UDP;
PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
- key.port[pd2.sidx] = uh.uh_sport;
- key.port[pd2.didx] = uh.uh_dport;
+ key.port[pd2.sidx] = uh->uh_sport;
+ key.port[pd2.didx] = uh->uh_dport;
STATE_LOOKUP(&key, *state, pd);
@@ -8182,33 +8189,33 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
&nk->addr[didx], pd->af,
nk->af))
return (PF_DROP);
- pf_change_ap(pd, pd2.src, &uh.uh_sport,
- pd->ip_sum, &uh.uh_sum, &nk->addr[pd2.sidx],
+ pf_change_ap(pd, pd2.src, &uh->uh_sport,
+ pd->ip_sum, &uh->uh_sum, &nk->addr[pd2.sidx],
nk->port[sidx], 1);
- pf_change_ap(pd, pd2.dst, &uh.uh_dport,
- pd->ip_sum, &uh.uh_sum, &nk->addr[pd2.didx],
+ pf_change_ap(pd, pd2.dst, &uh->uh_dport,
+ pd->ip_sum, &uh->uh_sum, &nk->addr[pd2.didx],
nk->port[didx], 1);
- m_copyback(pd2.m, pd2.off, sizeof(uh),
- (c_caddr_t)&uh);
+ m_copyback(pd2.m, pd2.off, sizeof(*uh),
+ (c_caddr_t)uh);
return (PF_AFRT);
}
#endif /* INET && INET6 */
if (PF_ANEQ(pd2.src,
&nk->addr[pd2.sidx], pd2.af) ||
- nk->port[pd2.sidx] != uh.uh_sport)
- pf_change_icmp(pd2.src, &uh.uh_sport,
+ nk->port[pd2.sidx] != uh->uh_sport)
+ pf_change_icmp(pd2.src, &uh->uh_sport,
daddr, &nk->addr[pd2.sidx],
- nk->port[pd2.sidx], &uh.uh_sum,
+ nk->port[pd2.sidx], &uh->uh_sum,
pd2.ip_sum, icmpsum,
pd->ip_sum, 1, pd2.af);
if (PF_ANEQ(pd2.dst,
&nk->addr[pd2.didx], pd2.af) ||
- nk->port[pd2.didx] != uh.uh_dport)
- pf_change_icmp(pd2.dst, &uh.uh_dport,
+ nk->port[pd2.didx] != uh->uh_dport)
+ pf_change_icmp(pd2.dst, &uh->uh_dport,
saddr, &nk->addr[pd2.didx],
- nk->port[pd2.didx], &uh.uh_sum,
+ nk->port[pd2.didx], &uh->uh_sum,
pd2.ip_sum, icmpsum,
pd->ip_sum, 1, pd2.af);
@@ -8230,18 +8237,18 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
break;
#endif /* INET6 */
}
- m_copyback(pd->m, pd2.off, sizeof(uh), (caddr_t)&uh);
+ m_copyback(pd->m, pd2.off, sizeof(*uh), (caddr_t)uh);
}
return (PF_PASS);
break;
}
#ifdef INET
case IPPROTO_SCTP: {
- struct sctphdr sh;
+ struct sctphdr *sh = &pd2.hdr.sctp;
struct pf_state_peer *src;
int copyback = 0;
- if (! pf_pull_hdr(pd->m, pd2.off, &sh, sizeof(sh), NULL, reason,
+ if (! pf_pull_hdr(pd->m, pd2.off, sh, sizeof(*sh), NULL, reason,
pd2.af)) {
DPFPRINTF(PF_DEBUG_MISC,
("pf: ICMP error message too short "
@@ -8253,8 +8260,8 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
key.proto = IPPROTO_SCTP;
PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
- key.port[pd2.sidx] = sh.src_port;
- key.port[pd2.didx] = sh.dest_port;
+ key.port[pd2.sidx] = sh->src_port;
+ key.port[pd2.didx] = sh->dest_port;
STATE_LOOKUP(&key, *state, pd);
@@ -8270,7 +8277,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
src = &(*state)->src;
}
- if (src->scrub->pfss_v_tag != sh.v_tag) {
+ if (src->scrub->pfss_v_tag != sh->v_tag) {
DPFPRINTF(PF_DEBUG_MISC,
("pf: ICMP error message has incorrect "
"SCTP v_tag\n"));
@@ -8313,9 +8320,9 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
&nk->addr[didx], pd->af,
nk->af))
return (PF_DROP);
- sh.src_port = nk->port[sidx];
- sh.dest_port = nk->port[didx];
- m_copyback(pd2.m, pd2.off, sizeof(sh), (c_caddr_t)&sh);
+ 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->nsaddr,
&nk->addr[pd2.sidx], nk->af);
PF_ACPY(&pd->ndaddr,
@@ -8341,8 +8348,8 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
if (PF_ANEQ(pd2.src,
&nk->addr[pd2.sidx], pd2.af) ||
- nk->port[pd2.sidx] != sh.src_port)
- pf_change_icmp(pd2.src, &sh.src_port,
+ nk->port[pd2.sidx] != sh->src_port)
+ pf_change_icmp(pd2.src, &sh->src_port,
daddr, &nk->addr[pd2.sidx],
nk->port[pd2.sidx], NULL,
pd2.ip_sum, icmpsum,
@@ -8350,8 +8357,8 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
if (PF_ANEQ(pd2.dst,
&nk->addr[pd2.didx], pd2.af) ||
- nk->port[pd2.didx] != sh.dest_port)
- pf_change_icmp(pd2.dst, &sh.dest_port,
+ nk->port[pd2.didx] != sh->dest_port)
+ pf_change_icmp(pd2.dst, &sh->dest_port,
saddr, &nk->addr[pd2.didx],
nk->port[pd2.didx], NULL,
pd2.ip_sum, icmpsum,
@@ -8379,7 +8386,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
break;
#endif /* INET6 */
}
- m_copyback(pd->m, pd2.off, sizeof(sh), (caddr_t)&sh);
+ m_copyback(pd->m, pd2.off, sizeof(*sh), (caddr_t)sh);
}
return (PF_PASS);