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