Index | Thread | Search

From:
Jon Bentley <wirewhisk@ymail.com>
Subject:
PATCH: Allow 'set queue' in dynamic anchor updates
To:
"tech@openbsd.org" <tech@openbsd.org>
Date:
Mon, 23 Jun 2025 07:43:38 +0000

Download raw body.

Thread
  • Jon Bentley:

    PATCH: Allow 'set queue' in dynamic anchor updates

If you have existing queues and try to dynamically update an anchor with:
   # pfctl -a myanchor -F rules -f myanchor.rules
It will fail on any rules with 'set queue'. This patch preloads queues to fix this.
diff --git sbin/pfctl/pfctl.c sbin/pfctl/pfctl.cindex 96f7b9dac06..dd052bff3d7 100644--- sbin/pfctl/pfctl.c+++ sbin/pfctl/pfctl.c@@ -122,6 +122,9 @@ int pfctl_call_cleartables(int, int, struct pfr_anchoritem *); int    pfctl_call_clearanchors(int, int, struct pfr_anchoritem *); int    pfctl_call_showtables(int, int, struct pfr_anchoritem *);
+/* Preload queues for dynamic anchor updates. */+extern void pfctl_preload_queues(int dev, struct pf_qihead *qhead);+ const char     *clearopt; char           *rulesopt; const char     *showopt;@@ -2970,6 +2973,12 @@ main(int argc, char *argv[])        }
        if (rulesopt != NULL) {+               /* Do we need to pre-load the table and queue definitions? */+               if (anchorname[0]) {+                       /* Preload queues for dynamic anchor updates. */+                        pfctl_preload_queues(dev, &qspecs);+               } /* if (working with an anchor) */+                if (pfctl_rules(dev, rulesopt, opts, optimize,                    anchorname, NULL))                        exit_val = 1;diff --git sbin/pfctl/pfctl_queue.c sbin/pfctl/pfctl_queue.cindex 1f0d456300c..2cb362473e4 100644--- sbin/pfctl/pfctl_queue.c+++ sbin/pfctl/pfctl_queue.c@@ -71,6 +71,9 @@ void                   pfctl_print_queue_nodestat(int, void                    update_avg(struct queue_stats *); char                   *rate2str(double);
+/* Preload queues for dynamic anchor updates. */+void pfctl_preload_queues(int dev, struct pf_qihead *qhead);+ int pfctl_show_queues(int dev, const char *iface, int opts, int verbose2) {@@ -285,3 +288,34 @@ rate2str(double rate)
        return (buf); }++/* Preload queues for dynamic anchor updates. */+void pfctl_preload_queues(int dev, struct pf_qihead *qhead)+{+ struct pfctl_queue_node+   *node;   /* Transfer node. */+ struct pfctl_qsitem+   *qi;     /* Transfer item. */++ /* Pull in the current queue definitions. */+ pfctl_update_qstats(dev);++ /* Loop through each queue. */+ TAILQ_FOREACH(node, &qnodes, entries) {+   /* Allocate and pre-clear a new queue item. */+   qi = calloc(1, sizeof(*qi));++   /* Check for allocation failure. */+   if (qi == NULL)+     err(1, "pfctl_preload_queues: calloc");++   /* Copy over the existing queue specification. */+   bcopy(&node->qs, &qi->qs, sizeof(qi->qs));++   /* Initialize the child pointer. */+   TAILQ_INIT(&qi->children);++   /* Insert this into the main definition. */+   TAILQ_INSERT_TAIL(&qspecs, qi, entries);+ }+} /* pfctl_preload_queues() */