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