git: 17ed12dc476d - main - pf: push 'field changed' guards into 'change field' functions

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Wed, 23 Apr 2025 11:56:53 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=17ed12dc476df18a11fd7e852d868d8604ae0c18

commit 17ed12dc476df18a11fd7e852d868d8604ae0c18
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-04-21 15:31:43 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-04-23 08:15:08 +0000

    pf: push 'field changed' guards into 'change field' functions
    
    optimise pf_patch_32(); simplify pf_match_addr()
    OK mikeb@
    
    Obtained from:  OpenBSD, procter <procter@openbsd.org>, 7f3e6f164e
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/net/pfvar.h          |  4 +--
 sys/netpfil/pf/pf.c      | 74 +++++++++++++++++++++++-------------------------
 sys/netpfil/pf/pf_norm.c |  6 ++--
 3 files changed, 40 insertions(+), 44 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index c7a2bde63184..a94ac62558ca 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2453,8 +2453,8 @@ void	pf_change_a(void *, u_int16_t *, u_int32_t, u_int8_t);
 void	pf_change_proto_a(struct mbuf *, void *, u_int16_t *, u_int32_t,
 	    u_int8_t);
 void	pf_change_tcp_a(struct mbuf *, void *, u_int16_t *, u_int32_t);
-void	pf_patch_16(struct pf_pdesc *, void *, u_int16_t, bool);
-void	pf_patch_32(struct pf_pdesc *, void *, u_int32_t, bool);
+int	pf_patch_16(struct pf_pdesc *, void *, u_int16_t, bool);
+int	pf_patch_32(struct pf_pdesc *, void *, u_int32_t, bool);
 void	pf_send_deferred_syn(struct pf_kstate *);
 int	pf_match_addr(u_int8_t, const struct pf_addr *,
 	    const struct pf_addr *, const struct pf_addr *, sa_family_t);
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index a4a24148da72..a154e0c7b446 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -381,7 +381,7 @@ 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 *);
-static void		 pf_patch_8(struct pf_pdesc *, u_int8_t *, u_int8_t,
+static int		 pf_patch_8(struct pf_pdesc *, u_int8_t *, u_int8_t,
 			    bool);
 static struct pf_kstate	*pf_find_state(struct pfi_kkif *,
 			    const struct pf_state_key_cmp *, u_int);
@@ -3208,44 +3208,54 @@ pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp)
 	return (u_int16_t)(x);
 }
 
-static void
+static int
 pf_patch_8(struct pf_pdesc *pd, u_int8_t *f, u_int8_t v, bool hi)
 {
-	u_int16_t old = htons(hi ? (*f << 8) : *f);
-	u_int16_t new = htons(hi ? ( v << 8) :  v);
+	int	 rewrite = 0;
 
-	if (*f == v)
-		return;
+	if (*f != v) {
+		uint16_t old = htons(hi ? (*f << 8) : *f);
+		uint16_t new = htons(hi ? ( v << 8) :  v);
 
-	*f = v;
+		*f = v;
 
-	if (pd->m->m_pkthdr.csum_flags & (CSUM_DELAY_DATA | CSUM_DELAY_DATA_IPV6))
-		return;
+		if (! (pd->m->m_pkthdr.csum_flags & (CSUM_DELAY_DATA |
+		    CSUM_DELAY_DATA_IPV6)))
+			*pd->pcksum = pf_cksum_fixup(*pd->pcksum, old, new,
+			    pd->proto == IPPROTO_UDP);
+
+		rewrite = 1;
+	}
 
-	*pd->pcksum = pf_cksum_fixup(*pd->pcksum, old, new,
-	    pd->proto == IPPROTO_UDP);
+	return (rewrite);
 }
 
-void
+int
 pf_patch_16(struct pf_pdesc *pd, void *f, u_int16_t v, bool hi)
 {
+	int rewrite = 0;
 	u_int8_t *fb = (u_int8_t *)f;
 	u_int8_t *vb = (u_int8_t *)&v;
 
-	pf_patch_8(pd, fb++, *vb++, hi);
-	pf_patch_8(pd, fb++, *vb++, !hi);
+	rewrite += pf_patch_8(pd, fb++, *vb++, hi);
+	rewrite += pf_patch_8(pd, fb++, *vb++, !hi);
+
+	return (rewrite);
 }
 
