libnl  3.6.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 
39 static 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 
46 static 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 
69 static 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 
110 static 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 
128 static 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 
148 static 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 
191 static 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 
211 static 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 
276 nla_put_failure:
277  return -NLE_MSGSIZE;
278 }
279 
280 static struct rtnl_tc_ops htb_qdisc_ops;
281 static struct rtnl_tc_ops htb_class_ops;
282 
283 static 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 
288 static 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  */
304 uint32_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 
315 int 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  */
338 uint32_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  */
354 int 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 
368 uint32_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 
379 int 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  */
401 uint32_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  */
422 int 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  */
442 int 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  */
454 int 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  */
477 uint32_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  */
498 int 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  */
518 int 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  */
530 int 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  */
551 uint32_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  */
567 int 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  */
587 uint32_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  */
603 int 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  */
625 uint32_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  */
645 int 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  */
669 int 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  */
693 int 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 
709 static 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 
718 static 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 
730 static void __init htb_init(void)
731 {
732  rtnl_tc_register(&htb_qdisc_ops);
733  rtnl_tc_register(&htb_class_ops);
734 }
735 
736 static 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
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:1018
void rtnl_tc_unregister(struct rtnl_tc_ops *ops)
Unregister a traffic control module.
Definition: tc.c:1052
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:1114
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