qdisc_cbq.c revision 1.1
11.1Sthorpej/*	$KAME: qdisc_cbq.c,v 1.2 2000/10/18 09:15:16 kjc Exp $	*/
21.1Sthorpej/*
31.1Sthorpej * Copyright (C) 1999-2000
41.1Sthorpej *	Sony Computer Science Laboratories, Inc.  All rights reserved.
51.1Sthorpej *
61.1Sthorpej * Redistribution and use in source and binary forms, with or without
71.1Sthorpej * modification, are permitted provided that the following conditions
81.1Sthorpej * are met:
91.1Sthorpej * 1. Redistributions of source code must retain the above copyright
101.1Sthorpej *    notice, this list of conditions and the following disclaimer.
111.1Sthorpej * 2. Redistributions in binary form must reproduce the above copyright
121.1Sthorpej *    notice, this list of conditions and the following disclaimer in the
131.1Sthorpej *    documentation and/or other materials provided with the distribution.
141.1Sthorpej *
151.1Sthorpej * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
161.1Sthorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
171.1Sthorpej * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
181.1Sthorpej * ARE DISCLAIMED.  IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
191.1Sthorpej * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
201.1Sthorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
211.1Sthorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
221.1Sthorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
231.1Sthorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
241.1Sthorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
251.1Sthorpej * SUCH DAMAGE.
261.1Sthorpej */
271.1Sthorpej
281.1Sthorpej#include <sys/param.h>
291.1Sthorpej#include <sys/ioctl.h>
301.1Sthorpej#include <sys/time.h>
311.1Sthorpej#include <sys/socket.h>
321.1Sthorpej#include <net/if.h>
331.1Sthorpej#include <netinet/in.h>
341.1Sthorpej#include <altq/altq.h>
351.1Sthorpej#include <altq/altq_cbq.h>
361.1Sthorpej
371.1Sthorpej#include <stdio.h>
381.1Sthorpej#include <stdlib.h>
391.1Sthorpej#include <unistd.h>
401.1Sthorpej#include <string.h>
411.1Sthorpej#include <math.h>
421.1Sthorpej#include <errno.h>
431.1Sthorpej#include <err.h>
441.1Sthorpej
451.1Sthorpej#include "quip_client.h"
461.1Sthorpej#include "altqstat.h"
471.1Sthorpej
481.1Sthorpej#define NCLASSES	64
491.1Sthorpej
501.1Sthorpej#ifndef RM_FILTER_GAIN
511.1Sthorpej#define	RM_FILTER_GAIN	5	/* log2 of gain, e.g., 5 => 31/32 */
521.1Sthorpej#endif
531.1Sthorpej#ifndef RM_POWER
541.1Sthorpej#define RM_POWER	(1 << RM_FILTER_GAIN)
551.1Sthorpej#endif
561.1Sthorpej
571.1Sthorpejvoid
581.1Sthorpejcbq_stat_loop(int fd, const char *ifname, int count, int interval)
591.1Sthorpej{
601.1Sthorpej	class_stats_t stats1[NCLASSES], stats2[NCLASSES];
611.1Sthorpej	char clnames[NCLASSES][128];
621.1Sthorpej	u_long clhandles[NCLASSES];
631.1Sthorpej	struct cbq_getstats	get_stats;
641.1Sthorpej	class_stats_t		*sp, *lp, *new, *last, *tmp;
651.1Sthorpej	struct timeval		cur_time, last_time;
661.1Sthorpej	int			i;
671.1Sthorpej	double			flow_bps, sec;
681.1Sthorpej	int cnt = count;
691.1Sthorpej
701.1Sthorpej	strcpy(get_stats.iface.cbq_ifacename, ifname);
711.1Sthorpej	new = &stats1[0];
721.1Sthorpej	last = &stats2[0];
731.1Sthorpej
741.1Sthorpej	for (i = 0; i < NCLASSES; i++)
751.1Sthorpej	    clhandles[i] = NULL_CLASS_HANDLE;
761.1Sthorpej
771.1Sthorpej	while (count == 0 || cnt-- > 0) {
781.1Sthorpej		get_stats.nclasses = NCLASSES;
791.1Sthorpej		get_stats.stats = new;
801.1Sthorpej		if (ioctl(fd, CBQ_GETSTATS, &get_stats) < 0)
811.1Sthorpej			err(1, "ioctl CBQ_GETSTATS");
821.1Sthorpej
831.1Sthorpej		gettimeofday(&cur_time, NULL);
841.1Sthorpej		sec = calc_interval(&cur_time, &last_time);
851.1Sthorpej
861.1Sthorpej		for (i=0; i<get_stats.nclasses; i++) {
871.1Sthorpej			sp = &new[i];
881.1Sthorpej			lp = &last[i];
891.1Sthorpej
901.1Sthorpej			if (sp->handle != clhandles[i]) {
911.1Sthorpej				quip_chandle2name(ifname, sp->handle,
921.1Sthorpej						  clnames[i]);
931.1Sthorpej				clhandles[i] = sp->handle;
941.1Sthorpej				continue;
951.1Sthorpej			}
961.1Sthorpej
971.1Sthorpej			switch (sp->handle) {
981.1Sthorpej			case ROOT_CLASS_HANDLE:
991.1Sthorpej				printf("Root Class for Interface %s: %s\n",
1001.1Sthorpej				       ifname, clnames[i]);
1011.1Sthorpej				break;
1021.1Sthorpej			case DEFAULT_CLASS_HANDLE:
1031.1Sthorpej				printf("Default Class for Interface %s: %s\n",
1041.1Sthorpej				       ifname, clnames[i]);
1051.1Sthorpej				break;
1061.1Sthorpej			case CTL_CLASS_HANDLE:
1071.1Sthorpej				printf("Ctl Class for Interface %s: %s\n",
1081.1Sthorpej				       ifname, clnames[i]);
1091.1Sthorpej				break;
1101.1Sthorpej			default:
1111.1Sthorpej				printf("Class %d on Interface %s: %s\n",
1121.1Sthorpej				       sp->handle, ifname, clnames[i]);
1131.1Sthorpej				break;
1141.1Sthorpej			}
1151.1Sthorpej
1161.1Sthorpej			flow_bps = 8.0 / (double)sp->ns_per_byte
1171.1Sthorpej			    * 1000*1000*1000;
1181.1Sthorpej
1191.1Sthorpej			printf("\tpriority: %d depth: %d",
1201.1Sthorpej			       sp->priority, sp->depth);
1211.1Sthorpej			printf(" offtime: %d [us] wrr_allot: %d bytes\n",
1221.1Sthorpej			       sp->offtime, sp->wrr_allot);
1231.1Sthorpej			printf("\tnsPerByte: %d", sp->ns_per_byte);
1241.1Sthorpej			printf("\t(%s Mbps),", rate2str(flow_bps));
1251.1Sthorpej			printf("\tMeasured: %s [Mbps]\n",
1261.1Sthorpej			       rate2str(calc_rate(sp->xmit_cnt.bytes,
1271.1Sthorpej						  lp->xmit_cnt.bytes, sec)));
1281.1Sthorpej			printf("\tpkts: %llu,\tbytes: %llu\n",
1291.1Sthorpej			       (ull)sp->xmit_cnt.packets,
1301.1Sthorpej			       (ull)sp->xmit_cnt.bytes);
1311.1Sthorpej			printf("\tovers: %u,\toveractions: %u\n",
1321.1Sthorpej			       sp->over, sp->overactions);
1331.1Sthorpej			printf("\tborrows: %u,\tdelays: %u\n",
1341.1Sthorpej			       sp->borrows, sp->delays);
1351.1Sthorpej			printf("\tdrops: %llu,\tdrop_bytes: %llu\n",
1361.1Sthorpej			       (ull)sp->drop_cnt.bytes,
1371.1Sthorpej			       (ull)sp->drop_cnt.bytes);
1381.1Sthorpej			if (sp->qtype == Q_RED)
1391.1Sthorpej				print_redstats(sp->red);
1401.1Sthorpej			else if (sp->qtype == Q_RIO)
1411.1Sthorpej				print_riostats(sp->red);
1421.1Sthorpej
1431.1Sthorpej			printf("\tQCount: %d,\t(qmax: %d)\n",
1441.1Sthorpej			       sp->qcnt, sp->qmax);
1451.1Sthorpej			printf("\tAvgIdle: %d [us],\t(maxidle: %d minidle: %d [us])\n",
1461.1Sthorpej			       sp->avgidle >> RM_FILTER_GAIN,
1471.1Sthorpej			       sp->maxidle >> RM_FILTER_GAIN,
1481.1Sthorpej			       sp->minidle / RM_POWER);
1491.1Sthorpej		}
1501.1Sthorpej
1511.1Sthorpej		/* swap the buffer pointers */
1521.1Sthorpej		tmp = last;
1531.1Sthorpej		last = new;
1541.1Sthorpej		new = tmp;
1551.1Sthorpej
1561.1Sthorpej		last_time = cur_time;
1571.1Sthorpej		sleep(interval);
1581.1Sthorpej	}
1591.1Sthorpej}
160