libpfct: factor out pfctl_get_rules_info()

Introduce pfctl_get_rules_info(), similar to pfctl_get_eth_rules_info()
to retrieve rules information (ticket and total number of rules).

Use the new function in pfctl.

MFC after:	1 week
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D34443
This commit is contained in:
Kristof Provost 2022-03-04 17:12:01 +01:00
parent f0c334e4de
commit 8c1400b0a1
3 changed files with 72 additions and 50 deletions

View File

@ -884,6 +884,28 @@ pfctl_add_rule(int dev, const struct pfctl_rule *r, const char *anchor,
return (ret);
}
int
pfctl_get_rules_info(int dev, struct pfctl_rules_info *rules, uint32_t ruleset,
const char *path)
{
struct pfioc_rule pr;
int ret;
bzero(&pr, sizeof(pr));
if (strlcpy(pr.anchor, path, sizeof(pr.anchor)) >= sizeof(pr.anchor))
return (E2BIG);
pr.rule.action = ruleset;
ret = ioctl(dev, DIOCGETRULES, &pr);
if (ret != 0)
return (ret);
rules->nr = pr.nr;
rules->ticket = pr.ticket;
return (0);
}
int
pfctl_get_rule(int dev, uint32_t nr, uint32_t ticket, const char *anchor,
uint32_t ruleset, struct pfctl_rule *rule, char *anchor_call)

View File

