diff options
author | Alexandr Nedvedicky <sashan@cvs.openbsd.org> | 2023-04-28 14:08:39 +0000 |
---|---|---|
committer | Alexandr Nedvedicky <sashan@cvs.openbsd.org> | 2023-04-28 14:08:39 +0000 |
commit | 0d03b2d55c45a6392cde55a16be44706f7bf9af6 (patch) | |
tree | 8098c41c2fc55e4c1540679d0694276a8dac8881 /sbin | |
parent | 37a6fd995540f37a1411dbab338b203f562defc0 (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.c | 32 |
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; } /* |