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