12 #include <netlink-private/netlink.h>
13 #include <netlink-private/tc.h>
14 #include <netlink/netlink.h>
15 #include <netlink/utils.h>
16 #include <netlink-private/route/tc-api.h>
17 #include <netlink/route/qdisc.h>
18 #include <netlink/route/class.h>
19 #include <netlink/route/link.h>
20 #include <netlink/route/qdisc/cbq.h>
21 #include <netlink/route/cls/police.h>
30 static const struct trans_tbl ovl_strategies[] = {
31 __ADD(TC_CBQ_OVL_CLASSIC,classic)
32 __ADD(TC_CBQ_OVL_DELAY,delay)
33 __ADD(TC_CBQ_OVL_LOWPRIO,lowprio)
34 __ADD(TC_CBQ_OVL_DROP,drop)
35 __ADD(TC_CBQ_OVL_RCLASSIC,rclassic)
50 return __type2str(type, buf, len, ovl_strategies,
51 ARRAY_SIZE(ovl_strategies));
63 return __str2type(name, ovl_strategies, ARRAY_SIZE(ovl_strategies));
66 static struct nla_policy cbq_policy[TCA_CBQ_MAX+1] = {
67 [TCA_CBQ_LSSOPT] = { .
minlen =
sizeof(
struct tc_cbq_lssopt) },
68 [TCA_CBQ_RATE] = { .minlen =
sizeof(
struct tc_ratespec) },
69 [TCA_CBQ_WRROPT] = { .minlen =
sizeof(
struct tc_cbq_wrropt) },
70 [TCA_CBQ_OVL_STRATEGY] = { .minlen =
sizeof(
struct tc_cbq_ovl) },
71 [TCA_CBQ_FOPT] = { .minlen =
sizeof(
struct tc_cbq_fopt) },
72 [TCA_CBQ_POLICE] = { .minlen =
sizeof(
struct tc_cbq_police) },
75 static int cbq_msg_parser(
struct rtnl_tc *tc,
void *data)
77 struct nlattr *tb[TCA_CBQ_MAX + 1];
78 struct rtnl_cbq *cbq = data;
81 err = tca_parse(tb, TCA_CBQ_MAX, tc, cbq_policy);
85 nla_memcpy(&cbq->cbq_lss, tb[TCA_CBQ_LSSOPT],
sizeof(cbq->cbq_lss));
86 nla_memcpy(&cbq->cbq_rate, tb[TCA_CBQ_RATE],
sizeof(cbq->cbq_rate));
87 nla_memcpy(&cbq->cbq_wrr, tb[TCA_CBQ_WRROPT],
sizeof(cbq->cbq_wrr));
88 nla_memcpy(&cbq->cbq_fopt, tb[TCA_CBQ_FOPT],
sizeof(cbq->cbq_fopt));
89 nla_memcpy(&cbq->cbq_ovl, tb[TCA_CBQ_OVL_STRATEGY],
90 sizeof(cbq->cbq_ovl));
91 nla_memcpy(&cbq->cbq_police, tb[TCA_CBQ_POLICE],
92 sizeof(cbq->cbq_police));
97 static void cbq_dump_line(
struct rtnl_tc *tc,
void *data,
100 struct rtnl_cbq *cbq = data;
110 nl_dump(p,
" rate %.2f%s/s (%.0f%s) prio %u",
111 r, ru, rbit, rubit, cbq->cbq_wrr.priority);
114 static void cbq_dump_details(
struct rtnl_tc *tc,
void *data,
117 struct rtnl_cbq *cbq = data;
127 nl_dump(p,
"avgpkt %u mpu %u cell %u allot %u weight %.0f%s\n",
130 1 << cbq->cbq_rate.cell_log,
131 cbq->cbq_wrr.allot, w, unit);
133 el = cbq->cbq_lss.ewma_log;
134 nl_dump_line(p,
" minidle %uus maxidle %uus offtime "
135 "%uus level %u ewma_log %u\n",
140 cbq->cbq_lss.ewma_log);
142 nl_dump_line(p,
" penalty %uus strategy %s ",
146 nl_dump(p,
"split %s defmap 0x%08x ",
148 cbq->cbq_fopt.defmap);
151 nl_police2str(cbq->cbq_police.police, buf,
sizeof(buf)));
154 static void cbq_dump_stats(
struct rtnl_tc *tc,
void *data,
157 struct tc_cbq_xstats *x;
159 if (!(x = tca_xstats(tc)))
162 nl_dump_line(p,
" borrows overact "
163 " avgidle undertime\n");
164 nl_dump_line(p,
" %10u %10u %10u %10u\n",
165 x->borrows, x->overactions, x->avgidle, x->undertime);
168 static struct rtnl_tc_ops cbq_qdisc_ops = {
170 .to_type = RTNL_TC_TYPE_QDISC,
171 .to_size =
sizeof(
struct rtnl_cbq),
172 .to_msg_parser = cbq_msg_parser,
180 static struct rtnl_tc_ops cbq_class_ops = {
182 .to_type = RTNL_TC_TYPE_CLASS,
183 .to_size =
sizeof(
struct rtnl_cbq),
184 .to_msg_parser = cbq_msg_parser,
192 static void __init cbq_init(
void)
198 static void __exit cbq_exit(
void)