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)
int rtnl_qdisc_prio_get_bands(struct rtnl_qdisc *qdisc)
Get number of bands of PRIO qdisc.
Dump object briefly on one line.
int rtnl_qdisc_prio_set_priomap(struct rtnl_qdisc *qdisc, uint8_t priomap[], int len)
Set priomap of the PRIO qdisc.
int rtnl_tc_register(struct rtnl_tc_ops *ops)
Register a traffic control module.
void nl_new_line(struct nl_dump_params *params)
Handle a new line while dumping.
void rtnl_qdisc_prio_set_bands(struct rtnl_qdisc *qdisc, int bands)
Set number of bands of PRIO qdisc.
Dump all attributes but no statistics.
void rtnl_tc_unregister(struct rtnl_tc_ops *ops)
Unregister a traffic control module.
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
char * rtnl_prio2str(int prio, char *buf, size_t size)
Convert priority to character string.
void * rtnl_tc_data(struct rtnl_tc *tc)
Return pointer to private data of traffic control object.
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
uint8_t * rtnl_qdisc_prio_get_priomap(struct rtnl_qdisc *qdisc)
Get priomap of a PRIO qdisc.
int rtnl_str2prio(const char *name)
Convert character string to priority.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.