summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorAlexandr Nedvedicky <sashan@cvs.openbsd.org>2023-04-28 14:08:39 +0000
committerAlexandr Nedvedicky <sashan@cvs.openbsd.org>2023-04-28 14:08:39 +0000
commit0d03b2d55c45a6392cde55a16be44706f7bf9af6 (patch)
tree8098c41c2fc55e4c1540679d0694276a8dac8881 /sbin
parent37a6fd995540f37a1411dbab338b203f562defc0 (diff)
This change speeds up DIOCGETRULE ioctl(2) which pfctl(8) uses to
retrieve rules from kernel. The current implementation requires like O((n^2)/2) operation to read the complete rule set, because each DIOCGETRULE operation must iterate over previous n rules to find (n + 1)-th rule to read. To address the issue diff introduces a pf_trans structure to keep pointer to next rule to read, thus reading process does not need to iterate from beginning of rule set to reach the next rule. All transactions opened by process get closed either when process is done (reads all rules) or when /dev/pf device is closed. the diff also comes with lots of improvements from dlg@ and kn@ OK dlg@, kn@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/pfctl/pfctl.c32
1 files changed, 12 insertions, 20 deletions
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 8cbd9d77b4f..bf85aa0e148 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.390 2023/01/06 17:44:33 sashan Exp $ */
+/* $OpenBSD: pfctl.c,v 1.391 2023/04/28 14:08:38 sashan Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -837,7 +837,7 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
char *anchorname, int depth, int wildcard, long shownr)
{
struct pfioc_rule pr;
- u_int32_t nr, mnr, header = 0;
+ u_int32_t header = 0;
int len = strlen(path), ret = 0;
char *npath, *p;
@@ -893,24 +893,9 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
goto error;
}
- if (shownr < 0) {
- mnr = pr.nr;
- nr = 0;
- } else if (shownr < pr.nr) {
- nr = shownr;
- mnr = shownr + 1;
- } else {
- warnx("rule %ld not found", shownr);
- ret = -1;
- goto error;
- }
- for (; nr < mnr; ++nr) {
- pr.nr = nr;
- if (ioctl(dev, DIOCGETRULE, &pr) == -1) {
- warn("DIOCGETRULE");
- ret = -1;
- goto error;
- }
+ while (ioctl(dev, DIOCGETRULE, &pr) != -1) {
+ if (shownr != -1 && shownr != pr.nr)
+ continue;
/* anchor is the same for all rules in it */
if (pr.rule.anchor_wildcard == 0)
@@ -968,6 +953,13 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
case PFCTL_SHOW_NOTHING:
break;
}
+ errno = 0;
+ }
+
+ if (errno != 0 && errno != ENOENT) {
+ warn("DIOCGETRULE");
+ ret = -1;
+ goto error;
}
/*