git: 5c3d74eca642 - main - pf: add ttl to pf_pdesc

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Thu, 10 Oct 2024 12:37:16 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=5c3d74eca642220c1a6137528f66245b86d6939d

commit 5c3d74eca642220c1a6137528f66245b86d6939d
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-09-27 22:13:23 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-10-10 12:10:39 +0000

    pf: add ttl to pf_pdesc
    
    This simplifies the code a little, because we can now avoid looking at the
    IP(v6) header at all in pf_test() itself.
    
    We do have to move the Jumbogram check into pf_setup_pdesc as well.
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D46928
---
 sys/net/pfvar.h                |  3 ++-
 sys/netpfil/pf/pf.c            | 59 ++++++++++--------------------------------
 sys/netpfil/pf/pf_syncookies.c |  4 +--
 3 files changed, 17 insertions(+), 49 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 1e28693b960d..66e3e53b8b37 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1618,6 +1618,7 @@ struct pf_pdesc {
 	sa_family_t	 af;
 	u_int8_t	 proto;
 	u_int8_t	 tos;
+	u_int8_t	 ttl;
 	u_int8_t	 dir;		/* direction */
 	u_int8_t	 sidx;		/* key index for source */
 	u_int8_t	 didx;		/* key index for destination */
@@ -2509,7 +2510,7 @@ void			 pf_syncookie_send(struct mbuf *m, int off,
 			    struct pf_pdesc *);
 bool			 pf_syncookie_check(struct pf_pdesc *);
 u_int8_t		 pf_syncookie_validate(struct pf_pdesc *);
-struct mbuf *		 pf_syncookie_recreate_syn(uint8_t, int,
+struct mbuf *		 pf_syncookie_recreate_syn(int,
 			    struct pf_pdesc *);
 
 VNET_DECLARE(struct pf_kstatus, pf_status);
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index a482e08dd6ac..aa63c2c1d390 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -8666,6 +8666,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
 		pd->sidx = (dir == PF_IN) ? 0 : 1;
 		pd->didx = (dir == PF_IN) ? 1 : 0;
 		pd->tos = h->ip_tos;
+		pd->ttl = h->ip_ttl;
 		pd->tot_len = ntohs(h->ip_len);
 		pd->act.rtableid = -1;
 
@@ -8724,10 +8725,20 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
 		pd->sidx = (dir == PF_IN) ? 0 : 1;
 		pd->didx = (dir == PF_IN) ? 1 : 0;
 		pd->tos = IPV6_DSCP(h);
+		pd->ttl = h->ip6_hlim;
 		pd->tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
 		pd->virtual_proto = pd->proto = h->ip6_nxt;
 		pd->act.rtableid = -1;
 
+		/*
+		 * we do not support jumbogram.  if we keep going, zero ip6_plen
+		 * will do something bad, so drop the packet for now.
+		 */
+		if (htons(h->ip6_plen) == 0) {
+			*action = PF_DROP;
+			return (-1);
+		}
+
 		/* We do IP header normalization and packet reassembly here */
 		if (pf_normalize_ip6(m0, kif, *off, reason, pd) !=
 		    PF_PASS) {
@@ -8974,12 +8985,6 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0
 	struct pfi_kkif		*kif;
 	u_short			 action, reason = 0;
 	struct mbuf		*m = *m0;
-#ifdef INET
-	struct ip		*h = NULL;
-#endif
-#ifdef INET6
-	struct ip6_hdr		*h6 = NULL;
-#endif
 	struct m_tag		*mtag;
 	struct pf_krule		*a = NULL, *r = &V_pf_default_rule;
 	struct pf_kstate	*s = NULL;
@@ -8988,7 +8993,6 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0
 	int			 off, hdrlen, use_2nd_queue = 0;
 	uint16_t		 tag;
 	uint8_t			 rt;
-	uint8_t			 ttl;
 
 	PF_RULES_RLOCK_TRACKER;
 	KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: bad direction %d\n", __func__, dir));
@@ -9079,23 +9083,6 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0
 	}
 	m = *m0;
 
-	switch (af) {
-#ifdef INET
-	case AF_INET:
-		h = mtod(m, struct ip *);
-		ttl = h->ip_ttl;
-		break;
-#endif
-#ifdef INET6
-	case AF_INET6:
-		h6 = mtod(m, struct ip6_hdr *);
-		ttl = h6->ip6_hlim;
-		break;
-#endif
-	default:
-		panic("Unknown af %d", af);
-	}
-
 	if (__predict_false(ip_divert_ptr != NULL) &&
 	    ((mtag = m_tag_locate(m, MTAG_PF_DIVERT, 0, NULL)) != NULL)) {
 		struct pf_divert_mtag *dt = (struct pf_divert_mtag *)(mtag+1);
@@ -9119,18 +9106,6 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0
 			m_tag_delete(m, mtag);
 	}
 
-#ifdef INET6
-	/*
-	 * we do not support jumbogram.  if we keep going, zero ip6_plen
-	 * will do something bad, so drop the packet for now.
-	 */
-	if (af == AF_INET6 && htons(h6->ip6_plen) == 0) {
-		action = PF_DROP;
-		REASON_SET(&reason, PFRES_NORM);	/*XXX*/
-		goto done;
-	}
-#endif
-
 	switch (pd.proto) {
 	case IPPROTO_TCP: {
 		/* Respond to SYN with a syncookie. */
@@ -9160,8 +9135,7 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0
 			    pd.dir == PF_IN) {
 				struct mbuf *msyn;
 
-				msyn = pf_syncookie_recreate_syn(ttl, off,
-				    &pd);
+				msyn = pf_syncookie_recreate_syn(off, &pd);
 				if (msyn == NULL) {
 					action = PF_DROP;
 					break;
@@ -9340,14 +9314,7 @@ done:
 			else
 				pd.pf_mtag->qid = pd.act.qid;
 			/* Add hints for ecn. */
-#ifdef INET
-			if (af == AF_INET)
-				pd.pf_mtag->hdr = h;
-#endif
-#ifdef INET6
-			if (af == AF_INET6)
-				pd.pf_mtag->hdr = h6;
-#endif
+			pd.pf_mtag->hdr = mtod(m, void *);
 		}
 	}
 #endif /* ALTQ */
diff --git a/sys/netpfil/pf/pf_syncookies.c b/sys/netpfil/pf/pf_syncookies.c
index 538ab1dfd94c..40c664f48914 100644
--- a/sys/netpfil/pf/pf_syncookies.c
+++ b/sys/netpfil/pf/pf_syncookies.c
@@ -498,7 +498,7 @@ pf_syncookie_generate(struct mbuf *m, int off, struct pf_pdesc *pd,
 }
 
 struct mbuf *
-pf_syncookie_recreate_syn(uint8_t ttl, int off, struct pf_pdesc *pd)
+pf_syncookie_recreate_syn(int off, struct pf_pdesc *pd)
 {
 	uint8_t			 wscale;
 	uint16_t		 mss;
@@ -517,6 +517,6 @@ pf_syncookie_recreate_syn(uint8_t ttl, int off, struct pf_pdesc *pd)
 	wscale = pf_syncookie_wstab[cookie.flags.wscale_idx];
 
 	return (pf_build_tcp(NULL, pd->af, pd->src, pd->dst, *pd->sport,
-	    *pd->dport, seq, 0, TH_SYN, wscale, mss, ttl, false, 0,
+	    *pd->dport, seq, 0, TH_SYN, wscale, mss, pd->ttl, false, 0,
 	    PF_MTAG_FLAG_SYNCOOKIE_RECREATED, pd->act.rtableid));
 }