iproute2/tc/tc_qevent.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
   2
   3/*
   4 * Helpers for handling qevents.
   5 */
   6
   7#include <stdio.h>
   8#include <string.h>
   9
  10#include "tc_qevent.h"
  11#include "utils.h"
  12
  13void qevents_init(struct qevent_util *qevents)
  14{
  15        if (!qevents)
  16                return;
  17
  18        for (; qevents->id; qevents++)
  19                memset(qevents->data, 0, qevents->data_size);
  20}
  21
  22int qevent_parse(struct qevent_util *qevents, int *p_argc, char ***p_argv)
  23{
  24        char **argv = *p_argv;
  25        int argc = *p_argc;
  26        const char *name = *argv;
  27        int err;
  28
  29        if (!qevents)
  30                goto out;
  31
  32        for (; qevents->id; qevents++) {
  33                if (strcmp(name, qevents->id) == 0) {
  34                        NEXT_ARG();
  35                        err = qevents->parse_qevent(qevents, &argc, &argv);
  36                        if (err)
  37                                return err;
  38
  39                        *p_argc = argc;
  40                        *p_argv = argv;
  41                        return 0;
  42                }
  43        }
  44
  45out:
  46        fprintf(stderr, "Unknown qevent `%s'\n", name);
  47        return -1;
  48}
  49
  50int qevents_read(struct qevent_util *qevents, struct rtattr **tb)
  51{
  52        int err;
  53
  54        if (!qevents)
  55                return 0;
  56
  57        for (; qevents->id; qevents++) {
  58                if (tb[qevents->attr]) {
  59                        err = qevents->read_qevent(qevents, tb);
  60                        if (err)
  61                                return err;
  62                }
  63        }
  64
  65        return 0;
  66}
  67
  68void qevents_print(struct qevent_util *qevents, FILE *f)
  69{
  70        int first = true;
  71
  72        if (!qevents)
  73                return;
  74
  75        for (; qevents->id; qevents++) {
  76                struct qevent_base *qeb = qevents->data;
  77
  78                if (qeb->block_idx) {
  79                        if (first) {
  80                                open_json_array(PRINT_JSON, "qevents");
  81                                first = false;
  82                        }
  83
  84                        open_json_object(NULL);
  85                        print_string(PRINT_ANY, "kind", "qevent %s", qevents->id);
  86                        qevents->print_qevent(qevents, f);
  87                        print_string(PRINT_FP, NULL, "%s", " ");
  88                        close_json_object();
  89                }
  90        }
  91
  92        if (!first)
  93                close_json_array(PRINT_ANY, "");
  94}
  95
  96bool qevents_have_block(struct qevent_util *qevents, __u32 block_idx)
  97{
  98        if (!qevents)
  99                return false;
 100
 101        for (; qevents->id; qevents++) {
 102                struct qevent_base *qeb = qevents->data;
 103
 104                if (qeb->block_idx == block_idx)
 105                        return true;
 106        }
 107
 108        return false;
 109}
 110
 111int qevents_dump(struct qevent_util *qevents, struct nlmsghdr *n)
 112{
 113        int err;
 114
 115        if (!qevents)
 116                return 0;
 117
 118        for (; qevents->id; qevents++) {
 119                struct qevent_base *qeb = qevents->data;
 120
 121                if (qeb->block_idx) {
 122                        err = qevents->dump_qevent(qevents, n);
 123                        if (err)
 124                                return err;
 125                }
 126        }
 127
 128        return 0;
 129}
 130
 131static int parse_block_idx(const char *arg, struct qevent_base *qeb)
 132{
 133        if (qeb->block_idx) {
 134                fprintf(stderr, "Qevent block index already specified\n");
 135                return -1;
 136        }
 137
 138        if (get_unsigned(&qeb->block_idx, arg, 10) || !qeb->block_idx) {
 139                fprintf(stderr, "Illegal qevent block index\n");
 140                return -1;
 141        }
 142
 143        return 0;
 144}
 145
 146static int read_block_idx(struct rtattr *attr, struct qevent_base *qeb)
 147{
 148        if (qeb->block_idx) {
 149                fprintf(stderr, "Qevent block index already specified\n");
 150                return -1;
 151        }
 152
 153        qeb->block_idx = rta_getattr_u32(attr);
 154        if (!qeb->block_idx) {
 155                fprintf(stderr, "Illegal qevent block index\n");
 156                return -1;
 157        }
 158
 159        return 0;
 160}
 161
 162static void print_block_idx(FILE *f, __u32 block_idx)
 163{
 164        print_uint(PRINT_ANY, "block", " block %u", block_idx);
 165}
 166
 167int qevent_parse_plain(struct qevent_util *qu, int *p_argc, char ***p_argv)
 168{
 169        struct qevent_plain *qe = qu->data;
 170        char **argv = *p_argv;
 171        int argc = *p_argc;
 172
 173        if (qe->base.block_idx) {
 174                fprintf(stderr, "Duplicate qevent\n");
 175                return -1;
 176        }
 177
 178        while (argc > 0) {
 179                if (strcmp(*argv, "block") == 0) {
 180                        NEXT_ARG();
 181                        if (parse_block_idx(*argv, &qe->base))
 182                                return -1;
 183                } else {
 184                        break;
 185                }
 186                NEXT_ARG_FWD();
 187        }
 188
 189        if (!qe->base.block_idx) {
 190                fprintf(stderr, "Unspecified qevent block index\n");
 191                return -1;
 192        }
 193
 194        *p_argc = argc;
 195        *p_argv = argv;
 196        return 0;
 197}
 198
 199int qevent_read_plain(struct qevent_util *qu, struct rtattr **tb)
 200{
 201        struct qevent_plain *qe = qu->data;
 202
 203        return read_block_idx(tb[qu->attr], &qe->base);
 204}
 205
 206void qevent_print_plain(struct qevent_util *qu, FILE *f)
 207{
 208        struct qevent_plain *qe = qu->data;
 209
 210        print_block_idx(f, qe->base.block_idx);
 211}
 212
 213int qevent_dump_plain(struct qevent_util *qu, struct nlmsghdr *n)
 214{
 215        struct qevent_plain *qe = qu->data;
 216
 217        return addattr32(n, 1024, qu->attr, qe->base.block_idx);
 218}
 219