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)
This commit is contained in:
Mark Johnston 2024-09-10 14:34:45 +00:00 committed by Franco Fichtner
parent f88dfd37e6
commit b2f41381bd

View file

@ -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,