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