1839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna/* 2839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna * tc_stab.c "tc qdisc ... stab *". 3839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna * 4839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna * This program is free software; you can redistribute it and/or 5839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna * modify it under the terms of the GNU General Public License 6839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna * as published by the Free Software Foundation; either version 7839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna * 2 of the License, or (at your option) any later version. 8839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna * 9839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna * Authors: Jussi Kivilinna, <jussi.kivilinna@mbnet.fi> 10839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna * 11839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna */ 12839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 13839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include <stdio.h> 14839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include <stdlib.h> 15839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include <unistd.h> 16839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include <syslog.h> 17839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include <fcntl.h> 18839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include <math.h> 19839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include <sys/socket.h> 20839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include <netinet/in.h> 21839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include <arpa/inet.h> 22839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include <string.h> 23839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include <malloc.h> 24839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 25839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include "utils.h" 26839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include "tc_util.h" 27839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include "tc_core.h" 28839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#include "tc_common.h" 29839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 30839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinnastatic void stab_help(void) 31839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna{ 32839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna fprintf(stderr, 33839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna "Usage: ... stab [ mtu BYTES ] [ tsize SLOTS ] [ mpu BYTES ] \n" 34839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna " [ overhead BYTES ] [ linklayer TYPE ] ...\n" 35839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna " mtu : max packet size we create rate map for {2047}\n" 36839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna " tsize : how many slots should size table have {512}\n" 37839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna " mpu : minimum packet size used in rate computations\n" 38839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna " overhead : per-packet size overhead used in rate computations\n" 39839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna " linklayer : adapting to a linklayer e.g. atm\n" 40839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna "Example: ... stab overhead 20 linklayer atm\n"); 41839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 42839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna return; 43839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna} 44839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 45839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinnaint check_size_table_opts(struct tc_sizespec *s) 46839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna{ 47839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna return s->linklayer >= LINKLAYER_ETHERNET || s->mpu != 0 || 48839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna s->overhead != 0; 49839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna} 50839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 51839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinnaint parse_size_table(int *argcp, char ***argvp, struct tc_sizespec *sp) 52839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna{ 53839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna char **argv = *argvp; 54839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna int argc = *argcp; 55839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna struct tc_sizespec s; 56839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 57839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna memset(&s, 0, sizeof(s)); 58839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 59839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna NEXT_ARG(); 60839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (matches(*argv, "help") == 0) { 61839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna stab_help(); 62839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna return -1; 63839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } 64839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna while (argc > 0) { 65839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (matches(*argv, "mtu") == 0) { 66839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna NEXT_ARG(); 67839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (s.mtu) 68839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna duparg("mtu", *argv); 69839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (get_u32(&s.mtu, *argv, 10)) { 70839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna invarg("mtu", "invalid mtu"); 71839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna return -1; 72839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } 73839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } else if (matches(*argv, "mpu") == 0) { 74839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna NEXT_ARG(); 75839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (s.mpu) 76839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna duparg("mpu", *argv); 77839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (get_u32(&s.mpu, *argv, 10)) { 78839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna invarg("mpu", "invalid mpu"); 79839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna return -1; 80839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } 81839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } else if (matches(*argv, "overhead") == 0) { 82839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna NEXT_ARG(); 83839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (s.overhead) 84839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna duparg("overhead", *argv); 85839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (get_integer(&s.overhead, *argv, 10)) { 86839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna invarg("overhead", "invalid overhead"); 87839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna return -1; 88839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } 89839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } else if (matches(*argv, "tsize") == 0) { 90839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna NEXT_ARG(); 91839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (s.tsize) 92839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna duparg("tsize", *argv); 93839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (get_u32(&s.tsize, *argv, 10)) { 94839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna invarg("tsize", "invalid table size"); 95839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna return -1; 96839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } 97839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } else if (matches(*argv, "linklayer") == 0) { 98839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna NEXT_ARG(); 99839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (s.linklayer != LINKLAYER_UNSPEC) 100839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna duparg("linklayer", *argv); 101839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (get_linklayer(&s.linklayer, *argv)) { 102839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna invarg("linklayer", "invalid linklayer"); 103839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna return -1; 104839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } 105839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } else 106839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna break; 107839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna argc--; argv++; 108839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } 109839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 110839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (!check_size_table_opts(&s)) 111839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna return -1; 112839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 113839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna *sp = s; 114839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna *argvp = argv; 115839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna *argcp = argc; 116839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna return 0; 117839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna} 118839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 119839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinnavoid print_size_table(FILE *fp, const char *prefix, struct rtattr *rta) 120839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna{ 121839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna struct rtattr *tb[TCA_STAB_MAX + 1]; 122839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna SPRINT_BUF(b1); 123839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 124839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna parse_rtattr_nested(tb, TCA_STAB_MAX, rta); 125839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 126839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (tb[TCA_STAB_BASE]) { 127839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna struct tc_sizespec s = {0}; 128839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna memcpy(&s, RTA_DATA(tb[TCA_STAB_BASE]), 129839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna MIN(RTA_PAYLOAD(tb[TCA_STAB_BASE]), sizeof(s))); 130839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 131839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna fprintf(fp, "%s", prefix); 132839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (s.linklayer) 133839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna fprintf(fp, "linklayer %s ", 134839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna sprint_linklayer(s.linklayer, b1)); 135839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (s.overhead) 136839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna fprintf(fp, "overhead %d ", s.overhead); 137839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (s.mpu) 138839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna fprintf(fp, "mpu %u ", s.mpu); 139839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (s.mtu) 140839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna fprintf(fp, "mtu %u ", s.mtu); 141839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (s.tsize) 142839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna fprintf(fp, "tsize %u ", s.tsize); 143839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } 144839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 145839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#if 0 146839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna if (tb[TCA_STAB_DATA]) { 147839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna unsigned i, j, dlen; 148839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna __u16 *data = RTA_DATA(tb[TCA_STAB_DATA]); 149839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna dlen = RTA_PAYLOAD(tb[TCA_STAB_DATA]) / sizeof(__u16); 150839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 151839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna fprintf(fp, "\n%sstab data:", prefix); 152839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna for (i = 0; i < dlen/12; i++) { 153839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna fprintf(fp, "\n%s %3u:", prefix, i * 12); 154839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna for (j = 0; i * 12 + j < dlen; j++) 155839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna fprintf(fp, " %05x", data[i * 12 + j]); 156839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } 157839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna } 158839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna#endif 159839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna} 160839c8456fbe08fc2497857673805b84dffb45507Jussi Kivilinna 161