q_tbf.c revision 2c42579f9c15bdd9d0fdd5e6571c382bfa31399a
1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* 2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * q_tbf.c TBF. 3aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 4aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * This program is free software; you can redistribute it and/or 5aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * modify it under the terms of the GNU General Public License 6aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * as published by the Free Software Foundation; either version 7aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 2 of the License, or (at your option) any later version. 8aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 9aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 11aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */ 12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h> 14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h> 15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h> 16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h> 17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h> 18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h> 19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h> 20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <arpa/inet.h> 21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h> 22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h" 24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "tc_util.h" 25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void explain(void) 27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Usage: ... tbf limit BYTES burst BYTES[/BYTES] rate KBPS [ mtu BYTES[/BYTES] ]\n"); 292c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer fprintf(stderr, " [ peakrate KBPS ] [ latency TIME ] "); 302c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer fprintf(stderr, "[ overhead BYTES ]\n"); 31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void explain1(char *arg) 34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Illegal \"%s\"\n", arg); 36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define usage() return(-1) 40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 41aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) 42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int ok=0; 44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct tc_tbf_qopt opt; 45aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 rtab[256]; 46aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 ptab[256]; 47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned buffer=0, mtu=0, mpu=0, latency=0; 48ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger int Rcell_log=-1, Pcell_log = -1; 492c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer unsigned short overhead=0; 50aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct rtattr *tail; 51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&opt, 0, sizeof(opt)); 53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (argc > 0) { 55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "limit") == 0) { 56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt.limit || latency) { 58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Double \"limit/latency\" spec\n"); 59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_size(&opt.limit, *argv)) { 62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain1("limit"); 63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 64aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 65aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 66aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "latency") == 0) { 67aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt.limit || latency) { 69aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Double \"limit/latency\" spec\n"); 70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 71aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 728f34caafbdbc8f87d228d577872591e138caadb1Patrick McHardy if (get_time(&latency, *argv)) { 73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain1("latency"); 74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 75aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 76aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 77aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "burst") == 0 || 78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcmp(*argv, "buffer") == 0 || 79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcmp(*argv, "maxburst") == 0) { 80aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (buffer) { 82aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Double \"buffer/burst\" spec\n"); 83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_size_and_cell(&buffer, &Rcell_log, *argv) < 0) { 86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain1("buffer"); 87aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "mtu") == 0 || 91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcmp(*argv, "minburst") == 0) { 92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (mtu) { 94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Double \"mtu/minburst\" spec\n"); 95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_size_and_cell(&mtu, &Pcell_log, *argv) < 0) { 98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain1("mtu"); 99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 101aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 102aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "mpu") == 0) { 103aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 104aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (mpu) { 105aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Double \"mpu\" spec\n"); 106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 107aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_size(&mpu, *argv)) { 109aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain1("mpu"); 110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 112aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 113aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "rate") == 0) { 114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt.rate.rate) { 116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Double \"rate\" spec\n"); 117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 118aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_rate(&opt.rate.rate, *argv)) { 120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain1("rate"); 121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "peakrate") == 0) { 125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt.peakrate.rate) { 127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Double \"peakrate\" spec\n"); 128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 129aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_rate(&opt.peakrate.rate, *argv)) { 131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain1("peakrate"); 132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 1352c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer } else if (matches(*argv, "overhead") == 0) { 1362c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer NEXT_ARG(); 1372c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer if (overhead) { 1382c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer fprintf(stderr, "Double \"overhead\" spec\n"); 1392c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer return -1; 1402c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer } 1412c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer if (get_u16(&overhead, *argv, 10)) { 1422c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer explain1("overhead"); return -1; 1432c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer } 144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "help") == 0) { 145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain(); 146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 148aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "What is \"%s\"?\n", *argv); 149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain(); 150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; argv++; 153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!ok) 156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt.rate.rate == 0 || !buffer) { 159aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Both \"rate\" and \"burst\" are required.\n"); 160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 162aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt.peakrate.rate) { 163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!mtu) { 164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "\"mtu\" is required, if \"peakrate\" is requested.\n"); 165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt.limit == 0 && latency == 0) { 170aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Either \"limit\" or \"latency\" are required.\n"); 171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 173aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt.limit == 0) { 175f0bda7e5a52d880a85af698a041afa7dc379e76ePatrick McHardy double lim = opt.rate.rate*(double)latency/TIME_UNITS_PER_SEC + buffer; 176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt.peakrate.rate) { 177f0bda7e5a52d880a85af698a041afa7dc379e76ePatrick McHardy double lim2 = opt.peakrate.rate*(double)latency/TIME_UNITS_PER_SEC + mtu; 178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (lim2 < lim) 179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger lim = lim2; 180aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger opt.limit = lim; 182aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 183aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 1842c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer opt.rate.mpu = mpu; 1852c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer opt.rate.overhead = overhead; 186d5f46f9cc3856af532e852ef29fd7ddfd141faf0Jesper Dangaard Brouer if (tc_calc_rtable(&opt.rate, rtab, Rcell_log, mtu) < 0) { 187aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "TBF: failed to calculate rate table.\n"); 188aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 189aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 190aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger opt.buffer = tc_calc_xmittime(opt.rate.rate, buffer); 191d5f46f9cc3856af532e852ef29fd7ddfd141faf0Jesper Dangaard Brouer 192aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt.peakrate.rate) { 1932c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer opt.peakrate.mpu = mpu; 1942c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer opt.peakrate.overhead = overhead; 195d5f46f9cc3856af532e852ef29fd7ddfd141faf0Jesper Dangaard Brouer if (tc_calc_rtable(&opt.peakrate, ptab, Pcell_log, mtu) < 0) { 196aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "TBF: failed to calculate peak rate table.\n"); 197aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 198aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 199aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger opt.mtu = tc_calc_xmittime(opt.peakrate.rate, mtu); 200aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 201aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 202228569c3ff79468f4c7580fd88b0d6a34ebdc311n); tail = NLMSG_TAIL(n); 203aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); 204aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(n, 2024, TCA_TBF_PARMS, &opt, sizeof(opt)); 205aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(n, 3024, TCA_TBF_RTAB, rtab, 1024); 206aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt.peakrate.rate) 207aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(n, 4096, TCA_TBF_PTAB, ptab, 1024); 208228569c3ff79468f4c7580fd88b0d6a34ebdc311void *) NLMSG_TAIL(n) - (void *) tail; tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 209aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 210aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 211aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 212aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) 213aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 214aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct rtattr *tb[TCA_TBF_PTAB+1]; 215aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct tc_tbf_qopt *qopt; 216aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger double buffer, mtu; 217aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger double latency; 218aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger SPRINT_BUF(b1); 219aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger SPRINT_BUF(b2); 220aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 221aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt == NULL) 222aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 223aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 2243b3ecd31c1e513f029ebbb83f2e808553de0a741tb, TCA_TBF_PTAB, opt); parse_rtattr_nested(tb, TCA_TBF_PTAB, opt); 225aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 226aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (tb[TCA_TBF_PARMS] == NULL) 227aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 228aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 229aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger qopt = RTA_DATA(tb[TCA_TBF_PARMS]); 230aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (RTA_PAYLOAD(tb[TCA_TBF_PARMS]) < sizeof(*qopt)) 231aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 232aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "rate %s ", sprint_rate(qopt->rate.rate, b1)); 23376dc0aa28fe6fa78e263bf0250c1e42c584dd544Patrick McHardy buffer = tc_calc_xmitsize(qopt->rate.rate, qopt->buffer); 234aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (show_details) { 235aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "burst %s/%u mpu %s ", sprint_size(buffer, b1), 236aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 1<<qopt->rate.cell_log, sprint_size(qopt->rate.mpu, b2)); 237aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 238aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "burst %s ", sprint_size(buffer, b1)); 239aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 240aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (show_raw) 241aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "[%08x] ", qopt->buffer); 242aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (qopt->peakrate.rate) { 243aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "peakrate %s ", sprint_rate(qopt->peakrate.rate, b1)); 244aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (qopt->mtu || qopt->peakrate.mpu) { 24576dc0aa28fe6fa78e263bf0250c1e42c584dd544Patrick McHardy mtu = tc_calc_xmitsize(qopt->peakrate.rate, qopt->mtu); 246aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (show_details) { 247aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "mtu %s/%u mpu %s ", sprint_size(mtu, b1), 248aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 1<<qopt->peakrate.cell_log, sprint_size(qopt->peakrate.mpu, b2)); 249aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 250aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "minburst %s ", sprint_size(mtu, b1)); 251aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 252aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (show_raw) 253aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "[%08x] ", qopt->mtu); 254aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 255aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 256aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 257aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (show_raw) 258aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "limit %s ", sprint_size(qopt->limit, b1)); 259aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 2608f34caafbdbc8f87d228d577872591e138caadb1Patrick McHardy latency = TIME_UNITS_PER_SEC*(qopt->limit/(double)qopt->rate.rate) - tc_core_tick2time(qopt->buffer); 261aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (qopt->peakrate.rate) { 2628f34caafbdbc8f87d228d577872591e138caadb1Patrick McHardy double lat2 = TIME_UNITS_PER_SEC*(qopt->limit/(double)qopt->peakrate.rate) - tc_core_tick2time(qopt->mtu); 263aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (lat2 > latency) 264aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger latency = lat2; 265aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 2668f34caafbdbc8f87d228d577872591e138caadb1Patrick McHardy fprintf(f, "lat %s ", sprint_time(latency, b1)); 267aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 2682c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer if (qopt->rate.overhead) { 2692c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer fprintf(f, "overhead %d", qopt->rate.overhead); 2702c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer } 2712c42579f9c15bdd9d0fdd5e6571c382bfa31399aJesper Dangaard Brouer 272aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 273aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 274aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 27595812b56a5a66e7e9a21744cfe8bc0bb9791ea98net[shemminger]!kaberstruct qdisc_util tbf_qdisc_util = { 276f2f99e2eefdbd9cb6a750b19a7b3036db351b983osdl.net!shemminger .id = "tbf", 277f2f99e2eefdbd9cb6a750b19a7b3036db351b983osdl.net!shemminger .parse_qopt = tbf_parse_opt, 278f2f99e2eefdbd9cb6a750b19a7b3036db351b983osdl.net!shemminger .print_qopt = tbf_print_opt, 279aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}; 280aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 281