summaryrefslogtreecommitdiff
path: root/sbin/pfctl
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2003-01-09 17:33:21 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2003-01-09 17:33:21 +0000
commitad5f03ac09ff82fbd25e08695ca1e59e87b3ae77 (patch)
treea28eb3fbe5e7a90783d6e580defd1d0421584dc0 /sbin/pfctl
parentc47d7f93536d14c6893f5d473cc90350959c804a (diff)
first attack at pfctl queue statistics, to be displayed with pfctl -vsq
This commit is dedicated to the cute KLM girls who made part of this possible with giving me a seat in the plane where you actually have enough place to hack. Thanks, girls. ok markus@ dhartmei@
Diffstat (limited to 'sbin/pfctl')
-rw-r--r--sbin/pfctl/Makefile4
-rw-r--r--sbin/pfctl/pfctl.c37
-rw-r--r--sbin/pfctl/pfctl.h17
-rw-r--r--sbin/pfctl/pfctl_altq.c100
-rw-r--r--sbin/pfctl/pfctl_qstats.c277
5 files changed, 285 insertions, 150 deletions
diff --git a/sbin/pfctl/Makefile b/sbin/pfctl/Makefile
index 73c1a969f0a..073484f978a 100644
--- a/sbin/pfctl/Makefile
+++ b/sbin/pfctl/Makefile
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile,v 1.11 2003/01/03 21:37:44 cedric Exp $
+# $OpenBSD: Makefile,v 1.12 2003/01/09 17:33:19 henning Exp $
PROG= pfctl
SRCS= pfctl.c parse.y pfctl_parser.c pf_print_state.c pfctl_altq.c
-SRCS+= pfctl_radix.c pfctl_table.c
+SRCS+= pfctl_radix.c pfctl_table.c pfctl_qstats.c
CFLAGS+= -Wall -Wmissing-prototypes -Wno-uninitialized
CFLAGS+= -Wstrict-prototypes
YFLAGS=
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 3e673c6a8cb..ded52ec4e3d 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.126 2003/01/09 10:40:44 cedric Exp $ */
+/* $OpenBSD: pfctl.c,v 1.127 2003/01/09 17:33:19 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -67,7 +67,6 @@ void pfctl_clear_pool(struct pf_pool *);
void pfctl_print_rule_counters(struct pf_rule *, int);
int pfctl_show_rules(int, int, int);
int pfctl_show_nat(int, int);
-int pfctl_show_altq(int);
int pfctl_show_states(int, u_int8_t, int);
int pfctl_show_status(int);
int pfctl_show_timeouts(int);
@@ -604,36 +603,6 @@ pfctl_show_rules(int dev, int opts, int format)
}
int
-pfctl_show_altq(int dev)
-{
- struct pf_altq_node *root = NULL;
-
- struct pfioc_altq pa;
- u_int32_t mnr, nr;
-
- if (!altqsupport)
- return (-1);
- memset(&pa, 0, sizeof(pa));
- if (ioctl(dev, DIOCGETALTQS, &pa)) {
- warn("DIOCGETALTQS");
- return (-1);
- }
- mnr = pa.nr;
- for (nr = 0; nr < mnr; ++nr) {
- pa.nr = nr;
- if (ioctl(dev, DIOCGETALTQ, &pa)) {
- warn("DIOCGETALTQ");
- return (-1);
- }
- pfctl_insert_altq_node(&root, pa.altq);
- }
- for (; root != NULL; root = root->next)
- pfctl_print_altq_node(root, 0);
- pfctl_free_altq_node(root);
- return (0);
-}
-
-int
pfctl_show_nat(int dev, int opts)
{
struct pfioc_rule pr;
@@ -1467,7 +1436,7 @@ main(int argc, char *argv[])
pfctl_show_nat(dev, opts);
break;
case 'q':
- pfctl_show_altq(dev);
+ pfctl_show_altq(dev, opts);
break;
case 's':
pfctl_show_states(dev, 0, opts);
@@ -1484,7 +1453,7 @@ main(int argc, char *argv[])
case 'a':
pfctl_show_rules(dev, opts, 0);
pfctl_show_nat(dev, opts);
- pfctl_show_altq(dev);
+ pfctl_show_altq(dev, opts);
pfctl_show_states(dev, 0, opts);
pfctl_show_status(dev);
pfctl_show_rules(dev, opts, 1);
diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h
index 0d6f1f3161b..dd37cffb94b 100644
--- a/sbin/pfctl/pfctl.h
+++ b/sbin/pfctl/pfctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.h,v 1.4 2003/01/09 10:40:44 cedric Exp $ */
+/* $OpenBSD: pfctl.h,v 1.5 2003/01/09 17:33:19 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -58,6 +58,7 @@ int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
int pfctl_clear_tables(int);
int pfctl_show_tables(int);
int pfctl_command_tables(int, char *[], char *, char *, char *, int);
+int pfctl_show_altq(int, int);
#ifndef DEFAULT_PRIORITY
#define DEFAULT_PRIORITY 1
@@ -75,20 +76,6 @@ struct segment {
double x, y, d, m;
};
-struct pf_altq_node {
- struct pf_altq altq;
- struct pf_altq_node *next;
- struct pf_altq_node *children;
-};
-
-void pfctl_insert_altq_node(struct pf_altq_node **,
- const struct pf_altq);
-struct pf_altq_node *pfctl_find_altq_node(struct pf_altq_node *,
- const char *, const char *);
-void pfctl_print_altq_node(const struct pf_altq_node *,
- unsigned);
-void pfctl_free_altq_node(struct pf_altq_node *);
-
int check_commit_altq(int, int);
void pfaltq_store(struct pf_altq *);
void pfaltq_free(struct pf_altq *);
diff --git a/sbin/pfctl/pfctl_altq.c b/sbin/pfctl/pfctl_altq.c
index 73e53532c03..c31af54f90c 100644
--- a/sbin/pfctl/pfctl_altq.c
+++ b/sbin/pfctl/pfctl_altq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_altq.c,v 1.30 2003/01/05 02:17:09 dhartmei Exp $ */
+/* $OpenBSD: pfctl_altq.c,v 1.31 2003/01/09 17:33:19 henning Exp $ */
/*
* Copyright (C) 2002
@@ -1003,104 +1003,6 @@ sc_x2y(struct service_curve *sc, double x)
return (y);
}
-void
-pfctl_insert_altq_node(struct pf_altq_node **root,
- const struct pf_altq altq)
-{
- struct pf_altq_node *node;
-
- node = calloc(1, sizeof(struct pf_altq_node));
- if (node == NULL)
- err(1, "pfctl_insert_altq_node: calloc");
- memcpy(&node->altq, &altq, sizeof(struct pf_altq));
- node->next = node->children = NULL;
-
- if (*root == NULL)
- *root = node;
- else if (!altq.parent[0]) {
- struct pf_altq_node *prev = *root;
-
- while (prev->next != NULL)
- prev = prev->next;
- prev->next = node;
- } else {
- struct pf_altq_node *parent;
-
- parent = pfctl_find_altq_node(*root, altq.parent, altq.ifname);
- if (parent == NULL)
- errx(1, "parent %s not found", altq.parent);
- if (parent->children == NULL)
- parent->children = node;
- else {
- struct pf_altq_node *prev = parent->children;
-
- while (prev->next != NULL)
- prev = prev->next;
- prev->next = node;
- }
- }
-}
-
-struct pf_altq_node *
-pfctl_find_altq_node(struct pf_altq_node *root, const char *qname,
- const char *ifname)
-{
- struct pf_altq_node *node, *child;
-
- for (node = root; node != NULL; node = node->next) {
- if (!strcmp(node->altq.qname, qname) &&
- !(strcmp(node->altq.ifname, ifname)))
- return (node);
- if (node->children != NULL) {
- child = pfctl_find_altq_node(node->children, qname,
- ifname);
- if (child != NULL)
- return (child);
- }
- }
- return (NULL);
-}
-
-void
-pfctl_print_altq_node(const struct pf_altq_node *node, unsigned level)
-{
- const struct pf_altq_node *child;
-
- if (node == NULL)
- return;
-
- print_altq(&node->altq, level);
-
- if (node->children != NULL) {
- printf("{");
- for (child = node->children; child != NULL;
- child = child->next) {
- printf("%s", child->altq.qname);
- if (child->next != NULL)
- printf(", ");
- }
- printf("}");
- }
- printf("\n");
- for (child = node->children; child != NULL;
- child = child->next)
- pfctl_print_altq_node(child, level+1);
-}
-
-void
-pfctl_free_altq_node(struct pf_altq_node *node)
-{
- while (node != NULL) {
- struct pf_altq_node *prev;
-
- if (node->children != NULL)
- pfctl_free_altq_node(node->children);
- prev = node;
- node = node->next;
- free(prev);
- }
-}
-
/*
* misc utilities
*/
diff --git a/sbin/pfctl/pfctl_qstats.c b/sbin/pfctl/pfctl_qstats.c
new file mode 100644
index 00000000000..e63b76bdbdc
--- /dev/null
+++ b/sbin/pfctl/pfctl_qstats.c
@@ -0,0 +1,277 @@
+/* $OpenBSD: pfctl_qstats.c,v 1.1 2003/01/09 17:33:20 henning Exp $ */
+
+/*
+ * Copyright (c) 2003 Henning Brauer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <net/pfvar.h>
+#include <arpa/inet.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <altq/altq.h>
+#include <altq/altq_cbq.h>
+#include <altq/altq_priq.h>
+#include <altq/altq_hfsc.h>
+
+#include "pfctl_parser.h"
+#include "pfctl.h"
+
+union class_stats {
+ class_stats_t cbq_stats;
+ struct priq_classstats priq_stats;
+ struct hfsc_classstats hfsc_stats;
+ struct timeval timestamp;
+};
+
+struct pf_altq_node {
+ struct pf_altq altq;
+ struct pf_altq_node *next;
+ struct pf_altq_node *children;
+ union class_stats qstats;
+ union class_stats qstats_last;
+};
+
+int pfctl_update_qstats(int, struct pf_altq_node **);
+void pfctl_insert_altq_node(struct pf_altq_node **,
+ const struct pf_altq, const union class_stats);
+struct pf_altq_node *pfctl_find_altq_node(struct pf_altq_node *,
+ const char *, const char *);
+void pfctl_print_altq_node(int, const struct pf_altq_node *,
+ unsigned, int);
+void print_cbqstats(class_stats_t);
+void pfctl_free_altq_node(struct pf_altq_node *);
+void pfctl_print_altq_nodestat(int,
+ const struct pf_altq_node *);
+
+int
+pfctl_show_altq(int dev, int opts)
+{
+ struct pf_altq_node *root = NULL, *node;
+
+ if (pfctl_update_qstats(dev, &root))
+ return (-1);
+
+ for (node = root; node != NULL; node = node->next)
+ pfctl_print_altq_node(dev, node, 0, opts & PF_OPT_VERBOSE);
+ pfctl_free_altq_node(root);
+ return (0);
+}
+
+int
+pfctl_update_qstats(int dev, struct pf_altq_node **root)
+{
+ struct pf_altq_node *node;
+ struct pfioc_altq pa;
+ struct pfioc_qstats pq;
+ u_int32_t mnr, nr;
+ union class_stats qstats;
+
+ memset(&pa, 0, sizeof(pa));
+ memset(&pq, 0, sizeof(pq));
+ memset(&qstats, 0, sizeof(qstats));
+ if (ioctl(dev, DIOCGETALTQS, &pa)) {
+ warn("DIOCGETALTQS");
+ return (-1);
+ }
+ mnr = pa.nr;
+ for (nr = 0; nr < mnr; ++nr) {
+ pa.nr = nr;
+ if (ioctl(dev, DIOCGETALTQ, &pa)) {
+ warn("DIOCGETALTQ");
+ return (-1);
+ }
+ if (pa.altq.qid > 0) {
+ pq.nr = nr;
+ pq.ticket = pa.ticket;
+ pq.buf = &qstats;
+ pq.nbytes = sizeof(qstats);
+ if (ioctl(dev, DIOCGETQSTATS, &pq)) {
+ warn("DIOCGETQSTATS");
+ return (-1);
+ }
+ gettimeofday(&qstats.timestamp, NULL);
+ if ((node = pfctl_find_altq_node(*root, pa.altq.qname,
+ pa.altq.ifname)) != NULL) {
+ memcpy(&node->qstats_last, &node->qstats,
+ sizeof(union class_stats));
+ memcpy(&node->qstats, &qstats,
+ sizeof(union class_stats));
+ } else
+ pfctl_insert_altq_node(root, pa.altq, qstats);
+ }
+ }
+ return (0);
+}
+
+void
+pfctl_insert_altq_node(struct pf_altq_node **root,
+ const struct pf_altq altq, const union class_stats qstats)
+{
+ struct pf_altq_node *node;
+
+ node = calloc(1, sizeof(struct pf_altq_node));
+ if (node == NULL) {
+ errx(1, "pfctl_insert_altq_node: calloc");
+ return;
+ }
+ memcpy(&node->altq, &altq, sizeof(struct pf_altq));
+ memcpy(&node->qstats, &qstats, sizeof(union class_stats));
+ node->next = node->children = NULL;
+
+ if (*root == NULL)
+ *root = node;
+ else if (!altq.parent[0]) {
+ struct pf_altq_node *prev = *root;
+
+ while (prev->next != NULL)
+ prev = prev->next;
+ prev->next = node;
+ } else {
+ struct pf_altq_node *parent;
+
+ parent = pfctl_find_altq_node(*root, altq.parent, altq.ifname);
+ if (parent == NULL) {
+ errx(1, "parent %s not found", altq.parent);
+ return;
+ }
+ if (parent->children == NULL)
+ parent->children = node;
+ else {
+ struct pf_altq_node *prev = parent->children;
+
+ while (prev->next != NULL)
+ prev = prev->next;
+ prev->next = node;
+ }
+ }
+}
+
+struct pf_altq_node *
+pfctl_find_altq_node(struct pf_altq_node *root, const char *qname,
+ const char *ifname)
+{
+ struct pf_altq_node *node, *child;
+
+ for (node = root; node != NULL; node = node->next) {
+ if (!strcmp(node->altq.qname, qname)
+ && !(strcmp(node->altq.ifname, ifname)))
+ return (node);
+ if (node->children != NULL) {
+ child = pfctl_find_altq_node(node->children, qname,
+ ifname);
+ if (child != NULL)
+ return (child);
+ }
+ }
+ return (NULL);
+}
+
+void
+pfctl_print_altq_node(int dev, const struct pf_altq_node *node, unsigned level,
+ int verbose)
+{
+ const struct pf_altq_node *child;
+
+ if (node == NULL)
+ return;
+
+ print_altq(&node->altq, level);
+
+ if (node->children != NULL) {
+ printf("{");
+ for (child = node->children; child != NULL;
+ child = child->next) {
+ printf("%s", child->altq.qname);
+ if (child->next != NULL)
+ printf(", ");
+ }
+ printf("}");
+ }
+ printf("\n");
+
+ if (verbose)
+ pfctl_print_altq_nodestat(dev, node);
+
+ for (child = node->children; child != NULL;
+ child = child->next)
+ pfctl_print_altq_node(dev, child, level+1, verbose);
+}
+
+void
+pfctl_print_altq_nodestat(int dev, const struct pf_altq_node *a)
+{
+ if (a->altq.qid == 0)
+ return;
+
+ switch (a->altq.scheduler) {
+ case ALTQT_CBQ:
+ print_cbqstats(a->qstats.cbq_stats);
+ break;
+ case ALTQT_PRIQ:
+ break;
+ }
+}
+
+void
+print_cbqstats(class_stats_t qstats)
+{
+ printf("[ pkts: %10llu bytes: %10llu "
+ "dropped pkts: %6llu bytes: %6llu ]\n",
+ qstats.xmit_cnt.packets, qstats.xmit_cnt.bytes,
+ qstats.drop_cnt.packets, qstats.drop_cnt.bytes);
+ printf("[ qcount: %3d/%3d borrows: %6u suspends: %6u ]\n",
+ qstats.qcnt, qstats.qmax, qstats.borrows, qstats.delays);
+}
+
+
+void
+pfctl_free_altq_node(struct pf_altq_node *node)
+{
+ while (node != NULL) {
+ struct pf_altq_node *prev;
+
+ if (node->children != NULL)
+ pfctl_free_altq_node(node->children);
+ prev = node;
+ node = node->next;
+ free(prev);
+ }
+}