iproute2/tc/tc_stab.c
<<
>>
Prefs
   1/*
   2 * tc_stab.c            "tc qdisc ... stab *".
   3 *
   4 *              This program is free software; you can redistribute it and/or
   5 *              modify it under the terms of the GNU General Public License
   6 *              as published by the Free Software Foundation; either version
   7 *              2 of the License, or (at your option) any later version.
   8 *
   9 * Authors:     Jussi Kivilinna, <jussi.kivilinna@mbnet.fi>
  10 *
  11 */
  12
  13#include <stdio.h>
  14#include <stdlib.h>
  15#include <unistd.h>
  16#include <fcntl.h>
  17#include <math.h>
  18#include <sys/socket.h>
  19#include <sys/param.h>
  20#include <netinet/in.h>
  21#include <arpa/inet.h>
  22#include <string.h>
  23#include <malloc.h>
  24
  25#include "utils.h"
  26#include "tc_util.h"
  27#include "tc_core.h"
  28#include "tc_common.h"
  29
  30static void stab_help(void)
  31{
  32        fprintf(stderr,
  33                "Usage: ... stab [ mtu BYTES ] [ tsize SLOTS ] [ mpu BYTES ]\n"
  34                "                [ overhead BYTES ] [ linklayer TYPE ] ...\n"
  35                "   mtu       : max packet size we create rate map for {2047}\n"
  36                "   tsize     : how many slots should size table have {512}\n"
  37                "   mpu       : minimum packet size used in rate computations\n"
  38                "   overhead  : per-packet size overhead used in rate computations\n"
  39                "   linklayer : adapting to a linklayer e.g. atm\n"
  40                "Example: ... stab overhead 20 linklayer atm\n");
  41
  42}
  43
  44int check_size_table_opts(struct tc_sizespec *s)
  45{
  46        return s->linklayer >= LINKLAYER_ETHERNET || s->mpu != 0 ||
  47                                                        s->overhead != 0;
  48}
  49
  50int parse_size_table(int *argcp, char ***argvp, struct tc_sizespec *sp)
  51{
  52        char **argv = *argvp;
  53        int argc = *argcp;
  54        struct tc_sizespec s = {};
  55
  56        NEXT_ARG();
  57        if (matches(*argv, "help") == 0) {
  58                stab_help();
  59                return -1;
  60        }
  61        while (argc > 0) {
  62                if (matches(*argv, "mtu") == 0) {
  63                        NEXT_ARG();
  64                        if (s.mtu)
  65                                duparg("mtu", *argv);
  66                        if (get_u32(&s.mtu, *argv, 10))
  67                                invarg("mtu", "invalid mtu");
  68                } else if (matches(*argv, "mpu") == 0) {
  69                        NEXT_ARG();
  70                        if (s.mpu)
  71                                duparg("mpu", *argv);
  72                        if (get_u32(&s.mpu, *argv, 10))
  73                                invarg("mpu", "invalid mpu");
  74                } else if (matches(*argv, "overhead") == 0) {
  75                        NEXT_ARG();
  76                        if (s.overhead)
  77                                duparg("overhead", *argv);
  78                        if (get_integer(&s.overhead, *argv, 10))
  79                                invarg("overhead", "invalid overhead");
  80                } else if (matches(*argv, "tsize") == 0) {
  81                        NEXT_ARG();
  82                        if (s.tsize)
  83                                duparg("tsize", *argv);
  84                        if (get_u32(&s.tsize, *argv, 10))
  85                                invarg("tsize", "invalid table size");
  86                } else if (matches(*argv, "linklayer") == 0) {
  87                        NEXT_ARG();
  88                        if (s.linklayer != LINKLAYER_UNSPEC)
  89                                duparg("linklayer", *argv);
  90                        if (get_linklayer(&s.linklayer, *argv))
  91                                invarg("linklayer", "invalid linklayer");
  92                } else
  93                        break;
  94                argc--; argv++;
  95        }
  96
  97        if (!check_size_table_opts(&s))
  98                return -1;
  99
 100        *sp = s;
 101        *argvp = argv;
 102        *argcp = argc;
 103        return 0;
 104}
 105
 106void print_size_table(FILE *fp, const char *prefix, struct rtattr *rta)
 107{
 108        struct rtattr *tb[TCA_STAB_MAX + 1];
 109
 110        SPRINT_BUF(b1);
 111
 112        parse_rtattr_nested(tb, TCA_STAB_MAX, rta);
 113
 114        if (tb[TCA_STAB_BASE]) {
 115                struct tc_sizespec s = {0};
 116
 117                memcpy(&s, RTA_DATA(tb[TCA_STAB_BASE]),
 118                                MIN(RTA_PAYLOAD(tb[TCA_STAB_BASE]), sizeof(s)));
 119
 120                fprintf(fp, "%s", prefix);
 121                if (s.linklayer)
 122                        fprintf(fp, "linklayer %s ",
 123                                        sprint_linklayer(s.linklayer, b1));
 124                if (s.overhead)
 125                        fprintf(fp, "overhead %d ", s.overhead);
 126                if (s.mpu)
 127                        fprintf(fp, "mpu %u ", s.mpu);
 128                if (s.mtu)
 129                        fprintf(fp, "mtu %u ", s.mtu);
 130                if (s.tsize)
 131                        fprintf(fp, "tsize %u ", s.tsize);
 132        }
 133
 134#if 0
 135        if (tb[TCA_STAB_DATA]) {
 136                unsigned int i, j, dlen;
 137                __u16 *data = RTA_DATA(tb[TCA_STAB_DATA]);
 138
 139                dlen = RTA_PAYLOAD(tb[TCA_STAB_DATA]) / sizeof(__u16);
 140
 141                fprintf(fp, "\n%sstab data:", prefix);
 142                for (i = 0; i < dlen/12; i++) {
 143                        fprintf(fp, "\n%s %3u:", prefix, i * 12);
 144                        for (j = 0; i * 12 + j < dlen; j++)
 145                                fprintf(fp, " %05x", data[i * 12 + j]);
 146                }
 147        }
 148#endif
 149}
 150