libnl 3.10.0
htb.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2/*
3 * Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
4 * Copyright (c) 2005-2006 Petr Gotthard <petr.gotthard@siemens.com>
5 * Copyright (c) 2005-2006 Siemens AG Oesterreich
6 */
7
8/**
9 * @ingroup qdisc
10 * @ingroup class
11 * @defgroup qdisc_htb Hierachical Token Bucket (HTB)
12 * @{
13 */
14
15#include "nl-default.h"
16
17#include <netlink/netlink.h>
18#include <netlink/cache.h>
19#include <netlink/utils.h>
20#include <netlink/route/qdisc.h>
21#include <netlink/route/class.h>
22#include <netlink/route/link.h>
23#include <netlink/route/qdisc/htb.h>
24
25#include "tc-api.h"
26
27/** @cond SKIP */
28struct rtnl_htb_qdisc {
29 uint32_t qh_rate2quantum;
30 uint32_t qh_defcls;
31 uint32_t qh_mask;
32 uint32_t qh_direct_pkts;
33};
34
35struct rtnl_htb_class {
36 uint32_t ch_prio;
37 struct rtnl_ratespec ch_rate;
38 struct rtnl_ratespec ch_ceil;
39 uint32_t ch_rbuffer;
40 uint32_t ch_cbuffer;
41 uint32_t ch_quantum;
42 uint32_t ch_mask;
43 uint32_t ch_level;
44};
45
46#define SCH_HTB_HAS_RATE2QUANTUM 0x01
47#define SCH_HTB_HAS_DEFCLS 0x02
48
49#define SCH_HTB_HAS_PRIO 0x001
50#define SCH_HTB_HAS_RATE 0x002
51#define SCH_HTB_HAS_CEIL 0x004
52#define SCH_HTB_HAS_RBUFFER 0x008
53#define SCH_HTB_HAS_CBUFFER 0x010
54#define SCH_HTB_HAS_QUANTUM 0x020
55#define SCH_HTB_HAS_LEVEL 0x040
56/** @endcond */
57
58static struct nla_policy htb_policy[TCA_HTB_MAX+1] = {
59 [TCA_HTB_INIT] = { .minlen = sizeof(struct tc_htb_glob) },
60 [TCA_HTB_PARMS] = { .minlen = sizeof(struct tc_htb_opt) },
61 [TCA_HTB_RATE64] = { .minlen = sizeof(uint64_t) },
62 [TCA_HTB_CEIL64] = { .minlen = sizeof(uint64_t) },
63};
64
65static int htb_qdisc_msg_parser(struct rtnl_tc *tc, void *data)
66{
67 struct nlattr *tb[TCA_HTB_MAX + 1];
68 struct rtnl_htb_qdisc *htb = data;
69 int err;
70
71 if ((err = tca_parse(tb, TCA_HTB_MAX, tc, htb_policy)) < 0)
72 return err;
73
74 if (tb[TCA_HTB_INIT]) {
75 struct tc_htb_glob opts;
76
77 nla_memcpy(&opts, tb[TCA_HTB_INIT], sizeof(opts));
78 htb->qh_rate2quantum = opts.rate2quantum;
79 htb->qh_defcls = opts.defcls;
80 htb->qh_direct_pkts = opts.direct_pkts;
81
82 htb->qh_mask = (SCH_HTB_HAS_RATE2QUANTUM | SCH_HTB_HAS_DEFCLS);
83 }
84
85 return 0;
86}
87
88static int htb_class_msg_parser(struct rtnl_tc *tc, void *data)
89{
90 struct nlattr *tb[TCA_HTB_MAX + 1];
91 struct rtnl_htb_class *htb = data;
92 int err;
93
94 if ((err = tca_parse(tb, TCA_HTB_MAX, tc, htb_policy)) < 0)
95 return err;
96
97 if (tb[TCA_HTB_PARMS]) {
98 struct tc_htb_opt opts;
99
100 nla_memcpy(&opts, tb[TCA_HTB_PARMS], sizeof(opts));
101 htb->ch_prio = opts.prio;
102 rtnl_copy_ratespec(&htb->ch_rate, &opts.rate);
103 rtnl_copy_ratespec(&htb->ch_ceil, &opts.ceil);
104
105 if (tb[TCA_HTB_RATE64])
106 nla_memcpy(&htb->ch_rate.rs_rate64, tb[TCA_HTB_RATE64], sizeof(uint64_t));
107 if (tb[TCA_HTB_CEIL64])
108 nla_memcpy(&htb->ch_ceil.rs_rate64, tb[TCA_HTB_CEIL64], sizeof(uint64_t));
109
110 htb->ch_rbuffer = rtnl_tc_calc_bufsize64(nl_ticks2us(opts.buffer),
111 htb->ch_rate.rs_rate64);
112 htb->ch_cbuffer = rtnl_tc_calc_bufsize64(nl_ticks2us(opts.cbuffer),
113 htb->ch_ceil.rs_rate64);
114 htb->ch_quantum = opts.quantum;
115 htb->ch_level = opts.level;
116
117 rtnl_tc_set_mpu(tc, htb->ch_rate.rs_mpu);
118 rtnl_tc_set_overhead(tc, htb->ch_rate.rs_overhead);
119
120 htb->ch_mask = (SCH_HTB_HAS_PRIO | SCH_HTB_HAS_RATE |
121 SCH_HTB_HAS_CEIL | SCH_HTB_HAS_RBUFFER |
122 SCH_HTB_HAS_CBUFFER | SCH_HTB_HAS_QUANTUM |
123 SCH_HTB_HAS_LEVEL);
124 }
125
126 return 0;
127}
128
129static void htb_qdisc_dump_line(struct rtnl_tc *tc, void *data,
130 struct nl_dump_params *p)
131{
132 struct rtnl_htb_qdisc *htb = data;
133
134 if (!htb)
135 return;
136
137 if (htb->qh_mask & SCH_HTB_HAS_RATE2QUANTUM)
138 nl_dump(p, " r2q %u", htb->qh_rate2quantum);
139
140 if (htb->qh_mask & SCH_HTB_HAS_DEFCLS) {
141 char buf[64];
142 nl_dump(p, " default-class %s",
143 rtnl_tc_handle2str(htb->qh_defcls, buf, sizeof(buf)));
144 }
145}
146
147static void htb_class_dump_line(struct rtnl_tc *tc, void *data,
148 struct nl_dump_params *p)
149{
150 struct rtnl_htb_class *htb = data;
151
152 if (!htb)
153 return;
154
155 if (htb->ch_mask & SCH_HTB_HAS_RATE) {
156 double r, rbit;
157 char *ru, *rubit;
158
159 r = nl_cancel_down_bytes(htb->ch_rate.rs_rate64, &ru);
160 rbit = nl_cancel_down_bits(htb->ch_rate.rs_rate64*8, &rubit);
161
162 nl_dump(p, " rate %.2f%s/s (%.0f%s) log %u",
163 r, ru, rbit, rubit, 1<<htb->ch_rate.rs_cell_log);
164 }
165}
166
167static void htb_class_dump_details(struct rtnl_tc *tc, void *data,
168 struct nl_dump_params *p)
169{
170 struct rtnl_htb_class *htb = data;
171
172 if (!htb)
173 return;
174
175 /* line 1 */
176 if (htb->ch_mask & SCH_HTB_HAS_CEIL) {
177 double r, rbit;
178 char *ru, *rubit;
179
180 r = nl_cancel_down_bytes(htb->ch_ceil.rs_rate64, &ru);
181 rbit = nl_cancel_down_bits(htb->ch_ceil.rs_rate64*8, &rubit);
182
183 nl_dump(p, " ceil %.2f%s/s (%.0f%s) log %u",
184 r, ru, rbit, rubit, 1<<htb->ch_ceil.rs_cell_log);
185 }
186
187 if (htb->ch_mask & SCH_HTB_HAS_PRIO)
188 nl_dump(p, " prio %u", htb->ch_prio);
189
190 if (htb->ch_mask & SCH_HTB_HAS_RBUFFER) {
191 double b;
192 char *bu;
193
194 b = nl_cancel_down_bytes(htb->ch_rbuffer, &bu);
195 nl_dump(p, " rbuffer %.2f%s", b, bu);
196 }
197
198 if (htb->ch_mask & SCH_HTB_HAS_CBUFFER) {
199 double b;
200 char *bu;
201
202 b = nl_cancel_down_bytes(htb->ch_cbuffer, &bu);
203 nl_dump(p, " cbuffer %.2f%s", b, bu);
204 }
205
206 if (htb->ch_mask & SCH_HTB_HAS_QUANTUM)
207 nl_dump(p, " quantum %u", htb->ch_quantum);
208}
209
210static int htb_qdisc_msg_fill(struct rtnl_tc *tc, void *data,
211 struct nl_msg *msg)
212{
213 struct rtnl_htb_qdisc *htb = data;
214 struct tc_htb_glob opts = {
215 .version = TC_HTB_PROTOVER,
216 .rate2quantum = 10,
217 };
218
219 if (htb) {
220 if (htb->qh_mask & SCH_HTB_HAS_RATE2QUANTUM)
221 opts.rate2quantum = htb->qh_rate2quantum;
222
223 if (htb->qh_mask & SCH_HTB_HAS_DEFCLS)
224 opts.defcls = htb->qh_defcls;
225 }
226
227 return nla_put(msg, TCA_HTB_INIT, sizeof(opts), &opts);
228}
229
230static int htb_class_msg_fill(struct rtnl_tc *tc, void *data,
231 struct nl_msg *msg)
232{
233 struct rtnl_htb_class *htb = data;
234 uint32_t mtu, rtable[RTNL_TC_RTABLE_SIZE], ctable[RTNL_TC_RTABLE_SIZE];
235 struct tc_htb_opt opts;
236 int buffer, cbuffer;
237 uint64_t rate64;
238 uint64_t ceil64;
239
240 if (!htb || !(htb->ch_mask & SCH_HTB_HAS_RATE))
241 BUG();
242
243 memset(&opts, 0, sizeof(opts));
244
245 /* if not set, zero (0) is used as priority */
246 if (htb->ch_mask & SCH_HTB_HAS_PRIO)
247 opts.prio = htb->ch_prio;
248
249 mtu = rtnl_tc_get_mtu(tc);
250
251 rtnl_tc_build_rate_table(tc, &htb->ch_rate, rtable);
252 rtnl_rcopy_ratespec(&opts.rate, &htb->ch_rate);
253 rate64 = htb->ch_rate.rs_rate64;
254
255 if (htb->ch_mask & SCH_HTB_HAS_CEIL) {
256 rtnl_tc_build_rate_table(tc, &htb->ch_ceil, ctable);
257 rtnl_rcopy_ratespec(&opts.ceil, &htb->ch_ceil);
258 ceil64 = htb->ch_ceil.rs_rate64;
259 } else {
260 /*
261 * If not set, configured rate is used as ceil, which implies
262 * no borrowing.
263 */
264 memcpy(&opts.ceil, &opts.rate, sizeof(struct tc_ratespec));
265 ceil64 = rate64;
266 }
267
268 if (htb->ch_mask & SCH_HTB_HAS_RBUFFER)
269 buffer = htb->ch_rbuffer;
270 else
271 buffer = rate64 / nl_get_psched_hz() + mtu; /* XXX */
272
273 opts.buffer = nl_us2ticks(rtnl_tc_calc_txtime64(buffer, rate64));
274
275 if (htb->ch_mask & SCH_HTB_HAS_CBUFFER)
276 cbuffer = htb->ch_cbuffer;
277 else
278 cbuffer = ceil64 / nl_get_psched_hz() + mtu; /* XXX */
279
280 opts.cbuffer = nl_us2ticks(rtnl_tc_calc_txtime64(cbuffer, ceil64));
281
282 if (htb->ch_mask & SCH_HTB_HAS_QUANTUM)
283 opts.quantum = htb->ch_quantum;
284
285 NLA_PUT(msg, TCA_HTB_PARMS, sizeof(opts), &opts);
286 if (rate64 > 0xFFFFFFFFull)
287 NLA_PUT(msg, TCA_HTB_RATE64, sizeof(uint64_t), &rate64);
288 if (ceil64 > 0xFFFFFFFFull)
289 NLA_PUT(msg, TCA_HTB_CEIL64, sizeof(uint64_t), &ceil64);
290 NLA_PUT(msg, TCA_HTB_RTAB, sizeof(rtable), &rtable);
291 NLA_PUT(msg, TCA_HTB_CTAB, sizeof(ctable), &ctable);
292
293 return 0;
294
295nla_put_failure:
296 return -NLE_MSGSIZE;
297}
298
299static struct rtnl_tc_ops htb_qdisc_ops;
300static struct rtnl_tc_ops htb_class_ops;
301
302static struct rtnl_htb_qdisc *htb_qdisc_data(struct rtnl_qdisc *qdisc, int *err)
303{
304 return rtnl_tc_data_check(TC_CAST(qdisc), &htb_qdisc_ops, err);
305}
306
307static struct rtnl_htb_class *htb_class_data(struct rtnl_class *class, int *err)
308{
309 return rtnl_tc_data_check(TC_CAST(class), &htb_class_ops, err);
310}
311
312/**
313 * @name Attribute Modifications
314 * @{
315 */
316
317/**
318 * Return rate/quantum ratio of HTB qdisc
319 * @arg qdisc htb qdisc object
320 *
321 * @return rate/quantum ratio or 0 if unspecified
322 */
324{
325 struct rtnl_htb_qdisc *htb;
326
327 if ((htb = htb_qdisc_data(qdisc, NULL)) &&
328 (htb->qh_mask & SCH_HTB_HAS_RATE2QUANTUM))
329 return htb->qh_rate2quantum;
330
331 return 0;
332}
333
334int rtnl_htb_set_rate2quantum(struct rtnl_qdisc *qdisc, uint32_t rate2quantum)
335{
336 struct rtnl_htb_qdisc *htb;
337 int err;
338
339 if (!(htb = htb_qdisc_data(qdisc, &err)))
340 return err;
341
342 htb->qh_rate2quantum = rate2quantum;
343 htb->qh_mask |= SCH_HTB_HAS_RATE2QUANTUM;
344
345 return 0;
346}
347
348/**
349 * Return default class of HTB qdisc
350 * @arg qdisc htb qdisc object
351 *
352 * Returns the classid of the class where all unclassified traffic
353 * goes to.
354 *
355 * @return classid or TC_H_UNSPEC if unspecified.
356 */
357uint32_t rtnl_htb_get_defcls(struct rtnl_qdisc *qdisc)
358{
359 struct rtnl_htb_qdisc *htb;
360
361 if ((htb = htb_qdisc_data(qdisc, NULL)) &&
362 htb->qh_mask & SCH_HTB_HAS_DEFCLS)
363 return htb->qh_defcls;
364
365 return TC_H_UNSPEC;
366}
367
368/**
369 * Set default class of the htb qdisc to the specified value
370 * @arg qdisc qdisc to change
371 * @arg defcls new default class
372 */
373int rtnl_htb_set_defcls(struct rtnl_qdisc *qdisc, uint32_t defcls)
374{
375 struct rtnl_htb_qdisc *htb;
376 int err;
377
378 if (!(htb = htb_qdisc_data(qdisc, &err)))
379 return err;
380
381 htb->qh_defcls = defcls;
382 htb->qh_mask |= SCH_HTB_HAS_DEFCLS;
383
384 return 0;
385}
386
387uint32_t rtnl_htb_get_prio(struct rtnl_class *class)
388{
389 struct rtnl_htb_class *htb;
390
391 if ((htb = htb_class_data(class, NULL)) &&
392 (htb->ch_mask & SCH_HTB_HAS_PRIO))
393 return htb->ch_prio;
394
395 return 0;
396}
397
398int rtnl_htb_set_prio(struct rtnl_class *class, uint32_t prio)
399{
400 struct rtnl_htb_class *htb;
401 int err;
402
403 if (!(htb = htb_class_data(class, &err)))
404 return err;
405
406 htb->ch_prio = prio;
407 htb->ch_mask |= SCH_HTB_HAS_PRIO;
408
409 return 0;
410}
411
412/**
413 * Return rate of HTB class
414 * @arg class htb class object
415 *
416 * @return Rate in bytes/s or 0 if unspecified. If the value
417 * cannot be represented as 32 bit integer, (1<<32) is returned.
418 * Use rtnl_htb_get_rate64() instead.
419 */
420uint32_t rtnl_htb_get_rate(struct rtnl_class *class)
421{
422 struct rtnl_htb_class *htb;
423
424 if ( !(htb = htb_class_data(class, NULL))
425 || !(htb->ch_mask & SCH_HTB_HAS_RATE))
426 return 0;
427
428 if (htb->ch_rate.rs_rate64 > 0xFFFFFFFFull)
429 return 0xFFFFFFFFull;
430
431 return htb->ch_rate.rs_rate64;
432}
433
434/**
435 * Return rate of HTB class
436 * @arg class htb class object
437 * @arg out_rate64 on success, the set rate.
438 *
439 * @return 0 on success or a negative error code.
440 */
441int rtnl_htb_get_rate64(struct rtnl_class *class, uint64_t *out_rate64)
442{
443 struct rtnl_htb_class *htb;
444
445 if (!(htb = htb_class_data(class, NULL)))
446 return -NLE_INVAL;
447 if (!(htb->ch_mask & SCH_HTB_HAS_RATE))
448 return -NLE_NOATTR;
449
450 *out_rate64 = htb->ch_rate.rs_rate64;
451 return 0;
452}
453
454/**
455 * Set rate of HTB class
456 * @arg class htb class object
457 * @arg rate new rate in bytes per second
458 *
459 * @return 0 on success or a negative error code.
460 */
461int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t rate)
462{
463 return rtnl_htb_set_rate64(class, rate);
464}
465
466/**
467 * Set rate of HTB class
468 * @arg class htb class object
469 * @arg rate new rate in bytes per second
470 *
471 * @return 0 on success or a negative error code.
472 */
473int rtnl_htb_set_rate64(struct rtnl_class *class, uint64_t rate)
474{
475 struct rtnl_htb_class *htb;
476 int err;
477
478 if (!(htb = htb_class_data(class, &err)))
479 return err;
480
481 htb->ch_rate.rs_cell_log = UINT8_MAX; /* use default value */
482 htb->ch_rate.rs_rate64 = rate;
483 htb->ch_mask |= SCH_HTB_HAS_RATE;
484
485 return 0;
486}
487
488/**
489 * Return ceil rate of HTB class
490 * @arg class htb class object
491 *
492 * @return Ceil rate in bytes/s or 0 if unspecified. If the value
493 * cannot be represented as 32 bit integer, (1<<32) is returned.
494 * Use rtnl_htb_get_ceil64() instead.
495 */
496uint32_t rtnl_htb_get_ceil(struct rtnl_class *class)
497{
498 struct rtnl_htb_class *htb;
499
500 if ( !(htb = htb_class_data(class, NULL))
501 || !(htb->ch_mask & SCH_HTB_HAS_CEIL))
502 return 0;
503
504 if (htb->ch_ceil.rs_rate64 > 0xFFFFFFFFull)
505 return 0xFFFFFFFFull;
506
507 return htb->ch_ceil.rs_rate64;
508}
509
510/**
511 * Return ceil rate of HTB class
512 * @arg class htb class object
513 * @arg out_ceil64 on success, the set ceil value.
514 *
515 * @return 0 on success or a negative error code.
516 */
517int rtnl_htb_get_ceil64(struct rtnl_class *class, uint64_t *out_ceil64)
518{
519 struct rtnl_htb_class *htb;
520
521 if (!(htb = htb_class_data(class, NULL)))
522 return -NLE_INVAL;
523 if (!(htb->ch_mask & SCH_HTB_HAS_CEIL))
524 return -NLE_NOATTR;
525
526 *out_ceil64 = htb->ch_ceil.rs_rate64;
527 return 0;
528}
529
530/**
531 * Set ceil rate of HTB class
532 * @arg class htb class object
533 * @arg ceil new ceil rate number of bytes per second
534 *
535 * @return 0 on success or a negative error code.
536 */
537int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil)
538{
539 return rtnl_htb_set_ceil64(class, ceil);
540}
541
542/**
543 * Set ceil rate of HTB class
544 * @arg class htb class object
545 * @arg ceil64 new ceil rate number of bytes per second
546 *
547 * @return 0 on success or a negative error code.
548 */
549int rtnl_htb_set_ceil64(struct rtnl_class *class, uint64_t ceil64)
550{
551 struct rtnl_htb_class *htb;
552 int err;
553
554 if (!(htb = htb_class_data(class, &err)))
555 return err;
556
557 htb->ch_ceil.rs_cell_log = UINT8_MAX; /* use default value */
558 htb->ch_ceil.rs_rate64 = ceil64;
559 htb->ch_mask |= SCH_HTB_HAS_CEIL;
560
561 return 0;
562}
563
564/**
565 * Return burst buffer size of HTB class
566 * @arg class htb class object
567 *
568 * @return Burst buffer size or 0 if unspecified
569 */
570uint32_t rtnl_htb_get_rbuffer(struct rtnl_class *class)
571{
572 struct rtnl_htb_class *htb;
573
574 if ((htb = htb_class_data(class, NULL)) &&
575 htb->ch_mask & SCH_HTB_HAS_RBUFFER)
576 return htb->ch_rbuffer;
577
578 return 0;
579}
580
581/**
582 * Set size of the rate bucket of HTB class.
583 * @arg class HTB class to be modified.
584 * @arg rbuffer New size in bytes.
585 */
586int rtnl_htb_set_rbuffer(struct rtnl_class *class, uint32_t rbuffer)
587{
588 struct rtnl_htb_class *htb;
589 int err;
590
591 if (!(htb = htb_class_data(class, &err)))
592 return err;
593
594 htb->ch_rbuffer = rbuffer;
595 htb->ch_mask |= SCH_HTB_HAS_RBUFFER;
596
597 return 0;
598}
599
600/**
601 * Return ceil burst buffer size of HTB class
602 * @arg class htb class object
603 *
604 * @return Ceil burst buffer size or 0 if unspecified
605 */
606uint32_t rtnl_htb_get_cbuffer(struct rtnl_class *class)
607{
608 struct rtnl_htb_class *htb;
609
610 if ((htb = htb_class_data(class, NULL)) &&
611 htb->ch_mask & SCH_HTB_HAS_CBUFFER)
612 return htb->ch_cbuffer;
613
614 return 0;
615}
616
617/**
618 * Set size of the ceil bucket of HTB class.
619 * @arg class HTB class to be modified.
620 * @arg cbuffer New size in bytes.
621 */
622int rtnl_htb_set_cbuffer(struct rtnl_class *class, uint32_t cbuffer)
623{
624 struct rtnl_htb_class *htb;
625 int err;
626
627 if (!(htb = htb_class_data(class, &err)))
628 return err;
629
630 htb->ch_cbuffer = cbuffer;
631 htb->ch_mask |= SCH_HTB_HAS_CBUFFER;
632
633 return 0;
634}
635
636/**
637 * Return quantum of HTB class
638 * @arg class htb class object
639 *
640 * See XXX[quantum def]
641 *
642 * @return Quantum or 0 if unspecified.
643 */
644uint32_t rtnl_htb_get_quantum(struct rtnl_class *class)
645{
646 struct rtnl_htb_class *htb;
647
648 if ((htb = htb_class_data(class, NULL)) &&
649 htb->ch_mask & SCH_HTB_HAS_QUANTUM)
650 return htb->ch_quantum;
651
652 return 0;
653}
654
655/**
656 * Set quantum of HTB class (overwrites value calculated based on r2q)
657 * @arg class htb class object
658 * @arg quantum new quantum in number of bytes
659 *
660 * See XXX[quantum def]
661 *
662 * @return 0 on success or a negative error code.
663 */
664int rtnl_htb_set_quantum(struct rtnl_class *class, uint32_t quantum)
665{
666 struct rtnl_htb_class *htb;
667 int err;
668
669 if (!(htb = htb_class_data(class, &err)))
670 return err;
671
672 htb->ch_quantum = quantum;
673 htb->ch_mask |= SCH_HTB_HAS_QUANTUM;
674
675 return 0;
676}
677
678/**
679 * Return level of HTB class
680 * @arg class htb class object
681 *
682 * Returns the level of the HTB class. Leaf classes are assigned level
683 * 0, root classes have level (TC_HTB_MAXDEPTH - 1). Interior classes
684 * have a level of one less than their parent.
685 *
686 * @return Level or a negative error code.
687 */
689{
690 struct rtnl_htb_class *htb;
691 int err = -NLE_OPNOTSUPP;
692
693 if ((htb = htb_class_data(class, &err)) &&
694 (htb->ch_mask & SCH_HTB_HAS_LEVEL))
695 return htb->ch_level;
696
697 return err;
698}
699
700/**
701 * Set level of HTB class
702 * @arg class htb class object
703 * @arg level new level of HTB class
704 *
705 * Sets the level of a HTB class. Note that changing the level of a HTB
706 * class does not change the level of its in kernel counterpart. This
707 * function is provided only to create HTB objects which can be compared
708 * against or filtered upon.
709 *
710 * @return 0 on success or a negative error code.
711 */
712int rtnl_htb_set_level(struct rtnl_class *class, int level)
713{
714 struct rtnl_htb_class *htb;
715 int err;
716
717 if (!(htb = htb_class_data(class, &err)))
718 return err;
719
720 htb->ch_level = level;
721 htb->ch_mask |= SCH_HTB_HAS_LEVEL;
722
723 return 0;
724}
725
726/** @} */
727
728static struct rtnl_tc_ops htb_qdisc_ops = {
729 .to_kind = "htb",
730 .to_type = RTNL_TC_TYPE_QDISC,
731 .to_size = sizeof(struct rtnl_htb_qdisc),
732 .to_msg_parser = htb_qdisc_msg_parser,
733 .to_dump[NL_DUMP_LINE] = htb_qdisc_dump_line,
734 .to_msg_fill = htb_qdisc_msg_fill,
735};
736
737static struct rtnl_tc_ops htb_class_ops = {
738 .to_kind = "htb",
739 .to_type = RTNL_TC_TYPE_CLASS,
740 .to_size = sizeof(struct rtnl_htb_class),
741 .to_msg_parser = htb_class_msg_parser,
742 .to_dump = {
743 [NL_DUMP_LINE] = htb_class_dump_line,
744 [NL_DUMP_DETAILS] = htb_class_dump_details,
745 },
746 .to_msg_fill = htb_class_msg_fill,
747};
748
749static void _nl_init htb_init(void)
750{
751 rtnl_tc_register(&htb_qdisc_ops);
752 rtnl_tc_register(&htb_class_ops);
753}
754
755static void _nl_exit htb_exit(void)
756{
757 rtnl_tc_unregister(&htb_qdisc_ops);
758 rtnl_tc_unregister(&htb_class_ops);
759}
760
761/** @} */
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
Definition attr.h:159
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition attr.c:353
int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data)
Add a unspecific attribute to netlink message.
Definition attr.c:503
char * rtnl_tc_handle2str(uint32_t handle, char *buf, size_t len)
Convert a traffic control handle to a character string (Reentrant).
Definition classid.c:109
int rtnl_htb_set_rbuffer(struct rtnl_class *class, uint32_t rbuffer)
Set size of the rate bucket of HTB class.
Definition htb.c:586
int rtnl_htb_set_level(struct rtnl_class *class, int level)
Set level of HTB class.
Definition htb.c:712
uint32_t rtnl_htb_get_ceil(struct rtnl_class *class)
Return ceil rate of HTB class.
Definition htb.c:496
int rtnl_htb_set_defcls(struct rtnl_qdisc *qdisc, uint32_t defcls)
Set default class of the htb qdisc to the specified value.
Definition htb.c:373
uint32_t rtnl_htb_get_defcls(struct rtnl_qdisc *qdisc)
Return default class of HTB qdisc.
Definition htb.c:357
int rtnl_htb_set_quantum(struct rtnl_class *class, uint32_t quantum)
Set quantum of HTB class (overwrites value calculated based on r2q)
Definition htb.c:664
int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t rate)
Set rate of HTB class.
Definition htb.c:461
int rtnl_htb_get_ceil64(struct rtnl_class *class, uint64_t *out_ceil64)
Return ceil rate of HTB class.
Definition htb.c:517
int rtnl_htb_get_rate64(struct rtnl_class *class, uint64_t *out_rate64)
Return rate of HTB class.
Definition htb.c:441
uint32_t rtnl_htb_get_rate2quantum(struct rtnl_qdisc *qdisc)
Return rate/quantum ratio of HTB qdisc.
Definition htb.c:323
int rtnl_htb_set_rate64(struct rtnl_class *class, uint64_t rate)
Set rate of HTB class.
Definition htb.c:473
uint32_t rtnl_htb_get_rbuffer(struct rtnl_class *class)
Return burst buffer size of HTB class.
Definition htb.c:570
int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil)
Set ceil rate of HTB class.
Definition htb.c:537
int rtnl_htb_set_cbuffer(struct rtnl_class *class, uint32_t cbuffer)
Set size of the ceil bucket of HTB class.
Definition htb.c:622
int rtnl_htb_set_ceil64(struct rtnl_class *class, uint64_t ceil64)
Set ceil rate of HTB class.
Definition htb.c:549
uint32_t rtnl_htb_get_quantum(struct rtnl_class *class)
Return quantum of HTB class.
Definition htb.c:644
uint32_t rtnl_htb_get_rate(struct rtnl_class *class)
Return rate of HTB class.
Definition htb.c:420
uint32_t rtnl_htb_get_cbuffer(struct rtnl_class *class)
Return ceil burst buffer size of HTB class.
Definition htb.c:606
int rtnl_htb_get_level(struct rtnl_class *class)
Return level of HTB class.
Definition htb.c:688
void rtnl_tc_set_mpu(struct rtnl_tc *tc, uint32_t mpu)
Set the Minimum Packet Unit (MPU) of a traffic control object.
Definition tc.c:398
void * rtnl_tc_data_check(struct rtnl_tc *, struct rtnl_tc_ops *, int *)
Check traffic control object type and return private data section.
Definition tc.c:1114
int rtnl_tc_build_rate_table(struct rtnl_tc *tc, struct rtnl_ratespec *, uint32_t *)
Compute a transmission time lookup table.
Definition tc.c:750
void rtnl_tc_set_overhead(struct rtnl_tc *tc, uint32_t overhead)
Set per packet overhead of a traffic control object.
Definition tc.c:427
uint32_t rtnl_tc_get_mtu(struct rtnl_tc *tc)
Return the MTU of traffic control object.
Definition tc.c:378
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
Definition tc.h:50
int rtnl_tc_register(struct rtnl_tc_ops *)
Register a traffic control module.
Definition tc.c:1018
void rtnl_tc_unregister(struct rtnl_tc_ops *)
Unregister a traffic control module.
Definition tc.c:1052
int nl_get_psched_hz(void)
Return the value of packet scheduler HZ.
Definition utils.c:571
double nl_cancel_down_bits(unsigned long long l, char **unit)
Cancel down a bit counter.
Definition utils.c:254
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition utils.c:1015
double nl_cancel_down_bytes(unsigned long long l, char **unit)
Cancel down a byte counter.
Definition utils.c:223
uint32_t nl_ticks2us(uint32_t ticks)
Convert ticks to micro seconds.
Definition utils.c:594
uint32_t nl_us2ticks(uint32_t us)
Convert micro seconds to ticks.
Definition utils.c:582
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition types.h:20
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition types.h:21
Dumping parameters.
Definition types.h:32
Attribute validation policy.
Definition attr.h:63
uint16_t minlen
Minimal length of payload required.
Definition attr.h:68
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition attr.h:65