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