@ -135,6 +135,11 @@ struct pfctl_pool {
uint8_t opts;
};
struct pfctl_rules_info {
uint32_t nr;
uint32_t ticket;
};
struct pfctl_rule {
struct pf_rule_addr src;
struct pf_rule_addr dst;
@ -357,6 +362,8 @@ int pfctl_get_eth_rule(int dev, uint32_t nr, uint32_t ticket,
char *anchor_call);
int pfctl_add_eth_rule(int dev, const struct pfctl_eth_rule *r,
const char *anchor, const char *anchor_call, uint32_t ticket);
int pfctl_get_rules_info(int dev, struct pfctl_rules_info *rules,
uint32_t ruleset, const char *path);
int pfctl_get_rule(int dev, uint32_t nr, uint32_t ticket,
const char *anchor, uint32_t ruleset, struct pfctl_rule *rule,
char *anchor_call);

View File

@ -1133,13 +1133,15 @@ int
pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
char *anchorname, int depth)
{
struct pfioc_rule pr;
struct pfctl_rules_info ri;
struct pfctl_rule rule;
u_int32_t nr, mnr, header = 0;
char anchor_call[MAXPATHLEN];
u_int32_t nr, header = 0;
int rule_numbers = opts & (PF_OPT_VERBOSE2 | PF_OPT_DEBUG);
int numeric = opts & PF_OPT_NUMERIC;
int len = strlen(path);
int brace;
int ret;
char *p;
if (path[0])
@ -1147,39 +1149,35 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
else
snprintf(&path[len], MAXPATHLEN - len, "%s", anchorname);
memset(&pr, 0, sizeof(pr));
memcpy(pr.anchor, path, sizeof(pr.anchor));
if (opts & PF_OPT_SHOWALL) {
pr.rule.action = PF_PASS;
if (ioctl(dev, DIOCGETRULES, &pr)) {
ret = pfctl_get_rules_info(dev, &ri, PF_PASS, anchorname);
if (ret != 0) {
warn("DIOCGETRULES");
goto error;
}
header++;
}
pr.rule.action = PF_SCRUB;
if (ioctl(dev, DIOCGETRULES, &pr)) {
ret = pfctl_get_rules_info(dev, &ri, PF_SCRUB, anchorname);
if (ret != 0) {
warn("DIOCGETRULES");
goto error;
}
if (opts & PF_OPT_SHOWALL) {
if (format == PFCTL_SHOW_RULES && (pr.nr > 0 || header))
if (format == PFCTL_SHOW_RULES && (ri.nr > 0 || header))
pfctl_print_title("FILTER RULES:");
else if (format == PFCTL_SHOW_LABELS && labels)
pfctl_print_title("LABEL COUNTERS:");
}
mnr = pr.nr;
for (nr = 0; nr < mnr; ++nr) {
pr.nr = nr;
if (pfctl_get_clear_rule(dev, nr, pr.ticket, path, PF_SCRUB,
&rule, pr.anchor_call, opts & PF_OPT_CLRRULECTRS)) {
for (nr = 0; nr < ri.nr; ++nr) {
if (pfctl_get_clear_rule(dev, nr, ri.ticket, path, PF_SCRUB,
&rule, anchor_call, opts & PF_OPT_CLRRULECTRS)) {
warn("DIOCGETRULENV");
goto error;
}
if (pfctl_get_pool(dev, &rule.rpool,
nr, pr.ticket, PF_SCRUB, path) != 0)
nr, ri.ticket, PF_SCRUB, path) != 0)
goto error;
switch (format) {
@ -1188,7 +1186,7 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
case PFCTL_SHOW_RULES:
if (rule.label[0] && (opts & PF_OPT_SHOWALL))
labels = 1;
print_rule(&rule, pr.anchor_call, rule_numbers, numeric);
print_rule(&rule, anchor_call, rule_numbers, numeric);
printf("\n");
pfctl_print_rule_counters(&rule, opts);
break;
@ -1197,22 +1195,20 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
}
pfctl_clear_pool(&rule.rpool);
}
pr.rule.action = PF_PASS;
if (ioctl(dev, DIOCGETRULES, &pr)) {
ret = pfctl_get_rules_info(dev, &ri, PF_PASS, anchorname);
if (ret != 0) {
warn("DIOCGETRULES");
goto error;
}
mnr = pr.nr;
for (nr = 0; nr < mnr; ++nr) {
pr.nr = nr;
if (pfctl_get_clear_rule(dev, nr, pr.ticket, path, PF_PASS,
&rule, pr.anchor_call, opts & PF_OPT_CLRRULECTRS)) {
for (nr = 0; nr < ri.nr; ++nr) {
if (pfctl_get_clear_rule(dev, nr, ri.ticket, path, PF_PASS,
&rule, anchor_call, opts & PF_OPT_CLRRULECTRS)) {
warn("DIOCGETRULE");
goto error;
}
if (pfctl_get_pool(dev, &rule.rpool,
nr, pr.ticket, PF_PASS, path) != 0)
nr, ri.ticket, PF_PASS, path) != 0)
goto error;
switch (format) {
@ -1246,18 +1242,18 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
if (rule.label[0] && (opts & PF_OPT_SHOWALL))
labels = 1;
INDENT(depth, !(opts & PF_OPT_VERBOSE));
if (pr.anchor_call[0] &&
((((p = strrchr(pr.anchor_call, '_')) != NULL) &&
((void *)p == (void *)pr.anchor_call ||
if (anchor_call[0] &&
((((p = strrchr(anchor_call, '_')) != NULL) &&
((void *)p == (void *)anchor_call ||
*(--p) == '/')) || (opts & PF_OPT_RECURSE))) {
brace++;
if ((p = strrchr(pr.anchor_call, '/')) !=
if ((p = strrchr(anchor_call, '/')) !=
NULL)
p++;
else
p = &pr.anchor_call[0];
p = &anchor_call[0];
} else
p = &pr.anchor_call[0];
p = &anchor_call[0];
print_rule(&rule, p, rule_numbers, numeric);
if (brace)
@ -1288,55 +1284,52 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
int
pfctl_show_nat(int dev, char *path, int opts, char *anchorname, int depth)
{
struct pfioc_rule pr;
struct pfctl_rules_info ri;
struct pfctl_rule rule;
u_int32_t mnr, nr;
char anchor_call[MAXPATHLEN];
u_int32_t nr;
static int nattype[3] = { PF_NAT, PF_RDR, PF_BINAT };
int i, dotitle = opts & PF_OPT_SHOWALL;
int brace;
int brace, ret;
char *p;
for (i = 0; i < 3; i++) {
memset(&pr, 0, sizeof(pr));
memcpy(pr.anchor, anchorname, sizeof(pr.anchor));
pr.rule.action = nattype[i];
if (ioctl(dev, DIOCGETRULES, &pr)) {
ret = pfctl_get_rules_info(dev, &ri, nattype[i], anchorname);
if (ret != 0) {
warn("DIOCGETRULES");
return (-1);
}
mnr = pr.nr;
for (nr = 0; nr < mnr; ++nr) {
for (nr = 0; nr < ri.nr; ++nr) {
brace = 0;
INDENT(depth, !(opts & PF_OPT_VERBOSE));
pr.nr = nr;
if (pfctl_get_rule(dev, nr, pr.ticket, anchorname,
nattype[i], &rule, pr.anchor_call)) {
if (pfctl_get_rule(dev, nr, ri.ticket, anchorname,
nattype[i], &rule, anchor_call)) {
warn("DIOCGETRULE");
return (-1);
}
if (pfctl_get_pool(dev, &rule.rpool, nr,
pr.ticket, nattype[i], anchorname) != 0)
ri.ticket, nattype[i], anchorname) != 0)
return (-1);
if (pr.anchor_call[0] &&
((((p = strrchr(pr.anchor_call, '_')) != NULL) &&
(p == pr.anchor_call ||
if (anchor_call[0] &&
((((p = strrchr(anchor_call, '_')) != NULL) &&
(p == anchor_call ||
*(--p) == '/')) || (opts & PF_OPT_RECURSE))) {
brace++;
if ((p = strrchr(pr.anchor_call, '/')) !=
if ((p = strrchr(anchor_call, '/')) !=
NULL)
p++;
else
p = &pr.anchor_call[0];
p = &anchor_call[0];
} else
p = &pr.anchor_call[0];
p = &anchor_call[0];
if (dotitle) {
pfctl_print_title("TRANSLATION RULES:");
dotitle = 0;
}
print_rule(&rule, pr.anchor_call,
print_rule(&rule, anchor_call,
opts & PF_OPT_VERBOSE2, opts & PF_OPT_NUMERIC);
if (brace)
printf(" {\n");