libnl 3.11.0
cbq.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2/*
3 * Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
4 */
5
6#include "nl-default.h"
7
8#include <netlink/netlink.h>
9#include <netlink/utils.h>
10#include <netlink/route/qdisc.h>
11#include <netlink/route/class.h>
12#include <netlink/route/link.h>
13#include <netlink/route/qdisc/cbq.h>
14#include <netlink/route/cls/police.h>
15
16#include "tc-api.h"
17
18struct rtnl_cbq {
19 struct tc_cbq_lssopt cbq_lss;
20 struct tc_ratespec cbq_rate;
21 struct tc_cbq_wrropt cbq_wrr;
22 struct tc_cbq_ovl cbq_ovl;
23 struct tc_cbq_fopt cbq_fopt;
24 struct tc_cbq_police cbq_police;
25};
26
27/**
28 * @ingroup qdisc
29 * @ingroup class
30 * @defgroup qdisc_cbq Class Based Queueing (CBQ)
31 * @{
32 */
33
34static const struct trans_tbl ovl_strategies[] = {
35 __ADD(TC_CBQ_OVL_CLASSIC,classic),
36 __ADD(TC_CBQ_OVL_DELAY,delay),
37 __ADD(TC_CBQ_OVL_LOWPRIO,lowprio),
38 __ADD(TC_CBQ_OVL_DROP,drop),
39 __ADD(TC_CBQ_OVL_RCLASSIC,rclassic),
40};
41
42/**
43 * Convert a CBQ OVL strategy to a character string
44 * @arg type CBQ OVL strategy
45 * @arg buf destination buffer
46 * @arg len length of destination buffer
47 *
48 * Converts a CBQ OVL strategy to a character string and stores in the
49 * provided buffer. Returns the destination buffer or the type
50 * encoded in hex if no match was found.
51 */
52char *nl_ovl_strategy2str(int type, char *buf, size_t len)
53{
54 return __type2str(type, buf, len, ovl_strategies,
55 ARRAY_SIZE(ovl_strategies));
56}
57
58/**
59 * Convert a string to a CBQ OVL strategy
60 * @arg name CBQ OVL stragegy name
61 *
62 * Converts a CBQ OVL stragegy name to it's corresponding CBQ OVL strategy
63 * type. Returns the type or -1 if none was found.
64 */
65int nl_str2ovl_strategy(const char *name)
66{
67 return __str2type(name, ovl_strategies, ARRAY_SIZE(ovl_strategies));
68}
69
70static struct nla_policy cbq_policy[TCA_CBQ_MAX+1] = {
71 [TCA_CBQ_LSSOPT] = { .minlen = sizeof(struct tc_cbq_lssopt) },
72 [TCA_CBQ_RATE] = { .minlen = sizeof(struct tc_ratespec) },
73 [TCA_CBQ_WRROPT] = { .minlen = sizeof(struct tc_cbq_wrropt) },
74 [TCA_CBQ_OVL_STRATEGY] = { .minlen = sizeof(struct tc_cbq_ovl) },
75 [TCA_CBQ_FOPT] = { .minlen = sizeof(struct tc_cbq_fopt) },
76 [TCA_CBQ_POLICE] = { .minlen = sizeof(struct tc_cbq_police) },
77};
78
79static int cbq_msg_parser(struct rtnl_tc *tc, void *data)
80{
81 struct nlattr *tb[TCA_CBQ_MAX + 1];
82 struct rtnl_cbq *cbq = data;
83 int err;
84
85 err = tca_parse(tb, TCA_CBQ_MAX, tc, cbq_policy);
86 if (err < 0)
87 return err;
88
89 nla_memcpy(&cbq->cbq_lss, tb[TCA_CBQ_LSSOPT], sizeof(cbq->cbq_lss));
90 nla_memcpy(&cbq->cbq_rate, tb[TCA_CBQ_RATE], sizeof(cbq->cbq_rate));
91 nla_memcpy(&cbq->cbq_wrr, tb[TCA_CBQ_WRROPT], sizeof(cbq->cbq_wrr));
92 nla_memcpy(&cbq->cbq_fopt, tb[TCA_CBQ_FOPT], sizeof(cbq->cbq_fopt));
93 nla_memcpy(&cbq->cbq_ovl, tb[TCA_CBQ_OVL_STRATEGY],
94 sizeof(cbq->cbq_ovl));
95 nla_memcpy(&cbq->cbq_police, tb[TCA_CBQ_POLICE],
96 sizeof(cbq->cbq_police));
97
98 return 0;
99}
100
101static void cbq_dump_line(struct rtnl_tc *tc, void *data,
102 struct nl_dump_params *p)
103{
104 struct rtnl_cbq *cbq = data;
105 double r, rbit;
106 char *ru, *rubit;
107
108 if (!cbq)
109 return;
110
111 r = nl_cancel_down_bytes(cbq->cbq_rate.rate, &ru);
112 rbit = nl_cancel_down_bits(cbq->cbq_rate.rate * 8, &rubit);
113
114 nl_dump(p, " rate %.2f%s/s (%.0f%s) prio %u",
115 r, ru, rbit, rubit, cbq->cbq_wrr.priority);
116}
117
118static void cbq_dump_details(struct rtnl_tc *tc, void *data,
119 struct nl_dump_params *p)
120{
121 struct rtnl_cbq *cbq = data;
122 char *unit, buf[32];
123 double w;
124 uint32_t el;
125
126 if (!cbq)
127 return;
128
129 w = nl_cancel_down_bits(cbq->cbq_wrr.weight * 8, &unit);
130
131 nl_dump(p, "avgpkt %u mpu %u cell %u allot %u weight %.0f%s\n",
132 cbq->cbq_lss.avpkt,
133 cbq->cbq_rate.mpu,
134 1 << cbq->cbq_rate.cell_log,
135 cbq->cbq_wrr.allot, w, unit);
136
137 el = cbq->cbq_lss.ewma_log;
138 nl_dump_line(p, " minidle %uus maxidle %uus offtime "
139 "%uus level %u ewma_log %u\n",
140 nl_ticks2us(cbq->cbq_lss.minidle >> el),
141 nl_ticks2us(cbq->cbq_lss.maxidle >> el),
142 nl_ticks2us(cbq->cbq_lss.offtime >> el),
143 cbq->cbq_lss.level,
144 cbq->cbq_lss.ewma_log);
145
146 nl_dump_line(p, " penalty %uus strategy %s ",
147 nl_ticks2us(cbq->cbq_ovl.penalty),
148 nl_ovl_strategy2str(cbq->cbq_ovl.strategy, buf, sizeof(buf)));
149
150 nl_dump(p, "split %s defmap 0x%08x ",
151 rtnl_tc_handle2str(cbq->cbq_fopt.split, buf, sizeof(buf)),
152 cbq->cbq_fopt.defmap);
153
154 nl_dump(p, "police %s",
155 nl_police2str(cbq->cbq_police.police, buf, sizeof(buf)));
156}
157
158static void cbq_dump_stats(struct rtnl_tc *tc, void *data,
159 struct nl_dump_params *p)
160{
161 struct tc_cbq_xstats *x;
162
163 if (!(x = tca_xstats(tc)))
164 return;
165
166 nl_dump_line(p, " borrows overact "
167 " avgidle undertime\n");
168 nl_dump_line(p, " %10u %10u %10u %10u\n",
169 x->borrows, x->overactions, x->avgidle, x->undertime);
170}
171
172static struct rtnl_tc_ops cbq_qdisc_ops = {
173 .to_kind = "cbq",
174 .to_type = RTNL_TC_TYPE_QDISC,
175 .to_size = sizeof(struct rtnl_cbq),
176 .to_msg_parser = cbq_msg_parser,
177 .to_dump = {
178 [NL_DUMP_LINE] = cbq_dump_line,
179 [NL_DUMP_DETAILS] = cbq_dump_details,
180 [NL_DUMP_STATS] = cbq_dump_stats,
181 },
182};
183
184static struct rtnl_tc_ops cbq_class_ops = {
185 .to_kind = "cbq",
186 .to_type = RTNL_TC_TYPE_CLASS,
187 .to_size = sizeof(struct rtnl_cbq),
188 .to_msg_parser = cbq_msg_parser,
189 .to_dump = {
190 [NL_DUMP_LINE] = cbq_dump_line,
191 [NL_DUMP_DETAILS] = cbq_dump_details,
192 [NL_DUMP_STATS] = cbq_dump_stats,
193 },
194};
195
196static void _nl_init cbq_init(void)
197{
198 rtnl_tc_register(&cbq_qdisc_ops);
199 rtnl_tc_register(&cbq_class_ops);
200}
201
202static void _nl_exit cbq_exit(void)
203{
204 rtnl_tc_unregister(&cbq_qdisc_ops);
205 rtnl_tc_unregister(&cbq_class_ops);
206}
207
208/** @} */
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition attr.c:355
char * rtnl_tc_handle2str(uint32_t handle, char *buf, size_t len)
Convert a traffic control handle to a character string (Reentrant).
Definition classid.c:109
int nl_str2ovl_strategy(const char *name)
Convert a string to a CBQ OVL strategy.
Definition cbq.c:65
char * nl_ovl_strategy2str(int type, char *buf, size_t len)
Convert a CBQ OVL strategy to a character string.
Definition cbq.c:52
int rtnl_tc_register(struct rtnl_tc_ops *)
Register a traffic control module.
Definition tc.c:1018
void rtnl_tc_unregister(struct rtnl_tc_ops *)
Unregister a traffic control module.
Definition tc.c:1052
double nl_cancel_down_bits(unsigned long long l, char **unit)
Cancel down a bit counter.
Definition utils.c:254
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition utils.c:1015
double nl_cancel_down_bytes(unsigned long long l, char **unit)
Cancel down a byte counter.
Definition utils.c:223
uint32_t nl_ticks2us(uint32_t ticks)
Convert ticks to micro seconds.
Definition utils.c:594
@ NL_DUMP_STATS
Dump all attributes including statistics.
Definition types.h:22
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition types.h:20
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition types.h:21
Dumping parameters.
Definition types.h:32
Attribute validation policy.
Definition attr.h:66
uint16_t minlen
Minimal length of payload required.
Definition attr.h:71
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition attr.h:68
Definition cbq.c:18