git: 9a445773752f - main - pf: teach pf_build_tcp() about SACK

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Wed, 28 May 2025 21:55:52 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=9a445773752f238226940da403e3a4773d2930a9

commit 9a445773752f238226940da403e3a4773d2930a9
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-05-27 10:02:15 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-05-28 21:40:37 +0000

    pf: teach pf_build_tcp() about SACK
    
    ok & with sashan
    
    Obtained from:  OpenBSD, henning <henning@openbsd.org>, 01c3818b6b
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/net/pfvar.h                |  2 +-
 sys/netpfil/pf/pf.c            | 14 ++++++++++++--
 sys/netpfil/pf/pf_syncookies.c |  2 +-
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 91fdcfcbec1d..1cdd575366e8 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2561,7 +2561,7 @@ 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,
 		    u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
-		    u_int16_t, u_int16_t, int);
+		    u_int16_t, u_int16_t, u_int, int);
 void		 pf_send_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,
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 996e329a204e..5c572dfcd425 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -3990,7 +3990,8 @@ pf_build_tcp(const struct pf_krule *r, sa_family_t af,
     const struct pf_addr *saddr, const struct pf_addr *daddr,
     u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
     u_int8_t tcp_flags, u_int16_t win, u_int16_t mss, u_int8_t ttl,
-    int mbuf_flags, u_int16_t mtag_tag, u_int16_t mtag_flags, int rtableid)
+    int mbuf_flags, u_int16_t mtag_tag, u_int16_t mtag_flags, u_int sack,
+    int rtableid)
 {
 	struct mbuf	*m;
 	int		 len, tlen;
@@ -4011,6 +4012,8 @@ pf_build_tcp(const struct pf_krule *r, sa_family_t af,
 	tlen = sizeof(struct tcphdr);
 	if (mss)
 		tlen += 4;
+	if (sack)
+		tlen += 2;
 
 	switch (af) {
 #ifdef INET
@@ -4115,12 +4118,19 @@ pf_build_tcp(const struct pf_krule *r, sa_family_t af,
 	tcp_set_flags(th, tcp_flags);
 	th->th_win = htons(win);
 
+	opt = (char *)(th + 1);
 	if (mss) {
 		opt = (char *)(th + 1);
 		opt[0] = TCPOPT_MAXSEG;
 		opt[1] = 4;
 		mss = htons(mss);
 		memcpy((opt + 2), &mss, 2);
+		opt += 4;
+	}
+	if (sack) {
+		opt[0] = TCPOPT_SACK_PERMITTED;
+		opt[1] = 2;
+		opt += 2;
 	}
 
 	return (m);
@@ -4253,7 +4263,7 @@ pf_send_tcp(const struct pf_krule *r, sa_family_t af,
 	struct mbuf	*m;
 
 	m = pf_build_tcp(r, af, saddr, daddr, sport, dport, seq, ack, tcp_flags,
-	    win, mss, ttl, mbuf_flags, mtag_tag, mtag_flags, rtableid);
+	    win, mss, ttl, mbuf_flags, mtag_tag, mtag_flags, 0, rtableid);
 	if (m == NULL)
 		return;
 
diff --git a/sys/netpfil/pf/pf_syncookies.c b/sys/netpfil/pf/pf_syncookies.c
index 3a0e23100f7c..66757fa4b756 100644
--- a/sys/netpfil/pf/pf_syncookies.c
+++ b/sys/netpfil/pf/pf_syncookies.c
@@ -518,5 +518,5 @@ pf_syncookie_recreate_syn(struct pf_pdesc *pd)
 	return (pf_build_tcp(NULL, pd->af, pd->src, pd->dst, *pd->sport,
 	    *pd->dport, seq, 0, TH_SYN, wscale, mss, pd->ttl,
 	    (pd->m->m_flags & M_LOOP), 0, PF_MTAG_FLAG_SYNCOOKIE_RECREATED,
-	    pd->act.rtableid));
+	    cookie.flags.sack_ok, pd->act.rtableid));
 }