htb.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * src/lib/htb.c HTB module for CLI lib
  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) 2010-2011 Thomas Graf <tgraf@suug.ch>
  10. */
  11. #include <netlink/cli/utils.h>
  12. #include <netlink/cli/tc.h>
  13. #include <netlink/route/qdisc/htb.h>
  14. static void print_qdisc_usage(void)
  15. {
  16. printf(
  17. "Usage: nl-qdisc-add [...] htb [OPTIONS]...\n"
  18. "\n"
  19. "OPTIONS\n"
  20. " --help Show this help text.\n"
  21. " --r2q=DIV Rate to quantum divisor (default: 10)\n"
  22. " --default=ID Default class for unclassified traffic.\n"
  23. "\n"
  24. "EXAMPLE"
  25. " # Create htb root qdisc 1: and direct unclassified traffic to class 1:10\n"
  26. " nl-qdisc-add --dev=eth1 --parent=root --handle=1: htb --default=10\n");
  27. }
  28. static void htb_parse_qdisc_argv(struct rtnl_tc *tc, int argc, char **argv)
  29. {
  30. struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) tc;
  31. for (;;) {
  32. int c, optidx = 0;
  33. enum {
  34. ARG_R2Q = 257,
  35. ARG_DEFAULT = 258,
  36. };
  37. static struct option long_opts[] = {
  38. { "help", 0, 0, 'h' },
  39. { "r2q", 1, 0, ARG_R2Q },
  40. { "default", 1, 0, ARG_DEFAULT },
  41. { 0, 0, 0, 0 }
  42. };
  43. c = getopt_long(argc, argv, "hv", long_opts, &optidx);
  44. if (c == -1)
  45. break;
  46. switch (c) {
  47. case 'h':
  48. print_qdisc_usage();
  49. return;
  50. case ARG_R2Q:
  51. rtnl_htb_set_rate2quantum(qdisc, nl_cli_parse_u32(optarg));
  52. break;
  53. case ARG_DEFAULT:
  54. rtnl_htb_set_defcls(qdisc, nl_cli_parse_u32(optarg));
  55. break;
  56. }
  57. }
  58. }
  59. static void print_class_usage(void)
  60. {
  61. printf(
  62. "Usage: nl-class-add [...] htb [OPTIONS]...\n"
  63. "\n"
  64. "OPTIONS\n"
  65. " --help Show this help text.\n"
  66. " --rate=RATE Rate limit.\n"
  67. " --ceil=RATE Rate limit while borrowing (default: equal to --rate).\n"
  68. " --prio=PRIO Priority, lower is served first (default: 0).\n"
  69. " --quantum=SIZE Amount of bytes to serve at once (default: rate/r2q).\n"
  70. " --burst=SIZE Max charge size of rate burst buffer (default: auto).\n"
  71. " --cburst=SIZE Max charge size of ceil rate burst buffer (default: auto)\n"
  72. "\n"
  73. "EXAMPLE"
  74. " # Attach class 1:1 to htb qdisc 1: and rate limit it to 20mbit\n"
  75. " nl-class-add --dev=eth1 --parent=1: --classid=1:1 htb --rate=20mbit\n");
  76. }
  77. static void htb_parse_class_argv(struct rtnl_tc *tc, int argc, char **argv)
  78. {
  79. struct rtnl_class *class = (struct rtnl_class *) tc;
  80. long rate;
  81. for (;;) {
  82. int c, optidx = 0;
  83. enum {
  84. ARG_RATE = 257,
  85. ARG_QUANTUM = 258,
  86. ARG_CEIL,
  87. ARG_PRIO,
  88. ARG_BURST,
  89. ARG_CBURST,
  90. };
  91. static struct option long_opts[] = {
  92. { "help", 0, 0, 'h' },
  93. { "rate", 1, 0, ARG_RATE },
  94. { "quantum", 1, 0, ARG_QUANTUM },
  95. { "ceil", 1, 0, ARG_CEIL },
  96. { "prio", 1, 0, ARG_PRIO },
  97. { "burst", 1, 0, ARG_BURST },
  98. { "cburst", 1, 0, ARG_CBURST },
  99. { 0, 0, 0, 0 }
  100. };
  101. c = getopt_long(argc, argv, "h", long_opts, &optidx);
  102. if (c == -1)
  103. break;
  104. switch (c) {
  105. case 'h':
  106. print_class_usage();
  107. return;
  108. case ARG_RATE:
  109. rate = nl_size2int(optarg);
  110. if (rate < 0) {
  111. nl_cli_fatal(rate, "Unable to parse htb rate "
  112. "\"%s\": Invalid format.", optarg);
  113. }
  114. rtnl_htb_set_rate(class, rate);
  115. break;
  116. case ARG_CEIL:
  117. rate = nl_size2int(optarg);
  118. if (rate < 0) {
  119. nl_cli_fatal(rate, "Unable to parse htb ceil rate "
  120. "\"%s\": Invalid format.", optarg);
  121. }
  122. rtnl_htb_set_ceil(class, rate);
  123. break;
  124. case ARG_PRIO:
  125. rtnl_htb_set_prio(class, nl_cli_parse_u32(optarg));
  126. break;
  127. case ARG_QUANTUM:
  128. rate = nl_size2int(optarg);
  129. if (rate < 0) {
  130. nl_cli_fatal(rate, "Unable to parse quantum "
  131. "\"%s\": Invalid format.", optarg);
  132. }
  133. rtnl_htb_set_quantum(class, rate);
  134. break;
  135. case ARG_BURST:
  136. rate = nl_size2int(optarg);
  137. if (rate < 0) {
  138. nl_cli_fatal(rate, "Unable to parse burst "
  139. "\"%s\": Invalid format.", optarg);
  140. }
  141. rtnl_htb_set_rbuffer(class, rate);
  142. break;
  143. case ARG_CBURST:
  144. rate = nl_size2int(optarg);
  145. if (rate < 0) {
  146. nl_cli_fatal(rate, "Unable to parse cburst "
  147. "\"%s\": Invalid format.", optarg);
  148. }
  149. rtnl_htb_set_cbuffer(class, rate);
  150. break;
  151. }
  152. }
  153. }
  154. static struct nl_cli_tc_module htb_qdisc_module =
  155. {
  156. .tm_name = "htb",
  157. .tm_type = RTNL_TC_TYPE_QDISC,
  158. .tm_parse_argv = htb_parse_qdisc_argv,
  159. };
  160. static struct nl_cli_tc_module htb_class_module =
  161. {
  162. .tm_name = "htb",
  163. .tm_type = RTNL_TC_TYPE_CLASS,
  164. .tm_parse_argv = htb_parse_class_argv,
  165. };
  166. static void __init htb_init(void)
  167. {
  168. nl_cli_tc_register(&htb_qdisc_module);
  169. nl_cli_tc_register(&htb_class_module);
  170. }
  171. static void __exit htb_exit(void)
  172. {
  173. nl_cli_tc_unregister(&htb_class_module);
  174. nl_cli_tc_unregister(&htb_qdisc_module);
  175. }