xref: /aosp_15_r20/external/libnl/lib/cli/qdisc/hfsc.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) 2014 Cong Wang <[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 <linux/pkt_sched.h>
9*4dc78e53SAndroid Build Coastguard Worker 
10*4dc78e53SAndroid Build Coastguard Worker #include <netlink/cli/utils.h>
11*4dc78e53SAndroid Build Coastguard Worker #include <netlink/cli/tc.h>
12*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/qdisc/hfsc.h>
13*4dc78e53SAndroid Build Coastguard Worker 
print_qdisc_usage(void)14*4dc78e53SAndroid Build Coastguard Worker static void print_qdisc_usage(void)
15*4dc78e53SAndroid Build Coastguard Worker {
16*4dc78e53SAndroid Build Coastguard Worker 	printf(
17*4dc78e53SAndroid Build Coastguard Worker "Usage: nl-qdisc-add [...] hfsc [OPTIONS]...\n"
18*4dc78e53SAndroid Build Coastguard Worker "\n"
19*4dc78e53SAndroid Build Coastguard Worker "OPTIONS\n"
20*4dc78e53SAndroid Build Coastguard Worker "     --help                Show this help text.\n"
21*4dc78e53SAndroid Build Coastguard Worker "     --default=ID          Default class for unclassified traffic.\n"
22*4dc78e53SAndroid Build Coastguard Worker "\n"
23*4dc78e53SAndroid Build Coastguard Worker "EXAMPLE"
24*4dc78e53SAndroid Build Coastguard Worker "    # Create hfsc root qdisc 1: and direct unclassified traffic to class 1:10\n"
25*4dc78e53SAndroid Build Coastguard Worker "    nl-qdisc-add --dev=eth1 --parent=root --handle=1: hfsc --default=10\n");
26*4dc78e53SAndroid Build Coastguard Worker }
27*4dc78e53SAndroid Build Coastguard Worker 
hfsc_parse_qdisc_argv(struct rtnl_tc * tc,int argc,char ** argv)28*4dc78e53SAndroid Build Coastguard Worker static void hfsc_parse_qdisc_argv(struct rtnl_tc *tc, int argc, char **argv)
29*4dc78e53SAndroid Build Coastguard Worker {
30*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) tc;
31*4dc78e53SAndroid Build Coastguard Worker 
32*4dc78e53SAndroid Build Coastguard Worker 	for (;;) {
33*4dc78e53SAndroid Build Coastguard Worker 		int c, optidx = 0;
34*4dc78e53SAndroid Build Coastguard Worker 		enum {
35*4dc78e53SAndroid Build Coastguard Worker 			ARG_DEFAULT = 257,
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 			{ "default", 1, 0, ARG_DEFAULT },
40*4dc78e53SAndroid Build Coastguard Worker 			{ 0, 0, 0, 0 }
41*4dc78e53SAndroid Build Coastguard Worker 		};
42*4dc78e53SAndroid Build Coastguard Worker 
43*4dc78e53SAndroid Build Coastguard Worker 		c = getopt_long(argc, argv, "hv", long_opts, &optidx);
44*4dc78e53SAndroid Build Coastguard Worker 		if (c == -1)
45*4dc78e53SAndroid Build Coastguard Worker 			break;
46*4dc78e53SAndroid Build Coastguard Worker 
47*4dc78e53SAndroid Build Coastguard Worker 		switch (c) {
48*4dc78e53SAndroid Build Coastguard Worker 		case 'h':
49*4dc78e53SAndroid Build Coastguard Worker 			print_qdisc_usage();
50*4dc78e53SAndroid Build Coastguard Worker 			return;
51*4dc78e53SAndroid Build Coastguard Worker 
52*4dc78e53SAndroid Build Coastguard Worker 		case ARG_DEFAULT:
53*4dc78e53SAndroid Build Coastguard Worker 			rtnl_qdisc_hfsc_set_defcls(qdisc, nl_cli_parse_u32(optarg));
54*4dc78e53SAndroid Build Coastguard Worker 			break;
55*4dc78e53SAndroid Build Coastguard Worker 		}
56*4dc78e53SAndroid Build Coastguard Worker 	}
57*4dc78e53SAndroid Build Coastguard Worker }
58*4dc78e53SAndroid Build Coastguard Worker 
print_class_usage(void)59*4dc78e53SAndroid Build Coastguard Worker static void print_class_usage(void)
60*4dc78e53SAndroid Build Coastguard Worker {
61*4dc78e53SAndroid Build Coastguard Worker 	printf(
62*4dc78e53SAndroid Build Coastguard Worker "Usage: nl-class-add [...] hfsc [OPTIONS]...\n"
63*4dc78e53SAndroid Build Coastguard Worker "\n"
64*4dc78e53SAndroid Build Coastguard Worker "OPTIONS\n"
65*4dc78e53SAndroid Build Coastguard Worker "     --help                Show this help text.\n"
66*4dc78e53SAndroid Build Coastguard Worker "     --ls=SC               Link-sharing service curve\n"
67*4dc78e53SAndroid Build Coastguard Worker "     --rt=SC               Real-time service curve\n"
68*4dc78e53SAndroid Build Coastguard Worker "     --sc=SC               Specifiy both of the above\n"
69*4dc78e53SAndroid Build Coastguard Worker "     --ul=SC               Upper limit\n"
70*4dc78e53SAndroid Build Coastguard Worker "     where SC := [ [ m1 bits ] d usec ] m2 bits\n"
71*4dc78e53SAndroid Build Coastguard Worker "\n"
72*4dc78e53SAndroid Build Coastguard Worker "EXAMPLE"
73*4dc78e53SAndroid Build Coastguard Worker "    # Attach class 1:1 to hfsc qdisc 1: and use rt and ls curve\n"
74*4dc78e53SAndroid Build Coastguard Worker "    nl-class-add --dev=eth1 --parent=1: --classid=1:1 hfsc --sc=m1:250,d:8,m2:100\n");
75*4dc78e53SAndroid Build Coastguard Worker }
76*4dc78e53SAndroid Build Coastguard Worker 
77*4dc78e53SAndroid Build Coastguard Worker static int
hfsc_get_sc(char * optarg,struct tc_service_curve * sc)78*4dc78e53SAndroid Build Coastguard Worker hfsc_get_sc(char *optarg, struct tc_service_curve *sc)
79*4dc78e53SAndroid Build Coastguard Worker {
80*4dc78e53SAndroid Build Coastguard Worker 	unsigned int m1 = 0, d = 0, m2 = 0;
81*4dc78e53SAndroid Build Coastguard Worker 	char *tmp = strdup(optarg);
82*4dc78e53SAndroid Build Coastguard Worker 	char *p, *endptr;
83*4dc78e53SAndroid Build Coastguard Worker 	char *pp = tmp;
84*4dc78e53SAndroid Build Coastguard Worker 
85*4dc78e53SAndroid Build Coastguard Worker 	if (!tmp)
86*4dc78e53SAndroid Build Coastguard Worker 		return -ENOMEM;
87*4dc78e53SAndroid Build Coastguard Worker 
88*4dc78e53SAndroid Build Coastguard Worker 	p = strstr(pp, "m1:");
89*4dc78e53SAndroid Build Coastguard Worker 	if (p) {
90*4dc78e53SAndroid Build Coastguard Worker 		char *q;
91*4dc78e53SAndroid Build Coastguard Worker 		p += 3;
92*4dc78e53SAndroid Build Coastguard Worker 		if (*p == 0)
93*4dc78e53SAndroid Build Coastguard Worker 			goto err;
94*4dc78e53SAndroid Build Coastguard Worker 		q = strchr(p, ',');
95*4dc78e53SAndroid Build Coastguard Worker 		if (!q)
96*4dc78e53SAndroid Build Coastguard Worker 			goto err;
97*4dc78e53SAndroid Build Coastguard Worker 		*q = 0;
98*4dc78e53SAndroid Build Coastguard Worker 		m1 = strtoul(p, &endptr, 10);
99*4dc78e53SAndroid Build Coastguard Worker 		if (endptr == p)
100*4dc78e53SAndroid Build Coastguard Worker 			goto err;
101*4dc78e53SAndroid Build Coastguard Worker 		pp = q + 1;
102*4dc78e53SAndroid Build Coastguard Worker 	}
103*4dc78e53SAndroid Build Coastguard Worker 
104*4dc78e53SAndroid Build Coastguard Worker 	p = strstr(pp, "d:");
105*4dc78e53SAndroid Build Coastguard Worker 	if (p) {
106*4dc78e53SAndroid Build Coastguard Worker 		char *q;
107*4dc78e53SAndroid Build Coastguard Worker 		p += 2;
108*4dc78e53SAndroid Build Coastguard Worker 		if (*p == 0)
109*4dc78e53SAndroid Build Coastguard Worker 			goto err;
110*4dc78e53SAndroid Build Coastguard Worker 		q = strchr(p, ',');
111*4dc78e53SAndroid Build Coastguard Worker 		if (!q)
112*4dc78e53SAndroid Build Coastguard Worker 			goto err;
113*4dc78e53SAndroid Build Coastguard Worker 		*q = 0;
114*4dc78e53SAndroid Build Coastguard Worker 		d = strtoul(p, &endptr, 10);
115*4dc78e53SAndroid Build Coastguard Worker 		if (endptr == p)
116*4dc78e53SAndroid Build Coastguard Worker 			goto err;
117*4dc78e53SAndroid Build Coastguard Worker 		pp = q + 1;
118*4dc78e53SAndroid Build Coastguard Worker 	}
119*4dc78e53SAndroid Build Coastguard Worker 
120*4dc78e53SAndroid Build Coastguard Worker 	p = strstr(pp, "m2:");
121*4dc78e53SAndroid Build Coastguard Worker 	if (p) {
122*4dc78e53SAndroid Build Coastguard Worker 		p += 3;
123*4dc78e53SAndroid Build Coastguard Worker 		if (*p == 0)
124*4dc78e53SAndroid Build Coastguard Worker 			goto err;
125*4dc78e53SAndroid Build Coastguard Worker 		m2 = strtoul(p, &endptr, 10);
126*4dc78e53SAndroid Build Coastguard Worker 		if (endptr == p)
127*4dc78e53SAndroid Build Coastguard Worker 			goto err;
128*4dc78e53SAndroid Build Coastguard Worker 	} else
129*4dc78e53SAndroid Build Coastguard Worker 		goto err;
130*4dc78e53SAndroid Build Coastguard Worker 
131*4dc78e53SAndroid Build Coastguard Worker 	free(tmp);
132*4dc78e53SAndroid Build Coastguard Worker 	sc->m1 = m1;
133*4dc78e53SAndroid Build Coastguard Worker 	sc->d  = d;
134*4dc78e53SAndroid Build Coastguard Worker 	sc->m2 = m2;
135*4dc78e53SAndroid Build Coastguard Worker 	return 0;
136*4dc78e53SAndroid Build Coastguard Worker 
137*4dc78e53SAndroid Build Coastguard Worker err:
138*4dc78e53SAndroid Build Coastguard Worker 	free(tmp);
139*4dc78e53SAndroid Build Coastguard Worker 	return -EINVAL;
140*4dc78e53SAndroid Build Coastguard Worker }
141*4dc78e53SAndroid Build Coastguard Worker 
hfsc_parse_class_argv(struct rtnl_tc * tc,int argc,char ** argv)142*4dc78e53SAndroid Build Coastguard Worker static void hfsc_parse_class_argv(struct rtnl_tc *tc, int argc, char **argv)
143*4dc78e53SAndroid Build Coastguard Worker {
144*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_class *class = (struct rtnl_class *) tc;
145*4dc78e53SAndroid Build Coastguard Worker 	int arg_ok = 0, ret = -EINVAL;
146*4dc78e53SAndroid Build Coastguard Worker 
147*4dc78e53SAndroid Build Coastguard Worker 	for (;;) {
148*4dc78e53SAndroid Build Coastguard Worker 		int c, optidx = 0;
149*4dc78e53SAndroid Build Coastguard Worker 		enum {
150*4dc78e53SAndroid Build Coastguard Worker 			ARG_RT = 257,
151*4dc78e53SAndroid Build Coastguard Worker 			ARG_LS = 258,
152*4dc78e53SAndroid Build Coastguard Worker 			ARG_SC,
153*4dc78e53SAndroid Build Coastguard Worker 			ARG_UL,
154*4dc78e53SAndroid Build Coastguard Worker 		};
155*4dc78e53SAndroid Build Coastguard Worker 		static struct option long_opts[] = {
156*4dc78e53SAndroid Build Coastguard Worker 			{ "help", 0, 0, 'h' },
157*4dc78e53SAndroid Build Coastguard Worker 			{ "rt", 1, 0, ARG_RT },
158*4dc78e53SAndroid Build Coastguard Worker 			{ "ls", 1, 0, ARG_LS },
159*4dc78e53SAndroid Build Coastguard Worker 			{ "sc", 1, 0, ARG_SC },
160*4dc78e53SAndroid Build Coastguard Worker 			{ "ul", 1, 0, ARG_UL },
161*4dc78e53SAndroid Build Coastguard Worker 			{ 0, 0, 0, 0 }
162*4dc78e53SAndroid Build Coastguard Worker 		};
163*4dc78e53SAndroid Build Coastguard Worker 		struct tc_service_curve tsc;
164*4dc78e53SAndroid Build Coastguard Worker 
165*4dc78e53SAndroid Build Coastguard Worker 		c = getopt_long(argc, argv, "h", long_opts, &optidx);
166*4dc78e53SAndroid Build Coastguard Worker 		if (c == -1)
167*4dc78e53SAndroid Build Coastguard Worker 			break;
168*4dc78e53SAndroid Build Coastguard Worker 
169*4dc78e53SAndroid Build Coastguard Worker 		switch (c) {
170*4dc78e53SAndroid Build Coastguard Worker 		case 'h':
171*4dc78e53SAndroid Build Coastguard Worker 			print_class_usage();
172*4dc78e53SAndroid Build Coastguard Worker 			return;
173*4dc78e53SAndroid Build Coastguard Worker 
174*4dc78e53SAndroid Build Coastguard Worker 		case ARG_RT:
175*4dc78e53SAndroid Build Coastguard Worker 			ret = hfsc_get_sc(optarg, &tsc);
176*4dc78e53SAndroid Build Coastguard Worker 			if (ret < 0) {
177*4dc78e53SAndroid Build Coastguard Worker 				nl_cli_fatal(ret, "Unable to parse sc "
178*4dc78e53SAndroid Build Coastguard Worker 					"\"%s\": Invalid format.", optarg);
179*4dc78e53SAndroid Build Coastguard Worker 			}
180*4dc78e53SAndroid Build Coastguard Worker 
181*4dc78e53SAndroid Build Coastguard Worker 			rtnl_class_hfsc_set_rsc(class, &tsc);
182*4dc78e53SAndroid Build Coastguard Worker 			arg_ok++;
183*4dc78e53SAndroid Build Coastguard Worker 			break;
184*4dc78e53SAndroid Build Coastguard Worker 
185*4dc78e53SAndroid Build Coastguard Worker 		case ARG_LS:
186*4dc78e53SAndroid Build Coastguard Worker 			ret = hfsc_get_sc(optarg, &tsc);
187*4dc78e53SAndroid Build Coastguard Worker 			if (ret < 0) {
188*4dc78e53SAndroid Build Coastguard Worker 				nl_cli_fatal(ret, "Unable to parse sc "
189*4dc78e53SAndroid Build Coastguard Worker 					"\"%s\": Invalid format.", optarg);
190*4dc78e53SAndroid Build Coastguard Worker 			}
191*4dc78e53SAndroid Build Coastguard Worker 
192*4dc78e53SAndroid Build Coastguard Worker 			rtnl_class_hfsc_set_fsc(class, &tsc);
193*4dc78e53SAndroid Build Coastguard Worker 			arg_ok++;
194*4dc78e53SAndroid Build Coastguard Worker 			break;
195*4dc78e53SAndroid Build Coastguard Worker 
196*4dc78e53SAndroid Build Coastguard Worker 		case ARG_SC:
197*4dc78e53SAndroid Build Coastguard Worker 			ret = hfsc_get_sc(optarg, &tsc);
198*4dc78e53SAndroid Build Coastguard Worker 			if (ret < 0) {
199*4dc78e53SAndroid Build Coastguard Worker 				nl_cli_fatal(ret, "Unable to parse sc "
200*4dc78e53SAndroid Build Coastguard Worker 					"\"%s\": Invalid format.", optarg);
201*4dc78e53SAndroid Build Coastguard Worker 			}
202*4dc78e53SAndroid Build Coastguard Worker 
203*4dc78e53SAndroid Build Coastguard Worker 			rtnl_class_hfsc_set_rsc(class, &tsc);
204*4dc78e53SAndroid Build Coastguard Worker 			rtnl_class_hfsc_set_fsc(class, &tsc);
205*4dc78e53SAndroid Build Coastguard Worker 			arg_ok++;
206*4dc78e53SAndroid Build Coastguard Worker 			break;
207*4dc78e53SAndroid Build Coastguard Worker 
208*4dc78e53SAndroid Build Coastguard Worker 		case ARG_UL:
209*4dc78e53SAndroid Build Coastguard Worker 			ret = hfsc_get_sc(optarg, &tsc);
210*4dc78e53SAndroid Build Coastguard Worker 			if (ret < 0) {
211*4dc78e53SAndroid Build Coastguard Worker 				nl_cli_fatal(ret, "Unable to parse sc "
212*4dc78e53SAndroid Build Coastguard Worker 					"\"%s\": Invalid format.", optarg);
213*4dc78e53SAndroid Build Coastguard Worker 			}
214*4dc78e53SAndroid Build Coastguard Worker 
215*4dc78e53SAndroid Build Coastguard Worker 			rtnl_class_hfsc_set_usc(class, &tsc);
216*4dc78e53SAndroid Build Coastguard Worker 			arg_ok++;
217*4dc78e53SAndroid Build Coastguard Worker 			break;
218*4dc78e53SAndroid Build Coastguard Worker 		}
219*4dc78e53SAndroid Build Coastguard Worker 	}
220*4dc78e53SAndroid Build Coastguard Worker 
221*4dc78e53SAndroid Build Coastguard Worker 	if (!arg_ok)
222*4dc78e53SAndroid Build Coastguard Worker 		nl_cli_fatal(ret, "Invalid arguments");
223*4dc78e53SAndroid Build Coastguard Worker }
224*4dc78e53SAndroid Build Coastguard Worker 
225*4dc78e53SAndroid Build Coastguard Worker static struct nl_cli_tc_module hfsc_qdisc_module =
226*4dc78e53SAndroid Build Coastguard Worker {
227*4dc78e53SAndroid Build Coastguard Worker 	.tm_name		= "hfsc",
228*4dc78e53SAndroid Build Coastguard Worker 	.tm_type		= RTNL_TC_TYPE_QDISC,
229*4dc78e53SAndroid Build Coastguard Worker 	.tm_parse_argv		= hfsc_parse_qdisc_argv,
230*4dc78e53SAndroid Build Coastguard Worker };
231*4dc78e53SAndroid Build Coastguard Worker 
232*4dc78e53SAndroid Build Coastguard Worker static struct nl_cli_tc_module hfsc_class_module =
233*4dc78e53SAndroid Build Coastguard Worker {
234*4dc78e53SAndroid Build Coastguard Worker 	.tm_name		= "hfsc",
235*4dc78e53SAndroid Build Coastguard Worker 	.tm_type		= RTNL_TC_TYPE_CLASS,
236*4dc78e53SAndroid Build Coastguard Worker 	.tm_parse_argv		= hfsc_parse_class_argv,
237*4dc78e53SAndroid Build Coastguard Worker };
238*4dc78e53SAndroid Build Coastguard Worker 
hfsc_init(void)239*4dc78e53SAndroid Build Coastguard Worker static void _nl_init hfsc_init(void)
240*4dc78e53SAndroid Build Coastguard Worker {
241*4dc78e53SAndroid Build Coastguard Worker 	nl_cli_tc_register(&hfsc_qdisc_module);
242*4dc78e53SAndroid Build Coastguard Worker 	nl_cli_tc_register(&hfsc_class_module);
243*4dc78e53SAndroid Build Coastguard Worker }
244*4dc78e53SAndroid Build Coastguard Worker 
hfsc_exit(void)245*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit hfsc_exit(void)
246*4dc78e53SAndroid Build Coastguard Worker {
247*4dc78e53SAndroid Build Coastguard Worker 	nl_cli_tc_unregister(&hfsc_class_module);
248*4dc78e53SAndroid Build Coastguard Worker 	nl_cli_tc_unregister(&hfsc_qdisc_module);
249*4dc78e53SAndroid Build Coastguard Worker }
250