xref: /aosp_15_r20/external/libnl/lib/cli/qdisc/htb.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
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