libnl: /data/src/libnl/lib/route/qdisc/mqprio.c Source File

libnl 3.12.0

mqprio.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2/*
3 * Copyright (c) 2018 Volodymyr Bendiuga <volodymyr.bendiuga@westermo.se>
4 */
5
6#include "nl-default.h"
7
8#include <netlink/netlink.h>
9#include <netlink/utils.h>
10#include <netlink/route/qdisc.h>
11#include <netlink/route/qdisc/mqprio.h>
12
13#include "tc-api.h"
14
15/** @cond SKIP */
16struct rtnl_mqprio {
17 uint8_t qm_num_tc;
18 uint8_t qm_prio_map[TC_QOPT_BITMASK + 1];
19 uint8_t qm_hw;
20 uint16_t qm_count[TC_QOPT_MAX_QUEUE];
21 uint16_t qm_offset[TC_QOPT_MAX_QUEUE];
22 uint16_t qm_mode;
23 uint16_t qm_shaper;
24 uint64_t qm_min_rate[TC_QOPT_MAX_QUEUE];
25 uint64_t qm_max_rate[TC_QOPT_MAX_QUEUE];
26 uint32_t qm_mask;
27};
28
29#define SCH_MQPRIO_ATTR_NUMTC (1 << 0)
30#define SCH_MQPRIO_ATTR_PRIOMAP (1 << 1)
31#define SCH_MQPRIO_ATTR_HW (1 << 2)
32#define SCH_MQPRIO_ATTR_QUEUE (1 << 3)
33#define SCH_MQPRIO_ATTR_MODE (1 << 4)
34#define SCH_MQPRIO_ATTR_SHAPER (1 << 5)
35#define SCH_MQPRIO_ATTR_MIN_RATE (1 << 6)
36#define SCH_MQPRIO_ATTR_MAX_RATE (1 << 7)
37/** @endcond */
38
39static struct nla_policy mqprio_policy[TCA_MQPRIO_MAX + 1] = {
40 [TCA_MQPRIO_MODE] = { .minlen = sizeof(uint16_t) },
41 [TCA_MQPRIO_SHAPER] = { .minlen = sizeof(uint16_t) },
42 [TCA_MQPRIO_MIN_RATE64] = { .type = NLA_NESTED },
43 [TCA_MQPRIO_MAX_RATE64] = { .type = NLA_NESTED },
44};
45
46static int mqprio_msg_parser(struct rtnl_tc *tc, void *data)
47{
48 struct rtnl_mqprio *mqprio = data;
49 struct tc_mqprio_qopt *qopt;
50 struct nlattr *attr;
51 int len, rem, i, err;
52
53 if (tc->tc_opts->d_size < sizeof(*qopt))
54 return -NLE_INVAL;
55
56 qopt = (struct tc_mqprio_qopt *) tc->tc_opts->d_data;
57 mqprio->qm_num_tc = qopt->num_tc;
58 mqprio->qm_hw = qopt->hw;
59 memcpy(mqprio->qm_prio_map, qopt->prio_tc_map,
60 TC_QOPT_MAX_QUEUE * sizeof(uint8_t));
61 memcpy(mqprio->qm_count, qopt->count,
62 TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
63 memcpy(mqprio->qm_offset, qopt->offset,
64 TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
65 mqprio->qm_mask = (SCH_MQPRIO_ATTR_NUMTC | SCH_MQPRIO_ATTR_PRIOMAP |
66 SCH_MQPRIO_ATTR_QUEUE | SCH_MQPRIO_ATTR_HW);
67
68 len = tc->tc_opts->d_size - NLA_ALIGN(sizeof(*qopt));
69
70 if (len > 0) {
71 struct nlattr *tb[TCA_MQPRIO_MAX + 1];
72
73 err = nla_parse(tb, TCA_MQPRIO_MAX, (struct nlattr *)
74 ((char *) tc->tc_opts->d_data + NLA_ALIGN(sizeof(*qopt))),
75 len, mqprio_policy);
76 if (err < 0)
77 return err;
78
79 if (tb[TCA_MQPRIO_MODE]) {
80 mqprio->qm_mode = nla_get_u16(tb[TCA_MQPRIO_MODE]);
81 mqprio->qm_mask |= SCH_MQPRIO_ATTR_MODE;
82 }
83
84 if (tb[TCA_MQPRIO_SHAPER]) {
85 mqprio->qm_shaper = nla_get_u16(tb[TCA_MQPRIO_SHAPER]);
86 mqprio->qm_mask |= SCH_MQPRIO_ATTR_SHAPER;
87 }
88
89 if (tb[TCA_MQPRIO_MIN_RATE64]) {
90 i = 0;
91 nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64], rem) {
92 if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
93 return -EINVAL;
94
95 if (i >= mqprio->qm_num_tc)
96 break;
97
98 mqprio->qm_min_rate[i] = nla_get_u64(attr);
99 }
100
101 mqprio->qm_mask |= SCH_MQPRIO_ATTR_MIN_RATE;
102 }
103
104 if (tb[TCA_MQPRIO_MAX_RATE64]) {
105 i = 0;
106 nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64], rem) {
107 if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
108 return -EINVAL;
109
110 if (i >= mqprio->qm_num_tc)
111 break;
112
113 mqprio->qm_max_rate[i] = nla_get_u64(attr);
114 }
115
116 mqprio->qm_mask |= SCH_MQPRIO_ATTR_MAX_RATE;
117 }
118 }
119
120 return 0;
121}
122
123static int mqprio_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
124{
125 struct rtnl_mqprio *mqprio = data;
126 struct tc_mqprio_qopt qopt = { 0 };
127 struct nlattr *nest = NULL;
128 int i;
129
130 if (!mqprio ||
131 !(mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC) ||
132 !(mqprio->qm_mask & SCH_MQPRIO_ATTR_PRIOMAP) ||
133 !(mqprio->qm_mask & SCH_MQPRIO_ATTR_QUEUE))
134 return -NLE_INVAL;
135
136 if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_HW))
137 qopt.hw = 0;
138 else
139 qopt.hw = mqprio->qm_hw;
140
141 qopt.num_tc = mqprio->qm_num_tc;
142 memcpy(qopt.count, mqprio->qm_count, TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
143 memcpy(qopt.offset, mqprio->qm_offset, TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
144 memcpy(qopt.prio_tc_map, mqprio->qm_prio_map, TC_QOPT_MAX_QUEUE * sizeof(uint8_t));
145
146 nlmsg_append(msg, &qopt, sizeof(qopt), NL_DONTPAD);
147
148 if (mqprio->qm_hw) {
149 if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MODE)
150 NLA_PUT_U16(msg, TCA_MQPRIO_MODE, mqprio->qm_mode);
151
152 if (mqprio->qm_mask & SCH_MQPRIO_ATTR_SHAPER)
153 NLA_PUT_U16(msg, TCA_MQPRIO_SHAPER, mqprio->qm_shaper);
154
155 if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MIN_RATE) {
156 nest = nla_nest_start(msg, TCA_MQPRIO_MIN_RATE64);
157 if (!nest)
158 goto nla_put_failure;
159
160 for (i = 0; i < mqprio->qm_num_tc; i++) {
161 if (nla_put(msg, TCA_MQPRIO_MIN_RATE64,
162 sizeof(mqprio->qm_min_rate[i]),
163 &mqprio->qm_min_rate[i]) < 0)
164 goto nla_nest_cancel;
165 }
166 nla_nest_end(msg, nest);
167 }
168
169 if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MAX_RATE) {
170 nest = nla_nest_start(msg, TCA_MQPRIO_MAX_RATE64);
171 if (!nest)
172 goto nla_put_failure;
173
174 for (i = 0; i < mqprio->qm_num_tc; i++) {
175 if (nla_put(msg, TCA_MQPRIO_MAX_RATE64,
176 sizeof(mqprio->qm_max_rate[i]),
177 &mqprio->qm_max_rate[i]) < 0)
178 goto nla_nest_cancel;
179 }
180 nla_nest_end(msg, nest);
181 }
182 }
183
184 return 0;
185
186 nla_nest_cancel:
187 nla_nest_cancel(msg, nest);
188 return -NLE_MSGSIZE;
189
190nla_put_failure:
191 return -NLE_MSGSIZE;
192}
193
194static void mqprio_dump_line(struct rtnl_tc *tc, void *data,
195 struct nl_dump_params *p)
196{
197 struct rtnl_mqprio *mqprio = data;
198
199 if (mqprio)
200 nl_dump(p, " num_tc %u", mqprio->qm_num_tc);
201}
202
203static void mqprio_dump_details(struct rtnl_tc *tc, void *data,
204 struct nl_dump_params *p)
205{
206 struct rtnl_mqprio *mqprio = data;
207 int i;
208
209 if (!mqprio)
210 return;
211
212 nl_dump(p, "map [");
213
214 for (i = 0; i <= TC_QOPT_BITMASK; i++)
215 nl_dump(p, "%u%s", mqprio->qm_prio_map[i],
216 i < TC_QOPT_BITMASK ? " " : "");
217
218 nl_dump(p, "]\n");
219 nl_new_line(p);
220}
221
222/**
223 * @name Attribute Modification
224 * @{
225 */
226
227/**
228 * Set number of traffic classes.
229 * @arg qdisc MQPRIO qdisc to be modified.
230 * @arg num_tc Number of traffic classes to create.
231 * @return 0 on success or a negative error code.
232 */
233int rtnl_qdisc_mqprio_set_num_tc(struct rtnl_qdisc *qdisc, int num_tc)
234{
235 struct rtnl_mqprio *mqprio;
236
237 if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
238 return -NLE_NOMEM;
239
240 mqprio->qm_num_tc = num_tc;
241 mqprio->qm_mask |= SCH_MQPRIO_ATTR_NUMTC;
242 return 0;
243}
244
245/**
246 * Get number of traffic classes of MQPRIO qdisc.
247 * @arg qdisc MQPRIO qdisc.
248 * @return Number of traffic classes or a negative error code.
249 */
250int rtnl_qdisc_mqprio_get_num_tc(struct rtnl_qdisc *qdisc)
251{
252 struct rtnl_mqprio *mqprio;
253
254 if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
255 return -NLE_INVAL;
256
257 if (mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC)
258 return mqprio->qm_num_tc;
259 else
260 return -NLE_MISSING_ATTR;
261}
262
263/**
264 * Set priomap of the MQPRIO qdisc.
265 * @arg qdisc MQPRIO qdisc to be modified.
266 * @arg priomap New priority mapping.
267 * @arg len Length of priomap (# of elements).
268 * @return 0 on success or a negative error code.
269 */
270int rtnl_qdisc_mqprio_set_priomap(struct rtnl_qdisc *qdisc, uint8_t priomap[],
271 int len)
272{
273 struct rtnl_mqprio *mqprio;
274 int i;
275
276 if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
277 return -NLE_NOMEM;
278
279 if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC))
280 return -NLE_MISSING_ATTR;
281
282 if (len > TC_QOPT_BITMASK + 1)
283 return -NLE_RANGE;
284
285 for (i = 0; i < len; i++) {
286 if (priomap[i] > mqprio->qm_num_tc)
287 return -NLE_RANGE;
288 }
289
290 memset(mqprio->qm_prio_map, 0, sizeof(mqprio->qm_prio_map));
291 memcpy(mqprio->qm_prio_map, priomap, len * sizeof(uint8_t));
292 mqprio->qm_mask |= SCH_MQPRIO_ATTR_PRIOMAP;
293
294 return 0;
295}
296
297/**
298 * Get priomap of MQPRIO qdisc.
299 * @arg qdisc MQPRIO qdisc.
300 * @return Priority mapping as array of size TC_QOPT_BANDS+1
301 * or NULL if an error occured.
302 */
303uint8_t *rtnl_qdisc_mqprio_get_priomap(struct rtnl_qdisc *qdisc)
304{
305 struct rtnl_mqprio *mqprio;
306
307 if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
308 return NULL;
309
310 if (mqprio->qm_mask & SCH_MQPRIO_ATTR_PRIOMAP)
311 return mqprio->qm_prio_map;
312 else
313 return NULL;
314}
315
316/**
317 * Offload to HW or run in SW (default).
318 * @arg qdisc MQPRIO qdisc to be modified.
319 * @arg offload 1 - offload to HW, 0 - run in SW only (default).
320 * @return 0 on success or a negative error code.
321 */
322int rtnl_qdisc_mqprio_hw_offload(struct rtnl_qdisc *qdisc, int offload)
323{
324 struct rtnl_mqprio *mqprio;
325
326 if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
327 return -NLE_NOMEM;
328
329 switch (offload) {
330 case 0:
331 case 1:
332 mqprio->qm_hw = offload;
333 break;
334 default:
335 return -NLE_INVAL;
336 }
337
338 mqprio->qm_mask |= SCH_MQPRIO_ATTR_HW;
339 return 0;
340}
341
342/**
343 * Check whether running in HW or SW.
344 * @arg qdisc MQPRIO qdisc to be modified.
345 * @return 0 if running in SW, otherwise 1 (HW)
346 */
347int rtnl_qdisc_mqprio_get_hw_offload(struct rtnl_qdisc *qdisc)
348{
349 struct rtnl_mqprio *mqprio;
350
351 if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
352 return -NLE_INVAL;
353
354 if (mqprio->qm_mask & SCH_MQPRIO_ATTR_HW)
355 return mqprio->qm_hw;
356
357 return 0;
358}
359
360/**
361 * Set tc queue of the MQPRIO qdisc.
362 * @arg qdisc MQPRIO qdisc to be modified.
363 * @arg count count of queue range for each traffic class
364 * @arg offset offset of queue range for each traffic class
365 * @return 0 on success or a negative error code.
366 */
367int rtnl_qdisc_mqprio_set_queue(struct rtnl_qdisc *qdisc, uint16_t count[],
368 uint16_t offset[], int len)
369{
370 struct rtnl_mqprio *mqprio;
371
372 if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
373 return -NLE_NOMEM;
374
375 if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC))
376 return -NLE_MISSING_ATTR;
377
378 if (len < 0 || len > TC_QOPT_MAX_QUEUE)
379 return -NLE_RANGE;
380
381 memset(mqprio->qm_count, 0, sizeof(mqprio->qm_count));
382 memset(mqprio->qm_offset, 0, sizeof(mqprio->qm_offset));
383 memcpy(mqprio->qm_count, count, len * sizeof(uint16_t));
384 memcpy(mqprio->qm_offset, offset, len * sizeof(uint16_t));
385 mqprio->qm_mask |= SCH_MQPRIO_ATTR_QUEUE;
386
387 return 0;
388}
389
390/**
391 * Get tc queue of the MQPRIO qdisc.
392 * @arg qdisc MQPRIO qdisc to be modified.
393 * @arg count count of queue range for each traffic class
394 * @arg offset offset of queue range for each traffic class
395 * @return 0 on success or a negative error code.
396 */
397int rtnl_qdisc_mqprio_get_queue(struct rtnl_qdisc *qdisc, uint16_t *count,
398 uint16_t *offset)
399{
400 struct rtnl_mqprio *mqprio;
401
402 if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
403 return -NLE_INVAL;
404
405 if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_QUEUE))
406 return -NLE_MISSING_ATTR;
407
408 memcpy(count, mqprio->qm_count, TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
409 memcpy(offset, mqprio->qm_offset, TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
410
411 return 0;
412}
413
414/**
415 * Set mode of mqprio Qdisc
416 * @arg qdisc MQPRIO qdisc to be modified.
417 * @arg mode one of: TC_MQPRIO_MODE_DCB, TC_MQPRIO_MODE_CHANNEL
418 * @return 0 on success or a negative error code.
419 */
420int rtnl_qdisc_mqprio_set_mode(struct rtnl_qdisc *qdisc, uint16_t mode)
421{
422 struct rtnl_mqprio *mqprio;
423
424 if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
425 return -NLE_NOMEM;
426
427 if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_HW))
428 return -NLE_MISSING_ATTR;
429
430 mqprio->qm_mode = mode;
431 mqprio->qm_mask |= SCH_MQPRIO_ATTR_MODE;
432
433 return 0;
434}
435
436/**
437 * Get mode of mqprio Qdisc
438 * @arg qdisc MQPRIO qdisc.
439 * @return mode on success or negative error code.
440 */
441int rtnl_qdisc_mqprio_get_mode(struct rtnl_qdisc *qdisc)
442{
443 struct rtnl_mqprio *mqprio;
444
445 if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
446 return -NLE_INVAL;
447
448 if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MODE)
449 return mqprio->qm_mode;
450 else
451 return -NLE_MISSING_ATTR;
452}
453
454/**
455 * Set shaper of mqprio Qdisc
456 * @arg qdisc MQPRIO qdisc to be modified.
457 * @arg shaper one of: TC_MQPRIO_SHAPER_DCB, TC_MQPRIO_SHAPER_BW_RATE
458 * @return 0 on success or a negative error code.
459 */
460int rtnl_qdisc_mqprio_set_shaper(struct rtnl_qdisc *qdisc, uint16_t shaper)
461{
462 struct rtnl_mqprio *mqprio;
463
464 if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
465 return -NLE_NOMEM;
466
467 if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_HW))
468 return -NLE_MISSING_ATTR;
469
470 mqprio->qm_shaper = shaper;
471 mqprio->qm_mask |= SCH_MQPRIO_ATTR_SHAPER;
472
473 return 0;
474}
475
476/**
477 * Get shaper of mqprio Qdisc
478 * @arg qdisc MQPRIO qdisc.
479 * @return shaper on success or negative error code.
480 */
481int rtnl_qdisc_mqprio_get_shaper(struct rtnl_qdisc *qdisc)
482{
483 struct rtnl_mqprio *mqprio;
484
485 if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
486 return -NLE_INVAL;
487
488 if (mqprio->qm_mask & SCH_MQPRIO_ATTR_SHAPER)
489 return mqprio->qm_shaper;
490 else
491 return -NLE_MISSING_ATTR;
492}
493
494/**
495 * Set minimum value of bandwidth rate limit for each traffic class
496 * @arg qdisc MQPRIO qdisc.
497 * @arg min minimum rate for each traffic class
498 * @return 0 on success or a negative error code.
499 */
500int rtnl_qdisc_mqprio_set_min_rate(struct rtnl_qdisc *qdisc, uint64_t min[], int len)
501{
502 struct rtnl_mqprio *mqprio;
503
504 if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
505 return -NLE_NOMEM;
506
507 if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_SHAPER))
508 return -NLE_MISSING_ATTR;
509
510 if (mqprio->qm_shaper != TC_MQPRIO_SHAPER_BW_RATE)
511 return -NLE_INVAL;
512
513 if (len < 0 || len > TC_QOPT_MAX_QUEUE)
514 return -NLE_RANGE;
515
516 memset(mqprio->qm_min_rate, 0, sizeof(mqprio->qm_min_rate));
517 memcpy(mqprio->qm_min_rate, min, len * sizeof(uint64_t));
518 mqprio->qm_mask |= SCH_MQPRIO_ATTR_MIN_RATE;
519
520 return 0;
521}
522
523/**
524 * Get minimum value of bandwidth rate limit for each traffic class
525 * @arg qdisc MQPRIO qdisc.
526 * @arg min minimum rate for each traffic class
527 * @return 0 on success or a negative error code.
528 */
529int rtnl_qdisc_mqprio_get_min_rate(struct rtnl_qdisc *qdisc, uint64_t *min)
530{
531 struct rtnl_mqprio *mqprio;
532
533 if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
534 return -NLE_INVAL;
535
536 if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MIN_RATE) {
537 memcpy(min, mqprio->qm_min_rate, TC_QOPT_MAX_QUEUE * sizeof(uint64_t));
538 return 0;
539 }
540
541 return -NLE_MISSING_ATTR;
542}
543
544/**
545 * Set maximum value of bandwidth rate limit for each traffic class
546 * @arg qdisc MQPRIO qdisc.
547 * @arg max maximum rate for each traffic class
548 * @return 0 on success or a negative error code.
549 */
550int rtnl_qdisc_mqprio_set_max_rate(struct rtnl_qdisc *qdisc, uint64_t max[], int len)
551{
552 struct rtnl_mqprio *mqprio;
553
554 if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
555 return -NLE_NOMEM;
556
557 if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_SHAPER))
558 return -NLE_MISSING_ATTR;
559
560 if (mqprio->qm_shaper != TC_MQPRIO_SHAPER_BW_RATE)
561 return -NLE_INVAL;
562
563 if (len < 0 || len > TC_QOPT_MAX_QUEUE)
564 return -NLE_RANGE;
565
566 memset(mqprio->qm_max_rate, 0, sizeof(mqprio->qm_max_rate));
567 memcpy(mqprio->qm_max_rate, max, len * sizeof(uint64_t));
568 mqprio->qm_mask |= SCH_MQPRIO_ATTR_MAX_RATE;
569
570 return 0;
571}
572
573/**
574 * Get maximum value of bandwidth rate limit for each traffic class
575 * @arg qdisc MQPRIO qdisc.
576 * @arg min maximum rate for each traffic class
577 * @return 0 on success or a negative error code.
578 */
579int rtnl_qdisc_mqprio_get_max_rate(struct rtnl_qdisc *qdisc, uint64_t *max)
580{
581 struct rtnl_mqprio *mqprio;
582
583 if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
584 return -NLE_INVAL;
585
586 if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MAX_RATE) {
587 memcpy(max, mqprio->qm_max_rate, TC_QOPT_MAX_QUEUE * sizeof(uint64_t));
588 return 0;
589 }
590
591 return -NLE_MISSING_ATTR;
592}
593
594/** @} */
595
596static struct rtnl_tc_ops mqprio_ops = {
597 .to_kind = "mqprio",
598 .to_type = RTNL_TC_TYPE_QDISC,
599 .to_size = sizeof(struct rtnl_mqprio),
600 .to_msg_parser = mqprio_msg_parser,
601 .to_dump = {
602 [NL_DUMP_LINE] = mqprio_dump_line,
603 [NL_DUMP_DETAILS] = mqprio_dump_details,
604 },
605 .to_msg_fill = mqprio_msg_fill,
606};
607
608static void _nl_init mqprio_init(void)
609{
610 rtnl_tc_register(&mqprio_ops);
611}
612
613static void _nl_exit mqprio_exit(void)
614{
615 rtnl_tc_unregister(&mqprio_ops);
616}
617
618/** @} */
nla_get_u16
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition attr.c:664
NLA_PUT_U16
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
Definition attr.h:219
nla_parse
int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, const struct nla_policy *policy)
Create attribute index based on a stream of attributes.
Definition attr.c:245
nla_get_u64
uint64_t nla_get_u64(const struct nlattr *nla)
Return payload of u64 attribute.
Definition attr.c:769
nla_type
int nla_type(const struct nlattr *nla)
Return type of the attribute.
Definition attr.c:108
nla_nest_start
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition attr.c:974
nla_nest_cancel
void nla_nest_cancel(struct nl_msg *msg, const struct nlattr *attr)
Cancel the addition of a nested attribute.
Definition attr.c:1066
nla_for_each_nested
#define nla_for_each_nested(pos, nla, rem)
Iterate over a stream of nested attributes.
Definition attr.h:331
nla_nest_end
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition attr.c:1037
nla_put
int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data)
Add a unspecific attribute to netlink message.
Definition attr.c:505
NLA_NESTED
@ NLA_NESTED
Nested attributes.
Definition attr.h:42
nlmsg_append
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
Definition msg.c:456
rtnl_tc_data_peek
void * rtnl_tc_data_peek(struct rtnl_tc *tc)
Returns the private data of the traffic control object.
Definition tc.c:1065
TC_CAST
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
Definition tc.h:50
rtnl_tc_data
void * rtnl_tc_data(struct rtnl_tc *)
Return pointer to private data of traffic control object.
Definition tc.c:1079
rtnl_tc_register
int rtnl_tc_register(struct rtnl_tc_ops *)
Register a traffic control module.
Definition tc.c:1018
rtnl_tc_unregister
void rtnl_tc_unregister(struct rtnl_tc_ops *)
Unregister a traffic control module.
Definition tc.c:1052
nl_dump
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition utils.c:1015
nl_new_line
void nl_new_line(struct nl_dump_params *params)
Handle a new line while dumping.
Definition utils.c:966
NL_DUMP_LINE
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition types.h:20
NL_DUMP_DETAILS
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition types.h:21
nl_dump_params
Dumping parameters.
Definition types.h:32
nla_policy
Attribute validation policy.
Definition attr.h:66
rtnl_qdisc
Definition nl-route.h:119
rtnl_tc
Definition nl-route.h:115