Date: Mon, 03 Oct 2022 23:17:49 +0100 From: Kristof Provost <kp@FreeBSD.org> To: Bryan Drewery <bdrewery@FreeBSD.org> Cc: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org, matteo@freebsd.org Subject: Re: git: cfa1a1308709 - main - pfctl: fix recrusive printing of ethernet anchors Message-ID: <46F2B94F-DBCB-4E55-8055-051393C900C8@FreeBSD.org> In-Reply-To: <3fd7be3f-90b1-ae87-1b4e-8b183acf1a9c@FreeBSD.org> References: <202209061119.286BJnOV024965@gitrepo.freebsd.org> <3fd7be3f-90b1-ae87-1b4e-8b183acf1a9c@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Thanks for the report. I=E2=80=99ll try to dig into that in the next coup= le of days. Best regards, Kristof On 3 Oct 2022, at 18:13, Bryan Drewery wrote: > I think there's still a problem here. > > pfctl -a '*' -sr works > pfctl -a 'name/*' -sr does not. > > On 9/6/2022 4:19 AM, Kristof Provost wrote: >> The branch main has been updated by kp: >> >> URL: https://cgit.FreeBSD.org/src/commit/?id=3Dcfa1a13087096fe93d7a297= 6015ccda243476a64 >> >> commit cfa1a13087096fe93d7a2976015ccda243476a64 >> Author: Kristof Provost <kp@FreeBSD.org> >> AuthorDate: 2022-09-01 09:45:19 +0000 >> Commit: Kristof Provost <kp@FreeBSD.org> >> CommitDate: 2022-09-06 11:19:10 +0000 >> >> pfctl: fix recrusive printing of ethernet anchors >> Similar to the preceding fix for layer three rules, ensure th= at we >> recursively list wildcard anchors for ethernet rules. >> MFC after: 3 weeks >> Sponsored by: Rubicon Communications, LLC ("Netgate") >> Differential Revision: https://reviews.freebsd.org/D36417 >> --- >> sbin/pfctl/parse.y | 9 ++++++- >> sbin/pfctl/pfctl.c | 79 ++++++++++++++++++++++++++++++++++++++++++++= +--------- >> 2 files changed, 75 insertions(+), 13 deletions(-) >> >> diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y >> index 5d0320e909fb..eea9f89782be 100644 >> --- a/sbin/pfctl/parse.y >> +++ b/sbin/pfctl/parse.y >> @@ -1276,7 +1276,14 @@ etheranchorrule : ETHER ANCHOR anchorname dir q= uick interface etherproto etherfr >> memset(&r, 0, sizeof(r)); >> if (pf->eastack[pf->asd + 1]) { >> - /* move inline rules into relative location */ >> + if ($3 && strchr($3, '/') !=3D NULL) { >> + free($3); >> + yyerror("anchor paths containing '/' " >> + "cannot be used for inline anchors."); >> + YYERROR; >> + } >> + >> + /* Move inline rules into relative location. */ >> pfctl_eth_anchor_setup(pf, &r, >> &pf->eastack[pf->asd]->ruleset, >> $3 ? $3 : pf->ealast->name); >> diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c >> index 0445fdd32ea7..bc6f14e1c197 100644 >> --- a/sbin/pfctl/pfctl.c >> +++ b/sbin/pfctl/pfctl.c >> @@ -99,7 +99,7 @@ int pfctl_get_pool(int, struct pfctl_pool *, u_int3= 2_t, u_int32_t, int, >> char *); >> void pfctl_print_eth_rule_counters(struct pfctl_eth_rule *, int); >> void pfctl_print_rule_counters(struct pfctl_rule *, int); >> -int pfctl_show_eth_rules(int, char *, int, enum pfctl_show, char *, = int); >> +int pfctl_show_eth_rules(int, char *, int, enum pfctl_show, char *, = int, int); >> int pfctl_show_rules(int, char *, int, enum pfctl_show, char *, int= , int); >> int pfctl_show_nat(int, char *, int, char *, int); >> int pfctl_show_src_nodes(int, int); >> @@ -1091,20 +1091,73 @@ pfctl_print_title(char *title) >> int >> pfctl_show_eth_rules(int dev, char *path, int opts, enum pfctl_show = format, >> - char *anchorname, int depth) >> + char *anchorname, int depth, int wildcard) >> { >> char anchor_call[MAXPATHLEN]; >> struct pfctl_eth_rules_info info; >> struct pfctl_eth_rule rule; >> + int brace; >> int dotitle =3D opts & PF_OPT_SHOWALL; >> int len =3D strlen(path); >> - int brace; >> - char *p; >> + char *npath, *p; >> - if (path[0]) >> - snprintf(&path[len], MAXPATHLEN - len, "/%s", anchorname); >> - else >> - snprintf(&path[len], MAXPATHLEN - len, "%s", anchorname); >> + /* >> + * Truncate a trailing / and * on an anchorname before searching for= >> + * the ruleset, this is syntactic sugar that doesn't actually make i= t >> + * to the kernel. >> + */ >> + if ((p =3D strrchr(anchorname, '/')) !=3D NULL && >> + p[1] =3D=3D '*' && p[2] =3D=3D '\0') { >> + p[0] =3D '\0'; >> + } >> + >> + if (anchorname[0] =3D=3D '/') { >> + if ((npath =3D calloc(1, MAXPATHLEN)) =3D=3D NULL) >> + errx(1, "pfctl_rules: calloc"); >> + snprintf(npath, MAXPATHLEN, "%s", anchorname); >> + } else { >> + if (path[0]) >> + snprintf(&path[len], MAXPATHLEN - len, "/%s", anchorname); >> + else >> + snprintf(&path[len], MAXPATHLEN - len, "%s", anchorname); >> + npath =3D path; >> + } >> + >> + /* >> + * If this anchor was called with a wildcard path, go through >> + * the rulesets in the anchor rather than the rules. >> + */ >> + if (wildcard && (opts & PF_OPT_RECURSE)) { >> + struct pfctl_eth_rulesets_info ri; >> + u_int32_t mnr, nr; >> + >> + if (pfctl_get_eth_rulesets_info(dev, &ri, npath)) { >> + if (errno =3D=3D EINVAL) { >> + fprintf(stderr, "Anchor '%s' " >> + "not found.\n", anchorname); >> + } else { >> + warn("DIOCGETETHRULESETS"); >> + return (-1); >> + } >> + } >> + mnr =3D ri.nr; >> + >> + pfctl_print_eth_rule_counters(&rule, opts); >> + for (nr =3D 0; nr < mnr; ++nr) { >> + struct pfctl_eth_ruleset_info rs; >> + >> + if (pfctl_get_eth_ruleset(dev, npath, nr, &rs)) >> + err(1, "DIOCGETETHRULESET"); >> + INDENT(depth, !(opts & PF_OPT_VERBOSE)); >> + printf("anchor \"%s\" all {\n", rs.name); >> + pfctl_show_eth_rules(dev, npath, opts, >> + format, rs.name, depth + 1, 0); >> + INDENT(depth, !(opts & PF_OPT_VERBOSE)); >> + printf("}\n"); >> + } >> + path[len] =3D '\0'; >> + return (0); >> + } >> if (pfctl_get_eth_rules_info(dev, &info, path)) { >> warn("DIOCGETETHRULES"); >> @@ -1141,7 +1194,7 @@ pfctl_show_eth_rules(int dev, char *path, int op= ts, enum pfctl_show format, >> pfctl_print_eth_rule_counters(&rule, opts); >> if (brace) { >> pfctl_show_eth_rules(dev, path, opts, format, >> - p, depth + 1); >> + p, depth + 1, rule.anchor_wildcard); >> INDENT(depth, !(opts & PF_OPT_VERBOSE)); >> printf("}\n"); >> } >> @@ -2988,13 +3041,15 @@ main(int argc, char *argv[]) >> pfctl_show_limits(dev, opts); >> break; >> case 'e': >> - pfctl_show_eth_rules(dev, path, opts, 0, anchorname, 0); >> + pfctl_show_eth_rules(dev, path, opts, 0, anchorname, 0, >> + 0); >> break; >> case 'a': >> opts |=3D PF_OPT_SHOWALL; >> pfctl_load_fingerprints(dev, opts); >> - pfctl_show_eth_rules(dev, path, opts, 0, anchorname, 0); >> + pfctl_show_eth_rules(dev, path, opts, 0, anchorname, 0, >> + 0); >> pfctl_show_nat(dev, path, opts, anchorname, 0); >> pfctl_show_rules(dev, path, opts, 0, anchorname, 0, 0); >> @@ -3023,7 +3078,7 @@ main(int argc, char *argv[]) >> if ((opts & PF_OPT_CLRRULECTRS) && showopt =3D=3D NULL) { >> pfctl_show_eth_rules(dev, path, opts, PFCTL_SHOW_NOTHING, >> - anchorname, 0); >> + anchorname, 0, 0); >> pfctl_show_rules(dev, path, opts, PFCTL_SHOW_NOTHING, >> anchorname, 0, 0); >> } > > -- = > Bryan Drewery
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?46F2B94F-DBCB-4E55-8055-051393C900C8>