1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* 2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * q_gred.c GRED. 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 * 9ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger * Authors: J Hadi Salim(hadi@nortelnetworks.com) 10ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger * code ruthlessly ripped from 11ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger * Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */ 14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h> 16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h> 17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h> 18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h> 19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h> 20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h> 21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h> 22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <arpa/inet.h> 23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h> 241b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet#include <math.h> 25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h" 27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "tc_util.h" 28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "tc_red.h" 30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#if 0 33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define DPRINTF(format,args...) fprintf(stderr,format,##args) 34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#else 35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define DPRINTF(format,args...) 36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#endif 37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void explain(void) 39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Usage: ... gred DP drop-probability limit BYTES " 41aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger "min BYTES max BYTES\n"); 42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " avpkt BYTES burst PACKETS probability PROBABILITY " 43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger "bandwidth KBPS\n"); 44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " [prio value]\n"); 45aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr," OR ...\n"); 46aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr," gred setup DPs <num of DPs> default <default DP> " 47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger "[grio]\n"); 48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 49aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 50ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemmingerstatic int init_gred(struct qdisc_util *qu, int argc, char **argv, 51ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger struct nlmsghdr *n) 52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct rtattr *tail; 55cb4bd0ec8dcba856d1ebf8b3f72b79f669dad0f4Stephen Hemminger struct tc_gred_sopt opt = { 0 }; 56ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger int dps = 0; 57ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger int def_dp = -1; 58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (argc > 0) { 60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger DPRINTF(stderr,"init_gred: invoked with %s\n",*argv); 61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "DPs") == 0) { 62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger DPRINTF(stderr,"init_gred: next_arg with %s\n",*argv); 64ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger dps = strtol(*argv, (char **)NULL, 10); 65ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger if (dps < 0 || dps >MAX_DPs) { 66ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger fprintf(stderr, "DPs =%d\n", dps); 67aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Illegal \"DPs\"\n"); 68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "GRED: only %d DPs are " 69ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger "currently supported\n",MAX_DPs); 70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 71aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 72aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "default") == 0) { 73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 74ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger def_dp = strtol(*argv, (char **)NULL, 10); 751558971d43bbcd5db7f9be966654482a96179bf1Stephen Hemminger if (dps == 0) { 76aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "\"default DP\" must be " 77ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger "defined after DPs\n"); 78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 80ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger if (def_dp < 0 || def_dp > dps) { 81ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger fprintf(stderr, 82ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger "\"default DP\" must be less than %d\n", 83ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger opt.DPs); 84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "grio") == 0) { 87cb4bd0ec8dcba856d1ebf8b3f72b79f669dad0f4Stephen Hemminger opt.grio = 1; 88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "help") == 0) { 89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain(); 90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "What is \"%s\"?\n", *argv); 93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain(); 94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; argv++; 97ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger } 98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 99ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger if (!dps || def_dp == -1) { 100ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger fprintf(stderr, "Illegal gred setup parameters \n"); 101ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger return -1; 102ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger } 103ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger 104ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger opt.DPs = dps; 105ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger opt.def_DP = def_dp; 106ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger 107ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger DPRINTF("TC_GRED: sending DPs=%d default=%d\n",opt.DPs,opt.def_DP); 108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger n->nlmsg_flags|=NLM_F_CREATE; 109228569c3ff79468f4c7580fd88b0d6a34ebdc311n); tail = NLMSG_TAIL(n); 110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); 111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(n, 1024, TCA_GRED_DPS, &opt, sizeof(struct tc_gred_sopt)); 112228569c3ff79468f4c7580fd88b0d6a34ebdc311void *) NLMSG_TAIL(n) - (void *) tail; tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 113ebde878097a4494c47e682aff16233f2fe6a495eStephen Hemminger return 0; 114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* 116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger*/ 118aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int gred_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) 119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int ok=0; 121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct tc_gred_qopt opt; 122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned burst = 0; 123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned avpkt = 0; 124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger double probability = 0.02; 125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned rate = 0; 126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int wlog; 127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u8 sbuf[256]; 128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct rtattr *tail; 1291b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet __u32 max_P; 130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&opt, 0, sizeof(opt)); 132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (argc > 0) { 134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "limit") == 0) { 135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_size(&opt.limit, *argv)) { 137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Illegal \"limit\"\n"); 138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "setup") == 0) { 142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ok) { 143aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Illegal \"setup\"\n"); 144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return init_gred(qu,argc-1, argv+1,n); 147ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger 148aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "min") == 0) { 149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_size(&opt.qth_min, *argv)) { 151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Illegal \"min\"\n"); 152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "max") == 0) { 156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_size(&opt.qth_max, *argv)) { 158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Illegal \"max\"\n"); 159aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 162aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "DP") == 0) { 163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger opt.DP=strtol(*argv, (char **)NULL, 10); 165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger DPRINTF ("\n ******* DP =%u\n",opt.DP); 166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt.DP >MAX_DPs) { /* need a better error check */ 167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "DP =%u \n",opt.DP); 168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Illegal \"DP\"\n"); 169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "GRED: only %d DPs are currently supported\n",MAX_DPs); 170aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 173aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "burst") == 0) { 174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 175aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_unsigned(&burst, *argv, 0)) { 176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Illegal \"burst\"\n"); 177aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 180aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "avpkt") == 0) { 181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 182aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_size(&avpkt, *argv)) { 183aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Illegal \"avpkt\"\n"); 184aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 185aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 186aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 187aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "probability") == 0) { 188aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 189aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (sscanf(*argv, "%lg", &probability) != 1) { 190aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Illegal \"probability\"\n"); 191aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 192aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 193aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 194aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "prio") == 0) { 195aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 196aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger opt.prio=strtol(*argv, (char **)NULL, 10); 197aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger /* some error check here */ 198aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 199aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "bandwidth") == 0) { 200aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 201aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_rate(&rate, *argv)) { 202aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Illegal \"bandwidth\"\n"); 203aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 204aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 205aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ok++; 206aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "help") == 0) { 207aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain(); 208aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 209aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 210aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "What is \"%s\"?\n", *argv); 211aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger explain(); 212aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 213aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 214aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; argv++; 215aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 216aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 217aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rate == 0) 218aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger get_rate(&rate, "10Mbit"); 219aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 220ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet if (!opt.qth_min || !opt.qth_max || !opt.limit || !avpkt || 221aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger (opt.DP<0)) { 222ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet fprintf(stderr, "Required parameter (min, max, limit, " 223ddf216c8631195549dbf84e4ebe3da1d77b45ce0Florian Westphal "avpkt, DP) is missing\n"); 224aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 225aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 226ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet if (!burst) { 227ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet burst = (2 * opt.qth_min + opt.qth_max) / (3 * avpkt); 228ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet fprintf(stderr, "GRED: set burst to %u\n", burst); 229ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet } 230aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 231aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((wlog = tc_red_eval_ewma(opt.qth_min, burst, avpkt)) < 0) { 232aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "GRED: failed to calculate EWMA constant.\n"); 233aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 234aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 235aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (wlog >= 10) 236ab15aeacf5a106cfb8e72cd6760e8cf134161cebEric Dumazet fprintf(stderr, "GRED: WARNING. Burst %d seems to be too " 237aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger "large.\n", burst); 238aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger opt.Wlog = wlog; 239aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((wlog = tc_red_eval_P(opt.qth_min, opt.qth_max, probability)) < 0) { 240aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "GRED: failed to calculate probability.\n"); 241aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 242aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 243aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger opt.Plog = wlog; 244aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((wlog = tc_red_eval_idle_damping(opt.Wlog, avpkt, rate, sbuf)) < 0) 245aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger { 246aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "GRED: failed to calculate idle damping " 247aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger "table.\n"); 248aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 249aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 250aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger opt.Scell_log = wlog; 251aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 252228569c3ff79468f4c7580fd88b0d6a34ebdc311n); tail = NLMSG_TAIL(n); 253aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); 254aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(n, 1024, TCA_GRED_PARMS, &opt, sizeof(opt)); 255aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(n, 1024, TCA_GRED_STAB, sbuf, 256); 2561b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet max_P = probability * pow(2, 32); 2571b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet addattr32(n, 1024, TCA_GRED_MAX_P, max_P); 258228569c3ff79468f4c7580fd88b0d6a34ebdc311void *) NLMSG_TAIL(n) - (void *) tail; tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 259aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 260aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 261aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 262aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int gred_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) 263aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 2641b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet struct rtattr *tb[TCA_GRED_MAX + 1]; 265aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct tc_gred_qopt *qopt; 2661b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet __u32 *max_p = NULL; 267aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int i; 268aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger SPRINT_BUF(b1); 269aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger SPRINT_BUF(b2); 270aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger SPRINT_BUF(b3); 271aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger SPRINT_BUF(b4); 272aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger SPRINT_BUF(b5); 273aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 274aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (opt == NULL) 275aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 276aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 2771b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet parse_rtattr_nested(tb, TCA_GRED_MAX, opt); 278aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 279aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (tb[TCA_GRED_PARMS] == NULL) 280aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 281a5a6f1e80db7b124de236eb0dabafc7996c5f2f0osdl.net!shemminger 2821b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet if (tb[TCA_GRED_MAX_P] && 2831b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet RTA_PAYLOAD(tb[TCA_GRED_MAX_P]) >= sizeof(__u32) * MAX_DPs) 2841b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet max_p = RTA_DATA(tb[TCA_GRED_MAX_P]); 2851b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet 286aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger qopt = RTA_DATA(tb[TCA_GRED_PARMS]); 287aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (RTA_PAYLOAD(tb[TCA_GRED_PARMS]) < sizeof(*qopt)*MAX_DPs) { 288aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f,"\n GRED received message smaller than expected\n"); 289aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 290aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 291ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger 292aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* Bad hack! should really return a proper message as shown above*/ 293aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 294aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger for (i=0;i<MAX_DPs;i++, qopt++) { 295aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (qopt->DP >= MAX_DPs) continue; 296aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "\n DP:%d (prio %d) Average Queue %s Measured " 297aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger "Queue %s ", 298aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger qopt->DP, 299aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger qopt->prio, 300aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sprint_size(qopt->qave, b4), 301aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sprint_size(qopt->backlog, b5)); 302aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "\n\t Packet drops: %d (forced %d early %d) ", 303aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger qopt->forced+qopt->early, 304aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger qopt->forced, 305aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger qopt->early); 306aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "\n\t Packet totals: %u (bytes %u) ", 307aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger qopt->packets, 308aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger qopt->bytesin); 309aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (show_details) 310aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(f, "\n limit %s min %s max %s ", 311aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sprint_size(qopt->limit, b1), 312aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sprint_size(qopt->qth_min, b2), 313aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sprint_size(qopt->qth_max, b3)); 3141b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet fprintf(f, "ewma %u ", qopt->Wlog); 3151b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet if (max_p) 3161b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet fprintf(f, "probability %lg ", max_p[i] / pow(2, 32)); 3171b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet else 3181b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet fprintf(f, "Plog %u ", qopt->Plog); 3191b6f0bb5be5d71fd62ed6ccbc3665adc6e747b82Eric Dumazet fprintf(f, "Scell_log %u", qopt->Scell_log); 320aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 321aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 322aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 323aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 32495812b56a5a66e7e9a21744cfe8bc0bb9791ea98net[shemminger]!kaberstruct qdisc_util gred_qdisc_util = { 325f2f99e2eefdbd9cb6a750b19a7b3036db351b983osdl.net!shemminger .id = "gred", 326f2f99e2eefdbd9cb6a750b19a7b3036db351b983osdl.net!shemminger .parse_qopt = gred_parse_opt, 327f2f99e2eefdbd9cb6a750b19a7b3036db351b983osdl.net!shemminger .print_qopt = gred_print_opt, 328aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}; 329