From nobody Thu Sep 25 12:41:44 2025 X-Original-To: dev-commits-src-all@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 4cXYHr6rbMz68SZG; Thu, 25 Sep 2025 12:41:44 +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 "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4cXYHr3dz1z42pq; Thu, 25 Sep 2025 12:41:44 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1758804104; 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=acKPsrHgH7obVC+oTP/nWL2li0qFRpBJzBji2OuOu3o=; b=FcFALHfPQIWLLxh8jn2GNekR6ts9QQq4Gi82ld6bparYng6hNaLBAz2aUlt0hs3QzfLhU8 aYVDl5QVeeFGtwAdXUUeNr8BsFUitRXkIjTMhJijIIJGgIoG5BpkoZj37CPqQjqRqoaqei UQX6uJ7UA5Wod/UAJpskGd3pPEuxxROEfyUb3U3MVGgTA18Im+6hfyjMA+EK2IJrUAqjqI u7ldhnMxtWMMzgYHn4PsBPyodle5PyoO+MS8duJA6layC7zrd8zaKDPRotumgAAKor0pMh X6sdkOiFr6l9/ZrXm7aAHhj7EcnAQ9MemdwJ7qwhjE2NdLo0FwkLPPWV/K4l4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1758804104; 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=acKPsrHgH7obVC+oTP/nWL2li0qFRpBJzBji2OuOu3o=; b=jtGWHTK7DRZ26ZuNJkpLAsMniE4C+1fCuFurIdSDG8l5jt2B4E7Ijp5cu6BCYOvxIliU8Z U75RnRKX62clfgdBDDRi/mA/7GvdAefI/l2kq7kfD7+P9hSy3KZ9MUWAJG1x74Dlx7e4jR QpGhANFtG5WiyFGIpJrVs8vDS1pARWoeon/2MzDUyQVhE60j6hd9C9fVR5x0m9+kSF5uNt 6S5nOgJqqkMMhwJ+C0M4rYPGZN+Wj1s2ex/EvTZvm8bTpKagRH853MVfYSSCnkrp2xZ1ha hln2XurmnMtoELhQdA7Isnwy1GidpUWtMV/7UYypX0pHvP2SaupiIZmJhH0ePA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1758804104; a=rsa-sha256; cv=none; b=YnGsfTj8Z5f1I3YzPl8ijvHan47QJLhLO2Hjkf3qV5yQFSQAWmEKr6kuYaSUWPjFw1q99J Sg0TThYso9BJ2G+el+++RlN4RCxsZraVZmLhplYC/Rebll0HO65smC01CvDJ+tlsl8qaDJ M9TVtHTbvC+KUs+07OgJq1J7dT9LMqFEf3OqNDOdcr6hoGvn//O7D5BDax63BYDuDLUltN fV77J551MHpZiq4iZRewFSZY1cTE6HqNuWCxU8Q+Fsju6EVaBdwhoDm4B5hstHlg/n95Zs 4tisVlcOrCFRPHhE5s9yvvzRuyehue7n4TxBYYqCQVhlZXgM5AvEvZ6cq+ECEQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none 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 4cXYHr34fYz1GsW; Thu, 25 Sep 2025 12:41:44 +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 58PCfiGj004752; Thu, 25 Sep 2025 12:41:44 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 58PCfi6X004749; Thu, 25 Sep 2025 12:41:44 GMT (envelope-from git) Date: Thu, 25 Sep 2025 12:41:44 GMT Message-Id: <202509251241.58PCfi6X004749@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: ceff35a3aeef - main - pfctl: fix anchor handling for nat/rdr/binat anchors List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@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: ceff35a3aeef822976bd159c8bc403b68d5571ff Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=ceff35a3aeef822976bd159c8bc403b68d5571ff commit ceff35a3aeef822976bd159c8bc403b68d5571ff Author: Kristof Provost AuthorDate: 2025-08-28 14:26:59 +0000 Commit: Kristof Provost CommitDate: 2025-09-25 12:41:10 +0000 pfctl: fix anchor handling for nat/rdr/binat anchors After the refactoring in 'pfctl: fix once rules' we broke nat/rdr/binat rules. These no longer exist on OpenBSD, so were not considered in that patch. Factor out the common code and call it from all anchor types. Sponsored by: Rubicon Communications, LLC ("Netgate") --- sbin/pfctl/parse.y | 141 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 79 insertions(+), 62 deletions(-) diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index babe6b99013e..0f7702fc4630 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -432,6 +432,7 @@ int filteropts_to_rule(struct pfctl_rule *, struct filter_opts *); struct node_mac* node_mac_from_string(const char *); struct node_mac* node_mac_from_string_masklen(const char *, int); struct node_mac* node_mac_from_string_mask(const char *, const char *); +static bool pfctl_setup_anchor(struct pfctl_rule *, struct pfctl *, char *); static TAILQ_HEAD(loadanchorshead, loadanchors) loadanchorshead = TAILQ_HEAD_INITIALIZER(loadanchorshead); @@ -994,7 +995,6 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto { struct pfctl_rule r; struct node_proto *proto; - char *p; if (check_rulestate(PFCTL_STATE_FILTER)) { if ($2) @@ -1003,68 +1003,9 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto } pfctl_init_rule(&r); + if (! pfctl_setup_anchor(&r, pf, $2)) + YYERROR; - if (pf->astack[pf->asd + 1]) { - if ($2 && strchr($2, '/') != NULL) { - free($2); - yyerror("anchor paths containing '/' " - "cannot be used for inline anchors."); - YYERROR; - } - - /* Move inline rules into relative location. */ - pfctl_anchor_setup(&r, - &pf->astack[pf->asd]->ruleset, - $2 ? $2 : pf->alast->name); - - if (r.anchor == NULL) - err(1, "anchorrule: unable to " - "create ruleset"); - - if (pf->alast != r.anchor) { - if (r.anchor->match) { - yyerror("inline anchor '%s' " - "already exists", - r.anchor->name); - YYERROR; - } - mv_rules(&pf->alast->ruleset, - &r.anchor->ruleset); - mv_tables(pf, &pfr_ktables, r.anchor, pf->alast); - } - pf_remove_if_empty_ruleset(&pf->alast->ruleset); - pf->alast = r.anchor; - } else { - if (!$2) { - yyerror("anchors without explicit " - "rules must specify a name"); - YYERROR; - } - /* - * Don't make non-brace anchors part of the main anchor pool. - */ - if ((r.anchor = calloc(1, sizeof(*r.anchor))) == NULL) { - err(1, "anchorrule: calloc"); - } - pf_init_ruleset(&r.anchor->ruleset); - r.anchor->ruleset.anchor = r.anchor; - if (strlcpy(r.anchor->path, $2, - sizeof(r.anchor->path)) >= sizeof(r.anchor->path)) { - errx(1, "anchorrule: strlcpy"); - } - if ((p = strrchr($2, '/')) != NULL) { - if (strlen(p) == 1) { - yyerror("anchorrule: bad anchor name %s", - $2); - YYERROR; - } - } else - p = $2; - if (strlcpy(r.anchor->name, p, - sizeof(r.anchor->name)) >= sizeof(r.anchor->name)) { - errx(1, "anchorrule: strlcpy"); - } - } r.direction = $3; r.quick = $4.quick; r.af = $6; @@ -1113,6 +1054,8 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto } pfctl_init_rule(&r); + if (! pfctl_setup_anchor(&r, pf, $2)) + YYERROR; r.action = PF_NAT; r.af = $4; @@ -1135,6 +1078,8 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto } pfctl_init_rule(&r); + if (! pfctl_setup_anchor(&r, pf, $2)) + YYERROR; r.action = PF_RDR; r.af = $4; @@ -1178,6 +1123,8 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto } pfctl_init_rule(&r); + if (! pfctl_setup_anchor(&r, pf, $2)) + YYERROR; r.action = PF_BINAT; r.af = $4; @@ -7860,3 +7807,73 @@ filteropts_to_rule(struct pfctl_rule *r, struct filter_opts *opts) return (0); } + +static bool +pfctl_setup_anchor(struct pfctl_rule *r, struct pfctl *pf, char *anchorname) +{ + char *p; + + if (pf->astack[pf->asd + 1]) { + if (anchorname && strchr(anchorname, '/') != NULL) { + free(anchorname); + yyerror("anchor paths containing '/' " + "cannot be used for inline anchors."); + return (false); + } + + /* Move inline rules into relative location. */ + pfctl_anchor_setup(r, + &pf->astack[pf->asd]->ruleset, + anchorname ? anchorname : pf->alast->name); + + if (r->anchor == NULL) + err(1, "anchorrule: unable to " + "create ruleset"); + + if (pf->alast != r->anchor) { + if (r->anchor->match) { + yyerror("inline anchor '%s' " + "already exists", + r->anchor->name); + return (false); + } + mv_rules(&pf->alast->ruleset, + &r->anchor->ruleset); + mv_tables(pf, &pfr_ktables, r->anchor, pf->alast); + } + pf_remove_if_empty_ruleset(&pf->alast->ruleset); + pf->alast = r->anchor; + } else { + if (! anchorname) { + yyerror("anchors without explicit " + "rules must specify a name"); + return (false); + } + /* + * Don't make non-brace anchors part of the main anchor pool. + */ + if ((r->anchor = calloc(1, sizeof(*r->anchor))) == NULL) { + err(1, "anchorrule: calloc"); + } + pf_init_ruleset(&r->anchor->ruleset); + r->anchor->ruleset.anchor = r->anchor; + if (strlcpy(r->anchor->path, anchorname, + sizeof(r->anchor->path)) >= sizeof(r->anchor->path)) { + errx(1, "anchorrule: strlcpy"); + } + if ((p = strrchr(anchorname, '/')) != NULL) { + if (strlen(p) == 1) { + yyerror("anchorrule: bad anchor name %s", + anchorname); + return (false); + } + } else + p = anchorname; + if (strlcpy(r->anchor->name, p, + sizeof(r->anchor->name)) >= sizeof(r->anchor->name)) { + errx(1, "anchorrule: strlcpy"); + } + } + + return (true); +}