qdisc_cbq.c revision 1.9
11.9Sozaki/*	$NetBSD: qdisc_cbq.c,v 1.9 2021/07/21 06:42:07 ozaki-r Exp $	*/
21.6Speter/*	$KAME: qdisc_cbq.c,v 1.7 2003/09/17 14:27:37 kjc Exp $	*/
31.1Sthorpej/*
41.1Sthorpej * Copyright (C) 1999-2000
51.1Sthorpej *	Sony Computer Science Laboratories, Inc.  All rights reserved.
61.1Sthorpej *
71.1Sthorpej * Redistribution and use in source and binary forms, with or without
81.1Sthorpej * modification, are permitted provided that the following conditions
91.1Sthorpej * are met:
101.1Sthorpej * 1. Redistributions of source code must retain the above copyright
111.1Sthorpej *    notice, this list of conditions and the following disclaimer.
121.1Sthorpej * 2. Redistributions in binary form must reproduce the above copyright
131.1Sthorpej *    notice, this list of conditions and the following disclaimer in the
141.1Sthorpej *    documentation and/or other materials provided with the distribution.
151.1Sthorpej *
161.1Sthorpej * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
171.1Sthorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
181.1Sthorpej * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
191.1Sthorpej * ARE DISCLAIMED.  IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
201.1Sthorpej * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
211.1Sthorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
221.1Sthorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
231.1Sthorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
241.1Sthorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
251.1Sthorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
261.1Sthorpej * SUCH DAMAGE.
271.1Sthorpej */
281.1Sthorpej
291.1Sthorpej#include <sys/param.h>
301.1Sthorpej#include <sys/ioctl.h>
311.1Sthorpej#include <sys/time.h>
321.1Sthorpej#include <sys/socket.h>
331.1Sthorpej#include <net/if.h>
341.1Sthorpej#include <netinet/in.h>
351.1Sthorpej#include <altq/altq.h>
361.1Sthorpej#include <altq/altq_cbq.h>
371.1Sthorpej
381.1Sthorpej#include <stdio.h>
391.1Sthorpej#include <stdlib.h>
401.1Sthorpej#include <unistd.h>
411.1Sthorpej#include <string.h>
421.6Speter#include <signal.h>
431.1Sthorpej#include <math.h>
441.1Sthorpej#include <errno.h>
451.1Sthorpej#include <err.h>
461.1Sthorpej
471.1Sthorpej#include "quip_client.h"
481.1Sthorpej#include "altqstat.h"
491.1Sthorpej
501.1Sthorpej#define NCLASSES	64
511.1Sthorpej
521.1Sthorpej#ifndef RM_FILTER_GAIN
531.1Sthorpej#define	RM_FILTER_GAIN	5	/* log2 of gain, e.g., 5 => 31/32 */
541.1Sthorpej#endif
551.1Sthorpej#ifndef RM_POWER
561.1Sthorpej#define RM_POWER	(1 << RM_FILTER_GAIN)
571.1Sthorpej#endif
581.1Sthorpej
591.1Sthorpejvoid
601.1Sthorpejcbq_stat_loop(int fd, const char *ifname, int count, int interval)
611.1Sthorpej{
621.1Sthorpej	class_stats_t stats1[NCLASSES], stats2[NCLASSES];
631.1Sthorpej	char clnames[NCLASSES][128];
641.1Sthorpej	u_long clhandles[NCLASSES];
651.1Sthorpej	struct cbq_getstats	get_stats;
661.1Sthorpej	class_stats_t		*sp, *lp, *new, *last, *tmp;
671.1Sthorpej	struct timeval		cur_time, last_time;
681.1Sthorpej	int			i;
691.1Sthorpej	double			flow_bps, sec;
701.7Speter	int			cnt = count;
711.6Speter	sigset_t		omask;
721.1Sthorpej
731.3Sitojun	strlcpy(get_stats.iface.cbq_ifacename, ifname,
741.3Sitojun		sizeof(get_stats.iface.cbq_ifacename));
751.1Sthorpej	new = &stats1[0];
761.1Sthorpej	last = &stats2[0];
771.1Sthorpej
781.1Sthorpej	for (i = 0; i < NCLASSES; i++)
791.1Sthorpej	    clhandles[i] = NULL_CLASS_HANDLE;
801.1Sthorpej
811.7Speter	for (;;) {
821.1Sthorpej		get_stats.nclasses = NCLASSES;
831.1Sthorpej		get_stats.stats = new;
841.1Sthorpej		if (ioctl(fd, CBQ_GETSTATS, &get_stats) < 0)
851.1Sthorpej			err(1, "ioctl CBQ_GETSTATS");
861.1Sthorpej
871.1Sthorpej		gettimeofday(&cur_time, NULL);
881.1Sthorpej		sec = calc_interval(&cur_time, &last_time);
891.1Sthorpej
901.1Sthorpej		for (i=0; i<get_stats.nclasses; i++) {
911.1Sthorpej			sp = &new[i];
921.1Sthorpej			lp = &last[i];
931.1Sthorpej
941.1Sthorpej			if (sp->handle != clhandles[i]) {
951.1Sthorpej				quip_chandle2name(ifname, sp->handle,
961.7Speter				    clnames[i], sizeof(clnames[0]));
971.1Sthorpej				clhandles[i] = sp->handle;
981.1Sthorpej			}
991.1Sthorpej
1001.6Speter			printf("Class %d on Interface %s: %s\n",
1011.6Speter			    sp->handle, ifname, clnames[i]);
1021.1Sthorpej
1031.8Sozaki			flow_bps = 8.0 / (double)sp->ps_per_byte
1041.8Sozaki			    * 1000*1000*1000*1000;
1051.1Sthorpej
1061.1Sthorpej			printf("\tpriority: %d depth: %d",
1071.1Sthorpej			       sp->priority, sp->depth);
1081.1Sthorpej			printf(" offtime: %d [us] wrr_allot: %d bytes\n",
1091.1Sthorpej			       sp->offtime, sp->wrr_allot);
1101.8Sozaki			printf("\tpsPerByte: %ld", sp->ps_per_byte);
1111.7Speter			printf("\t(%sbps)", rate2str(flow_bps));
1121.7Speter			if (lp->handle != NULL_CLASS_HANDLE) {
1131.7Speter				printf(",\tMeasured: %s [bps]\n",
1141.7Speter				       rate2str(calc_rate(sp->xmit_cnt.bytes,
1151.7Speter						lp->xmit_cnt.bytes, sec)));
1161.7Speter			} else {
1171.7Speter				printf("\n");
1181.7Speter			}
1191.1Sthorpej			printf("\tpkts: %llu,\tbytes: %llu\n",
1201.1Sthorpej			       (ull)sp->xmit_cnt.packets,
1211.1Sthorpej			       (ull)sp->xmit_cnt.bytes);
1221.1Sthorpej			printf("\tovers: %u,\toveractions: %u\n",
1231.1Sthorpej			       sp->over, sp->overactions);
1241.1Sthorpej			printf("\tborrows: %u,\tdelays: %u\n",
1251.1Sthorpej			       sp->borrows, sp->delays);
1261.1Sthorpej			printf("\tdrops: %llu,\tdrop_bytes: %llu\n",
1271.5Sitojun			       (ull)sp->drop_cnt.packets,
1281.1Sthorpej			       (ull)sp->drop_cnt.bytes);
1291.1Sthorpej			if (sp->qtype == Q_RED)
1301.1Sthorpej				print_redstats(sp->red);
1311.1Sthorpej			else if (sp->qtype == Q_RIO)
1321.1Sthorpej				print_riostats(sp->red);
1331.1Sthorpej
1341.1Sthorpej			printf("\tQCount: %d,\t(qmax: %d)\n",
1351.1Sthorpej			       sp->qcnt, sp->qmax);
1361.9Sozaki#if 0
1371.1Sthorpej			printf("\tAvgIdle: %d [us],\t(maxidle: %d minidle: %d [us])\n",
1381.1Sthorpej			       sp->avgidle >> RM_FILTER_GAIN,
1391.1Sthorpej			       sp->maxidle >> RM_FILTER_GAIN,
1401.1Sthorpej			       sp->minidle / RM_POWER);
1411.9Sozaki#else
1421.9Sozaki			printf("\tAvgIdle: %d [us],\t(maxidle: %d minidle: %d [us])\n",
1431.9Sozaki			       sp->avgidle, sp->maxidle, sp->minidle);
1441.9Sozaki#endif
1451.1Sthorpej		}
1461.1Sthorpej
1471.1Sthorpej		/* swap the buffer pointers */
1481.1Sthorpej		tmp = last;
1491.1Sthorpej		last = new;
1501.1Sthorpej		new = tmp;
1511.1Sthorpej
1521.1Sthorpej		last_time = cur_time;
1531.6Speter
1541.7Speter		if (count != 0 && --cnt == 0)
1551.7Speter			break;
1561.7Speter
1571.6Speter		/* wait for alarm signal */
1581.6Speter		if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0)
1591.6Speter			sigsuspend(&omask);
1601.1Sthorpej	}
1611.1Sthorpej}
162