29 #include <netlink-private/netlink.h>
30 #include <netlink-private/tc.h>
31 #include <netlink/netlink.h>
32 #include <netlink/utils.h>
33 #include <netlink-private/route/tc-api.h>
34 #include <netlink/route/qdisc.h>
35 #include <netlink/route/qdisc/prio.h>
38 #define SCH_PRIO_ATTR_BANDS 1
39 #define SCH_PRIO_ATTR_PRIOMAP 2
42 static int prio_msg_parser(
struct rtnl_tc *tc,
void *data)
44 struct rtnl_prio *prio = data;
45 struct tc_prio_qopt *opt;
47 if (tc->tc_opts->d_size <
sizeof(*opt))
50 opt = (
struct tc_prio_qopt *) tc->tc_opts->d_data;
51 prio->qp_bands = opt->bands;
52 memcpy(prio->qp_priomap, opt->priomap,
sizeof(prio->qp_priomap));
53 prio->qp_mask = (SCH_PRIO_ATTR_BANDS | SCH_PRIO_ATTR_PRIOMAP);
58 static void prio_dump_line(
struct rtnl_tc *tc,
void *data,
61 struct rtnl_prio *prio = data;
64 nl_dump(p,
" bands %u", prio->qp_bands);
67 static void prio_dump_details(
struct rtnl_tc *tc,
void *data,
70 struct rtnl_prio *prio = data;
78 for (i = 0; i <= TC_PRIO_MAX; i++)
79 nl_dump(p,
"%u%s", prio->qp_priomap[i],
80 i < TC_PRIO_MAX ?
" " :
"");
85 hp = (((TC_PRIO_MAX/2) + 1) & ~1);
87 for (i = 0; i < hp; i++) {
92 if (hp+i <= TC_PRIO_MAX) {
95 prio->qp_priomap[hp+i]);
104 static int prio_msg_fill(
struct rtnl_tc *tc,
void *data,
struct nl_msg *msg)
106 struct rtnl_prio *prio = data;
107 struct tc_prio_qopt opts;
109 if (!prio || !(prio->qp_mask & SCH_PRIO_ATTR_PRIOMAP))
112 opts.bands = prio->qp_bands;
113 memcpy(opts.priomap, prio->qp_priomap,
sizeof(opts.priomap));
115 return nlmsg_append(msg, &opts,
sizeof(opts), NL_DONTPAD);
131 struct rtnl_prio *prio;
136 prio->qp_bands = bands;
137 prio->qp_mask |= SCH_PRIO_ATTR_BANDS;
147 struct rtnl_prio *prio;
152 if (prio->qp_mask & SCH_PRIO_ATTR_BANDS)
153 return prio->qp_bands;
168 struct rtnl_prio *prio;
174 if (!(prio->qp_mask & SCH_PRIO_ATTR_BANDS))
175 return -NLE_MISSING_ATTR;
177 if ((len /
sizeof(uint8_t)) > (TC_PRIO_MAX+1))
180 for (i = 0; i <= TC_PRIO_MAX; i++) {
181 if (priomap[i] > prio->qp_bands)
185 memcpy(prio->qp_priomap, priomap, len);
186 prio->qp_mask |= SCH_PRIO_ATTR_PRIOMAP;
199 struct rtnl_prio *prio;
204 if (prio->qp_mask & SCH_PRIO_ATTR_PRIOMAP)
205 return prio->qp_priomap;
217 static const struct trans_tbl prios[] = {
218 __ADD(TC_PRIO_BESTEFFORT,besteffort)
219 __ADD(TC_PRIO_FILLER,filler)
220 __ADD(TC_PRIO_BULK,bulk)
221 __ADD(TC_PRIO_INTERACTIVE_BULK,interactive_bulk)
222 __ADD(TC_PRIO_INTERACTIVE,interactive)
223 __ADD(TC_PRIO_CONTROL,control)
239 return __type2str(prio, buf, size, prios, ARRAY_SIZE(prios));
253 return __str2type(name, prios, ARRAY_SIZE(prios));
258 static struct rtnl_tc_ops prio_ops = {
260 .to_type = RTNL_TC_TYPE_QDISC,
261 .to_size =
sizeof(
struct rtnl_prio),
262 .to_msg_parser = prio_msg_parser,
267 .to_msg_fill = prio_msg_fill,
270 static struct rtnl_tc_ops pfifo_fast_ops = {
271 .to_kind =
"pfifo_fast",
272 .to_type = RTNL_TC_TYPE_QDISC,
273 .to_size =
sizeof(
struct rtnl_prio),
274 .to_msg_parser = prio_msg_parser,
279 .to_msg_fill = prio_msg_fill,
282 static void __init prio_init(
void)
288 static void __exit prio_exit(
void)