Download raw body.
[PATCH] Allow 'set queue' in dynamic anchor updates (v2)
On 2025/06/23 08:27, Jon Bentley wrote:
> (n.b. I really hate it when I forget to switch to text mode. Sorry about that!)
> (Thank you to Omar for pointing out my idiocy. :-)
In both cases, the diff is mangled, whitespace is not maintained
(tabs were converted to spaces).
> 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.c
> index 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.c
> index 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() */
>
[PATCH] Allow 'set queue' in dynamic anchor updates (v2)