From nobody Tue Jan 14 10:37:58 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 4YXQZG6MGTz5kVwQ; Tue, 14 Jan 2025 10:37:58 +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 "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YXQZG3W3sz3BxT; Tue, 14 Jan 2025 10:37:58 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1736851078; 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=8Bn2vp0JSlxc7a2s0LeB+YIckHkJo5q6KffkzwZ60r4=; b=YeiO6aXOGsCdZaumlsbxqcwzxFaQddrcnL6c0l/QJGF3O1tmN+U50UVEw3muq2SH3cE5X+ 4mp2+IvOuPmkl8Xo/xBg0/h2OpEO2ryYkkJ20xzKhUsoRMoMtUnU6rUePXcRZ9eUsnUrFB Y/X6IFUkCdmcj8pC4i76ysNfYW0wYFGDxwZv7GnJoYMQ4f87Be2qoNLVerkF8lg9+dSl9N +Ns9ieHeh7Cls64dvQJn7M5uuSYjv1+vjnTojWIOlHkNnTO/+2jrJkvk1opcjPjJ1FcUdT 54HT7OTBnNariJHV0rlXNkv8VMJ87bgcRqnJ6BV4K1Vg2t+97nB8PeDE3QDe3A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1736851078; 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=8Bn2vp0JSlxc7a2s0LeB+YIckHkJo5q6KffkzwZ60r4=; b=ZcqNvaV/VfY+wRxn9r8p8EyAEXXPQelbibGU7o7zAp28aYlwgD+Uu78RteIb9rHV97G2Pj k9UOPOuM59b+AflZER5ZXnz+n+kWKcs9fImDAJhXqk/gjUyZQIhFMgs9JxaApfgN1n9xwB lYXcLP7mRgtryMwhpB0mRIWnh10XvbDwAp89EZ1ZV2GmcMyHsMIkdt9gdaFz+Nk/y3zYK5 Y4Ux/0bRN0X0YMxWq2R8GcuR5UYOxDJrZpk6mWILpqHqzJRKC4wsTxqA0hmIAsbS7nOXHc 7FEXtcR31KYgxR6pf88TKMC1jl+YyLDaycYQ0r+m5tyDuJndPWnBca82n+zFfA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1736851078; a=rsa-sha256; cv=none; b=ipXmLXFBKnwaP6WSsD4mLtqEBCXht1M041QjPEGdZ7oG7aWVi2cK+7V68mcR3xNYIbXrHg v7nwBkmpz9Jbh1cTefDQ77b48e9mo7KhVs/S1AOMHVYZOZiuNzOS6mlJb6pZJXg2Z+oaDI Lr9t6BK4f3KBd1gVhIXqXsqYTS4FTLe5kcUJM+jcUrpt8N9+XjFDD0jhsWRRSnSpGDKtYf PW7H5YZ7QRcIIX/NmPEugRKkKThI01pF7FbioK2QFlTzZ7quR3jqqI1jcX5EvOHOE7jR3C RpJIwET2tm0etsrhzMXW9elwqw+5hqu3RsAlC9INabZkEWaBvLGhrOUvZW3kjg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none 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 4YXQZG36s1z1C6V; Tue, 14 Jan 2025 10:37:58 +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 50EAbwst048297; Tue, 14 Jan 2025 10:37:58 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 50EAbwBp048294; Tue, 14 Jan 2025 10:37:58 GMT (envelope-from git) Date: Tue, 14 Jan 2025 10:37:58 GMT Message-Id: <202501141037.50EAbwBp048294@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: 1941d370bf89 - main - pf: pass struct pf_pdesc to pf_walk_option6() and pf_walk_header6() 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: 1941d370bf89ea9a1c3aab5ce33e04d6ba0f635d Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=1941d370bf89ea9a1c3aab5ce33e04d6ba0f635d commit 1941d370bf89ea9a1c3aab5ce33e04d6ba0f635d Author: Kristof Provost AuthorDate: 2025-01-09 11:02:39 +0000 Commit: Kristof Provost CommitDate: 2025-01-14 08:54:19 +0000 pf: pass struct pf_pdesc to pf_walk_option6() and pf_walk_header6() This makes their argument list shorter. Also fix a bug where pf_walk_option6() used the outer header in the pd2 case. ok henning@ mikeb@ Obtained from: OpenBSD, bluhm , dfff4707a1 Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/net/pfvar.h | 6 +-- sys/netpfil/pf/pf.c | 143 +++++++++++++++++++++++++--------------------------- 2 files changed, 72 insertions(+), 77 deletions(-) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 3432f8dc99e1..3f109d31ccde 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1626,6 +1626,9 @@ struct pf_pdesc { 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 extoff; /* extentsion header offset */ + u_int32_t fragoff; /* fragment header offset */ + u_int32_t jumbolen; /* length from v6 jumbo header */ u_int32_t badopts; /* v4 options or v6 routing headers */ u_int16_t *ip_sum; @@ -1634,7 +1637,6 @@ struct pf_pdesc { #define PFDESC_TCP_NORM 0x0001 /* TCP shall be statefully scrubbed */ u_int16_t virtual_proto; #define PF_VPROTO_FRAGMENT 256 - int extoff; sa_family_t af; sa_family_t naf; u_int8_t proto; @@ -2391,8 +2393,6 @@ int pf_normalize_ip(struct mbuf **, u_short *, struct pf_pdesc *); #endif /* INET */ #ifdef INET6 -int pf_walk_header6(struct mbuf *, struct ip6_hdr *, int *, int *, int *, - uint8_t *, uint32_t *, u_short *); int pf_normalize_ip6(struct mbuf **, int, u_short *, struct pf_pdesc *); void pf_poolmask(struct pf_addr *, struct pf_addr*, struct pf_addr *, struct pf_addr *, sa_family_t); diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 3d1ba8e8deb4..11b6be239ca7 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -367,7 +367,9 @@ static u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, int, u_int16_t); static int pf_check_proto_cksum(struct mbuf *, int, int, u_int8_t, sa_family_t); -static int pf_walk_option6(struct mbuf *, int, int, uint32_t *, +static int pf_walk_option6(struct pf_pdesc *, struct ip6_hdr *, + int, int, u_short *); +static int pf_walk_header6(struct pf_pdesc *, struct ip6_hdr *, u_short *); static void pf_print_state_parts(struct pf_kstate *, struct pf_state_key *, struct pf_state_key *); @@ -7850,8 +7852,6 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd, #endif /* INET */ #ifdef INET6 struct ip6_hdr h2_6; - int fragoff2, extoff2; - u_int32_t jumbolen; #endif /* INET6 */ int ipoff2 = 0; @@ -7904,9 +7904,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd, return (PF_DROP); } pd2.off = ipoff2; - if (pf_walk_header6(pd->m, &h2_6, &pd2.off, &extoff2, - &fragoff2, &pd2.proto, &jumbolen, - reason) != PF_PASS) + if (pf_walk_header6(&pd2, &h2_6, reason) != PF_PASS) return (PF_DROP); pd2.src = (struct pf_addr *)&h2_6.ip6_src; @@ -9655,16 +9653,15 @@ pf_dummynet_route(struct pf_pdesc *pd, struct pf_kstate *s, #ifdef INET6 static int -pf_walk_option6(struct mbuf *m, int off, int end, uint32_t *jumbolen, +pf_walk_option6(struct pf_pdesc *pd, struct ip6_hdr *h, int off, int end, u_short *reason) { struct ip6_opt opt; struct ip6_opt_jumbo jumbo; - struct ip6_hdr *h = mtod(m, struct ip6_hdr *); while (off < end) { - if (!pf_pull_hdr(m, off, &opt.ip6o_type, sizeof(opt.ip6o_type), - NULL, reason, AF_INET6)) { + if (!pf_pull_hdr(pd->m, off, &opt.ip6o_type, + sizeof(opt.ip6o_type), NULL, reason, AF_INET6)) { DPFPRINTF(PF_DEBUG_MISC, ("IPv6 short opt type")); return (PF_DROP); } @@ -9672,8 +9669,8 @@ pf_walk_option6(struct mbuf *m, int off, int end, uint32_t *jumbolen, off++; continue; } - if (!pf_pull_hdr(m, off, &opt, sizeof(opt), NULL, reason, - AF_INET6)) { + if (!pf_pull_hdr(pd->m, off, &opt, sizeof(opt), NULL, + reason, AF_INET6)) { DPFPRINTF(PF_DEBUG_MISC, ("IPv6 short opt")); return (PF_DROP); } @@ -9684,7 +9681,7 @@ pf_walk_option6(struct mbuf *m, int off, int end, uint32_t *jumbolen, } switch (opt.ip6o_type) { case IP6OPT_JUMBO: - if (*jumbolen != 0) { + if (pd->jumbolen != 0) { DPFPRINTF(PF_DEBUG_MISC, ("IPv6 multiple jumbo")); REASON_SET(reason, PFRES_IPOPTIONS); return (PF_DROP); @@ -9694,15 +9691,15 @@ pf_walk_option6(struct mbuf *m, int off, int end, uint32_t *jumbolen, REASON_SET(reason, PFRES_IPOPTIONS); return (PF_DROP); } - if (!pf_pull_hdr(m, off, &jumbo, sizeof(jumbo), NULL, + if (!pf_pull_hdr(pd->m, off, &jumbo, sizeof(jumbo), NULL, reason, AF_INET6)) { DPFPRINTF(PF_DEBUG_MISC, ("IPv6 short jumbo")); return (PF_DROP); } - memcpy(jumbolen, jumbo.ip6oj_jumbo_len, - sizeof(*jumbolen)); - *jumbolen = ntohl(*jumbolen); - if (*jumbolen < IPV6_MAXPACKET) { + memcpy(&pd->jumbolen, jumbo.ip6oj_jumbo_len, + sizeof(pd->jumbolen)); + pd->jumbolen = ntohl(pd->jumbolen); + if (pd->jumbolen < IPV6_MAXPACKET) { DPFPRINTF(PF_DEBUG_MISC, ("IPv6 short jumbolen")); REASON_SET(reason, PFRES_IPOPTIONS); return (PF_DROP); @@ -9718,43 +9715,41 @@ pf_walk_option6(struct mbuf *m, int off, int end, uint32_t *jumbolen, } int -pf_walk_header6(struct mbuf *m, struct ip6_hdr *h, int *off, int *extoff, - int *fragoff, uint8_t *nxt, uint32_t *jumbolen, u_short *reason) +pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason) { struct ip6_frag frag; struct ip6_ext ext; struct ip6_rthdr rthdr; int rthdr_cnt = 0; - *off += sizeof(struct ip6_hdr); - *extoff = *fragoff = 0; - *nxt = h->ip6_nxt; - *jumbolen = 0; + pd->off += sizeof(struct ip6_hdr); + pd->fragoff = pd->extoff = pd->jumbolen = 0; + pd->proto = h->ip6_nxt; for (;;) { - switch (*nxt) { + switch (pd->proto) { case IPPROTO_FRAGMENT: - if (*fragoff != 0) { + if (pd->fragoff != 0) { DPFPRINTF(PF_DEBUG_MISC, ("IPv6 multiple fragment")); REASON_SET(reason, PFRES_FRAG); return (PF_DROP); } /* jumbo payload packets cannot be fragmented */ - if (*jumbolen != 0) { + if (pd->jumbolen != 0) { DPFPRINTF(PF_DEBUG_MISC, ("IPv6 fragmented jumbo")); REASON_SET(reason, PFRES_FRAG); return (PF_DROP); } - if (!pf_pull_hdr(m, *off, &frag, sizeof(frag), NULL, - reason, AF_INET6)) { + if (!pf_pull_hdr(pd->m, pd->off, &frag, sizeof(frag), + NULL, reason, AF_INET6)) { DPFPRINTF(PF_DEBUG_MISC, ("IPv6 short fragment")); return (PF_DROP); } - *fragoff = *off; + pd->fragoff = pd->off; /* stop walking over non initial fragments */ if ((frag.ip6f_offlg & IP6F_OFF_MASK) != 0) return (PF_PASS); - *off += sizeof(frag); - *nxt = frag.ip6f_nxt; + pd->off += sizeof(frag); + pd->proto = frag.ip6f_nxt; break; case IPPROTO_ROUTING: if (rthdr_cnt++) { @@ -9762,12 +9757,12 @@ pf_walk_header6(struct mbuf *m, struct ip6_hdr *h, int *off, int *extoff, REASON_SET(reason, PFRES_IPOPTIONS); return (PF_DROP); } - if (!pf_pull_hdr(m, *off, &rthdr, sizeof(rthdr), NULL, - reason, AF_INET6)) { + if (!pf_pull_hdr(pd->m, pd->off, &rthdr, sizeof(rthdr), + NULL, reason, AF_INET6)) { /* fragments may be short */ - if (*fragoff != 0) { - *off = *fragoff; - *nxt = IPPROTO_FRAGMENT; + if (pd->fragoff != 0) { + pd->off = pd->fragoff; + pd->proto = IPPROTO_FRAGMENT; return (PF_PASS); } DPFPRINTF(PF_DEBUG_MISC, ("IPv6 short rthdr")); @@ -9782,50 +9777,51 @@ pf_walk_header6(struct mbuf *m, struct ip6_hdr *h, int *off, int *extoff, case IPPROTO_AH: case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: - if (!pf_pull_hdr(m, *off, &ext, sizeof(ext), NULL, - reason, AF_INET6)) { + if (!pf_pull_hdr(pd->m, pd->off, &ext, sizeof(ext), + NULL, reason, AF_INET6)) { /* fragments may be short */ - if (*fragoff != 0) { - *off = *fragoff; - *nxt = IPPROTO_FRAGMENT; + if (pd->fragoff != 0) { + pd->off = pd->fragoff; + pd->proto = IPPROTO_FRAGMENT; return (PF_PASS); } DPFPRINTF(PF_DEBUG_MISC, ("IPv6 short exthdr")); return (PF_DROP); } /* reassembly needs the ext header before the frag */ - if (*fragoff == 0) - *extoff = *off; - if (*nxt == IPPROTO_HOPOPTS && *fragoff == 0) { - if (pf_walk_option6(m, *off + sizeof(ext), - *off + (ext.ip6e_len + 1) * 8, jumbolen, - reason) != PF_PASS) + if (pd->fragoff == 0) + pd->extoff = pd->off; + if (pd->proto == IPPROTO_HOPOPTS && pd->fragoff == 0) { + if (pf_walk_option6(pd, h, + pd->off + sizeof(ext), + pd->off + (ext.ip6e_len + 1) * 8, reason) + != PF_PASS) return (PF_DROP); - if (ntohs(h->ip6_plen) == 0 && *jumbolen != 0) { + if (ntohs(h->ip6_plen) == 0 && pd->jumbolen != 0) { DPFPRINTF(PF_DEBUG_MISC, ("IPv6 missing jumbo")); REASON_SET(reason, PFRES_IPOPTIONS); return (PF_DROP); } } - if (*nxt == IPPROTO_AH) - *off += (ext.ip6e_len + 2) * 4; + if (pd->proto == IPPROTO_AH) + pd->off += (ext.ip6e_len + 2) * 4; else - *off += (ext.ip6e_len + 1) * 8; - *nxt = ext.ip6e_nxt; + pd->off += (ext.ip6e_len + 1) * 8; + pd->proto = ext.ip6e_nxt; break; case IPPROTO_TCP: case IPPROTO_UDP: case IPPROTO_SCTP: case IPPROTO_ICMPV6: /* fragments may be short, ignore inner header then */ - if (*fragoff != 0 && ntohs(h->ip6_plen) < *off + - (*nxt == IPPROTO_TCP ? sizeof(struct tcphdr) : - *nxt == IPPROTO_UDP ? sizeof(struct udphdr) : - *nxt == IPPROTO_SCTP ? sizeof(struct sctphdr) : + if (pd->fragoff != 0 && ntohs(h->ip6_plen) < pd->off + + (pd->proto == IPPROTO_TCP ? sizeof(struct tcphdr) : + pd->proto == IPPROTO_UDP ? sizeof(struct udphdr) : + pd->proto == IPPROTO_SCTP ? sizeof(struct sctphdr) : sizeof(struct icmp6_hdr))) { - *off = *fragoff; - *nxt = IPPROTO_FRAGMENT; + pd->off = pd->fragoff; + pd->proto = IPPROTO_FRAGMENT; } /* FALLTHROUGH */ default: @@ -9913,9 +9909,6 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0, #ifdef INET6 case AF_INET6: { struct ip6_hdr *h; - int fragoff; - uint32_t jumbolen; - uint8_t nxt; if (__predict_false((*m0)->m_len < sizeof(struct ip6_hdr)) && (pd->m = *m0 = m_pullup(*m0, sizeof(struct ip6_hdr))) == NULL) { @@ -9929,8 +9922,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0, h = mtod(pd->m, struct ip6_hdr *); pd->off = 0; - if (pf_walk_header6(pd->m, h, &pd->off, &pd->extoff, &fragoff, &nxt, - &jumbolen, reason) != PF_PASS) { + if (pf_walk_header6(pd, h, reason) != PF_PASS) { *action = PF_DROP; return (-1); } @@ -9945,7 +9937,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0, pd->virtual_proto = pd->proto = h->ip6_nxt; pd->act.rtableid = -1; - if (fragoff != 0) + if (pd->fragoff != 0) pd->virtual_proto = PF_VPROTO_FRAGMENT; /* @@ -9958,7 +9950,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0, } /* We do IP header normalization and packet reassembly here */ - if (pf_normalize_ip6(m0, fragoff, reason, pd) != + if (pf_normalize_ip6(m0, pd->fragoff, reason, pd) != PF_PASS) { *action = PF_DROP; return (-1); @@ -9975,20 +9967,23 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0, pd->src = (struct pf_addr *)&h->ip6_src; pd->dst = (struct pf_addr *)&h->ip6_dst; - /* - * Reassembly may have changed the next protocol from fragment - * to something else, so update. - */ - pd->virtual_proto = pd->proto = h->ip6_nxt; pd->off = 0; - if (pf_walk_header6(pd->m, h, &pd->off, &pd->extoff, &fragoff, &nxt, - &jumbolen, reason) != PF_PASS) { + if (pf_walk_header6(pd, h, reason) != PF_PASS) { *action = PF_DROP; return (-1); } - if (fragoff != 0) + if (m_tag_find(pd->m, PACKET_TAG_PF_REASSEMBLED, NULL) != NULL) { + /* + * Reassembly may have changed the next protocol from + * fragment to something else, so update. + */ + pd->virtual_proto = pd->proto; + MPASS(pd->fragoff == 0); + } + + if (pd->fragoff != 0) pd->virtual_proto = PF_VPROTO_FRAGMENT; break;