git: f4f4c52c0f46 - stable/14 - pf: Let pf_state_insert() handle redirect state conflicts

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Wed, 20 Nov 2024 21:41:24 UTC
The branch stable/14 has been updated by markj:

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

commit f4f4c52c0f46531082925aded23510f9adeb6fff
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2024-09-10 14:34:45 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-11-20 21:41:09 +0000

    pf: Let pf_state_insert() handle redirect state conflicts
    
    When handling a redirect state conflict, pf_get_translation() tries
    modifying the source port to avoid it.  If it fails to find a free port,
    the translation is aborted.
    
    Instead, if we fail to find a free source port, simply press on with the
    original source port and let pf_state_insert() handle the conflict as it
    pleases, rather than second-guessing what it will do.  In particular,
    pf_state_insert() has special handling for TCP connections in a terminal
    state, and might succeed despite a state conflict.
    
    Reviewed by:    kp
    MFC after:      3 months
    Sponsored by:   Klara, Inc.
    Sponsored by:   Modirum
    Differential Revision:  https://reviews.freebsd.org/D46612
    
    (cherry picked from commit 9569fddd8d0e48211e67fdc63dd72eba83883525)
---
 sys/netpfil/pf/pf_lb.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
index 6b0b95e9ce01..3f5b3f90a4e4 100644
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -370,7 +370,7 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
     struct pf_addr *naddr, struct pfi_kkif **nkif, struct pf_addr *init_addr,
     struct pf_ksrc_node **sn)
 {
-	u_short			 reason = 0;
+	u_short			 reason = PFRES_MATCH;
 	struct pf_kpool		*rpool = &r->rpool;
 	struct pf_addr		*raddr = NULL, *rmask = NULL;
 	struct pf_srchash	*sh = NULL;
@@ -828,10 +828,15 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
 			}
 		}
 
+		/*
+		 * We failed to find a match.  Push on ahead anyway, let
+		 * pf_state_insert() be the arbiter of whether the state
+		 * conflict is tolerable.  In particular, with TCP connections
+		 * the state may be reused if the TCP state is terminal.
+		 */
 		DPFPRINTF(PF_DEBUG_MISC,
 		    ("pf: RDR source port allocation failed\n"));
-		reason = PFRES_MAPFAILED;
-		goto notrans;
+		break;
 
 out:
 		DPFPRINTF(PF_DEBUG_MISC,