From nobody Wed Sep 09 08:35:24 2026 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 4hfvJX5fXlz6rj2L for ; Wed, 09 Sep 2026 08:35:24 +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 "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hfvJX58HDz4Nc0 for ; Wed, 09 Sep 2026 08:35:24 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788942924; 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=mvTdnd6B6XBhBNL0kqTwg7EdlJp1NBzUh1Lcreu8ZII=; b=OROpmk0YUvmwOzNjMRWmcOA50ktwSY9pxWlI90HXvJaAvpjfG23N/hP9moqPa3PqRywd1U ZpAnPpt9vwlKlQ2lLyWhnlMne3l8hiMGhAyhZqNvaYFDMXZjxzOvTWbCladFL833IWZQuN J5XFYIAntphQAnBjz/LnKW2G/0wyT4dQiAJHdvcaBfpE/l5hhLweNs8TO9kVRWanTXgLpy ZL4hpvWVKlsd+sldUW1Kso/BHUJQZLvaE76yJfoCHYSqPm2zYA60iHbYc/dy1iT2+N7FUC AyKnl8GtN1CxKfi2FtgrbxKsDhCxKuA00VnK4rHgNCHbMgIHXxo9XVvTOnqngA== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1788942924; b=S420E0LtVkr2+Jc0OUKykqso5cRoIz50cD7cGonzXE3kJk1dJe9lzdpkg/nZZ3jzSM8aSt XsRfswKBVm3pr5KWv3Dm4rC6y/xS7BlNj17o2NQqcrCSsbFot/VyFZUtjJ5PhUA5U2Dd22 H/1/ccsoi6rimCgLYpRCyYsxCcJnv1CDex2IUND/Z3NGH8QiXQrIhTlGb+zFtBOE9lii6X 07yLGgR6gCLrw9j3uy7pm8dr3U43f/Pz4p+k1vQssoLgMSe9tr/ed134OkWsR0gohvGeJO 4SHKGMb/xFqBKIVIcM3kY7yiuR86adLr29iVDX0HpcJNmcYJNnwJSfHHOvEBAw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788942924; 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=mvTdnd6B6XBhBNL0kqTwg7EdlJp1NBzUh1Lcreu8ZII=; b=WyQzIPnP7Owt4gJvlJq/VmFi4Uuj+Riaj+00ZJgln5lY2TuiublCtH6VYycEh7d2J4qmwu SfvvPgZE0zrRpOghWZZQh3fS51BTnLukpxTHva5gshFo/CT0lOCa0GpO7VO5SuLHHKZGS6 GBv0J3X/BKybm90Yy4H9cOm6LysotGpQdpLg4FeszHLZRYb2p9+8Z874dR8KdrvkjhohMN hFGfu071nf+jufDWitn8XuT64Q0t3GcaEBK8XeBbscyFD7Cy7ApE09Mc1t6bcuV8RNb7Wc knMzUOipMonfTmaABusHqmzX4f8rmEYl6OcplSn3Hivj7Ff1fxI4MBsNYdufNg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hfvJX4C1JzpmK for ; Wed, 09 Sep 2026 08:35:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1c70d by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 09 Sep 2026 08:35:24 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: 266331cb8bbc - stable/15 - pf: Re-optimize state key handling 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 List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list 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/15 X-Git-Reftype: branch X-Git-Commit: 266331cb8bbcdaab45f183ddba8775cb0c4f79d0 Auto-Submitted: auto-generated Date: Wed, 09 Sep 2026 08:35:24 +0000 Message-Id: <6aa11a4c.1c70d.55dcfc8e@gitrepo.freebsd.org> The branch stable/15 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=266331cb8bbcdaab45f183ddba8775cb0c4f79d0 commit 266331cb8bbcdaab45f183ddba8775cb0c4f79d0 Author: Mark Johnston AuthorDate: 2026-08-25 18:09:37 +0000 Commit: Mark Johnston CommitDate: 2026-09-09 08:34:33 +0000 pf: Re-optimize state key handling pf states may be looked up using one of two keys: the stack key or the wire key. For states involving address translation, these will be distinct; the stack key describes the addresses seen by the local network stack, and the wire key has the translated addresses. Historically, pf would avoid allocating separate keys if both are identical. This changed in commit fcdb520c1b4e ("pf: nat64") to always allocate separate state key structures. Incidentally, OpenBSD seems to maintain the optimization, but also has an explicit reference count embedded in state keys. The change breaks another optimization: pf_state_key_attach() still uses state key pointer equality to check whether the stack and wire keys are equal, so those checks are always false after the aforementioned commit. Thus we never skip the second key lookup, even when that's possible (i.e., no address translation is involved). So, for some rulesets we're consuming more memory than needed and performing more state key lookups than needed. The behaviour of always looking up the stack key also happens to break some existing rulesets involving RDR and divert-to, which is how I noticed the problem. I think those rulesets effectively worked by accident before, but it seems worth restoring the optimization regardless. Reviewed by: kp MFC after: 2 weeks Fixes: fcdb520c1b4e ("pf: nat64") Sponsored by: OPNsense Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D58922 (cherry picked from commit 918fbc947356c1434760b1bc0deb8558283ce8c5) --- sys/netpfil/pf/pf.c | 25 +++++++++++++++---------- sys/netpfil/pf/pf_lb.c | 11 ++++++++++- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index d8010ef7c224..8b17abb81b09 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -1742,14 +1742,14 @@ pf_state_key_setup(struct pf_pdesc *pd, u_int16_t sport, u_int16_t dport, (*sk)->proto = pd->proto; (*sk)->af = pd->af; - *nk = pf_state_key_clone(*sk); - if (*nk == NULL) { - uma_zfree(V_pf_state_key_z, *sk); - *sk = NULL; - return (ENOMEM); - } - if (pd->af != pd->naf) { + *nk = pf_state_key_clone(*sk); + if (*nk == NULL) { + uma_zfree(V_pf_state_key_z, *sk); + *sk = NULL; + return (ENOMEM); + } + (*sk)->port[pd->sidx] = pd->osport; (*sk)->port[pd->didx] = pd->odport; @@ -1787,6 +1787,8 @@ pf_state_key_setup(struct pf_pdesc *pd, u_int16_t sport, u_int16_t dport, default: (*nk)->proto = pd->proto; } + } else { + *nk = *sk; } return (0); @@ -6090,7 +6092,8 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, } } else { uma_zfree(V_pf_state_key_z, ctx.sk); - uma_zfree(V_pf_state_key_z, ctx.nk); + if (ctx.sk != ctx.nk) + uma_zfree(V_pf_state_key_z, ctx.nk); ctx.sk = ctx.nk = NULL; pf_udp_mapping_release(ctx.udp_mapping); } @@ -6117,7 +6120,8 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm, cleanup: uma_zfree(V_pf_state_key_z, ctx.sk); - uma_zfree(V_pf_state_key_z, ctx.nk); + if (ctx.sk != ctx.nk) + uma_zfree(V_pf_state_key_z, ctx.nk); pf_udp_mapping_release(ctx.udp_mapping); *reason = ctx.reason; @@ -6356,7 +6360,8 @@ pf_create_state(struct pf_krule *r, struct pf_test_ctx *ctx, csfailed: uma_zfree(V_pf_state_key_z, ctx->sk); - uma_zfree(V_pf_state_key_z, ctx->nk); + if (ctx->sk != ctx->nk) + uma_zfree(V_pf_state_key_z, ctx->nk); for (pf_sn_types_t sn_type=0; sn_typensport, pd->ndport, &ctx->sk, &ctx->nk)) return (PFRES_MEMORY); + if (ctx->sk == ctx->nk) { + ctx->nk = pf_state_key_clone(ctx->sk); + if (ctx->nk == NULL) { + uma_zfree(V_pf_state_key_z, ctx->sk); + ctx->sk = NULL; + return (PFRES_MEMORY); + } + } } switch (nat_action) { @@ -1242,7 +1250,8 @@ out: reason = PFRES_MAX; notrans: uma_zfree(V_pf_state_key_z, ctx->nk); - uma_zfree(V_pf_state_key_z, ctx->sk); + if (ctx->nk != ctx->sk) + uma_zfree(V_pf_state_key_z, ctx->sk); ctx->sk = ctx->nk = NULL; return (reason);