Re: git: cfa1a1308709 - main - pfctl: fix recrusive printing of ethernet anchors
Date: Mon, 03 Oct 2022 22:17:49 UTC
Thanks for the report. I’ll try to dig into that in the next couple 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=cfa1a13087096fe93d7a2976015ccda243476a64 >> >> 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 that 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 quick interface etherproto etherfr >> memset(&r, 0, sizeof(r)); >> if (pf->eastack[pf->asd + 1]) { >> - /* move inline rules into relative location */ >> + if ($3 && strchr($3, '/') != 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_int32_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 = opts & PF_OPT_SHOWALL; >> int len = 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 it >> + * to the kernel. >> + */ >> + if ((p = strrchr(anchorname, '/')) != NULL && >> + p[1] == '*' && p[2] == '\0') { >> + p[0] = '\0'; >> + } >> + >> + if (anchorname[0] == '/') { >> + if ((npath = calloc(1, MAXPATHLEN)) == 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 = 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 == EINVAL) { >> + fprintf(stderr, "Anchor '%s' " >> + "not found.\n", anchorname); >> + } else { >> + warn("DIOCGETETHRULESETS"); >> + return (-1); >> + } >> + } >> + mnr = ri.nr; >> + >> + pfctl_print_eth_rule_counters(&rule, opts); >> + for (nr = 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] = '\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 opts, 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 |= 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 == 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