pf: consolidate pf function parameters

Move off and hdrlen into pdesc
and change their type from int to u_int32_t.  Do not pass struct
tcphdr *th and sa_family_t af, it is in pd anyway.  Do not use af
and pd->af intermixed, the latter makes clear where it comes from.
Do not calculate the packet length again if pd already has it.  Use
pd2.off instead of off2.
go go go go don't stop henning@ mpf@

Obtained from:	OpenBSD, bluhm <bluhm@openbsd.org>, 110e53770d
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D46937
This commit is contained in:
Kristof Provost 2024-10-02 16:45:05 +02:00
parent 9414b8dbf1
commit 739731b8ca
6 changed files with 230 additions and 262 deletions

View File

@ -1604,7 +1604,9 @@ struct pf_pdesc {
struct pf_mtag *pf_mtag;
struct pf_rule_actions act;
u_int32_t p_len; /* total length of payload */
u_int32_t off; /* protocol header offset */
u_int32_t hdrlen; /* protocol header length */
u_int32_t p_len; /* total length of protocol payload */
u_int32_t badopts; /* v4 options or v6 routing headers */
u_int16_t *ip_sum;
@ -2398,18 +2400,16 @@ int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t);
void pf_normalize_init(void);
void pf_normalize_cleanup(void);
int pf_normalize_tcp(struct pfi_kkif *, struct mbuf *, int, int,
struct pf_pdesc *);
int pf_normalize_tcp(struct pfi_kkif *, struct mbuf *, struct pf_pdesc *);
void pf_normalize_tcp_cleanup(struct pf_kstate *);
int pf_normalize_tcp_init(struct mbuf *, int, struct pf_pdesc *,
int pf_normalize_tcp_init(struct mbuf *, struct pf_pdesc *,
struct tcphdr *, struct pf_state_peer *, struct pf_state_peer *);
int pf_normalize_tcp_stateful(struct mbuf *, int, struct pf_pdesc *,
int pf_normalize_tcp_stateful(struct mbuf *, struct pf_pdesc *,
u_short *, struct tcphdr *, struct pf_kstate *,
struct pf_state_peer *, struct pf_state_peer *, int *);
int pf_normalize_sctp_init(struct mbuf *, int, struct pf_pdesc *,
int pf_normalize_sctp_init(struct mbuf *, struct pf_pdesc *,
struct pf_state_peer *, struct pf_state_peer *);
int pf_normalize_sctp(int, struct pfi_kkif *, struct mbuf *, int,
int, struct pf_pdesc *);
int pf_normalize_sctp(struct pfi_kkif *, struct mbuf *, struct pf_pdesc *);
u_int32_t
pf_state_expires(const struct pf_kstate *);
void pf_purge_expired_fragments(void);
@ -2488,8 +2488,8 @@ int pf_tag_packet(struct mbuf *, struct pf_pdesc *, int);
int pf_addr_cmp(struct pf_addr *, struct pf_addr *,
sa_family_t);
u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t, sa_family_t);
u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t, sa_family_t);
u_int16_t pf_get_mss(struct mbuf *, struct pf_pdesc *);
u_int8_t pf_get_wscale(struct mbuf *, struct pf_pdesc *);
struct mbuf *pf_build_tcp(const struct pf_krule *, sa_family_t,
const struct pf_addr *, const struct pf_addr *,
u_int16_t, u_int16_t, u_int32_t, u_int32_t,
@ -2506,7 +2506,7 @@ void pf_syncookies_cleanup(void);
int pf_get_syncookies(struct pfioc_nv *);
int pf_set_syncookies(struct pfioc_nv *);
int pf_synflood_check(struct pf_pdesc *);
void pf_syncookie_send(struct mbuf *m, int off,
void pf_syncookie_send(struct mbuf *m,
struct pf_pdesc *);
bool pf_syncookie_check(struct pf_pdesc *);
u_int8_t pf_syncookie_validate(struct pf_pdesc *);
@ -2591,7 +2591,7 @@ void pf_addr_copyout(struct pf_addr_wrap *);
int pf_osfp_add(struct pf_osfp_ioctl *);
#ifdef _KERNEL
struct pf_osfp_enlist *
pf_osfp_fingerprint(struct pf_pdesc *, struct mbuf *, int,
pf_osfp_fingerprint(struct pf_pdesc *, struct mbuf *,
const struct tcphdr *);
#endif /* _KERNEL */
void pf_osfp_flush(void);
@ -2631,13 +2631,12 @@ u_short pf_get_translation(struct pf_pdesc *, struct mbuf *,
struct pf_krule **,
struct pf_udp_mapping **udp_mapping);
struct pf_state_key *pf_state_key_setup(struct pf_pdesc *, struct mbuf *, int,
struct pf_state_key *pf_state_key_setup(struct pf_pdesc *, struct mbuf *,
struct pf_addr *, struct pf_addr *, u_int16_t, u_int16_t);
struct pf_state_key *pf_state_key_clone(const struct pf_state_key *);
void pf_rule_to_actions(struct pf_krule *,
struct pf_rule_actions *);
int pf_normalize_mss(struct mbuf *m, int off,
struct pf_pdesc *pd);
int pf_normalize_mss(struct mbuf *m, struct pf_pdesc *pd);
#if defined(INET) || defined(INET6)
void pf_scrub(struct mbuf *, struct pf_pdesc *);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -64,9 +64,9 @@ VNET_DEFINE_STATIC(int, pf_rdr_srcport_rewrite_tries) = 16;
static void pf_hash(struct pf_addr *, struct pf_addr *,
struct pf_poolhashkey *, sa_family_t);
static struct pf_krule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
int, struct pfi_kkif *,
struct pf_addr *, u_int16_t, struct pf_addr *,
uint16_t, int, struct pf_kanchor_stackframe *);
struct pfi_kkif *, struct pf_addr *, u_int16_t,
struct pf_addr *, uint16_t, int,
struct pf_kanchor_stackframe *);
static int pf_get_sport(sa_family_t, uint8_t, struct pf_krule *,
struct pf_addr *, uint16_t, struct pf_addr *, uint16_t, struct pf_addr *,
uint16_t *, uint16_t, uint16_t, struct pf_ksrc_node **,
@ -131,7 +131,7 @@ pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
}
static struct pf_krule *
pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
pf_match_translation(struct pf_pdesc *pd, struct mbuf *m,
struct pfi_kkif *kif, struct pf_addr *saddr, u_int16_t sport,
struct pf_addr *daddr, uint16_t dport, int rs_num,
struct pf_kanchor_stackframe *anchor_stack)
@ -189,7 +189,7 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
r = TAILQ_NEXT(r, entries);
else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
off, &pd->hdr.tcp), r->os_fingerprint)))
&pd->hdr.tcp), r->os_fingerprint)))
r = TAILQ_NEXT(r, entries);
else {
if (r->tag)
@ -717,17 +717,17 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
*rp = NULL;
if (pd->dir == PF_OUT) {
r = pf_match_translation(pd, m, off, kif, saddr,
r = pf_match_translation(pd, m, kif, saddr,
sport, daddr, dport, PF_RULESET_BINAT, anchor_stack);
if (r == NULL)
r = pf_match_translation(pd, m, off, kif,
r = pf_match_translation(pd, m, kif,
saddr, sport, daddr, dport, PF_RULESET_NAT,
anchor_stack);
} else {
r = pf_match_translation(pd, m, off, kif, saddr,
r = pf_match_translation(pd, m, kif, saddr,
sport, daddr, dport, PF_RULESET_RDR, anchor_stack);
if (r == NULL)
r = pf_match_translation(pd, m, off, kif,
r = pf_match_translation(pd, m, kif,
saddr, sport, daddr, dport, PF_RULESET_BINAT,
anchor_stack);
}
@ -742,7 +742,7 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
return (PFRES_MAX);
}
*skp = pf_state_key_setup(pd, m, off, saddr, daddr, sport, dport);
*skp = pf_state_key_setup(pd, m, saddr, daddr, sport, dport);
if (*skp == NULL)
return (PFRES_MEMORY);
*nkp = pf_state_key_clone(*skp);

View File

@ -1287,8 +1287,7 @@ pf_normalize_ip6(struct mbuf **m0, struct pfi_kkif *kif,
#endif /* INET6 */
int
pf_normalize_tcp(struct pfi_kkif *kif, struct mbuf *m, int ipoff,
int off, struct pf_pdesc *pd)
pf_normalize_tcp(struct pfi_kkif *kif, struct mbuf *m, struct pf_pdesc *pd)
{
struct pf_krule *r, *rm = NULL;
struct tcphdr *th = &pd->hdr.tcp;
@ -1327,7 +1326,7 @@ pf_normalize_tcp(struct pfi_kkif *kif, struct mbuf *m, int ipoff,
r->dst.port[0], r->dst.port[1], th->th_dport))
r = r->skip[PF_SKIP_DST_PORT];
else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
pf_osfp_fingerprint(pd, m, off, th),
pf_osfp_fingerprint(pd, m, th),
r->os_fingerprint))
r = TAILQ_NEXT(r, entries);
else {
@ -1400,7 +1399,7 @@ pf_normalize_tcp(struct pfi_kkif *kif, struct mbuf *m, int ipoff,
/* copy back packet headers if we sanitized */
if (rewrite)
m_copyback(m, off, sizeof(*th), (caddr_t)th);
m_copyback(m, pd->off, sizeof(*th), (caddr_t)th);
return (PF_PASS);
@ -1412,7 +1411,7 @@ pf_normalize_tcp(struct pfi_kkif *kif, struct mbuf *m, int ipoff,
}
int
pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
pf_normalize_tcp_init(struct mbuf *m, struct pf_pdesc *pd,
struct tcphdr *th, struct pf_state_peer *src, struct pf_state_peer *dst)
{
u_int32_t tsval, tsecr;
@ -1451,7 +1450,7 @@ pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
return (0);
if (th->th_off > (sizeof(struct tcphdr) >> 2) && src->scrub &&
pf_pull_hdr(m, off, hdr, th->th_off << 2, NULL, NULL, pd->af)) {
pf_pull_hdr(m, pd->off, hdr, th->th_off << 2, NULL, NULL, pd->af)) {
/* Diddle with TCP options */
int hlen;
opt = hdr + sizeof(struct tcphdr);
@ -1502,7 +1501,7 @@ pf_normalize_tcp_cleanup(struct pf_kstate *state)
/* Someday... flush the TCP segment reassembly descriptors. */
}
int
pf_normalize_sctp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
pf_normalize_sctp_init(struct mbuf *m, struct pf_pdesc *pd,
struct pf_state_peer *src, struct pf_state_peer *dst)
{
src->scrub = uma_zalloc(V_pf_state_scrub_z, M_ZERO | M_NOWAIT);
@ -1521,7 +1520,7 @@ pf_normalize_sctp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
}
int
pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
pf_normalize_tcp_stateful(struct mbuf *m, struct pf_pdesc *pd,
u_short *reason, struct tcphdr *th, struct pf_kstate *state,
struct pf_state_peer *src, struct pf_state_peer *dst, int *writeback)
{
@ -1570,7 +1569,7 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
if (th->th_off > (sizeof(struct tcphdr) >> 2) &&
((src->scrub && (src->scrub->pfss_flags & PFSS_TIMESTAMP)) ||
(dst->scrub && (dst->scrub->pfss_flags & PFSS_TIMESTAMP))) &&
pf_pull_hdr(m, off, hdr, th->th_off << 2, NULL, NULL, pd->af)) {
pf_pull_hdr(m, pd->off, hdr, th->th_off << 2, NULL, NULL, pd->af)) {
/* Diddle with TCP options */
int hlen;
opt = hdr + sizeof(struct tcphdr);
@ -1644,7 +1643,7 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
if (copyback) {
/* Copyback the options, caller copys back header */
*writeback = 1;
m_copyback(m, off + sizeof(struct tcphdr),
m_copyback(m, pd->off + sizeof(struct tcphdr),
(th->th_off << 2) - sizeof(struct tcphdr), hdr +
sizeof(struct tcphdr));
}
@ -1916,7 +1915,7 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
}
int
pf_normalize_mss(struct mbuf *m, int off, struct pf_pdesc *pd)
pf_normalize_mss(struct mbuf *m, struct pf_pdesc *pd)
{
struct tcphdr *th = &pd->hdr.tcp;
u_int16_t *mss;
@ -1929,7 +1928,7 @@ pf_normalize_mss(struct mbuf *m, int off, struct pf_pdesc *pd)
thoff = th->th_off << 2;
cnt = thoff - sizeof(struct tcphdr);
if (cnt > 0 && !pf_pull_hdr(m, off + sizeof(*th), opts, cnt,
if (cnt > 0 && !pf_pull_hdr(m, pd->off + sizeof(*th), opts, cnt,
NULL, NULL, pd->af))
return (0);
@ -1956,9 +1955,9 @@ pf_normalize_mss(struct mbuf *m, int off, struct pf_pdesc *pd)
mss, htons(pd->act.max_mss),
PF_ALGNMNT(startoff),
0);
m_copyback(m, off + sizeof(*th),
m_copyback(m, pd->off + sizeof(*th),
thoff - sizeof(*th), opts);
m_copyback(m, off, sizeof(*th), (caddr_t)th);
m_copyback(m, pd->off, sizeof(*th), (caddr_t)th);
}
break;
default:
@ -2095,8 +2094,8 @@ pf_scan_sctp(struct mbuf *m, int off, struct pf_pdesc *pd,
}
int
pf_normalize_sctp(int dir, struct pfi_kkif *kif, struct mbuf *m, int ipoff,
int off, struct pf_pdesc *pd)
pf_normalize_sctp(struct pfi_kkif *kif, struct mbuf *m,
struct pf_pdesc *pd)
{
struct pf_krule *r, *rm = NULL;
struct sctphdr *sh = &pd->hdr.sctp;
@ -2114,7 +2113,7 @@ pf_normalize_sctp(int dir, struct pfi_kkif *kif, struct mbuf *m, int ipoff,
pf_counter_u64_add(&r->evaluations, 1);
if (pfi_kkif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP];
else if (r->direction && r->direction != dir)
else if (r->direction && r->direction != pd->dir)
r = r->skip[PF_SKIP_DIR];
else if (r->af && r->af != af)
r = r->skip[PF_SKIP_AF];
@ -2145,13 +2144,13 @@ pf_normalize_sctp(int dir, struct pfi_kkif *kif, struct mbuf *m, int ipoff,
return (PF_PASS);
pf_counter_u64_critical_enter();
pf_counter_u64_add_protected(&r->packets[dir == PF_OUT], 1);
pf_counter_u64_add_protected(&r->bytes[dir == PF_OUT], pd->tot_len);
pf_counter_u64_add_protected(&r->packets[pd->dir == PF_OUT], 1);
pf_counter_u64_add_protected(&r->bytes[pd->dir == PF_OUT], pd->tot_len);
pf_counter_u64_critical_exit();
}
/* Verify we're a multiple of 4 bytes long */
if ((pd->tot_len - off - sizeof(struct sctphdr)) % 4)
if ((pd->tot_len - pd->off - sizeof(struct sctphdr)) % 4)
goto sctp_drop;
/* INIT chunk needs to be the only chunk */

View File

@ -67,7 +67,7 @@ static struct pf_os_fingerprint *pf_osfp_validate(void);
* Returns the list of possible OSes.
*/
struct pf_osfp_enlist *
pf_osfp_fingerprint(struct pf_pdesc *pd, struct mbuf *m, int off,
pf_osfp_fingerprint(struct pf_pdesc *pd, struct mbuf *m,
const struct tcphdr *tcp)
{
struct ip *ip;
@ -85,7 +85,7 @@ pf_osfp_fingerprint(struct pf_pdesc *pd, struct mbuf *m, int off,
ip = (struct ip *)NULL;
ip6 = mtod(m, struct ip6_hdr *);
}
if (!pf_pull_hdr(m, off, hdr, tcp->th_off << 2, NULL, NULL,
if (!pf_pull_hdr(m, pd->off, hdr, tcp->th_off << 2, NULL, NULL,
pd->af)) return (NULL);
return (pf_osfp_fingerprint_hdr(ip, ip6, (struct tcphdr *)hdr));

View File

@ -119,7 +119,7 @@ void pf_syncookie_rotate(void *);
void pf_syncookie_newkey(void);
uint32_t pf_syncookie_mac(struct pf_pdesc *, union pf_syncookie,
uint32_t);
uint32_t pf_syncookie_generate(struct mbuf *m, int off, struct pf_pdesc *,
uint32_t pf_syncookie_generate(struct mbuf *m, struct pf_pdesc *,
uint16_t);
void
@ -290,13 +290,13 @@ pf_synflood_check(struct pf_pdesc *pd)
}
void
pf_syncookie_send(struct mbuf *m, int off, struct pf_pdesc *pd)
pf_syncookie_send(struct mbuf *m, struct pf_pdesc *pd)
{
uint16_t mss;
uint32_t iss;
mss = max(V_tcp_mssdflt, pf_get_mss(m, off, pd->hdr.tcp.th_off, pd->af));
iss = pf_syncookie_generate(m, off, pd, mss);
mss = max(V_tcp_mssdflt, pf_get_mss(m, pd));
iss = pf_syncookie_generate(m, pd, mss);
pf_send_tcp(NULL, pd->af, pd->dst, pd->src, *pd->dport, *pd->sport,
iss, ntohl(pd->hdr.tcp.th_seq) + 1, TH_SYN|TH_ACK, 0, mss,
0, true, 0, 0, pd->act.rtableid);
@ -457,8 +457,7 @@ pf_syncookie_mac(struct pf_pdesc *pd, union pf_syncookie cookie, uint32_t seq)
}
uint32_t
pf_syncookie_generate(struct mbuf *m, int off, struct pf_pdesc *pd,
uint16_t mss)
pf_syncookie_generate(struct mbuf *m, struct pf_pdesc *pd, uint16_t mss)
{
uint8_t i, wscale;
uint32_t iss, hash;
@ -475,7 +474,7 @@ pf_syncookie_generate(struct mbuf *m, int off, struct pf_pdesc *pd,
cookie.flags.mss_idx = i;
/* map WSCALE */
wscale = pf_get_wscale(m, off, pd->hdr.tcp.th_off, pd->af);
wscale = pf_get_wscale(m, pd);
for (i = nitems(pf_syncookie_wstab) - 1;
pf_syncookie_wstab[i] > wscale && i > 0; i--)
/* nada */;