1/* $NetBSD: qdisc_cbq.c,v 1.6 2006/10/12 19:59:13 peter Exp $ */ 2/* $KAME: qdisc_cbq.c,v 1.7 2003/09/17 14:27:37 kjc Exp $ */ 3/* 4 * Copyright (C) 1999-2000 5 * Sony Computer Science Laboratories, Inc. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/param.h> 30#include <sys/ioctl.h> 31#include <sys/time.h> 32#include <sys/socket.h> 33#include <net/if.h> 34#include <netinet/in.h> 35#include <altq/altq.h> 36#include <altq/altq_cbq.h> 37 38#include <stdio.h> 39#include <stdlib.h> 40#include <unistd.h> 41#include <string.h> 42#include <signal.h> 43#include <math.h> 44#include <errno.h> 45#include <err.h> 46 47#include "quip_client.h" 48#include "altqstat.h" 49 50#define NCLASSES 64 51 52#ifndef RM_FILTER_GAIN 53#define RM_FILTER_GAIN 5 /* log2 of gain, e.g., 5 => 31/32 */ 54#endif 55#ifndef RM_POWER 56#define RM_POWER (1 << RM_FILTER_GAIN) 57#endif 58 59void 60cbq_stat_loop(int fd, const char *ifname, int count, int interval) 61{ 62 class_stats_t stats1[NCLASSES], stats2[NCLASSES]; 63 char clnames[NCLASSES][128]; 64 u_long clhandles[NCLASSES]; 65 struct cbq_getstats get_stats; 66 class_stats_t *sp, *lp, *new, *last, *tmp; 67 struct timeval cur_time, last_time; 68 int i; 69 double flow_bps, sec; 70 int cnt = count; 71 sigset_t omask; 72 73 strlcpy(get_stats.iface.cbq_ifacename, ifname, 74 sizeof(get_stats.iface.cbq_ifacename)); 75 new = &stats1[0]; 76 last = &stats2[0]; 77 78 for (i = 0; i < NCLASSES; i++) 79 clhandles[i] = NULL_CLASS_HANDLE; 80 81 for (;;) { 82 get_stats.nclasses = NCLASSES; 83 get_stats.stats = new; 84 if (ioctl(fd, CBQ_GETSTATS, &get_stats) < 0) 85 err(1, "ioctl CBQ_GETSTATS"); 86 87 gettimeofday(&cur_time, NULL); 88 sec = calc_interval(&cur_time, &last_time); 89 90 for (i=0; i<get_stats.nclasses; i++) { 91 sp = &new[i]; 92 lp = &last[i]; 93 94 if (sp->handle != clhandles[i]) { 95 quip_chandle2name(ifname, sp->handle, 96 clnames[i], sizeof(clnames[0])); 97 clhandles[i] = sp->handle; 98 } 99 100 printf("Class %d on Interface %s: %s\n", 101 sp->handle, ifname, clnames[i]); 102 103 flow_bps = 8.0 / (double)sp->ns_per_byte 104 * 1000*1000*1000; 105 106 printf("\tpriority: %d depth: %d", 107 sp->priority, sp->depth); 108 printf(" offtime: %d [us] wrr_allot: %d bytes\n", 109 sp->offtime, sp->wrr_allot); 110 printf("\tnsPerByte: %d", sp->ns_per_byte); 111 printf("\t(%sbps)", rate2str(flow_bps)); 112 if (lp->handle != NULL_CLASS_HANDLE) { 113 printf(",\tMeasured: %s [bps]\n", 114 rate2str(calc_rate(sp->xmit_cnt.bytes, 115 lp->xmit_cnt.bytes, sec))); 116 } else { 117 printf("\n"); 118 } 119 printf("\tpkts: %llu,\tbytes: %llu\n", 120 (ull)sp->xmit_cnt.packets, 121 (ull)sp->xmit_cnt.bytes); 122 printf("\tovers: %u,\toveractions: %u\n", 123 sp->over, sp->overactions); 124 printf("\tborrows: %u,\tdelays: %u\n", 125 sp->borrows, sp->delays); 126 printf("\tdrops: %llu,\tdrop_bytes: %llu\n", 127 (ull)sp->drop_cnt.packets, 128 (ull)sp->drop_cnt.bytes); 129 if (sp->qtype == Q_RED) 130 print_redstats(sp->red); 131 else if (sp->qtype == Q_RIO) 132 print_riostats(sp->red); 133 134 printf("\tQCount: %d,\t(qmax: %d)\n", 135 sp->qcnt, sp->qmax); 136 printf("\tAvgIdle: %d [us],\t(maxidle: %d minidle: %d [us])\n", 137 sp->avgidle >> RM_FILTER_GAIN, 138 sp->maxidle >> RM_FILTER_GAIN, 139 sp->minidle / RM_POWER); 140 } 141 142 /* swap the buffer pointers */ 143 tmp = last; 144 last = new; 145 new = tmp; 146 147 last_time = cur_time; 148 149 if (count != 0 && --cnt == 0) 150 break; 151 152 /* wait for alarm signal */ 153 if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0) 154 sigsuspend(&omask); 155 } 156} 157