xref: /aosp_15_r20/external/libnl/lib/route/qdisc/red.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) 2003-2011 Thomas Graf <[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  * @defgroup qdisc_red Random Early Detection (RED)
9*4dc78e53SAndroid Build Coastguard Worker  * @brief
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/utils.h>
17*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/qdisc.h>
18*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/qdisc/red.h>
19*4dc78e53SAndroid Build Coastguard Worker 
20*4dc78e53SAndroid Build Coastguard Worker #include "tc-api.h"
21*4dc78e53SAndroid Build Coastguard Worker 
22*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
23*4dc78e53SAndroid Build Coastguard Worker struct rtnl_red {
24*4dc78e53SAndroid Build Coastguard Worker 	uint32_t qr_limit;
25*4dc78e53SAndroid Build Coastguard Worker 	uint32_t qr_qth_min;
26*4dc78e53SAndroid Build Coastguard Worker 	uint32_t qr_qth_max;
27*4dc78e53SAndroid Build Coastguard Worker 	uint8_t qr_flags;
28*4dc78e53SAndroid Build Coastguard Worker 	uint8_t qr_wlog;
29*4dc78e53SAndroid Build Coastguard Worker 	uint8_t qr_plog;
30*4dc78e53SAndroid Build Coastguard Worker 	uint8_t qr_scell_log;
31*4dc78e53SAndroid Build Coastguard Worker 	uint32_t qr_mask;
32*4dc78e53SAndroid Build Coastguard Worker };
33*4dc78e53SAndroid Build Coastguard Worker 
34*4dc78e53SAndroid Build Coastguard Worker #define RED_ATTR_LIMIT		0x01
35*4dc78e53SAndroid Build Coastguard Worker #define RED_ATTR_QTH_MIN	0x02
36*4dc78e53SAndroid Build Coastguard Worker #define RED_ATTR_QTH_MAX	0x04
37*4dc78e53SAndroid Build Coastguard Worker #define RED_ATTR_FLAGS		0x08
38*4dc78e53SAndroid Build Coastguard Worker #define RED_ATTR_WLOG		0x10
39*4dc78e53SAndroid Build Coastguard Worker #define RED_ATTR_PLOG		0x20
40*4dc78e53SAndroid Build Coastguard Worker #define RED_ATTR_SCELL_LOG	0x40
41*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
42*4dc78e53SAndroid Build Coastguard Worker 
43*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy red_policy[TCA_RED_MAX+1] = {
44*4dc78e53SAndroid Build Coastguard Worker 	[TCA_RED_PARMS]		= { .minlen = sizeof(struct tc_red_qopt) },
45*4dc78e53SAndroid Build Coastguard Worker };
46*4dc78e53SAndroid Build Coastguard Worker 
red_msg_parser(struct rtnl_tc * tc,void * data)47*4dc78e53SAndroid Build Coastguard Worker static int red_msg_parser(struct rtnl_tc *tc, void *data)
48*4dc78e53SAndroid Build Coastguard Worker {
49*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *tb[TCA_RED_MAX+1];
50*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_red *red = data;
51*4dc78e53SAndroid Build Coastguard Worker 	struct tc_red_qopt *opts;
52*4dc78e53SAndroid Build Coastguard Worker 	int err;
53*4dc78e53SAndroid Build Coastguard Worker 
54*4dc78e53SAndroid Build Coastguard Worker 	if (!(tc->ce_mask & TCA_ATTR_OPTS))
55*4dc78e53SAndroid Build Coastguard Worker 		return 0;
56*4dc78e53SAndroid Build Coastguard Worker 
57*4dc78e53SAndroid Build Coastguard Worker 	err = tca_parse(tb, TCA_RED_MAX, tc, red_policy);
58*4dc78e53SAndroid Build Coastguard Worker 	if (err < 0)
59*4dc78e53SAndroid Build Coastguard Worker 		return err;
60*4dc78e53SAndroid Build Coastguard Worker 
61*4dc78e53SAndroid Build Coastguard Worker 	if (!tb[TCA_RED_PARMS])
62*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
63*4dc78e53SAndroid Build Coastguard Worker 
64*4dc78e53SAndroid Build Coastguard Worker 	opts = nla_data(tb[TCA_RED_PARMS]);
65*4dc78e53SAndroid Build Coastguard Worker 
66*4dc78e53SAndroid Build Coastguard Worker 	red->qr_limit = opts->limit;
67*4dc78e53SAndroid Build Coastguard Worker 	red->qr_qth_min = opts->qth_min;
68*4dc78e53SAndroid Build Coastguard Worker 	red->qr_qth_max = opts->qth_max;
69*4dc78e53SAndroid Build Coastguard Worker 	red->qr_flags = opts->flags;
70*4dc78e53SAndroid Build Coastguard Worker 	red->qr_wlog = opts->Wlog;
71*4dc78e53SAndroid Build Coastguard Worker 	red->qr_plog = opts->Plog;
72*4dc78e53SAndroid Build Coastguard Worker 	red->qr_scell_log = opts->Scell_log;
73*4dc78e53SAndroid Build Coastguard Worker 
74*4dc78e53SAndroid Build Coastguard Worker 	red->qr_mask = (RED_ATTR_LIMIT | RED_ATTR_QTH_MIN | RED_ATTR_QTH_MAX |
75*4dc78e53SAndroid Build Coastguard Worker 			RED_ATTR_FLAGS | RED_ATTR_WLOG | RED_ATTR_PLOG |
76*4dc78e53SAndroid Build Coastguard Worker 			RED_ATTR_SCELL_LOG);
77*4dc78e53SAndroid Build Coastguard Worker 
78*4dc78e53SAndroid Build Coastguard Worker 	return 0;
79*4dc78e53SAndroid Build Coastguard Worker }
80*4dc78e53SAndroid Build Coastguard Worker 
red_dump_line(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)81*4dc78e53SAndroid Build Coastguard Worker static void red_dump_line(struct rtnl_tc *tc, void *data,
82*4dc78e53SAndroid Build Coastguard Worker 			  struct nl_dump_params *p)
83*4dc78e53SAndroid Build Coastguard Worker {
84*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_red *red = data;
85*4dc78e53SAndroid Build Coastguard Worker 
86*4dc78e53SAndroid Build Coastguard Worker 	if (red) {
87*4dc78e53SAndroid Build Coastguard Worker 		/* XXX: limit, min, max, flags */
88*4dc78e53SAndroid Build Coastguard Worker 	}
89*4dc78e53SAndroid Build Coastguard Worker }
90*4dc78e53SAndroid Build Coastguard Worker 
red_dump_details(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)91*4dc78e53SAndroid Build Coastguard Worker static void red_dump_details(struct rtnl_tc *tc, void *data,
92*4dc78e53SAndroid Build Coastguard Worker 			     struct nl_dump_params *p)
93*4dc78e53SAndroid Build Coastguard Worker {
94*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_red *red = data;
95*4dc78e53SAndroid Build Coastguard Worker 
96*4dc78e53SAndroid Build Coastguard Worker 	if (red) {
97*4dc78e53SAndroid Build Coastguard Worker 		/* XXX: wlog, plog, scell_log */
98*4dc78e53SAndroid Build Coastguard Worker 	}
99*4dc78e53SAndroid Build Coastguard Worker }
100*4dc78e53SAndroid Build Coastguard Worker 
red_dump_stats(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)101*4dc78e53SAndroid Build Coastguard Worker static void red_dump_stats(struct rtnl_tc *tc, void *data,
102*4dc78e53SAndroid Build Coastguard Worker 			   struct nl_dump_params *p)
103*4dc78e53SAndroid Build Coastguard Worker {
104*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_red *red = data;
105*4dc78e53SAndroid Build Coastguard Worker 
106*4dc78e53SAndroid Build Coastguard Worker 	if (red) {
107*4dc78e53SAndroid Build Coastguard Worker 		/* XXX: xstats */
108*4dc78e53SAndroid Build Coastguard Worker 	}
109*4dc78e53SAndroid Build Coastguard Worker }
110*4dc78e53SAndroid Build Coastguard Worker 
red_msg_fill(struct rtnl_tc * tc,void * data,struct nl_msg * msg)111*4dc78e53SAndroid Build Coastguard Worker static int red_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
112*4dc78e53SAndroid Build Coastguard Worker {
113*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_red *red = data;
114*4dc78e53SAndroid Build Coastguard Worker 
115*4dc78e53SAndroid Build Coastguard Worker 	if (!red)
116*4dc78e53SAndroid Build Coastguard Worker 		BUG();
117*4dc78e53SAndroid Build Coastguard Worker 
118*4dc78e53SAndroid Build Coastguard Worker #if 0
119*4dc78e53SAndroid Build Coastguard Worker 	memset(&opts, 0, sizeof(opts));
120*4dc78e53SAndroid Build Coastguard Worker 	opts.quantum = sfq->qs_quantum;
121*4dc78e53SAndroid Build Coastguard Worker 	opts.perturb_period = sfq->qs_perturb;
122*4dc78e53SAndroid Build Coastguard Worker 	opts.limit = sfq->qs_limit;
123*4dc78e53SAndroid Build Coastguard Worker 
124*4dc78e53SAndroid Build Coastguard Worker 	if (nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD) < 0)
125*4dc78e53SAndroid Build Coastguard Worker 		goto errout;
126*4dc78e53SAndroid Build Coastguard Worker #endif
127*4dc78e53SAndroid Build Coastguard Worker 
128*4dc78e53SAndroid Build Coastguard Worker 	return -NLE_OPNOTSUPP;
129*4dc78e53SAndroid Build Coastguard Worker }
130*4dc78e53SAndroid Build Coastguard Worker 
131*4dc78e53SAndroid Build Coastguard Worker /**
132*4dc78e53SAndroid Build Coastguard Worker  * @name Attribute Access
133*4dc78e53SAndroid Build Coastguard Worker  * @{
134*4dc78e53SAndroid Build Coastguard Worker  */
135*4dc78e53SAndroid Build Coastguard Worker 
136*4dc78e53SAndroid Build Coastguard Worker /**
137*4dc78e53SAndroid Build Coastguard Worker  * Set limit of RED qdisc.
138*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc		RED qdisc to be modified.
139*4dc78e53SAndroid Build Coastguard Worker  * @arg limit		New limit in number of packets.
140*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
141*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_red_set_limit(struct rtnl_qdisc * qdisc,int limit)142*4dc78e53SAndroid Build Coastguard Worker void rtnl_red_set_limit(struct rtnl_qdisc *qdisc, int limit)
143*4dc78e53SAndroid Build Coastguard Worker {
144*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_red *red;
145*4dc78e53SAndroid Build Coastguard Worker 
146*4dc78e53SAndroid Build Coastguard Worker 	if (!(red = rtnl_tc_data(TC_CAST(qdisc))))
147*4dc78e53SAndroid Build Coastguard Worker 		BUG();
148*4dc78e53SAndroid Build Coastguard Worker 
149*4dc78e53SAndroid Build Coastguard Worker 	red->qr_limit = limit;
150*4dc78e53SAndroid Build Coastguard Worker 	red->qr_mask |= RED_ATTR_LIMIT;
151*4dc78e53SAndroid Build Coastguard Worker }
152*4dc78e53SAndroid Build Coastguard Worker 
153*4dc78e53SAndroid Build Coastguard Worker /**
154*4dc78e53SAndroid Build Coastguard Worker  * Get limit of RED qdisc.
155*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc		RED qdisc.
156*4dc78e53SAndroid Build Coastguard Worker  * @return Limit or a negative error code.
157*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_red_get_limit(struct rtnl_qdisc * qdisc)158*4dc78e53SAndroid Build Coastguard Worker int rtnl_red_get_limit(struct rtnl_qdisc *qdisc)
159*4dc78e53SAndroid Build Coastguard Worker {
160*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_red *red;
161*4dc78e53SAndroid Build Coastguard Worker 
162*4dc78e53SAndroid Build Coastguard Worker 	if (!(red = rtnl_tc_data(TC_CAST(qdisc))))
163*4dc78e53SAndroid Build Coastguard Worker 		BUG();
164*4dc78e53SAndroid Build Coastguard Worker 
165*4dc78e53SAndroid Build Coastguard Worker 	if (red->qr_mask & RED_ATTR_LIMIT)
166*4dc78e53SAndroid Build Coastguard Worker 		return red->qr_limit;
167*4dc78e53SAndroid Build Coastguard Worker 	else
168*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOATTR;
169*4dc78e53SAndroid Build Coastguard Worker }
170*4dc78e53SAndroid Build Coastguard Worker 
171*4dc78e53SAndroid Build Coastguard Worker /** @} */
172*4dc78e53SAndroid Build Coastguard Worker 
173*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops red_ops = {
174*4dc78e53SAndroid Build Coastguard Worker 	.to_kind		= "red",
175*4dc78e53SAndroid Build Coastguard Worker 	.to_type		= RTNL_TC_TYPE_QDISC,
176*4dc78e53SAndroid Build Coastguard Worker 	.to_size		= sizeof(struct rtnl_red),
177*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_parser		= red_msg_parser,
178*4dc78e53SAndroid Build Coastguard Worker 	.to_dump = {
179*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_LINE]	= red_dump_line,
180*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_DETAILS]	= red_dump_details,
181*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_STATS]	= red_dump_stats,
182*4dc78e53SAndroid Build Coastguard Worker 	},
183*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_fill		= red_msg_fill,
184*4dc78e53SAndroid Build Coastguard Worker };
185*4dc78e53SAndroid Build Coastguard Worker 
red_init(void)186*4dc78e53SAndroid Build Coastguard Worker static void _nl_init red_init(void)
187*4dc78e53SAndroid Build Coastguard Worker {
188*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_register(&red_ops);
189*4dc78e53SAndroid Build Coastguard Worker }
190*4dc78e53SAndroid Build Coastguard Worker 
red_exit(void)191*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit red_exit(void)
192*4dc78e53SAndroid Build Coastguard Worker {
193*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_unregister(&red_ops);
194*4dc78e53SAndroid Build Coastguard Worker }
195*4dc78e53SAndroid Build Coastguard Worker 
196*4dc78e53SAndroid Build Coastguard Worker /** @} */
197