xref: /aosp_15_r20/external/libnl/lib/route/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 /**
7*4dc78e53SAndroid Build Coastguard Worker  * @ingroup qdisc
8*4dc78e53SAndroid Build Coastguard Worker  * @ingroup class
9*4dc78e53SAndroid Build Coastguard Worker  * @defgroup qdisc_hfsc Hierarchical Fair Service Curve (HFSC)
10*4dc78e53SAndroid Build Coastguard Worker  * @{
11*4dc78e53SAndroid Build Coastguard Worker  */
12*4dc78e53SAndroid Build Coastguard Worker 
13*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
14*4dc78e53SAndroid Build Coastguard Worker 
15*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
16*4dc78e53SAndroid Build Coastguard Worker #include <netlink/cache.h>
17*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
18*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/qdisc.h>
19*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/class.h>
20*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/link.h>
21*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/qdisc/hfsc.h>
22*4dc78e53SAndroid Build Coastguard Worker 
23*4dc78e53SAndroid Build Coastguard Worker #include "tc-api.h"
24*4dc78e53SAndroid Build Coastguard Worker 
25*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
26*4dc78e53SAndroid Build Coastguard Worker struct rtnl_hfsc_qdisc {
27*4dc78e53SAndroid Build Coastguard Worker 	uint32_t qh_defcls;
28*4dc78e53SAndroid Build Coastguard Worker 	uint32_t qh_mask;
29*4dc78e53SAndroid Build Coastguard Worker };
30*4dc78e53SAndroid Build Coastguard Worker 
31*4dc78e53SAndroid Build Coastguard Worker struct rtnl_hfsc_class {
32*4dc78e53SAndroid Build Coastguard Worker 	struct tc_service_curve ch_rsc;
33*4dc78e53SAndroid Build Coastguard Worker 	struct tc_service_curve ch_fsc;
34*4dc78e53SAndroid Build Coastguard Worker 	struct tc_service_curve ch_usc;
35*4dc78e53SAndroid Build Coastguard Worker 	uint32_t ch_mask;
36*4dc78e53SAndroid Build Coastguard Worker };
37*4dc78e53SAndroid Build Coastguard Worker 
38*4dc78e53SAndroid Build Coastguard Worker #define SCH_HFSC_CLS_HAS_RSC		0x001
39*4dc78e53SAndroid Build Coastguard Worker #define SCH_HFSC_CLS_HAS_FSC		0x002
40*4dc78e53SAndroid Build Coastguard Worker #define SCH_HFSC_CLS_HAS_USC		0x004
41*4dc78e53SAndroid Build Coastguard Worker 
42*4dc78e53SAndroid Build Coastguard Worker #define SCH_HFSC_QD_HAS_DEFCLS		0x01
43*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
44*4dc78e53SAndroid Build Coastguard Worker 
45*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy hfsc_policy[TCA_HFSC_MAX + 1] = {
46*4dc78e53SAndroid Build Coastguard Worker 	[TCA_HFSC_RSC]  = { .minlen = sizeof(struct tc_service_curve) },
47*4dc78e53SAndroid Build Coastguard Worker 	[TCA_HFSC_FSC]  = { .minlen = sizeof(struct tc_service_curve) },
48*4dc78e53SAndroid Build Coastguard Worker 	[TCA_HFSC_USC]  = { .minlen = sizeof(struct tc_service_curve) },
49*4dc78e53SAndroid Build Coastguard Worker };
50*4dc78e53SAndroid Build Coastguard Worker 
hfsc_qdisc_msg_parser(struct rtnl_tc * tc,void * data)51*4dc78e53SAndroid Build Coastguard Worker static int hfsc_qdisc_msg_parser(struct rtnl_tc *tc, void *data)
52*4dc78e53SAndroid Build Coastguard Worker {
53*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_qdisc *hfsc = data;
54*4dc78e53SAndroid Build Coastguard Worker 	struct tc_hfsc_qopt *opts;
55*4dc78e53SAndroid Build Coastguard Worker 
56*4dc78e53SAndroid Build Coastguard Worker 	opts = (struct tc_hfsc_qopt *) tc->tc_opts->d_data;
57*4dc78e53SAndroid Build Coastguard Worker 	hfsc->qh_defcls = opts->defcls;
58*4dc78e53SAndroid Build Coastguard Worker 	hfsc->qh_mask |= SCH_HFSC_QD_HAS_DEFCLS;
59*4dc78e53SAndroid Build Coastguard Worker 	return 0;
60*4dc78e53SAndroid Build Coastguard Worker }
61*4dc78e53SAndroid Build Coastguard Worker 
hfsc_class_msg_parser(struct rtnl_tc * tc,void * data)62*4dc78e53SAndroid Build Coastguard Worker static int hfsc_class_msg_parser(struct rtnl_tc *tc, void *data)
63*4dc78e53SAndroid Build Coastguard Worker {
64*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *tb[TCA_HFSC_MAX + 1];
65*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_class *hfsc = data;
66*4dc78e53SAndroid Build Coastguard Worker 	int err;
67*4dc78e53SAndroid Build Coastguard Worker 
68*4dc78e53SAndroid Build Coastguard Worker 	if ((err = tca_parse(tb, TCA_HFSC_MAX, tc, hfsc_policy)) < 0)
69*4dc78e53SAndroid Build Coastguard Worker 		return err;
70*4dc78e53SAndroid Build Coastguard Worker 
71*4dc78e53SAndroid Build Coastguard Worker 	if (tb[TCA_HFSC_RSC]) {
72*4dc78e53SAndroid Build Coastguard Worker 		struct tc_service_curve tsc;
73*4dc78e53SAndroid Build Coastguard Worker 
74*4dc78e53SAndroid Build Coastguard Worker 		nla_memcpy(&tsc, tb[TCA_HFSC_RSC], sizeof(tsc));
75*4dc78e53SAndroid Build Coastguard Worker 		hfsc->ch_rsc = tsc;
76*4dc78e53SAndroid Build Coastguard Worker 		hfsc->ch_mask |= SCH_HFSC_CLS_HAS_RSC;
77*4dc78e53SAndroid Build Coastguard Worker 	}
78*4dc78e53SAndroid Build Coastguard Worker 
79*4dc78e53SAndroid Build Coastguard Worker 	if (tb[TCA_HFSC_FSC]) {
80*4dc78e53SAndroid Build Coastguard Worker 		struct tc_service_curve tsc;
81*4dc78e53SAndroid Build Coastguard Worker 
82*4dc78e53SAndroid Build Coastguard Worker 		nla_memcpy(&tsc, tb[TCA_HFSC_FSC], sizeof(tsc));
83*4dc78e53SAndroid Build Coastguard Worker 		hfsc->ch_fsc = tsc;
84*4dc78e53SAndroid Build Coastguard Worker 		hfsc->ch_mask |= SCH_HFSC_CLS_HAS_FSC;
85*4dc78e53SAndroid Build Coastguard Worker 	}
86*4dc78e53SAndroid Build Coastguard Worker 
87*4dc78e53SAndroid Build Coastguard Worker 	if (tb[TCA_HFSC_USC]) {
88*4dc78e53SAndroid Build Coastguard Worker 		struct tc_service_curve tsc;
89*4dc78e53SAndroid Build Coastguard Worker 
90*4dc78e53SAndroid Build Coastguard Worker 		nla_memcpy(&tsc, tb[TCA_HFSC_USC], sizeof(tsc));
91*4dc78e53SAndroid Build Coastguard Worker 		hfsc->ch_usc = tsc;
92*4dc78e53SAndroid Build Coastguard Worker 		hfsc->ch_mask |= SCH_HFSC_CLS_HAS_USC;
93*4dc78e53SAndroid Build Coastguard Worker 	}
94*4dc78e53SAndroid Build Coastguard Worker 
95*4dc78e53SAndroid Build Coastguard Worker 	return 0;
96*4dc78e53SAndroid Build Coastguard Worker }
97*4dc78e53SAndroid Build Coastguard Worker 
hfsc_qdisc_dump_line(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)98*4dc78e53SAndroid Build Coastguard Worker static void hfsc_qdisc_dump_line(struct rtnl_tc *tc, void *data,
99*4dc78e53SAndroid Build Coastguard Worker 				struct nl_dump_params *p)
100*4dc78e53SAndroid Build Coastguard Worker {
101*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_qdisc *hfsc = data;
102*4dc78e53SAndroid Build Coastguard Worker 
103*4dc78e53SAndroid Build Coastguard Worker 	if (!hfsc)
104*4dc78e53SAndroid Build Coastguard Worker 		return;
105*4dc78e53SAndroid Build Coastguard Worker 
106*4dc78e53SAndroid Build Coastguard Worker 	if (hfsc->qh_mask & SCH_HFSC_QD_HAS_DEFCLS) {
107*4dc78e53SAndroid Build Coastguard Worker 		char buf[64];
108*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " default-class %s",
109*4dc78e53SAndroid Build Coastguard Worker 			rtnl_tc_handle2str(hfsc->qh_defcls, buf, sizeof(buf)));
110*4dc78e53SAndroid Build Coastguard Worker 	}
111*4dc78e53SAndroid Build Coastguard Worker }
112*4dc78e53SAndroid Build Coastguard Worker 
hfsc_dump_tsc(struct nl_dump_params * p,struct tc_service_curve * tsc)113*4dc78e53SAndroid Build Coastguard Worker static void hfsc_dump_tsc(struct nl_dump_params *p, struct tc_service_curve *tsc)
114*4dc78e53SAndroid Build Coastguard Worker {
115*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, " m1 %u d %u m2 %u\n", tsc->m1, tsc->d, tsc->m2);
116*4dc78e53SAndroid Build Coastguard Worker }
117*4dc78e53SAndroid Build Coastguard Worker 
hfsc_class_dump_line(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)118*4dc78e53SAndroid Build Coastguard Worker static void hfsc_class_dump_line(struct rtnl_tc *tc, void *data,
119*4dc78e53SAndroid Build Coastguard Worker 				struct nl_dump_params *p)
120*4dc78e53SAndroid Build Coastguard Worker {
121*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_class *hfsc = data;
122*4dc78e53SAndroid Build Coastguard Worker 
123*4dc78e53SAndroid Build Coastguard Worker 	if (!hfsc)
124*4dc78e53SAndroid Build Coastguard Worker 		return;
125*4dc78e53SAndroid Build Coastguard Worker 	if (hfsc->ch_mask & SCH_HFSC_CLS_HAS_RSC)
126*4dc78e53SAndroid Build Coastguard Worker 		hfsc_dump_tsc(p, &hfsc->ch_rsc);
127*4dc78e53SAndroid Build Coastguard Worker 	if (hfsc->ch_mask & SCH_HFSC_CLS_HAS_FSC)
128*4dc78e53SAndroid Build Coastguard Worker 		hfsc_dump_tsc(p, &hfsc->ch_fsc);
129*4dc78e53SAndroid Build Coastguard Worker 	if (hfsc->ch_mask & SCH_HFSC_CLS_HAS_USC)
130*4dc78e53SAndroid Build Coastguard Worker 		hfsc_dump_tsc(p, &hfsc->ch_usc);
131*4dc78e53SAndroid Build Coastguard Worker }
132*4dc78e53SAndroid Build Coastguard Worker 
hfsc_class_dump_details(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)133*4dc78e53SAndroid Build Coastguard Worker static void hfsc_class_dump_details(struct rtnl_tc *tc, void *data,
134*4dc78e53SAndroid Build Coastguard Worker 				   struct nl_dump_params *p)
135*4dc78e53SAndroid Build Coastguard Worker {
136*4dc78e53SAndroid Build Coastguard Worker 	return;
137*4dc78e53SAndroid Build Coastguard Worker }
138*4dc78e53SAndroid Build Coastguard Worker 
hfsc_qdisc_msg_fill(struct rtnl_tc * tc,void * data,struct nl_msg * msg)139*4dc78e53SAndroid Build Coastguard Worker static int hfsc_qdisc_msg_fill(struct rtnl_tc *tc, void *data,
140*4dc78e53SAndroid Build Coastguard Worker 			      struct nl_msg *msg)
141*4dc78e53SAndroid Build Coastguard Worker {
142*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_qdisc *hfsc = data;
143*4dc78e53SAndroid Build Coastguard Worker 	struct tc_hfsc_qopt opts = {0};
144*4dc78e53SAndroid Build Coastguard Worker 
145*4dc78e53SAndroid Build Coastguard Worker 	if (!hfsc)
146*4dc78e53SAndroid Build Coastguard Worker 		BUG();
147*4dc78e53SAndroid Build Coastguard Worker 
148*4dc78e53SAndroid Build Coastguard Worker 	opts.defcls = hfsc->qh_defcls;
149*4dc78e53SAndroid Build Coastguard Worker 	return nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD);
150*4dc78e53SAndroid Build Coastguard Worker }
151*4dc78e53SAndroid Build Coastguard Worker 
hfsc_class_msg_fill(struct rtnl_tc * tc,void * data,struct nl_msg * msg)152*4dc78e53SAndroid Build Coastguard Worker static int hfsc_class_msg_fill(struct rtnl_tc *tc, void *data,
153*4dc78e53SAndroid Build Coastguard Worker 			      struct nl_msg *msg)
154*4dc78e53SAndroid Build Coastguard Worker {
155*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_class *hfsc = data;
156*4dc78e53SAndroid Build Coastguard Worker 	struct tc_service_curve tsc;
157*4dc78e53SAndroid Build Coastguard Worker 
158*4dc78e53SAndroid Build Coastguard Worker 	if (!hfsc)
159*4dc78e53SAndroid Build Coastguard Worker 		BUG();
160*4dc78e53SAndroid Build Coastguard Worker 
161*4dc78e53SAndroid Build Coastguard Worker 	if (hfsc->ch_mask & SCH_HFSC_CLS_HAS_RSC) {
162*4dc78e53SAndroid Build Coastguard Worker 		tsc = hfsc->ch_rsc;
163*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, TCA_HFSC_RSC, sizeof(tsc), &tsc);
164*4dc78e53SAndroid Build Coastguard Worker 	}
165*4dc78e53SAndroid Build Coastguard Worker 
166*4dc78e53SAndroid Build Coastguard Worker 	if (hfsc->ch_mask & SCH_HFSC_CLS_HAS_FSC) {
167*4dc78e53SAndroid Build Coastguard Worker 		tsc = hfsc->ch_fsc;
168*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, TCA_HFSC_FSC, sizeof(tsc), &tsc);
169*4dc78e53SAndroid Build Coastguard Worker 	}
170*4dc78e53SAndroid Build Coastguard Worker 
171*4dc78e53SAndroid Build Coastguard Worker 	if (hfsc->ch_mask & SCH_HFSC_CLS_HAS_USC) {
172*4dc78e53SAndroid Build Coastguard Worker 		tsc = hfsc->ch_usc;
173*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT(msg, TCA_HFSC_USC, sizeof(tsc), &tsc);
174*4dc78e53SAndroid Build Coastguard Worker 	}
175*4dc78e53SAndroid Build Coastguard Worker 
176*4dc78e53SAndroid Build Coastguard Worker 	return 0;
177*4dc78e53SAndroid Build Coastguard Worker 
178*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
179*4dc78e53SAndroid Build Coastguard Worker 	return -NLE_MSGSIZE;
180*4dc78e53SAndroid Build Coastguard Worker }
181*4dc78e53SAndroid Build Coastguard Worker 
182*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops hfsc_qdisc_ops;
183*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops hfsc_class_ops;
184*4dc78e53SAndroid Build Coastguard Worker 
hfsc_qdisc_data(const struct rtnl_qdisc * qdisc,int * err)185*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_hfsc_qdisc *hfsc_qdisc_data(const struct rtnl_qdisc *qdisc, int *err)
186*4dc78e53SAndroid Build Coastguard Worker {
187*4dc78e53SAndroid Build Coastguard Worker 	return rtnl_tc_data_check(TC_CAST(qdisc), &hfsc_qdisc_ops, err);
188*4dc78e53SAndroid Build Coastguard Worker }
189*4dc78e53SAndroid Build Coastguard Worker 
hfsc_class_data(const struct rtnl_class * class,int * err)190*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_hfsc_class *hfsc_class_data(const struct rtnl_class *class, int *err)
191*4dc78e53SAndroid Build Coastguard Worker {
192*4dc78e53SAndroid Build Coastguard Worker 	return rtnl_tc_data_check(TC_CAST(class), &hfsc_class_ops, err);
193*4dc78e53SAndroid Build Coastguard Worker }
194*4dc78e53SAndroid Build Coastguard Worker 
195*4dc78e53SAndroid Build Coastguard Worker /**
196*4dc78e53SAndroid Build Coastguard Worker  * @name Attribute Modifications
197*4dc78e53SAndroid Build Coastguard Worker  * @{
198*4dc78e53SAndroid Build Coastguard Worker  */
199*4dc78e53SAndroid Build Coastguard Worker 
200*4dc78e53SAndroid Build Coastguard Worker /**
201*4dc78e53SAndroid Build Coastguard Worker  * Return default class of HFSC qdisc
202*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc		hfsc qdisc object
203*4dc78e53SAndroid Build Coastguard Worker  *
204*4dc78e53SAndroid Build Coastguard Worker  * Returns the classid of the class where all unclassified traffic
205*4dc78e53SAndroid Build Coastguard Worker  * goes to.
206*4dc78e53SAndroid Build Coastguard Worker  *
207*4dc78e53SAndroid Build Coastguard Worker  * @return classid or TC_H_UNSPEC if unspecified.
208*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_hfsc_get_defcls(const struct rtnl_qdisc * qdisc)209*4dc78e53SAndroid Build Coastguard Worker uint32_t rtnl_qdisc_hfsc_get_defcls(const struct rtnl_qdisc *qdisc)
210*4dc78e53SAndroid Build Coastguard Worker {
211*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_qdisc *hfsc;
212*4dc78e53SAndroid Build Coastguard Worker 
213*4dc78e53SAndroid Build Coastguard Worker 	if ((hfsc = hfsc_qdisc_data(qdisc, NULL)) &&
214*4dc78e53SAndroid Build Coastguard Worker 	    (hfsc->qh_mask & SCH_HFSC_QD_HAS_DEFCLS))
215*4dc78e53SAndroid Build Coastguard Worker 		return hfsc->qh_defcls;
216*4dc78e53SAndroid Build Coastguard Worker 
217*4dc78e53SAndroid Build Coastguard Worker 	return TC_H_UNSPEC;
218*4dc78e53SAndroid Build Coastguard Worker }
219*4dc78e53SAndroid Build Coastguard Worker 
220*4dc78e53SAndroid Build Coastguard Worker /**
221*4dc78e53SAndroid Build Coastguard Worker  * Set default class of the hfsc qdisc to the specified value
222*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc		qdisc to change
223*4dc78e53SAndroid Build Coastguard Worker  * @arg defcls		new default class
224*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_hfsc_set_defcls(struct rtnl_qdisc * qdisc,uint32_t defcls)225*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_hfsc_set_defcls(struct rtnl_qdisc *qdisc, uint32_t defcls)
226*4dc78e53SAndroid Build Coastguard Worker {
227*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_qdisc *hfsc;
228*4dc78e53SAndroid Build Coastguard Worker 	int err;
229*4dc78e53SAndroid Build Coastguard Worker 
230*4dc78e53SAndroid Build Coastguard Worker 	if (!(hfsc = hfsc_qdisc_data(qdisc, &err)))
231*4dc78e53SAndroid Build Coastguard Worker 		return err;
232*4dc78e53SAndroid Build Coastguard Worker 
233*4dc78e53SAndroid Build Coastguard Worker 	hfsc->qh_defcls = defcls;
234*4dc78e53SAndroid Build Coastguard Worker 	hfsc->qh_mask |= SCH_HFSC_QD_HAS_DEFCLS;
235*4dc78e53SAndroid Build Coastguard Worker 
236*4dc78e53SAndroid Build Coastguard Worker 	return 0;
237*4dc78e53SAndroid Build Coastguard Worker }
238*4dc78e53SAndroid Build Coastguard Worker 
rtnl_class_hfsc_get_rsc(const struct rtnl_class * class,struct tc_service_curve * tsc)239*4dc78e53SAndroid Build Coastguard Worker int rtnl_class_hfsc_get_rsc(const struct rtnl_class *class, struct tc_service_curve *tsc)
240*4dc78e53SAndroid Build Coastguard Worker {
241*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_class *hfsc;
242*4dc78e53SAndroid Build Coastguard Worker 	int err = -NLE_OPNOTSUPP;
243*4dc78e53SAndroid Build Coastguard Worker 
244*4dc78e53SAndroid Build Coastguard Worker 	if ((hfsc = hfsc_class_data(class, &err)) &&
245*4dc78e53SAndroid Build Coastguard Worker 	    (hfsc->ch_mask & SCH_HFSC_CLS_HAS_RSC)) {
246*4dc78e53SAndroid Build Coastguard Worker 		*tsc = hfsc->ch_rsc;
247*4dc78e53SAndroid Build Coastguard Worker 		return 0;
248*4dc78e53SAndroid Build Coastguard Worker 	}
249*4dc78e53SAndroid Build Coastguard Worker 
250*4dc78e53SAndroid Build Coastguard Worker 	return err;
251*4dc78e53SAndroid Build Coastguard Worker }
252*4dc78e53SAndroid Build Coastguard Worker 
rtnl_class_hfsc_set_rsc(struct rtnl_class * class,const struct tc_service_curve * tsc)253*4dc78e53SAndroid Build Coastguard Worker int rtnl_class_hfsc_set_rsc(struct rtnl_class *class, const struct tc_service_curve *tsc)
254*4dc78e53SAndroid Build Coastguard Worker {
255*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_class *hfsc;
256*4dc78e53SAndroid Build Coastguard Worker 	int err;
257*4dc78e53SAndroid Build Coastguard Worker 
258*4dc78e53SAndroid Build Coastguard Worker 	if (!(hfsc = hfsc_class_data(class, &err)))
259*4dc78e53SAndroid Build Coastguard Worker 		return err;
260*4dc78e53SAndroid Build Coastguard Worker 
261*4dc78e53SAndroid Build Coastguard Worker 	hfsc->ch_rsc = *tsc;
262*4dc78e53SAndroid Build Coastguard Worker 	hfsc->ch_mask |= SCH_HFSC_CLS_HAS_RSC;
263*4dc78e53SAndroid Build Coastguard Worker 
264*4dc78e53SAndroid Build Coastguard Worker 	return 0;
265*4dc78e53SAndroid Build Coastguard Worker }
266*4dc78e53SAndroid Build Coastguard Worker 
rtnl_class_hfsc_get_fsc(const struct rtnl_class * class,struct tc_service_curve * tsc)267*4dc78e53SAndroid Build Coastguard Worker int rtnl_class_hfsc_get_fsc(const struct rtnl_class *class, struct tc_service_curve *tsc)
268*4dc78e53SAndroid Build Coastguard Worker {
269*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_class *hfsc;
270*4dc78e53SAndroid Build Coastguard Worker 	int err = -NLE_OPNOTSUPP;
271*4dc78e53SAndroid Build Coastguard Worker 
272*4dc78e53SAndroid Build Coastguard Worker 	if ((hfsc = hfsc_class_data(class, &err)) &&
273*4dc78e53SAndroid Build Coastguard Worker 	    (hfsc->ch_mask & SCH_HFSC_CLS_HAS_FSC)) {
274*4dc78e53SAndroid Build Coastguard Worker 		*tsc = hfsc->ch_fsc;
275*4dc78e53SAndroid Build Coastguard Worker 		return 0;
276*4dc78e53SAndroid Build Coastguard Worker 	}
277*4dc78e53SAndroid Build Coastguard Worker 
278*4dc78e53SAndroid Build Coastguard Worker 	return err;
279*4dc78e53SAndroid Build Coastguard Worker }
280*4dc78e53SAndroid Build Coastguard Worker 
rtnl_class_hfsc_set_fsc(struct rtnl_class * class,const struct tc_service_curve * tsc)281*4dc78e53SAndroid Build Coastguard Worker int rtnl_class_hfsc_set_fsc(struct rtnl_class *class, const struct tc_service_curve *tsc)
282*4dc78e53SAndroid Build Coastguard Worker {
283*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_class *hfsc;
284*4dc78e53SAndroid Build Coastguard Worker 	int err;
285*4dc78e53SAndroid Build Coastguard Worker 
286*4dc78e53SAndroid Build Coastguard Worker 	if (!(hfsc = hfsc_class_data(class, &err)))
287*4dc78e53SAndroid Build Coastguard Worker 		return err;
288*4dc78e53SAndroid Build Coastguard Worker 
289*4dc78e53SAndroid Build Coastguard Worker 	hfsc->ch_fsc = *tsc;
290*4dc78e53SAndroid Build Coastguard Worker 	hfsc->ch_mask |= SCH_HFSC_CLS_HAS_FSC;
291*4dc78e53SAndroid Build Coastguard Worker 
292*4dc78e53SAndroid Build Coastguard Worker 	return 0;
293*4dc78e53SAndroid Build Coastguard Worker }
294*4dc78e53SAndroid Build Coastguard Worker 
rtnl_class_hfsc_get_usc(const struct rtnl_class * class,struct tc_service_curve * tsc)295*4dc78e53SAndroid Build Coastguard Worker int rtnl_class_hfsc_get_usc(const struct rtnl_class *class, struct tc_service_curve *tsc)
296*4dc78e53SAndroid Build Coastguard Worker {
297*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_class *hfsc;
298*4dc78e53SAndroid Build Coastguard Worker 	int err = -NLE_OPNOTSUPP;
299*4dc78e53SAndroid Build Coastguard Worker 
300*4dc78e53SAndroid Build Coastguard Worker 	if ((hfsc = hfsc_class_data(class, &err)) &&
301*4dc78e53SAndroid Build Coastguard Worker 	    (hfsc->ch_mask & SCH_HFSC_CLS_HAS_USC)) {
302*4dc78e53SAndroid Build Coastguard Worker 		*tsc = hfsc->ch_usc;
303*4dc78e53SAndroid Build Coastguard Worker 		return 0;
304*4dc78e53SAndroid Build Coastguard Worker 	}
305*4dc78e53SAndroid Build Coastguard Worker 
306*4dc78e53SAndroid Build Coastguard Worker 	return err;
307*4dc78e53SAndroid Build Coastguard Worker }
308*4dc78e53SAndroid Build Coastguard Worker 
rtnl_class_hfsc_set_usc(struct rtnl_class * class,const struct tc_service_curve * tsc)309*4dc78e53SAndroid Build Coastguard Worker int rtnl_class_hfsc_set_usc(struct rtnl_class *class, const struct tc_service_curve *tsc)
310*4dc78e53SAndroid Build Coastguard Worker {
311*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_hfsc_class *hfsc;
312*4dc78e53SAndroid Build Coastguard Worker 	int err;
313*4dc78e53SAndroid Build Coastguard Worker 
314*4dc78e53SAndroid Build Coastguard Worker 	if (!(hfsc = hfsc_class_data(class, &err)))
315*4dc78e53SAndroid Build Coastguard Worker 		return err;
316*4dc78e53SAndroid Build Coastguard Worker 
317*4dc78e53SAndroid Build Coastguard Worker 	hfsc->ch_usc = *tsc;
318*4dc78e53SAndroid Build Coastguard Worker 	hfsc->ch_mask |= SCH_HFSC_CLS_HAS_USC;
319*4dc78e53SAndroid Build Coastguard Worker 
320*4dc78e53SAndroid Build Coastguard Worker 	return 0;
321*4dc78e53SAndroid Build Coastguard Worker }
322*4dc78e53SAndroid Build Coastguard Worker 
323*4dc78e53SAndroid Build Coastguard Worker /** @} */
324*4dc78e53SAndroid Build Coastguard Worker 
325*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops hfsc_qdisc_ops = {
326*4dc78e53SAndroid Build Coastguard Worker 	.to_kind		= "hfsc",
327*4dc78e53SAndroid Build Coastguard Worker 	.to_type		= RTNL_TC_TYPE_QDISC,
328*4dc78e53SAndroid Build Coastguard Worker 	.to_size		= sizeof(struct rtnl_hfsc_qdisc),
329*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_parser		= hfsc_qdisc_msg_parser,
330*4dc78e53SAndroid Build Coastguard Worker 	.to_dump[NL_DUMP_LINE]	= hfsc_qdisc_dump_line,
331*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_fill		= hfsc_qdisc_msg_fill,
332*4dc78e53SAndroid Build Coastguard Worker };
333*4dc78e53SAndroid Build Coastguard Worker 
334*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops hfsc_class_ops = {
335*4dc78e53SAndroid Build Coastguard Worker 	.to_kind		= "hfsc",
336*4dc78e53SAndroid Build Coastguard Worker 	.to_type		= RTNL_TC_TYPE_CLASS,
337*4dc78e53SAndroid Build Coastguard Worker 	.to_size		= sizeof(struct rtnl_hfsc_class),
338*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_parser		= hfsc_class_msg_parser,
339*4dc78e53SAndroid Build Coastguard Worker 	.to_dump = {
340*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_LINE]	= hfsc_class_dump_line,
341*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_DETAILS]	= hfsc_class_dump_details,
342*4dc78e53SAndroid Build Coastguard Worker 	},
343*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_fill		= hfsc_class_msg_fill,
344*4dc78e53SAndroid Build Coastguard Worker };
345*4dc78e53SAndroid Build Coastguard Worker 
hfsc_init(void)346*4dc78e53SAndroid Build Coastguard Worker static void _nl_init hfsc_init(void)
347*4dc78e53SAndroid Build Coastguard Worker {
348*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_register(&hfsc_qdisc_ops);
349*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_register(&hfsc_class_ops);
350*4dc78e53SAndroid Build Coastguard Worker }
351*4dc78e53SAndroid Build Coastguard Worker 
hfsc_exit(void)352*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit hfsc_exit(void)
353*4dc78e53SAndroid Build Coastguard Worker {
354*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_unregister(&hfsc_qdisc_ops);
355*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_unregister(&hfsc_class_ops);
356*4dc78e53SAndroid Build Coastguard Worker }
357*4dc78e53SAndroid Build Coastguard Worker 
358*4dc78e53SAndroid Build Coastguard Worker /** @} */
359