1dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 2dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * q_cbq.c CBQ. 3dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 4dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * This program is free software; you can redistribute it and/or 5dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * modify it under the terms of the GNU General Public License 6dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * as published by the Free Software Foundation; either version 7dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 2 of the License, or (at your option) any later version. 8dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 9dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 11dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 12dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 13dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdio.h> 14dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdlib.h> 15dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <unistd.h> 16dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <syslog.h> 17dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <fcntl.h> 18dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/socket.h> 19dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netinet/in.h> 20dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <arpa/inet.h> 21dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <string.h> 22dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 23dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "utils.h" 24dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "tc_util.h" 25dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "tc_cbq.h" 26dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 27dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void explain_class(void) 28dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 29dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Usage: ... cbq bandwidth BPS rate BPS maxburst PKTS [ avpkt BYTES ]\n"); 30dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ minburst PKTS ] [ bounded ] [ isolated ]\n"); 31dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ allot BYTES ] [ mpu BYTES ] [ weight RATE ]\n"); 32dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ prio NUMBER ] [ cell BYTES ] [ ewma LOG ]\n"); 33dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ estimator INTERVAL TIME_CONSTANT ]\n"); 34dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ split CLASSID ] [ defmap MASK/CHANGE ]\n"); 35dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ overhead BYTES ] [ linklayer TYPE ]\n"); 36dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 37dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 38dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void explain(void) 39dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 40dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Usage: ... cbq bandwidth BPS avpkt BYTES [ mpu BYTES ]\n"); 41dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ cell BYTES ] [ ewma LOG ]\n"); 42dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 43dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 44dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void explain1(char *arg) 45dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 46dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"%s\"\n", arg); 47dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 48dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 49dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 50dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int cbq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) 51dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 52dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_ratespec r; 53dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_cbq_lssopt lss; 54dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 rtab[256]; 55dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned mpu=0, avpkt=0, allot=0; 56dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned short overhead=0; 57dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned int linklayer = LINKLAYER_ETHERNET; /* Assume ethernet */ 58dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int cell_log=-1; 59dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int ewma_log=-1; 60dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tail; 61dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 62dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&lss, 0, sizeof(lss)); 63dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&r, 0, sizeof(r)); 64dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 65dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (argc > 0) { 66dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "bandwidth") == 0 || 67dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat matches(*argv, "rate") == 0) { 68dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 69dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_rate(&r.rate, *argv)) { 70dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("bandwidth"); 71dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 72dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 73dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "ewma") == 0) { 74dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 75dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_integer(&ewma_log, *argv, 0)) { 76dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("ewma"); 77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ewma_log > 31) { 80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "ewma_log must be < 32\n"); 81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "cell") == 0) { 84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned cell; 85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_size(&cell, *argv)) { 88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("cell"); 89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i=0; i<32; i++) 92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((1<<i) == cell) 93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (i>=32) { 95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "cell must be 2^n\n"); 96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cell_log = i; 99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "avpkt") == 0) { 100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_size(&avpkt, *argv)) { 102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("avpkt"); 103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "mpu") == 0) { 106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_size(&mpu, *argv)) { 108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("mpu"); 109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "allot") == 0) { 112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* Accept and ignore "allot" for backward compatibility */ 114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_size(&allot, *argv)) { 115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("allot"); 116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "overhead") == 0) { 119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u16(&overhead, *argv, 10)) { 121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("overhead"); return -1; 122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "linklayer") == 0) { 124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_linklayer(&linklayer, *argv)) { 126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("linklayer"); return -1; 127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "help") == 0) { 129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain(); 130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "What is \"%s\"?\n", *argv); 133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain(); 134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; argv++; 137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* OK. All options are parsed. */ 140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (r.rate == 0) { 142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CBQ: bandwidth is required parameter.\n"); 143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (avpkt == 0) { 146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CBQ: \"avpkt\" is required.\n"); 147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (allot < (avpkt*3)/2) 150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat allot = (avpkt*3)/2; 151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat r.mpu = mpu; 153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat r.overhead = overhead; 154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tc_calc_rtable(&r, rtab, cell_log, allot, linklayer) < 0) { 155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CBQ: failed to calculate rate table.\n"); 156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ewma_log < 0) 160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ewma_log = TC_CBQ_DEF_EWMA; 161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.ewma_log = ewma_log; 162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.maxidle = tc_calc_xmittime(r.rate, avpkt); 163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change = TCF_CBQ_LSS_MAXIDLE|TCF_CBQ_LSS_EWMA|TCF_CBQ_LSS_AVPKT; 164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.avpkt = avpkt; 165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail = NLMSG_TAIL(n); 167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); 168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, TCA_CBQ_RATE, &r, sizeof(r)); 169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, TCA_CBQ_LSSOPT, &lss, sizeof(lss)); 170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 3024, TCA_CBQ_RTAB, rtab, 1024); 171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_raw) { 172dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i=0; i<256; i++) 174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("%u ", rtab[i]); 175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("\n"); 176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int cbq_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) 182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int wrr_ok=0, fopt_ok=0; 184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_ratespec r; 185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_cbq_lssopt lss; 186dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_cbq_wrropt wrr; 187dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_cbq_fopt fopt; 188dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_cbq_ovl ovl; 189dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 rtab[256]; 190dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned mpu=0; 191dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int cell_log=-1; 192dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int ewma_log=-1; 193dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned bndw = 0; 194dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned minburst=0, maxburst=0; 195dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned short overhead=0; 196dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned int linklayer = LINKLAYER_ETHERNET; /* Assume ethernet */ 197dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tail; 198dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 199dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&r, 0, sizeof(r)); 200dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&lss, 0, sizeof(lss)); 201dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&wrr, 0, sizeof(wrr)); 202dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&fopt, 0, sizeof(fopt)); 203dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&ovl, 0, sizeof(ovl)); 204dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 205dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (argc > 0) { 206dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "rate") == 0) { 207dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 208dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_rate(&r.rate, *argv)) { 209dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("rate"); 210dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 211dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 212dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "bandwidth") == 0) { 213dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 214dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_rate(&bndw, *argv)) { 215dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("bandwidth"); 216dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 217dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 218dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "minidle") == 0) { 219dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 220dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&lss.minidle, *argv, 0)) { 221dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("minidle"); 222dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 223dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 224dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_MINIDLE; 225dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "minburst") == 0) { 226dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 227dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&minburst, *argv, 0)) { 228dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("minburst"); 229dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 230dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 231dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_OFFTIME; 232dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "maxburst") == 0) { 233dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 234dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&maxburst, *argv, 0)) { 235dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("maxburst"); 236dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 237dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 238dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_MAXIDLE; 239dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "bounded") == 0) { 240dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.flags |= TCF_CBQ_LSS_BOUNDED; 241dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_FLAGS; 242dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "borrow") == 0) { 243dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.flags &= ~TCF_CBQ_LSS_BOUNDED; 244dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_FLAGS; 245dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "isolated") == 0) { 246dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.flags |= TCF_CBQ_LSS_ISOLATED; 247dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_FLAGS; 248dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "sharing") == 0) { 249dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.flags &= ~TCF_CBQ_LSS_ISOLATED; 250dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_FLAGS; 251dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "ewma") == 0) { 252dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 253dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_integer(&ewma_log, *argv, 0)) { 254dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("ewma"); 255dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 256dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 257dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ewma_log > 31) { 258dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "ewma_log must be < 32\n"); 259dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 260dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 261dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_EWMA; 262dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "cell") == 0) { 263dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned cell; 264dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 265dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 266dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_size(&cell, *argv)) { 267dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("cell"); 268dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 269dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 270dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i=0; i<32; i++) 271dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((1<<i) == cell) 272dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 273dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (i>=32) { 274dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "cell must be 2^n\n"); 275dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 276dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 277dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cell_log = i; 278dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "prio") == 0) { 279dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned prio; 280dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 281dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&prio, *argv, 0)) { 282dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("prio"); 283dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 284dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 285dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (prio > TC_CBQ_MAXPRIO) { 286dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "\"prio\" must be number in the range 1...%d\n", TC_CBQ_MAXPRIO); 287dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 288dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 289dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat wrr.priority = prio; 290dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat wrr_ok++; 291dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "allot") == 0) { 292dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 293dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_size(&wrr.allot, *argv)) { 294dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("allot"); 295dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 296dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 297dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "avpkt") == 0) { 298dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 299dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_size(&lss.avpkt, *argv)) { 300dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("avpkt"); 301dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 302dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 303dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_AVPKT; 304dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "mpu") == 0) { 305dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 306dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_size(&mpu, *argv)) { 307dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("mpu"); 308dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 309dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 310dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "weight") == 0) { 311dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 312dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_size(&wrr.weight, *argv)) { 313dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("weight"); 314dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 315dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 316dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat wrr_ok++; 317dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "split") == 0) { 318dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 319dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_tc_classid(&fopt.split, *argv)) { 320dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Invalid split node ID.\n"); 3211a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return -1; 322dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 323dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fopt_ok++; 324dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "defmap") == 0) { 325dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int err; 326dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 327dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat err = sscanf(*argv, "%08x/%08x", &fopt.defmap, &fopt.defchange); 328dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (err < 1) { 329dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Invalid defmap, should be MASK32[/MASK]\n"); 330dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 331dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 332dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (err == 1) 333dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fopt.defchange = ~0; 334dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fopt_ok++; 335dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "overhead") == 0) { 336dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 337dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u16(&overhead, *argv, 10)) { 338dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("overhead"); return -1; 339dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 340dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "linklayer") == 0) { 341dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 342dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_linklayer(&linklayer, *argv)) { 343dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain1("linklayer"); return -1; 344dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 345dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "help") == 0) { 346dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain_class(); 347dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 348dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 349dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "What is \"%s\"?\n", *argv); 350dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain_class(); 351dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 352dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 353dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; argv++; 354dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 355dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 356dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* OK. All options are parsed. */ 357dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 358dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* 1. Prepare link sharing scheduler parameters */ 359dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (r.rate) { 360dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned pktsize = wrr.allot; 361dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (wrr.allot < (lss.avpkt*3)/2) 362dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat wrr.allot = (lss.avpkt*3)/2; 363dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat r.mpu = mpu; 364dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat r.overhead = overhead; 365dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tc_calc_rtable(&r, rtab, cell_log, pktsize, linklayer) < 0) { 366dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CBQ: failed to calculate rate table.\n"); 367dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 368dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 369dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 370dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ewma_log < 0) 371dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ewma_log = TC_CBQ_DEF_EWMA; 372dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.ewma_log = ewma_log; 373dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss.change&(TCF_CBQ_LSS_OFFTIME|TCF_CBQ_LSS_MAXIDLE)) { 374dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss.avpkt == 0) { 375dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CBQ: avpkt is required for max/minburst.\n"); 376dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 377dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 378dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (bndw==0 || r.rate == 0) { 379dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CBQ: bandwidth&rate are required for max/minburst.\n"); 380dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 381dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 382dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 383dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (wrr.priority == 0 && (n->nlmsg_flags&NLM_F_EXCL)) { 384dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat wrr_ok = 1; 385dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat wrr.priority = TC_CBQ_MAXPRIO; 386dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (wrr.allot == 0) 387dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat wrr.allot = (lss.avpkt*3)/2; 388dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 389dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (wrr_ok) { 390dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (wrr.weight == 0) 391dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat wrr.weight = (wrr.priority == TC_CBQ_MAXPRIO) ? 1 : r.rate; 392dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (wrr.allot == 0) { 393dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CBQ: \"allot\" is required to set WRR parameters.\n"); 394dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 395dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 396dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 397dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss.change&TCF_CBQ_LSS_MAXIDLE) { 398dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.maxidle = tc_cbq_calc_maxidle(bndw, r.rate, lss.avpkt, ewma_log, maxburst); 399dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_MAXIDLE; 400dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_EWMA|TCF_CBQ_LSS_AVPKT; 401dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 402dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss.change&TCF_CBQ_LSS_OFFTIME) { 403dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.offtime = tc_cbq_calc_offtime(bndw, r.rate, lss.avpkt, ewma_log, minburst); 404dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_OFFTIME; 405dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_EWMA|TCF_CBQ_LSS_AVPKT; 406dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 407dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss.change&TCF_CBQ_LSS_MINIDLE) { 408dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.minidle <<= lss.ewma_log; 409dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_EWMA; 410dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 411dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 412dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail = NLMSG_TAIL(n); 413dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); 414dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss.change) { 415dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss.change |= TCF_CBQ_LSS_FLAGS; 416dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, TCA_CBQ_LSSOPT, &lss, sizeof(lss)); 417dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 418dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (wrr_ok) 419dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, TCA_CBQ_WRROPT, &wrr, sizeof(wrr)); 420dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (fopt_ok) 421dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, TCA_CBQ_FOPT, &fopt, sizeof(fopt)); 422dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (r.rate) { 423dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, TCA_CBQ_RATE, &r, sizeof(r)); 424dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 3024, TCA_CBQ_RTAB, rtab, 1024); 425dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_raw) { 426dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 427dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i=0; i<256; i++) 428dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("%u ", rtab[i]); 429dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("\n"); 430dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 431dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 432dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 433dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 434dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 435dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 436dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 437dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int cbq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) 438dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 439dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tb[TCA_CBQ_MAX+1]; 440dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_ratespec *r = NULL; 441dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_cbq_lssopt *lss = NULL; 442dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_cbq_wrropt *wrr = NULL; 443dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_cbq_fopt *fopt = NULL; 444dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_cbq_ovl *ovl = NULL; 445dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 446dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 447dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (opt == NULL) 448dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 449dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 450dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr_nested(tb, TCA_CBQ_MAX, opt); 451dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 452dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_CBQ_RATE]) { 453dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (RTA_PAYLOAD(tb[TCA_CBQ_RATE]) < sizeof(*r)) 454dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CBQ: too short rate opt\n"); 455dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 456dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat r = RTA_DATA(tb[TCA_CBQ_RATE]); 457dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 458dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_CBQ_LSSOPT]) { 459dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (RTA_PAYLOAD(tb[TCA_CBQ_LSSOPT]) < sizeof(*lss)) 460dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CBQ: too short lss opt\n"); 461dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 462dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lss = RTA_DATA(tb[TCA_CBQ_LSSOPT]); 463dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 464dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_CBQ_WRROPT]) { 465dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (RTA_PAYLOAD(tb[TCA_CBQ_WRROPT]) < sizeof(*wrr)) 466dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CBQ: too short wrr opt\n"); 467dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 468dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat wrr = RTA_DATA(tb[TCA_CBQ_WRROPT]); 469dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 470dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_CBQ_FOPT]) { 471dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (RTA_PAYLOAD(tb[TCA_CBQ_FOPT]) < sizeof(*fopt)) 472dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CBQ: too short fopt\n"); 473dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 474dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fopt = RTA_DATA(tb[TCA_CBQ_FOPT]); 475dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 476dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_CBQ_OVL_STRATEGY]) { 477dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (RTA_PAYLOAD(tb[TCA_CBQ_OVL_STRATEGY]) < sizeof(*ovl)) 478dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CBQ: too short overlimit strategy %u/%u\n", 479dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (unsigned) RTA_PAYLOAD(tb[TCA_CBQ_OVL_STRATEGY]), 480dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (unsigned) sizeof(*ovl)); 481dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 482dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ovl = RTA_DATA(tb[TCA_CBQ_OVL_STRATEGY]); 483dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 484dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 485dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (r) { 486dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char buf[64]; 487dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_rate(buf, sizeof(buf), r->rate); 488dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "rate %s ", buf); 489dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_details) { 490dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "cell %ub ", 1<<r->cell_log); 491dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (r->mpu) 492dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "mpu %ub ", r->mpu); 493dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (r->overhead) 494dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "overhead %ub ", r->overhead); 495dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 496dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 497dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss && lss->flags) { 498dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int comma=0; 499dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "("); 500dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss->flags&TCF_CBQ_LSS_BOUNDED) { 501dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "bounded"); 502dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat comma=1; 503dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 504dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss->flags&TCF_CBQ_LSS_ISOLATED) { 505dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (comma) 506dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, ","); 507dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "isolated"); 508dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 509dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, ") "); 510dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 511dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (wrr) { 512dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (wrr->priority != TC_CBQ_MAXPRIO) 513dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "prio %u", wrr->priority); 514dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 515dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "prio no-transmit"); 516dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_details) { 517dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char buf[64]; 518dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "/%u ", wrr->cpriority); 519dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (wrr->weight != 1) { 520dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_rate(buf, sizeof(buf), wrr->weight); 521dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "weight %s ", buf); 522dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 523dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (wrr->allot) 524dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "allot %ub ", wrr->allot); 525dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 526dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 527dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss && show_details) { 528dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "\nlevel %u ewma %u avpkt %ub ", lss->level, lss->ewma_log, lss->avpkt); 529dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss->maxidle) { 530dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "maxidle %s ", sprint_ticks(lss->maxidle>>lss->ewma_log, b1)); 531dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_raw) 532dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "[%08x] ", lss->maxidle); 533dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 534dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss->minidle!=0x7fffffff) { 535dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "minidle %s ", sprint_ticks(lss->minidle>>lss->ewma_log, b1)); 536dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_raw) 537dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "[%08x] ", lss->minidle); 538dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 539dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lss->offtime) { 540dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "offtime %s ", sprint_ticks(lss->offtime, b1)); 541dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_raw) 542dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "[%08x] ", lss->offtime); 543dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 544dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 545dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (fopt && show_details) { 546dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char buf[64]; 547dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_tc_classid(buf, sizeof(buf), fopt->split); 548dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "\nsplit %s ", buf); 549dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (fopt->defmap) { 550dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "defmap %08x", fopt->defmap); 551dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 552dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 553dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 554dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 555dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 556dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int cbq_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) 557dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 558dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_cbq_xstats *st; 559dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 560dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (xstats == NULL) 561dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 562dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 563dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (RTA_PAYLOAD(xstats) < sizeof(*st)) 564dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 565dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 566dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat st = RTA_DATA(xstats); 567dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " borrowed %u overactions %u avgidle %g undertime %g", st->borrows, 568dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat st->overactions, (double)st->avgidle, (double)st->undertime); 569dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 570dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 571dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 572dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct qdisc_util cbq_qdisc_util = { 573dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .id = "cbq", 574dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .parse_qopt = cbq_parse_opt, 575dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .print_qopt = cbq_print_opt, 576dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .print_xstats = cbq_print_xstats, 577dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .parse_copt = cbq_parse_class_opt, 578dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .print_copt = cbq_print_opt, 579dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 580dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 581