Deleted Added
full compact
pfctl_qstats.c (126354) pfctl_qstats.c (126355)
1/* $FreeBSD: head/contrib/pf/pfctl/pfctl_qstats.c 126355 2004-02-28 17:32:53Z mlaier $ */
1/* $OpenBSD: pfctl_qstats.c,v 1.24 2003/07/31 09:46:08 kjc Exp $ */
2
3/*
4 * Copyright (c) Henning Brauer <henning@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20#include <sys/ioctl.h>
21#include <sys/socket.h>
22
23#include <net/if.h>
24#include <netinet/in.h>
25#include <net/pfvar.h>
26#include <arpa/inet.h>
27
28#include <err.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <unistd.h>
33
34#include <altq/altq.h>
35#include <altq/altq_cbq.h>
36#include <altq/altq_priq.h>
37#include <altq/altq_hfsc.h>
38
2/* $OpenBSD: pfctl_qstats.c,v 1.24 2003/07/31 09:46:08 kjc Exp $ */
3
4/*
5 * Copyright (c) Henning Brauer <henning@openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <sys/types.h>
21#include <sys/ioctl.h>
22#include <sys/socket.h>
23
24#include <net/if.h>
25#include <netinet/in.h>
26#include <net/pfvar.h>
27#include <arpa/inet.h>
28
29#include <err.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <unistd.h>
34
35#include <altq/altq.h>
36#include <altq/altq_cbq.h>
37#include <altq/altq_priq.h>
38#include <altq/altq_hfsc.h>
39
40#if defined(__FreeBSD__)
41#include <inttypes.h>
42#else
43#define PRIu64 "llu"
44#endif
45
39#include "pfctl.h"
40#include "pfctl_parser.h"
41
42union class_stats {
43 class_stats_t cbq_stats;
44 struct priq_classstats priq_stats;
45 struct hfsc_classstats hfsc_stats;
46};
47
48#define AVGN_MAX 8
49#define STAT_INTERVAL 5
50
51struct queue_stats {
52 union class_stats data;
53 int avgn;
54 double avg_bytes;
55 double avg_packets;
56 u_int64_t prev_bytes;
57 u_int64_t prev_packets;
58};
59
60struct pf_altq_node {
61 struct pf_altq altq;
62 struct pf_altq_node *next;
63 struct pf_altq_node *children;
64 struct queue_stats qstats;
65};
66
67int pfctl_update_qstats(int, struct pf_altq_node **);
68void pfctl_insert_altq_node(struct pf_altq_node **,
69 const struct pf_altq, const struct queue_stats);
70struct pf_altq_node *pfctl_find_altq_node(struct pf_altq_node *,
71 const char *, const char *);
72void pfctl_print_altq_node(int, const struct pf_altq_node *,
73 unsigned, int);
74void print_cbqstats(struct queue_stats);
75void print_priqstats(struct queue_stats);
76void print_hfscstats(struct queue_stats);
77void pfctl_free_altq_node(struct pf_altq_node *);
78void pfctl_print_altq_nodestat(int,
79 const struct pf_altq_node *);
80
81void update_avg(struct pf_altq_node *);
82
83int
84pfctl_show_altq(int dev, int opts, int verbose2)
85{
86 struct pf_altq_node *root = NULL, *node;
87
46#include "pfctl.h"
47#include "pfctl_parser.h"
48
49union class_stats {
50 class_stats_t cbq_stats;
51 struct priq_classstats priq_stats;
52 struct hfsc_classstats hfsc_stats;
53};
54
55#define AVGN_MAX 8
56#define STAT_INTERVAL 5
57
58struct queue_stats {
59 union class_stats data;
60 int avgn;
61 double avg_bytes;
62 double avg_packets;
63 u_int64_t prev_bytes;
64 u_int64_t prev_packets;
65};
66
67struct pf_altq_node {
68 struct pf_altq altq;
69 struct pf_altq_node *next;
70 struct pf_altq_node *children;
71 struct queue_stats qstats;
72};
73
74int pfctl_update_qstats(int, struct pf_altq_node **);
75void pfctl_insert_altq_node(struct pf_altq_node **,
76 const struct pf_altq, const struct queue_stats);
77struct pf_altq_node *pfctl_find_altq_node(struct pf_altq_node *,
78 const char *, const char *);
79void pfctl_print_altq_node(int, const struct pf_altq_node *,
80 unsigned, int);
81void print_cbqstats(struct queue_stats);
82void print_priqstats(struct queue_stats);
83void print_hfscstats(struct queue_stats);
84void pfctl_free_altq_node(struct pf_altq_node *);
85void pfctl_print_altq_nodestat(int,
86 const struct pf_altq_node *);
87
88void update_avg(struct pf_altq_node *);
89
90int
91pfctl_show_altq(int dev, int opts, int verbose2)
92{
93 struct pf_altq_node *root = NULL, *node;
94
95#if defined(__FreeBSD__)
96 if (!altqsupport)
97 return (-1);
98#endif
88 if (pfctl_update_qstats(dev, &root))
89 return (-1);
90
91 for (node = root; node != NULL; node = node->next)
92 pfctl_print_altq_node(dev, node, 0, opts);
93
94 while (verbose2) {
95 printf("\n");
96 fflush(stdout);
97 sleep(STAT_INTERVAL);
98 if (pfctl_update_qstats(dev, &root))
99 return (-1);
100 for (node = root; node != NULL; node = node->next)
101 pfctl_print_altq_node(dev, node, 0, opts);
102 }
103 pfctl_free_altq_node(root);
104 return (0);
105}
106
107int
108pfctl_update_qstats(int dev, struct pf_altq_node **root)
109{
110 struct pf_altq_node *node;
111 struct pfioc_altq pa;
112 struct pfioc_qstats pq;
113 u_int32_t mnr, nr;
114 struct queue_stats qstats;
115 static u_int32_t last_ticket;
116
117 memset(&pa, 0, sizeof(pa));
118 memset(&pq, 0, sizeof(pq));
119 memset(&qstats, 0, sizeof(qstats));
120 if (ioctl(dev, DIOCGETALTQS, &pa)) {
121 warn("DIOCGETALTQS");
122 return (-1);
123 }
124
125 /* if a new set is found, start over */
126 if (pa.ticket != last_ticket && *root != NULL) {
127 pfctl_free_altq_node(*root);
128 *root = NULL;
129 }
130 last_ticket = pa.ticket;
131
132 mnr = pa.nr;
133 for (nr = 0; nr < mnr; ++nr) {
134 pa.nr = nr;
135 if (ioctl(dev, DIOCGETALTQ, &pa)) {
136 warn("DIOCGETALTQ");
137 return (-1);
138 }
139 if (pa.altq.qid > 0) {
140 pq.nr = nr;
141 pq.ticket = pa.ticket;
142 pq.buf = &qstats.data;
143 pq.nbytes = sizeof(qstats.data);
144 if (ioctl(dev, DIOCGETQSTATS, &pq)) {
145 warn("DIOCGETQSTATS");
146 return (-1);
147 }
148 if ((node = pfctl_find_altq_node(*root, pa.altq.qname,
149 pa.altq.ifname)) != NULL) {
150 memcpy(&node->qstats.data, &qstats.data,
151 sizeof(qstats.data));
152 update_avg(node);
153 } else {
154 pfctl_insert_altq_node(root, pa.altq, qstats);
155 }
156 }
157 }
158 return (0);
159}
160
161void
162pfctl_insert_altq_node(struct pf_altq_node **root,
163 const struct pf_altq altq, const struct queue_stats qstats)
164{
165 struct pf_altq_node *node;
166
167 node = calloc(1, sizeof(struct pf_altq_node));
168 if (node == NULL)
169 err(1, "pfctl_insert_altq_node: calloc");
170 memcpy(&node->altq, &altq, sizeof(struct pf_altq));
171 memcpy(&node->qstats, &qstats, sizeof(qstats));
172 node->next = node->children = NULL;
173
174 if (*root == NULL)
175 *root = node;
176 else if (!altq.parent[0]) {
177 struct pf_altq_node *prev = *root;
178
179 while (prev->next != NULL)
180 prev = prev->next;
181 prev->next = node;
182 } else {
183 struct pf_altq_node *parent;
184
185 parent = pfctl_find_altq_node(*root, altq.parent, altq.ifname);
186 if (parent == NULL)
187 errx(1, "parent %s not found", altq.parent);
188 if (parent->children == NULL)
189 parent->children = node;
190 else {
191 struct pf_altq_node *prev = parent->children;
192
193 while (prev->next != NULL)
194 prev = prev->next;
195 prev->next = node;
196 }
197 }
198 update_avg(node);
199}
200
201struct pf_altq_node *
202pfctl_find_altq_node(struct pf_altq_node *root, const char *qname,
203 const char *ifname)
204{
205 struct pf_altq_node *node, *child;
206
207 for (node = root; node != NULL; node = node->next) {
208 if (!strcmp(node->altq.qname, qname)
209 && !(strcmp(node->altq.ifname, ifname)))
210 return (node);
211 if (node->children != NULL) {
212 child = pfctl_find_altq_node(node->children, qname,
213 ifname);
214 if (child != NULL)
215 return (child);
216 }
217 }
218 return (NULL);
219}
220
221void
222pfctl_print_altq_node(int dev, const struct pf_altq_node *node, unsigned level,
223 int opts)
224{
225 const struct pf_altq_node *child;
226
227 if (node == NULL)
228 return;
229
230 print_altq(&node->altq, level, NULL, NULL);
231
232 if (node->children != NULL) {
233 printf("{");
234 for (child = node->children; child != NULL;
235 child = child->next) {
236 printf("%s", child->altq.qname);
237 if (child->next != NULL)
238 printf(", ");
239 }
240 printf("}");
241 }
242 printf("\n");
243
244 if (opts & PF_OPT_VERBOSE)
245 pfctl_print_altq_nodestat(dev, node);
246
247 if (opts & PF_OPT_DEBUG)
248 printf(" [ qid=%u ifname=%s ifbandwidth=%s ]\n", node->altq.qid,
249 node->altq.ifname, rate2str((double)(node->altq.ifbandwidth)));
250
251 for (child = node->children; child != NULL;
252 child = child->next)
253 pfctl_print_altq_node(dev, child, level+1, opts);
254}
255
256void
257pfctl_print_altq_nodestat(int dev, const struct pf_altq_node *a)
258{
259 if (a->altq.qid == 0)
260 return;
261
262 switch (a->altq.scheduler) {
263 case ALTQT_CBQ:
264 print_cbqstats(a->qstats);
265 break;
266 case ALTQT_PRIQ:
267 print_priqstats(a->qstats);
268 break;
269 case ALTQT_HFSC:
270 print_hfscstats(a->qstats);
271 break;
272 }
273}
274
275void
276print_cbqstats(struct queue_stats cur)
277{
99 if (pfctl_update_qstats(dev, &root))
100 return (-1);
101
102 for (node = root; node != NULL; node = node->next)
103 pfctl_print_altq_node(dev, node, 0, opts);
104
105 while (verbose2) {
106 printf("\n");
107 fflush(stdout);
108 sleep(STAT_INTERVAL);
109 if (pfctl_update_qstats(dev, &root))
110 return (-1);
111 for (node = root; node != NULL; node = node->next)
112 pfctl_print_altq_node(dev, node, 0, opts);
113 }
114 pfctl_free_altq_node(root);
115 return (0);
116}
117
118int
119pfctl_update_qstats(int dev, struct pf_altq_node **root)
120{
121 struct pf_altq_node *node;
122 struct pfioc_altq pa;
123 struct pfioc_qstats pq;
124 u_int32_t mnr, nr;
125 struct queue_stats qstats;
126 static u_int32_t last_ticket;
127
128 memset(&pa, 0, sizeof(pa));
129 memset(&pq, 0, sizeof(pq));
130 memset(&qstats, 0, sizeof(qstats));
131 if (ioctl(dev, DIOCGETALTQS, &pa)) {
132 warn("DIOCGETALTQS");
133 return (-1);
134 }
135
136 /* if a new set is found, start over */
137 if (pa.ticket != last_ticket && *root != NULL) {
138 pfctl_free_altq_node(*root);
139 *root = NULL;
140 }
141 last_ticket = pa.ticket;
142
143 mnr = pa.nr;
144 for (nr = 0; nr < mnr; ++nr) {
145 pa.nr = nr;
146 if (ioctl(dev, DIOCGETALTQ, &pa)) {
147 warn("DIOCGETALTQ");
148 return (-1);
149 }
150 if (pa.altq.qid > 0) {
151 pq.nr = nr;
152 pq.ticket = pa.ticket;
153 pq.buf = &qstats.data;
154 pq.nbytes = sizeof(qstats.data);
155 if (ioctl(dev, DIOCGETQSTATS, &pq)) {
156 warn("DIOCGETQSTATS");
157 return (-1);
158 }
159 if ((node = pfctl_find_altq_node(*root, pa.altq.qname,
160 pa.altq.ifname)) != NULL) {
161 memcpy(&node->qstats.data, &qstats.data,
162 sizeof(qstats.data));
163 update_avg(node);
164 } else {
165 pfctl_insert_altq_node(root, pa.altq, qstats);
166 }
167 }
168 }
169 return (0);
170}
171
172void
173pfctl_insert_altq_node(struct pf_altq_node **root,
174 const struct pf_altq altq, const struct queue_stats qstats)
175{
176 struct pf_altq_node *node;
177
178 node = calloc(1, sizeof(struct pf_altq_node));
179 if (node == NULL)
180 err(1, "pfctl_insert_altq_node: calloc");
181 memcpy(&node->altq, &altq, sizeof(struct pf_altq));
182 memcpy(&node->qstats, &qstats, sizeof(qstats));
183 node->next = node->children = NULL;
184
185 if (*root == NULL)
186 *root = node;
187 else if (!altq.parent[0]) {
188 struct pf_altq_node *prev = *root;
189
190 while (prev->next != NULL)
191 prev = prev->next;
192 prev->next = node;
193 } else {
194 struct pf_altq_node *parent;
195
196 parent = pfctl_find_altq_node(*root, altq.parent, altq.ifname);
197 if (parent == NULL)
198 errx(1, "parent %s not found", altq.parent);
199 if (parent->children == NULL)
200 parent->children = node;
201 else {
202 struct pf_altq_node *prev = parent->children;
203
204 while (prev->next != NULL)
205 prev = prev->next;
206 prev->next = node;
207 }
208 }
209 update_avg(node);
210}
211
212struct pf_altq_node *
213pfctl_find_altq_node(struct pf_altq_node *root, const char *qname,
214 const char *ifname)
215{
216 struct pf_altq_node *node, *child;
217
218 for (node = root; node != NULL; node = node->next) {
219 if (!strcmp(node->altq.qname, qname)
220 && !(strcmp(node->altq.ifname, ifname)))
221 return (node);
222 if (node->children != NULL) {
223 child = pfctl_find_altq_node(node->children, qname,
224 ifname);
225 if (child != NULL)
226 return (child);
227 }
228 }
229 return (NULL);
230}
231
232void
233pfctl_print_altq_node(int dev, const struct pf_altq_node *node, unsigned level,
234 int opts)
235{
236 const struct pf_altq_node *child;
237
238 if (node == NULL)
239 return;
240
241 print_altq(&node->altq, level, NULL, NULL);
242
243 if (node->children != NULL) {
244 printf("{");
245 for (child = node->children; child != NULL;
246 child = child->next) {
247 printf("%s", child->altq.qname);
248 if (child->next != NULL)
249 printf(", ");
250 }
251 printf("}");
252 }
253 printf("\n");
254
255 if (opts & PF_OPT_VERBOSE)
256 pfctl_print_altq_nodestat(dev, node);
257
258 if (opts & PF_OPT_DEBUG)
259 printf(" [ qid=%u ifname=%s ifbandwidth=%s ]\n", node->altq.qid,
260 node->altq.ifname, rate2str((double)(node->altq.ifbandwidth)));
261
262 for (child = node->children; child != NULL;
263 child = child->next)
264 pfctl_print_altq_node(dev, child, level+1, opts);
265}
266
267void
268pfctl_print_altq_nodestat(int dev, const struct pf_altq_node *a)
269{
270 if (a->altq.qid == 0)
271 return;
272
273 switch (a->altq.scheduler) {
274 case ALTQT_CBQ:
275 print_cbqstats(a->qstats);
276 break;
277 case ALTQT_PRIQ:
278 print_priqstats(a->qstats);
279 break;
280 case ALTQT_HFSC:
281 print_hfscstats(a->qstats);
282 break;
283 }
284}
285
286void
287print_cbqstats(struct queue_stats cur)
288{
278 printf(" [ pkts: %10llu bytes: %10llu "
279 "dropped pkts: %6llu bytes: %6llu ]\n",
289 printf(" [ pkts: %10"PRIu64" bytes: %10"PRIu64" "
290 "dropped pkts: %6"PRIu64" bytes: %6"PRIu64" ]\n",
280 cur.data.cbq_stats.xmit_cnt.packets,
281 cur.data.cbq_stats.xmit_cnt.bytes,
282 cur.data.cbq_stats.drop_cnt.packets,
283 cur.data.cbq_stats.drop_cnt.bytes);
284 printf(" [ qlength: %3d/%3d borrows: %6u suspends: %6u ]\n",
285 cur.data.cbq_stats.qcnt, cur.data.cbq_stats.qmax,
286 cur.data.cbq_stats.borrows, cur.data.cbq_stats.delays);
287
288 if (cur.avgn < 2)
289 return;
290
291 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
292 cur.avg_packets / STAT_INTERVAL,
293 rate2str((8 * cur.avg_bytes) / STAT_INTERVAL));
294}
295
296void
297print_priqstats(struct queue_stats cur)
298{
291 cur.data.cbq_stats.xmit_cnt.packets,
292 cur.data.cbq_stats.xmit_cnt.bytes,
293 cur.data.cbq_stats.drop_cnt.packets,
294 cur.data.cbq_stats.drop_cnt.bytes);
295 printf(" [ qlength: %3d/%3d borrows: %6u suspends: %6u ]\n",
296 cur.data.cbq_stats.qcnt, cur.data.cbq_stats.qmax,
297 cur.data.cbq_stats.borrows, cur.data.cbq_stats.delays);
298
299 if (cur.avgn < 2)
300 return;
301
302 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
303 cur.avg_packets / STAT_INTERVAL,
304 rate2str((8 * cur.avg_bytes) / STAT_INTERVAL));
305}
306
307void
308print_priqstats(struct queue_stats cur)
309{
299 printf(" [ pkts: %10llu bytes: %10llu "
300 "dropped pkts: %6llu bytes: %6llu ]\n",
310 printf(" [ pkts: %10"PRIu64" bytes: %10"PRIu64" "
311 "dropped pkts: %6"PRIu64" bytes: %6"PRIu64" ]\n",
301 cur.data.priq_stats.xmitcnt.packets,
302 cur.data.priq_stats.xmitcnt.bytes,
303 cur.data.priq_stats.dropcnt.packets,
304 cur.data.priq_stats.dropcnt.bytes);
305 printf(" [ qlength: %3d/%3d ]\n",
306 cur.data.priq_stats.qlength, cur.data.priq_stats.qlimit);
307
308 if (cur.avgn < 2)
309 return;
310
311 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
312 cur.avg_packets / STAT_INTERVAL,
313 rate2str((8 * cur.avg_bytes) / STAT_INTERVAL));
314}
315
316void
317print_hfscstats(struct queue_stats cur)
318{
312 cur.data.priq_stats.xmitcnt.packets,
313 cur.data.priq_stats.xmitcnt.bytes,
314 cur.data.priq_stats.dropcnt.packets,
315 cur.data.priq_stats.dropcnt.bytes);
316 printf(" [ qlength: %3d/%3d ]\n",
317 cur.data.priq_stats.qlength, cur.data.priq_stats.qlimit);
318
319 if (cur.avgn < 2)
320 return;
321
322 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
323 cur.avg_packets / STAT_INTERVAL,
324 rate2str((8 * cur.avg_bytes) / STAT_INTERVAL));
325}
326
327void
328print_hfscstats(struct queue_stats cur)
329{
319 printf(" [ pkts: %10llu bytes: %10llu "
320 "dropped pkts: %6llu bytes: %6llu ]\n",
330 printf(" [ pkts: %10"PRIu64" bytes: %10"PRIu64" "
331 "dropped pkts: %6"PRIu64" bytes: %6"PRIu64" ]\n",
321 cur.data.hfsc_stats.xmit_cnt.packets,
322 cur.data.hfsc_stats.xmit_cnt.bytes,
323 cur.data.hfsc_stats.drop_cnt.packets,
324 cur.data.hfsc_stats.drop_cnt.bytes);
325 printf(" [ qlength: %3d/%3d ]\n",
326 cur.data.hfsc_stats.qlength, cur.data.hfsc_stats.qlimit);
327
328 if (cur.avgn < 2)
329 return;
330
331 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
332 cur.avg_packets / STAT_INTERVAL,
333 rate2str((8 * cur.avg_bytes) / STAT_INTERVAL));
334}
335
336void
337pfctl_free_altq_node(struct pf_altq_node *node)
338{
339 while (node != NULL) {
340 struct pf_altq_node *prev;
341
342 if (node->children != NULL)
343 pfctl_free_altq_node(node->children);
344 prev = node;
345 node = node->next;
346 free(prev);
347 }
348}
349
350void
351update_avg(struct pf_altq_node *a)
352{
353 struct queue_stats *qs;
354 u_int64_t b, p;
355 int n;
356
357 if (a->altq.qid == 0)
358 return;
359
360 qs = &a->qstats;
361 n = qs->avgn;
362
363 switch (a->altq.scheduler) {
364 case ALTQT_CBQ:
365 b = qs->data.cbq_stats.xmit_cnt.bytes;
366 p = qs->data.cbq_stats.xmit_cnt.packets;
367 break;
368 case ALTQT_PRIQ:
369 b = qs->data.priq_stats.xmitcnt.bytes;
370 p = qs->data.priq_stats.xmitcnt.packets;
371 break;
372 case ALTQT_HFSC:
373 b = qs->data.hfsc_stats.xmit_cnt.bytes;
374 p = qs->data.hfsc_stats.xmit_cnt.packets;
375 break;
376 default:
377 b = 0;
378 p = 0;
379 break;
380 }
381
382 if (n == 0) {
383 qs->prev_bytes = b;
384 qs->prev_packets = p;
385 qs->avgn++;
386 return;
387 }
388
389 if (b >= qs->prev_bytes)
390 qs->avg_bytes = ((qs->avg_bytes * (n - 1)) +
391 (b - qs->prev_bytes)) / n;
392
393 if (p >= qs->prev_packets)
394 qs->avg_packets = ((qs->avg_packets * (n - 1)) +
395 (p - qs->prev_packets)) / n;
396
397 qs->prev_bytes = b;
398 qs->prev_packets = p;
399 if (n < AVGN_MAX)
400 qs->avgn++;
401}
332 cur.data.hfsc_stats.xmit_cnt.packets,
333 cur.data.hfsc_stats.xmit_cnt.bytes,
334 cur.data.hfsc_stats.drop_cnt.packets,
335 cur.data.hfsc_stats.drop_cnt.bytes);
336 printf(" [ qlength: %3d/%3d ]\n",
337 cur.data.hfsc_stats.qlength, cur.data.hfsc_stats.qlimit);
338
339 if (cur.avgn < 2)
340 return;
341
342 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
343 cur.avg_packets / STAT_INTERVAL,
344 rate2str((8 * cur.avg_bytes) / STAT_INTERVAL));
345}
346
347void
348pfctl_free_altq_node(struct pf_altq_node *node)
349{
350 while (node != NULL) {
351 struct pf_altq_node *prev;
352
353 if (node->children != NULL)
354 pfctl_free_altq_node(node->children);
355 prev = node;
356 node = node->next;
357 free(prev);
358 }
359}
360
361void
362update_avg(struct pf_altq_node *a)
363{
364 struct queue_stats *qs;
365 u_int64_t b, p;
366 int n;
367
368 if (a->altq.qid == 0)
369 return;
370
371 qs = &a->qstats;
372 n = qs->avgn;
373
374 switch (a->altq.scheduler) {
375 case ALTQT_CBQ:
376 b = qs->data.cbq_stats.xmit_cnt.bytes;
377 p = qs->data.cbq_stats.xmit_cnt.packets;
378 break;
379 case ALTQT_PRIQ:
380 b = qs->data.priq_stats.xmitcnt.bytes;
381 p = qs->data.priq_stats.xmitcnt.packets;
382 break;
383 case ALTQT_HFSC:
384 b = qs->data.hfsc_stats.xmit_cnt.bytes;
385 p = qs->data.hfsc_stats.xmit_cnt.packets;
386 break;
387 default:
388 b = 0;
389 p = 0;
390 break;
391 }
392
393 if (n == 0) {
394 qs->prev_bytes = b;
395 qs->prev_packets = p;
396 qs->avgn++;
397 return;
398 }
399
400 if (b >= qs->prev_bytes)
401 qs->avg_bytes = ((qs->avg_bytes * (n - 1)) +
402 (b - qs->prev_bytes)) / n;
403
404 if (p >= qs->prev_packets)
405 qs->avg_packets = ((qs->avg_packets * (n - 1)) +
406 (p - qs->prev_packets)) / n;
407
408 qs->prev_bytes = b;
409 qs->prev_packets = p;
410 if (n < AVGN_MAX)
411 qs->avgn++;
412}