From nobody Wed Nov 20 21:41:23 2024 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Xtvv75rgDz5dnRl; Wed, 20 Nov 2024 21:41:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Xtvv74sprz4vmf; Wed, 20 Nov 2024 21:41:23 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1732138883; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=cE2QgcN9wm2D/RD+tZ4tIiYHnF5hxFR/lr8sEAaKEOs=; b=Wzj2KQ3dNEUP9auD5IhIOFadkW0G8OClAFaFKd9BjGWXICKyhwguqhKYfh9+kWzPMIHisF B0vs2exv+G++xAqO+tR/nWqacLy9lo5Fo/NrG6/GubdTzwb/I2UmohRq7TPb9LGUTM1QzG PGTgXueIqS9x/C1V/TJXAOXvTtFE89s+ZHa2mhCwCYl1t92+xyCO9m9bIRhYrwTUb4L2vv YNlH6SNiHz2aC0Vm7mmKduS876pc3OCR9ICFqqkyPSAMAXU2bnehRJrPDY04uzsy4zKBqQ IRUTimQtJgBMH4cZCeK2o/mJvAy4UbBneKeIO3+bi9bk2ww1tlKksIy4rKl6pA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1732138883; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=cE2QgcN9wm2D/RD+tZ4tIiYHnF5hxFR/lr8sEAaKEOs=; b=ruw5JdvWi19w7vbo7B92PKhSUaGlbA/efRv1yxpVVfH/yG38DkF7KRAdBYep2W5Mm7hvlo EyN37CmBs84jh1/VUXUMdOPL9GS4LBdC5dB9jsgszOC7+Q4VmmcbT7cj2x0sg7OBC9LCd5 QAobi2k9uPUqLV8KqCNtziquekr1jhI/idDf3FK1JoH3aKxCPCP0jPx0oKu5rydTzJ4eL6 Ps6poMK4Eds+QF7QVHatMboaGdIeYIUICwiKQ7JSnnJjMgHGpr6Ff6k13oNqXBPBK1cYM5 9/cyrWv7rMpwQG+QuyQJ4xJKhJXFptVj1chSXv8/JnH1EguLw9FP3+vFSEPI5Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1732138883; a=rsa-sha256; cv=none; b=edRW/onxbTcsSxi7Q7lWSbGNQuo4Zw9bSQuScXoo17cij83OktrgjmapNpF+/27HefRBpD 8/FNyK/opu92V0RbkATWe3/K3Q5Rf7ytpXQAAOBrs/KWTosWH1Q048DIOuK+QAW/UJkn6g gTHw8EIA0fjWU4cQ3E0XaLhgYz2Y8m9Spl1H51wtOvS606GcwQiWz6BZj3yXXYtUw9EOoa 0NpR343Rj8ED23JSgy6jwfZzvYAIx3di7iNOz15zkmDXH2jrjZTiJAeBQYWyjh8wKtGg42 GC2+66S0zSNiavy7JMkE3OXcyejuDwufLVOeyeudQ9ExAY1EPs2tOmwOkJATQw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Xtvv74Tzvz19nw; Wed, 20 Nov 2024 21:41:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 4AKLfNw5022301; Wed, 20 Nov 2024 21:41:23 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4AKLfNoJ022298; Wed, 20 Nov 2024 21:41:23 GMT (envelope-from git) Date: Wed, 20 Nov 2024 21:41:23 GMT Message-Id: <202411202141.4AKLfNoJ022298@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: 5df40377e7b0 - stable/14 - pf: Make pf_get_translation() more expressive List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 5df40377e7b01c8fe7f5e36ffeb825514cf42072 Auto-Submitted: auto-generated The branch stable/14 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=5df40377e7b01c8fe7f5e36ffeb825514cf42072 commit 5df40377e7b01c8fe7f5e36ffeb825514cf42072 Author: Mark Johnston AuthorDate: 2024-08-19 14:14:30 +0000 Commit: Mark Johnston CommitDate: 2024-11-20 21:41:09 +0000 pf: Make pf_get_translation() more expressive Currently pf_get_translation() returns a pointer to a matching nat/rdr/binat rule, or NULL if no rule was matched or an error occurred while applying the translation. That is, we don't distinguish between errors and the lack of a matching rule. This, if an error (e.g., a memory allocation failure or a state conflict) occurs, we simply handle the packet as if no translation rule was present. This is not desireable. Make pf_get_translation() return the matching rule as an out-param and instead return a reason code which indicates whether there was no translation rule, or there was a translation rule and we failed to apply it, or there was a translation rule and we applied it successfully. Reviewed by: kp, allanjude MFC after: 3 months Sponsored by: Klara, Inc. Sponsored by: Modirum Differential Revision: https://reviews.freebsd.org/D45672 (cherry picked from commit 7e65cfc9bbe5a9d735ef38f7ed49965b234b8a20) --- sys/net/pfvar.h | 5 +++-- sys/netpfil/pf/pf.c | 18 ++++++++++++---- sys/netpfil/pf/pf_lb.c | 57 +++++++++++++++++++++++++++++++++----------------- 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 290f339e7d00..465e47b940b3 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -2510,11 +2510,12 @@ u_short pf_map_addr(u_int8_t, struct pf_krule *, struct pf_addr *, struct pf_addr *, struct pfi_kkif **nkif, struct pf_addr *, struct pf_ksrc_node **); -struct pf_krule *pf_get_translation(struct pf_pdesc *, struct mbuf *, +u_short pf_get_translation(struct pf_pdesc *, struct mbuf *, int, struct pfi_kkif *, struct pf_ksrc_node **, struct pf_state_key **, struct pf_state_key **, struct pf_addr *, struct pf_addr *, - uint16_t, uint16_t, struct pf_kanchor_stackframe *); + uint16_t, uint16_t, struct pf_kanchor_stackframe *, + struct pf_krule **); struct pf_state_key *pf_state_key_setup(struct pf_pdesc *, struct mbuf *, int, struct pf_addr *, struct pf_addr *, u_int16_t, u_int16_t); diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index d6541bc6627b..4fd884852d90 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -4641,7 +4641,7 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif, struct pf_ksrc_node *nsn = NULL; struct tcphdr *th = &pd->hdr.tcp; struct pf_state_key *sk = NULL, *nk = NULL; - u_short reason; + u_short reason, transerror; int rewrite = 0, hdrlen = 0; int tag = -1; int asd = 0; @@ -4654,6 +4654,8 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif, PF_RULES_RASSERT(); + SLIST_INIT(&match_rules); + if (inp != NULL) { INP_LOCK_ASSERT(inp); pd->lookup.uid = inp->inp_cred->cr_uid; @@ -4722,8 +4724,17 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif, r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); /* check packet for BINAT/NAT/RDR */ - if ((nr = pf_get_translation(pd, m, off, kif, &nsn, &sk, - &nk, saddr, daddr, sport, dport, anchor_stack)) != NULL) { + transerror = pf_get_translation(pd, m, off, kif, &nsn, &sk, + &nk, saddr, daddr, sport, dport, anchor_stack, &nr); + switch (transerror) { + default: + /* A translation error occurred. */ + REASON_SET(&reason, transerror); + goto cleanup; + case PFRES_MAX: + /* No match. */ + break; + case PFRES_MATCH: KASSERT(sk != NULL, ("%s: null sk", __func__)); KASSERT(nk != NULL, ("%s: null nk", __func__)); @@ -4872,7 +4883,6 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, struct pfi_kkif *kif, pd->nat_rule = nr; } - SLIST_INIT(&match_rules); while (r != NULL) { pf_counter_u64_add(&r->evaluations, 1); if (pfi_kkif_match(r->kif, kif) == r->ifnot) diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c index 7524bf138e6d..6b0b95e9ce01 100644 --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -591,22 +591,26 @@ done: return (reason); } -struct pf_krule * +u_short pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, struct pfi_kkif *kif, struct pf_ksrc_node **sn, struct pf_state_key **skp, struct pf_state_key **nkp, struct pf_addr *saddr, struct pf_addr *daddr, - uint16_t sport, uint16_t dport, struct pf_kanchor_stackframe *anchor_stack) + uint16_t sport, uint16_t dport, struct pf_kanchor_stackframe *anchor_stack, + struct pf_krule **rp) { struct pf_krule *r = NULL; struct pf_addr *naddr; uint16_t *nportp; uint16_t low, high; + u_short reason; PF_RULES_RASSERT(); KASSERT(*skp == NULL, ("*skp not NULL")); KASSERT(*nkp == NULL, ("*nkp not NULL")); + *rp = NULL; + if (pd->dir == PF_OUT) { r = pf_match_translation(pd, m, off, kif, saddr, sport, daddr, dport, PF_RULESET_BINAT, anchor_stack); @@ -624,23 +628,23 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, } if (r == NULL) - return (NULL); + return (PFRES_MAX); switch (r->action) { case PF_NONAT: case PF_NOBINAT: case PF_NORDR: - return (NULL); + return (PFRES_MAX); } *skp = pf_state_key_setup(pd, m, off, saddr, daddr, sport, dport); if (*skp == NULL) - return (NULL); + return (PFRES_MEMORY); *nkp = pf_state_key_clone(*skp); if (*nkp == NULL) { uma_zfree(V_pf_state_key_z, *skp); *skp = NULL; - return (NULL); + return (PFRES_MEMORY); } naddr = &(*nkp)->addr[1]; @@ -664,6 +668,7 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, r->rpool.mape.offset, r->rpool.mape.psidlen, r->rpool.mape.psid)); + reason = PFRES_MAPFAILED; goto notrans; } } else if (pf_get_sport(pd->af, pd->proto, r, saddr, sport, @@ -671,6 +676,7 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, DPFPRINTF(PF_DEBUG_MISC, ("pf: NAT proxy port allocation (%u-%u) failed\n", r->rpool.proxy_port[0], r->rpool.proxy_port[1])); + reason = PFRES_MAPFAILED; goto notrans; } break; @@ -682,8 +688,10 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, #ifdef INET case AF_INET: if (r->rpool.cur->addr.p.dyn-> - pfid_acnt4 < 1) + pfid_acnt4 < 1) { + reason = PFRES_MAPFAILED; goto notrans; + } PF_POOLMASK(naddr, &r->rpool.cur->addr.p.dyn-> pfid_addr4, @@ -694,8 +702,10 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, #ifdef INET6 case AF_INET6: if (r->rpool.cur->addr.p.dyn-> - pfid_acnt6 < 1) + pfid_acnt6 < 1) { + reason = PFRES_MAPFAILED; goto notrans; + } PF_POOLMASK(naddr, &r->rpool.cur->addr.p.dyn-> pfid_addr6, @@ -715,8 +725,10 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, switch (pd->af) { #ifdef INET case AF_INET: - if (r->src.addr.p.dyn-> pfid_acnt4 < 1) + if (r->src.addr.p.dyn->pfid_acnt4 < 1) { + reason = PFRES_MAPFAILED; goto notrans; + } PF_POOLMASK(naddr, &r->src.addr.p.dyn->pfid_addr4, &r->src.addr.p.dyn->pfid_mask4, @@ -725,8 +737,10 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, #endif /* INET */ #ifdef INET6 case AF_INET6: - if (r->src.addr.p.dyn->pfid_acnt6 < 1) + if (r->src.addr.p.dyn->pfid_acnt6 < 1) { + reason = PFRES_MAPFAILED; goto notrans; + } PF_POOLMASK(naddr, &r->src.addr.p.dyn->pfid_addr6, &r->src.addr.p.dyn->pfid_mask6, @@ -744,7 +758,8 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, struct pf_state_key_cmp key; uint16_t cut, low, high, nport; - if (pf_map_addr(pd->af, r, saddr, naddr, NULL, NULL, sn)) + reason = pf_map_addr(pd->af, r, saddr, naddr, NULL, NULL, sn); + if (reason != 0) goto notrans; if ((r->rpool.opts & PF_POOL_TYPEMASK) == PF_POOL_BITMASK) PF_POOLMASK(naddr, naddr, &r->rpool.cur->addr.v.a.mask, @@ -815,12 +830,13 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, DPFPRINTF(PF_DEBUG_MISC, ("pf: RDR source port allocation failed\n")); - if (0) { + reason = PFRES_MAPFAILED; + goto notrans; + out: - DPFPRINTF(PF_DEBUG_MISC, - ("pf: RDR source port allocation %u->%u\n", - ntohs(sport), ntohs((*nkp)->port[0]))); - } + DPFPRINTF(PF_DEBUG_MISC, + ("pf: RDR source port allocation %u->%u\n", + ntohs(sport), ntohs((*nkp)->port[0]))); break; } default: @@ -828,14 +844,17 @@ out: } /* Return success only if translation really happened. */ - if (bcmp(*skp, *nkp, sizeof(struct pf_state_key_cmp))) - return (r); + if (bcmp(*skp, *nkp, sizeof(struct pf_state_key_cmp))) { + *rp = r; + return (PFRES_MATCH); + } + reason = PFRES_MAX; notrans: uma_zfree(V_pf_state_key_z, *nkp); uma_zfree(V_pf_state_key_z, *skp); *skp = *nkp = NULL; *sn = NULL; - return (NULL); + return (reason); }