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