]> git.proxmox.com Git - mirror_iproute2.git/blob - tc/tc_qevent.c
Merge branch 'main' into next
[mirror_iproute2.git] / tc / tc_qevent.c
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
13 void 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
22 int 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
45 out:
46 fprintf(stderr, "Unknown qevent `%s'\n", name);
47 return -1;
48 }
49
50 int 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
68 void 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
96 bool 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
111 int 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
131 static 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
146 static 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
162 static void print_block_idx(FILE *f, __u32 block_idx)
163 {
164 print_uint(PRINT_ANY, "block", " block %u", block_idx);
165 }
166
167 int 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
199 int 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
206 void 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
213 int 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 }