Download raw body.
[PATCH] Allow 'set queue' in dynamic anchor updates (v2)
(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. :-)
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)