From nobody Mon Jun 9 21:06:55 2025 X-Original-To: dev-commits-src-main@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 4bGPcb3Pw6z5yVgK; Mon, 09 Jun 2025 21:06:55 +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 "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4bGPcb1gyQz3gHg; Mon, 09 Jun 2025 21:06:55 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1749503215; 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=FrDkNESrXzvgGAwXChEMQylEaeHoWsrxXRaKlg3zYdQ=; b=AjQoG5aCS8SW9yLn9sT9ng7avKfSq6IbByhviWnAUjrMKYgSomR0j8UlIzOvQXcDVajqAE XhaE+WZxqKBpUBSMo1I1UPvq4CxnV3JmFtUNidk1cEdfykrtmOTHJEYBi2f03yY7b71LVT iYcbNoXC+V7Yafso77X8HXN8ivdUR2Y5T5INZDD1+OqNrbLgHTFffGbpxxbael8vajnGOh qtP/YRBoaHiuZPvXav+o8flXL/Ym1laAH04bECqxJkvJNt68pPwf6A+5V1Q7hMcT5Cnn/0 /VfxEyhnsnpm7jS7bTpSNDRMJy+S5LDlpRuz5M/04HsGYJrpDfR9Z4xV2CnJfw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1749503215; 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=FrDkNESrXzvgGAwXChEMQylEaeHoWsrxXRaKlg3zYdQ=; b=J22OC7w0uVS0sNVOq+mYEOGL27K99sbEZNbLhoQlDXIR0tRdT+2aX898wHYWVWR09BPgSn /b2aTyB4d3VwRMtd/5ls1lEoWEUwBEwuPhnvWxKVJYLbxfiLUQgBqBaVPDImmquV+LVcb2 M+YhFAuya44/M+2fW2TXSgeXQRAMioa0T7vCrqLfv2PDDyM1fU45YDX8K7JG7fw7XThJUO tooYg/HTHdvCgOkCbT9ruk9mPa6o2DlJ3L7Pp9T8y1FRAAkilQSkfmjiPzR0gXr6o147Eo yhBF+/dETSTPq1i6M1MYZNhCZ8uiHhjYLwSH2oXFrZ4GUiRW5p7a83Um6HrhRA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1749503215; a=rsa-sha256; cv=none; b=aPmn/s9hrvNvpE7r/slYKXplLyrYu7Agf0u99plQIwjBf8mvMLl6f0hXAsStZc+h2g1lZV XRiqWUgLH8yL/cRTHlrmi+1Gpp685thNfDpqiM+W+cqlSAYUz0C65VXI07CsD8XiPbjwZ1 SaQBOpT9GqoaavQlnBaNpxHD8ZAJSAyHIMvBnaanewooBqq2euwprMyZiDCqTEPqIAixbw NrFtFM5VR04fx/FBk+Lc6/LY/EUGD+I7kWSCnsBwjwIle320teG5EtCuojJLbo+ZJyI0bT 2svhbDCs76oOLXyy9HGeRiLMT5jrSgeP78mzBEeBQe0BeRBrBJ2oPZv67KdFSw== 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 4bGPcb0rdLz1BJH; Mon, 09 Jun 2025 21:06:55 +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 559L6tXi089803; Mon, 9 Jun 2025 21:06:55 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 559L6tKd089800; Mon, 9 Jun 2025 21:06:55 GMT (envelope-from git) Date: Mon, 9 Jun 2025 21:06:55 GMT Message-Id: <202506092106.559L6tKd089800@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: 54a547fcb47c - main - pf: split pf_find_or_create_ruleset() into smaller chunks List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 54a547fcb47c9fce54789a8b091e900b291fd1ba Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=54a547fcb47c9fce54789a8b091e900b291fd1ba commit 54a547fcb47c9fce54789a8b091e900b291fd1ba Author: Kristof Provost AuthorDate: 2025-05-30 13:02:50 +0000 Commit: Kristof Provost CommitDate: 2025-06-09 19:38:47 +0000 pf: split pf_find_or_create_ruleset() into smaller chunks tested by Hrvoje OK mpi@, OK bluhm@ Obtained from: OpenBSD, sashan , 0d5abfc5ba Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D50725 --- sys/net/pfvar.h | 2 + sys/netpfil/pf/pf.h | 1 + sys/netpfil/pf/pf_ruleset.c | 178 ++++++++++++++++++++++++++++---------------- 3 files changed, 117 insertions(+), 64 deletions(-) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 6209a93dd995..65debf53e5ff 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -2664,6 +2664,8 @@ int pf_kanchor_nvcopyout(const struct pf_kruleset *, void pf_kanchor_remove(struct pf_krule *); void pf_remove_if_empty_kruleset(struct pf_kruleset *); struct pf_kruleset *pf_find_kruleset(const char *); +struct pf_kruleset *pf_get_leaf_kruleset(char *, char **); +struct pf_kanchor *pf_create_kanchor(struct pf_kanchor *, const char *); struct pf_kruleset *pf_find_or_create_kruleset(const char *); void pf_rs_initialize(void); diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h index b5c0eeaa8f01..2009d2907985 100644 --- a/sys/netpfil/pf/pf.h +++ b/sys/netpfil/pf/pf.h @@ -489,6 +489,7 @@ struct pf_osfp_ioctl { }; #define PF_ANCHOR_NAME_SIZE 64 +#define PF_ANCHOR_MAXPATH (MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 1) struct pf_rule { struct pf_rule_addr src; diff --git a/sys/netpfil/pf/pf_ruleset.c b/sys/netpfil/pf/pf_ruleset.c index 6fd92201439d..865c5ecd72d9 100644 --- a/sys/netpfil/pf/pf_ruleset.c +++ b/sys/netpfil/pf/pf_ruleset.c @@ -189,13 +189,108 @@ pf_find_kruleset(const char *path) else return (&anchor->ruleset); } +struct pf_kruleset * +pf_get_leaf_kruleset(char *path, char **path_remainder) +{ + struct pf_kruleset *ruleset; + char *leaf, *p; + int i = 0; + + p = path; + while (*p == '/') + p++; + + ruleset = pf_find_kruleset(p); + leaf = p; + while (ruleset == NULL) { + leaf = strrchr(p, '/'); + if (leaf != NULL) { + *leaf = '\0'; + i++; + ruleset = pf_find_kruleset(p); + } else { + leaf = path; + /* + * if no path component exists, then main ruleset is + * our parent. + */ + ruleset = &pf_main_ruleset; + } + } + + if (path_remainder != NULL) + *path_remainder = leaf; + + /* restore slashes in path. */ + while (i != 0) { + while (*leaf != '\0') + leaf++; + *leaf = '/'; + i--; + } + + return (ruleset); +} + +struct pf_kanchor * +pf_create_kanchor(struct pf_kanchor *parent, const char *aname) +{ + struct pf_kanchor *anchor, *dup; + + if (!*aname || (strlen(aname) >= PF_ANCHOR_NAME_SIZE) || + ((parent != NULL) && (strlen(parent->path) >= PF_ANCHOR_MAXPATH))) + return (NULL); + + anchor = rs_malloc(sizeof(*anchor)); + if (anchor == NULL) + return (NULL); + + RB_INIT(&anchor->children); + strlcpy(anchor->name, aname, sizeof(anchor->name)); + if (parent != NULL) { + /* + * Make sure path for levels 2, 3, ... is terminated by '/': + * 1/2/3/... + */ + strlcpy(anchor->path, parent->path, sizeof(anchor->path)); + strlcat(anchor->path, "/", sizeof(anchor->path)); + } + strlcat(anchor->path, anchor->name, sizeof(anchor->path)); + + if ((dup = RB_INSERT(pf_kanchor_global, &V_pf_anchors, anchor)) != + NULL) { + printf("pf_find_or_create_ruleset: RB_INSERT1 " + "'%s' '%s' collides with '%s' '%s'\n", + anchor->path, anchor->name, dup->path, dup->name); + rs_free(anchor); + return (NULL); + } + + if (parent != NULL) { + anchor->parent = parent; + if ((dup = RB_INSERT(pf_kanchor_node, &parent->children, + anchor)) != NULL) { + printf("pf_find_or_create_ruleset: " + "RB_INSERT2 '%s' '%s' collides with " + "'%s' '%s'\n", anchor->path, anchor->name, + dup->path, dup->name); + RB_REMOVE(pf_kanchor_global, &V_pf_anchors, + anchor); + rs_free(anchor); + return (NULL); + } + } + pf_init_kruleset(&anchor->ruleset); + anchor->ruleset.anchor = anchor; + return (anchor); +} struct pf_kruleset * pf_find_or_create_kruleset(const char *path) { - char *p, *q, *r; + char *p, *aname, *r; struct pf_kruleset *ruleset; - struct pf_kanchor *anchor = NULL, *dup, *parent = NULL; + struct pf_kanchor *anchor = NULL; if (path[0] == 0) return (&pf_main_ruleset); @@ -208,76 +303,31 @@ pf_find_or_create_kruleset(const char *path) if (p == NULL) return (NULL); strlcpy(p, path, MAXPATHLEN); - while (parent == NULL && (q = strrchr(p, '/')) != NULL) { - *q = 0; - if ((ruleset = pf_find_kruleset(p)) != NULL) { - parent = ruleset->anchor; - break; - } - } - if (q == NULL) - q = p; - else - q++; - strlcpy(p, path, MAXPATHLEN); - if (!*q) { - rs_free(p); - return (NULL); - } - while ((r = strchr(q, '/')) != NULL || *q) { + + ruleset = pf_get_leaf_kruleset(p, &aname); + anchor = ruleset->anchor; + + while (*aname == '/') + aname++; + /* + * aname is a path remainder, which contains nodes we must create. We + * process the aname path from left to right, effectively descending + * from parents to children. + */ + while ((r = strchr(aname, '/')) != NULL || *aname) { if (r != NULL) *r = 0; - if (!*q || strlen(q) >= PF_ANCHOR_NAME_SIZE || - (parent != NULL && strlen(parent->path) >= - MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 1)) { - rs_free(p); - return (NULL); - } - anchor = (struct pf_kanchor *)rs_malloc(sizeof(*anchor)); + anchor = pf_create_kanchor(anchor, aname); if (anchor == NULL) { rs_free(p); return (NULL); } - RB_INIT(&anchor->children); - strlcpy(anchor->name, q, sizeof(anchor->name)); - if (parent != NULL) { - strlcpy(anchor->path, parent->path, - sizeof(anchor->path)); - strlcat(anchor->path, "/", sizeof(anchor->path)); - } - strlcat(anchor->path, anchor->name, sizeof(anchor->path)); - if ((dup = RB_INSERT(pf_kanchor_global, &V_pf_anchors, anchor)) != - NULL) { - printf("pf_find_or_create_ruleset: RB_INSERT1 " - "'%s' '%s' collides with '%s' '%s'\n", - anchor->path, anchor->name, dup->path, dup->name); - rs_free(anchor); - rs_free(p); - return (NULL); - } - if (parent != NULL) { - anchor->parent = parent; - if ((dup = RB_INSERT(pf_kanchor_node, &parent->children, - anchor)) != NULL) { - printf("pf_find_or_create_ruleset: " - "RB_INSERT2 '%s' '%s' collides with " - "'%s' '%s'\n", anchor->path, anchor->name, - dup->path, dup->name); - RB_REMOVE(pf_kanchor_global, &V_pf_anchors, - anchor); - rs_free(anchor); - rs_free(p); - return (NULL); - } - } - pf_init_kruleset(&anchor->ruleset); - anchor->ruleset.anchor = anchor; - parent = anchor; - if (r != NULL) - q = r + 1; + if (r == NULL) + break; else - *q = 0; + aname = r + 1; } + rs_free(p); return (&anchor->ruleset); }