iproute2/tc/q_cbs.c
<<
>>
Prefs
   1/*
   2 * q_cbs.c              CBS.
   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:     Vinicius Costa Gomes <vinicius.gomes@intel.com>
  10 *
  11 */
  12
  13#include <stdio.h>
  14#include <stdlib.h>
  15#include <unistd.h>
  16#include <fcntl.h>
  17#include <sys/socket.h>
  18#include <netinet/in.h>
  19#include <arpa/inet.h>
  20#include <string.h>
  21
  22#include "utils.h"
  23#include "tc_util.h"
  24
  25static void explain(void)
  26{
  27        fprintf(stderr,
  28                "Usage: ... cbs hicredit BYTES locredit BYTES sendslope BPS idleslope BPS\n"
  29                "          [offload 0|1]\n");
  30}
  31
  32static void explain1(const char *arg, const char *val)
  33{
  34        fprintf(stderr, "cbs: illegal value for \"%s\": \"%s\"\n", arg, val);
  35}
  36
  37static int cbs_parse_opt(struct qdisc_util *qu, int argc,
  38                         char **argv, struct nlmsghdr *n, const char *dev)
  39{
  40        struct tc_cbs_qopt opt = {};
  41        struct rtattr *tail;
  42
  43        while (argc > 0) {
  44                if (matches(*argv, "offload") == 0) {
  45                        NEXT_ARG();
  46                        if (opt.offload) {
  47                                fprintf(stderr, "cbs: duplicate \"offload\" specification\n");
  48                                return -1;
  49                        }
  50                        if (get_u8(&opt.offload, *argv, 0)) {
  51                                explain1("offload", *argv);
  52                                return -1;
  53                        }
  54                } else if (matches(*argv, "hicredit") == 0) {
  55                        NEXT_ARG();
  56                        if (opt.hicredit) {
  57                                fprintf(stderr, "cbs: duplicate \"hicredit\" specification\n");
  58                                return -1;
  59                        }
  60                        if (get_s32(&opt.hicredit, *argv, 0)) {
  61                                explain1("hicredit", *argv);
  62                                return -1;
  63                        }
  64                } else if (matches(*argv, "locredit") == 0) {
  65                        NEXT_ARG();
  66                        if (opt.locredit) {
  67                                fprintf(stderr, "cbs: duplicate \"locredit\" specification\n");
  68                                return -1;
  69                        }
  70                        if (get_s32(&opt.locredit, *argv, 0)) {
  71                                explain1("locredit", *argv);
  72                                return -1;
  73                        }
  74                } else if (matches(*argv, "sendslope") == 0) {
  75                        NEXT_ARG();
  76                        if (opt.sendslope) {
  77                                fprintf(stderr, "cbs: duplicate \"sendslope\" specification\n");
  78                                return -1;
  79                        }
  80                        if (get_s32(&opt.sendslope, *argv, 0)) {
  81                                explain1("sendslope", *argv);
  82                                return -1;
  83                        }
  84                } else if (matches(*argv, "idleslope") == 0) {
  85                        NEXT_ARG();
  86                        if (opt.idleslope) {
  87                                fprintf(stderr, "cbs: duplicate \"idleslope\" specification\n");
  88                                return -1;
  89                        }
  90                        if (get_s32(&opt.idleslope, *argv, 0)) {
  91                                explain1("idleslope", *argv);
  92                                return -1;
  93                        }
  94                } else if (strcmp(*argv, "help") == 0) {
  95                        explain();
  96                        return -1;
  97                } else {
  98                        fprintf(stderr, "cbs: unknown parameter \"%s\"\n", *argv);
  99                        explain();
 100                        return -1;
 101                }
 102                argc--; argv++;
 103        }
 104
 105        tail = addattr_nest(n, 1024, TCA_OPTIONS);
 106        addattr_l(n, 2024, TCA_CBS_PARMS, &opt, sizeof(opt));
 107        addattr_nest_end(n, tail);
 108        return 0;
 109}
 110
 111static int cbs_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
 112{
 113        struct rtattr *tb[TCA_CBS_MAX+1];
 114        struct tc_cbs_qopt *qopt;
 115
 116        if (opt == NULL)
 117                return 0;
 118
 119        parse_rtattr_nested(tb, TCA_CBS_MAX, opt);
 120
 121        if (tb[TCA_CBS_PARMS] == NULL)
 122                return -1;
 123
 124        qopt = RTA_DATA(tb[TCA_CBS_PARMS]);
 125        if (RTA_PAYLOAD(tb[TCA_CBS_PARMS])  < sizeof(*qopt))
 126                return -1;
 127
 128        print_int(PRINT_ANY, "hicredit", "hicredit %d ", qopt->hicredit);
 129        print_int(PRINT_ANY, "locredit", "locredit %d ", qopt->locredit);
 130        print_int(PRINT_ANY, "sendslope", "sendslope %d ", qopt->sendslope);
 131        print_int(PRINT_ANY, "idleslope", "idleslope %d ", qopt->idleslope);
 132        print_int(PRINT_ANY, "offload", "offload %d ", qopt->offload);
 133
 134        return 0;
 135}
 136
 137struct qdisc_util cbs_qdisc_util = {
 138        .id             = "cbs",
 139        .parse_qopt     = cbs_parse_opt,
 140        .print_qopt     = cbs_print_opt,
 141};
 142