-void
+int
 pf_patch_32(struct pf_pdesc *pd, void *f, u_int32_t v, bool hi)
 {
+	int rewrite = 0;
 	u_int8_t *fb = (u_int8_t *)f;
 	u_int8_t *vb = (u_int8_t *)&v;
 
-	pf_patch_8(pd, fb++, *vb++, hi);
-	pf_patch_8(pd, fb++, *vb++, !hi);
-	pf_patch_8(pd, fb++, *vb++, hi);
-	pf_patch_8(pd, fb++, *vb++, !hi);
+	rewrite += pf_patch_8(pd, fb++, *vb++, hi);
+	rewrite += pf_patch_8(pd, fb++, *vb++, !hi);
+	rewrite += pf_patch_8(pd, fb++, *vb++, hi);
+	rewrite += pf_patch_8(pd, fb++, *vb++, !hi);
+
+	return (rewrite);
 }
 
 u_int16_t
@@ -3958,8 +3968,8 @@ pf_modulate_sack(struct pf_pdesc *pd, struct tcphdr *th,
 					    htonl(ntohl(sack.end) - dst->seqdiff),
 					    PF_ALGNMNT(startoff));
 					memcpy(&opt[i], &sack, sizeof(sack));
+					copyback = 1;
 				}
-				copyback = 1;
 			}
 			/* FALLTHROUGH */
 		default:
@@ -4434,41 +4444,29 @@ pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
 }
 
 /*
- * Return 1 if the addresses a and b match (with mask m), otherwise return 0.
- * If n is 0, they match if they are equal. If n is != 0, they match if they
- * are different.
+ * Return ((n = 0) == (a = b [with mask m]))
+ * Note: n != 0 => returns (a != b [with mask m])
  */
 int
 pf_match_addr(u_int8_t n, const struct pf_addr *a, const struct pf_addr *m,
     const struct pf_addr *b, sa_family_t af)
 {
-	int	match = 0;
-
 	switch (af) {
 #ifdef INET
 	case AF_INET:
 		if (IN_ARE_MASKED_ADDR_EQUAL(a->v4, b->v4, m->v4))
-			match++;
+			return (n == 0);
 		break;
 #endif /* INET */
 #ifdef INET6
 	case AF_INET6:
 		if (IN6_ARE_MASKED_ADDR_EQUAL(&a->v6, &b->v6, &m->v6))
-			match++;
+			return (n == 0);
 		break;
 #endif /* INET6 */
 	}
-	if (match) {
-		if (n)
-			return (0);
-		else
-			return (1);
-	} else {
-		if (n)
-			return (1);
-		else
-			return (0);
-	}
+
+	return (n != 0);
 }
 
 /*
diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
index 783e48627c0f..c77895d1829d 100644
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -1633,12 +1633,11 @@ pf_normalize_tcp_stateful(struct pf_pdesc *pd,
 					    (src->scrub->pfss_flags &
 					    PFSS_TIMESTAMP)) {
 						tsval = ntohl(tsval);
-						pf_patch_32(pd,
+						copyback += pf_patch_32(pd,
 						    &opt[2],
 						    htonl(tsval +
 						    src->scrub->pfss_ts_mod),
 						    PF_ALGNMNT(startoff));
-						copyback = 1;
 					}
 
 					/* Modulate TS reply iff valid (!0) */
@@ -1649,11 +1648,10 @@ pf_normalize_tcp_stateful(struct pf_pdesc *pd,
 					    PFSS_TIMESTAMP)) {
 						tsecr = ntohl(tsecr)
 						    - dst->scrub->pfss_ts_mod;
-						pf_patch_32(pd,
+						copyback += pf_patch_32(pd,
 						    &opt[6],
 						    htonl(tsecr),
 						    PF_ALGNMNT(startoff));
-						copyback = 1;
 					}
 					got_ts = 1;
 				}