libnl 1.1.4
cbq.c
1/*
2 * lib/route/sch/cbq.c Class Based Queueing
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation version 2.1
7 * of the License.
8 *
9 * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
10 */
11
12#include <netlink-local.h>
13#include <netlink-tc.h>
14#include <netlink/netlink.h>
15#include <netlink/utils.h>
16#include <netlink/route/qdisc.h>
17#include <netlink/route/qdisc-modules.h>
18#include <netlink/route/class.h>
19#include <netlink/route/class-modules.h>
20#include <netlink/route/link.h>
21#include <netlink/route/sch/cbq.h>
22#include <netlink/route/cls/police.h>
23
24/**
25 * @ingroup qdisc_api
26 * @ingroup class_api
27 * @defgroup cbq Class Based Queueing (CBQ)
28 * @{
29 */
30
31static struct trans_tbl ovl_strategies[] = {
32 __ADD(TC_CBQ_OVL_CLASSIC,classic)
33 __ADD(TC_CBQ_OVL_DELAY,delay)
34 __ADD(TC_CBQ_OVL_LOWPRIO,lowprio)
35 __ADD(TC_CBQ_OVL_DROP,drop)
36 __ADD(TC_CBQ_OVL_RCLASSIC,rclassic)
37};
38
39/**
40 * Convert a CBQ OVL strategy to a character string
41 * @arg type CBQ OVL strategy
42 * @arg buf destination buffer
43 * @arg len length of destination buffer
44 *
45 * Converts a CBQ OVL strategy to a character string and stores in the
46 * provided buffer. Returns the destination buffer or the type
47 * encoded in hex if no match was found.
48 */
49char *nl_ovl_strategy2str(int type, char *buf, size_t len)
50{
51 return __type2str(type, buf, len, ovl_strategies,
52 ARRAY_SIZE(ovl_strategies));
53}
54
55/**
56 * Convert a string to a CBQ OVL strategy
57 * @arg name CBQ OVL stragegy name
58 *
59 * Converts a CBQ OVL stragegy name to it's corresponding CBQ OVL strategy
60 * type. Returns the type or -1 if none was found.
61 */
62int nl_str2ovl_strategy(const char *name)
63{
64 return __str2type(name, ovl_strategies, ARRAY_SIZE(ovl_strategies));
65}
66
67static struct nla_policy cbq_policy[TCA_CBQ_MAX+1] = {
68 [TCA_CBQ_LSSOPT] = { .minlen = sizeof(struct tc_cbq_lssopt) },
69 [TCA_CBQ_RATE] = { .minlen = sizeof(struct tc_ratespec) },
70 [TCA_CBQ_WRROPT] = { .minlen = sizeof(struct tc_cbq_wrropt) },
71 [TCA_CBQ_OVL_STRATEGY] = { .minlen = sizeof(struct tc_cbq_ovl) },
72 [TCA_CBQ_FOPT] = { .minlen = sizeof(struct tc_cbq_fopt) },
73 [TCA_CBQ_POLICE] = { .minlen = sizeof(struct tc_cbq_police) },
74};
75
76static inline struct rtnl_cbq *cbq_qdisc(struct rtnl_tca *tca)
77{
78 return (struct rtnl_cbq *) tca->tc_subdata;
79}
80
81static inline struct rtnl_cbq *cbq_alloc(struct rtnl_tca *tca)
82{
83 if (!tca->tc_subdata)
84 tca->tc_subdata = calloc(1, sizeof(struct rtnl_qdisc));
85
86 return cbq_qdisc(tca);
87}
88
89
90static int cbq_msg_parser(struct rtnl_tca *tca)
91{
92 struct nlattr *tb[TCA_CBQ_MAX + 1];
93 struct rtnl_cbq *cbq;
94 int err;
95
96 err = tca_parse(tb, TCA_CBQ_MAX, tca, cbq_policy);
97 if (err < 0)
98 return err;
99
100 cbq = cbq_alloc(tca);
101 if (!cbq)
102 return nl_errno(ENOMEM);
103
104 nla_memcpy(&cbq->cbq_lss, tb[TCA_CBQ_LSSOPT], sizeof(cbq->cbq_lss));
105 nla_memcpy(&cbq->cbq_rate, tb[TCA_CBQ_RATE], sizeof(cbq->cbq_rate));
106 nla_memcpy(&cbq->cbq_wrr, tb[TCA_CBQ_WRROPT], sizeof(cbq->cbq_wrr));
107 nla_memcpy(&cbq->cbq_fopt, tb[TCA_CBQ_FOPT], sizeof(cbq->cbq_fopt));
108 nla_memcpy(&cbq->cbq_ovl, tb[TCA_CBQ_OVL_STRATEGY],
109 sizeof(cbq->cbq_ovl));
110 nla_memcpy(&cbq->cbq_police, tb[TCA_CBQ_POLICE],
111 sizeof(cbq->cbq_police));
112
113 return 0;
114}
115
116static int cbq_qdisc_msg_parser(struct rtnl_qdisc *qdisc)
117{
118 return cbq_msg_parser((struct rtnl_tca *) qdisc);
119}
120
121static int cbq_class_msg_parser(struct rtnl_class *class)
122{
123 return cbq_msg_parser((struct rtnl_tca *) class);
124}
125
126static void cbq_qdisc_free_data(struct rtnl_qdisc *qdisc)
127{
128 free(qdisc->q_subdata);
129}
130
131static int cbq_clone(struct rtnl_tca *_dst, struct rtnl_tca *_src)
132{
133 struct rtnl_cbq *src = cbq_qdisc(_src);
134
135 if (src && !cbq_alloc(_dst))
136 return nl_errno(ENOMEM);
137 else
138 return 0;
139}
140
141static int cbq_qdisc_clone(struct rtnl_qdisc *dst, struct rtnl_qdisc *src)
142{
143 return cbq_clone((struct rtnl_tca *) dst, (struct rtnl_tca *) src);
144}
145
146static void cbq_class_free_data(struct rtnl_class *class)
147{
148 free(class->c_subdata);
149}
150
151static int cbq_class_clone(struct rtnl_class *dst, struct rtnl_class *src)
152{
153 return cbq_clone((struct rtnl_tca *) dst, (struct rtnl_tca *) src);
154}
155
156static int cbq_dump_brief(struct rtnl_tca *tca, struct nl_dump_params *p,
157 int line)
158{
159 struct rtnl_cbq *cbq;
160 double r, rbit;
161 char *ru, *rubit;
162
163 cbq = cbq_qdisc(tca);
164 if (!cbq)
165 goto ignore;
166
167 r = nl_cancel_down_bytes(cbq->cbq_rate.rate, &ru);
168 rbit = nl_cancel_down_bits(cbq->cbq_rate.rate * 8, &rubit);
169
170 dp_dump(p, " rate %.2f%s/s (%.0f%s) prio %u",
171 r, ru, rbit, rubit, cbq->cbq_wrr.priority);
172
173ignore:
174 return line;
175}
176
177static int cbq_qdisc_dump_brief(struct rtnl_qdisc *qdisc,
178 struct nl_dump_params *p, int line)
179{
180 return cbq_dump_brief((struct rtnl_tca *) qdisc, p, line);
181}
182
183static int cbq_class_dump_brief(struct rtnl_class *class,
184 struct nl_dump_params *p, int line)
185{
186 return cbq_dump_brief((struct rtnl_tca *) class, p, line);
187}
188
189static int cbq_dump_full(struct rtnl_tca *tca, struct nl_dump_params *p,
190 int line)
191{
192 struct rtnl_cbq *cbq;
193 char *unit, buf[32];
194 double w;
195 uint32_t el;
196
197 cbq = cbq_qdisc(tca);
198 if (!cbq)
199 goto ignore;
200
201 w = nl_cancel_down_bits(cbq->cbq_wrr.weight * 8, &unit);
202
203 dp_dump(p, "avgpkt %u mpu %u cell %u allot %u weight %.0f%s\n",
204 cbq->cbq_lss.avpkt,
205 cbq->cbq_rate.mpu,
206 1 << cbq->cbq_rate.cell_log,
207 cbq->cbq_wrr.allot, w, unit);
208
209 el = cbq->cbq_lss.ewma_log;
210 dp_dump_line(p, line++, " minidle %uus maxidle %uus offtime "
211 "%uus level %u ewma_log %u\n",
212 nl_ticks2us(cbq->cbq_lss.minidle >> el),
213 nl_ticks2us(cbq->cbq_lss.maxidle >> el),
214 nl_ticks2us(cbq->cbq_lss.offtime >> el),
215 cbq->cbq_lss.level,
216 cbq->cbq_lss.ewma_log);
217
218 dp_dump_line(p, line++, " penalty %uus strategy %s ",
219 nl_ticks2us(cbq->cbq_ovl.penalty),
220 nl_ovl_strategy2str(cbq->cbq_ovl.strategy, buf, sizeof(buf)));
221
222 dp_dump(p, "split %s defmap 0x%08x ",
223 rtnl_tc_handle2str(cbq->cbq_fopt.split, buf, sizeof(buf)),
224 cbq->cbq_fopt.defmap);
225
226 dp_dump(p, "police %s",
227 nl_police2str(cbq->cbq_police.police, buf, sizeof(buf)));
228
229ignore:
230 return line;
231}
232
233static int cbq_qdisc_dump_full(struct rtnl_qdisc *qdisc,
234 struct nl_dump_params *p, int line)
235{
236 return cbq_dump_full((struct rtnl_tca *) qdisc, p, line);
237}
238
239static int cbq_class_dump_full(struct rtnl_class *class,
240 struct nl_dump_params *p, int line)
241{
242 return cbq_dump_full((struct rtnl_tca *) class, p, line);
243}
244
245static int cbq_dump_with_stats(struct rtnl_tca *tca, struct nl_dump_params *p,
246 int line)
247{
248 struct tc_cbq_xstats *x = tca_xstats(tca);
249
250 if (!x)
251 goto ignore;
252
253 dp_dump_line(p, line++, " borrows overact "
254 " avgidle undertime\n");
255 dp_dump_line(p, line++, " %10u %10u %10u %10u\n",
256 x->borrows, x->overactions, x->avgidle, x->undertime);
257
258ignore:
259 return line;
260}
261
262static int cbq_qdisc_dump_with_stats(struct rtnl_qdisc *qdisc,
263 struct nl_dump_params *p, int line)
264{
265 return cbq_dump_with_stats((struct rtnl_tca *) qdisc, p, line);
266}
267
268static int cbq_class_dump_with_stats(struct rtnl_class *class,
269 struct nl_dump_params *p, int line)
270{
271 return cbq_dump_with_stats((struct rtnl_tca *) class, p, line);
272}
273
274static struct rtnl_qdisc_ops cbq_qdisc_ops = {
275 .qo_kind = "cbq",
276 .qo_msg_parser = cbq_qdisc_msg_parser,
277 .qo_free_data = cbq_qdisc_free_data,
278 .qo_clone = cbq_qdisc_clone,
279 .qo_dump[NL_DUMP_BRIEF] = cbq_qdisc_dump_brief,
280 .qo_dump[NL_DUMP_FULL] = cbq_qdisc_dump_full,
281 .qo_dump[NL_DUMP_STATS] = cbq_qdisc_dump_with_stats,
282};
283
284static struct rtnl_class_ops cbq_class_ops = {
285 .co_kind = "cbq",
286 .co_msg_parser = cbq_class_msg_parser,
287 .co_free_data = cbq_class_free_data,
288 .co_clone = cbq_class_clone,
289 .co_dump[NL_DUMP_BRIEF] = cbq_class_dump_brief,
290 .co_dump[NL_DUMP_FULL] = cbq_class_dump_full,
291 .co_dump[NL_DUMP_STATS] = cbq_class_dump_with_stats,
292};
293
294static void __init cbq_init(void)
295{
296 rtnl_qdisc_register(&cbq_qdisc_ops);
297 rtnl_class_register(&cbq_class_ops);
298}
299
300static void __exit cbq_exit(void)
301{
302 rtnl_qdisc_unregister(&cbq_qdisc_ops);
303 rtnl_class_unregister(&cbq_class_ops);
304}
305
306/** @} */
int nla_memcpy(void *dest, struct nlattr *src, int count)
Copy a netlink attribute into another memory area.
Definition: attr.c:382
int nl_str2ovl_strategy(const char *name)
Convert a string to a CBQ OVL strategy.
Definition: cbq.c:62
char * nl_ovl_strategy2str(int type, char *buf, size_t len)
Convert a CBQ OVL strategy to a character string.
Definition: cbq.c:49
int rtnl_class_unregister(struct rtnl_class_ops *cops)
Unregister a class module.
Definition: class_api.c:58
int rtnl_class_register(struct rtnl_class_ops *cops)
Register a class module.
Definition: class_api.c:37
int rtnl_qdisc_unregister(struct rtnl_qdisc_ops *qops)
Unregister a qdisc module.
Definition: qdisc_api.c:61
int rtnl_qdisc_register(struct rtnl_qdisc_ops *qops)
Register a qdisc module.
Definition: qdisc_api.c:40
char * rtnl_tc_handle2str(uint32_t handle, char *buf, size_t len)
Convert a traffic control handle to a character string (Reentrant).
Definition: tc.c:493
double nl_cancel_down_bits(unsigned long long l, char **unit)
Cancel down a bit counter.
Definition: utils.c:220
double nl_cancel_down_bytes(unsigned long long l, char **unit)
Cancel down a byte counter.
Definition: utils.c:189
uint32_t nl_ticks2us(uint32_t ticks)
Convert ticks to micro seconds.
Definition: utils.c:450
@ NL_DUMP_FULL
Dump all attributes but no statistics.
Definition: types.h:23
@ NL_DUMP_BRIEF
Dump object in a brief one-liner.
Definition: types.h:22
@ NL_DUMP_STATS
Dump all attributes including statistics.
Definition: types.h:24
Dumping parameters.
Definition: types.h:37
attribute validation policy
Definition: attr.h:73
uint16_t minlen
Minimal length of payload required to be available.
Definition: attr.h:78
Class operations.
Definition: class-modules.h:26
char co_kind[32]
Kind/Name of class.
Definition: class-modules.h:30
Qdisc Operations.
Definition: qdisc-modules.h:26
char qo_kind[32]
Kind/Name of Qdisc.
Definition: qdisc-modules.h:30