23#include <netlink-private/netlink.h>
24#include <netlink-private/tc.h>
25#include <netlink/netlink.h>
26#include <netlink/utils.h>
27#include <netlink-private/route/tc-api.h>
28#include <netlink/route/qdisc.h>
29#include <netlink/route/qdisc/prio.h>
32#define SCH_PRIO_ATTR_BANDS 1
33#define SCH_PRIO_ATTR_PRIOMAP 2
36static int prio_msg_parser(
struct rtnl_tc *tc,
void *data)
38 struct rtnl_prio *prio = data;
39 struct tc_prio_qopt *opt;
41 if (tc->tc_opts->d_size <
sizeof(*opt))
44 opt = (
struct tc_prio_qopt *) tc->tc_opts->d_data;
45 prio->qp_bands = opt->bands;
46 memcpy(prio->qp_priomap, opt->priomap,
sizeof(prio->qp_priomap));
47 prio->qp_mask = (SCH_PRIO_ATTR_BANDS | SCH_PRIO_ATTR_PRIOMAP);
52static void prio_dump_line(
struct rtnl_tc *tc,
void *data,
55 struct rtnl_prio *prio = data;
58 nl_dump(p,
" bands %u", prio->qp_bands);
61static void prio_dump_details(
struct rtnl_tc *tc,
void *data,
64 struct rtnl_prio *prio = data;
72 for (i = 0; i <= TC_PRIO_MAX; i++)
73 nl_dump(p,
"%u%s", prio->qp_priomap[i],
74 i < TC_PRIO_MAX ?
" " :
"");
79 hp = (((TC_PRIO_MAX/2) + 1) & ~1);
81 for (i = 0; i < hp; i++) {
86 if (hp+i <= TC_PRIO_MAX) {
89 prio->qp_priomap[hp+i]);
98static int prio_msg_fill(
struct rtnl_tc *tc,
void *data,
struct nl_msg *msg)
100 struct rtnl_prio *prio = data;
101 struct tc_prio_qopt opts;
103 if (!prio || !(prio->qp_mask & SCH_PRIO_ATTR_PRIOMAP))
106 opts.bands = prio->qp_bands;
107 memcpy(opts.priomap, prio->qp_priomap,
sizeof(opts.priomap));
109 return nlmsg_append(msg, &opts,
sizeof(opts), NL_DONTPAD);
125 struct rtnl_prio *prio;
130 prio->qp_bands = bands;
131 prio->qp_mask |= SCH_PRIO_ATTR_BANDS;
141 struct rtnl_prio *prio;
146 if (prio->qp_mask & SCH_PRIO_ATTR_BANDS)
147 return prio->qp_bands;
162 struct rtnl_prio *prio;
168 if (!(prio->qp_mask & SCH_PRIO_ATTR_BANDS))
169 return -NLE_MISSING_ATTR;
171 if ((len /
sizeof(uint8_t)) > (TC_PRIO_MAX+1))
174 for (i = 0; i <= TC_PRIO_MAX; i++) {
175 if (priomap[i] > prio->qp_bands)
179 memcpy(prio->qp_priomap, priomap, len);
180 prio->qp_mask |= SCH_PRIO_ATTR_PRIOMAP;
193 struct rtnl_prio *prio;
198 if (prio->qp_mask & SCH_PRIO_ATTR_PRIOMAP)
199 return prio->qp_priomap;
211static const struct trans_tbl prios[] = {
212 __ADD(TC_PRIO_BESTEFFORT,besteffort),
213 __ADD(TC_PRIO_FILLER,filler),
214 __ADD(TC_PRIO_BULK,bulk),
215 __ADD(TC_PRIO_INTERACTIVE_BULK,interactive_bulk),
216 __ADD(TC_PRIO_INTERACTIVE,interactive),
217 __ADD(TC_PRIO_CONTROL,control),
233 return __type2str(prio, buf, size, prios, ARRAY_SIZE(prios));
247 return __str2type(name, prios, ARRAY_SIZE(prios));
252static struct rtnl_tc_ops prio_ops = {
254 .to_type = RTNL_TC_TYPE_QDISC,
255 .to_size =
sizeof(
struct rtnl_prio),
256 .to_msg_parser = prio_msg_parser,
261 .to_msg_fill = prio_msg_fill,
264static struct rtnl_tc_ops pfifo_fast_ops = {
265 .to_kind =
"pfifo_fast",
266 .to_type = RTNL_TC_TYPE_QDISC,
267 .to_size =
sizeof(
struct rtnl_prio),
268 .to_msg_parser = prio_msg_parser,
273 .to_msg_fill = prio_msg_fill,
276static void __init prio_init(
void)
282static void __exit prio_exit(
void)
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
int rtnl_qdisc_prio_get_bands(struct rtnl_qdisc *qdisc)
Get number of bands of PRIO qdisc.
int rtnl_str2prio(const char *name)
Convert character string to priority.
int rtnl_qdisc_prio_set_priomap(struct rtnl_qdisc *qdisc, uint8_t priomap[], int len)
Set priomap of the PRIO qdisc.
uint8_t * rtnl_qdisc_prio_get_priomap(struct rtnl_qdisc *qdisc)
Get priomap of a PRIO qdisc.
char * rtnl_prio2str(int prio, char *buf, size_t size)
Convert priority to character string.
void rtnl_qdisc_prio_set_bands(struct rtnl_qdisc *qdisc, int bands)
Set number of bands of PRIO qdisc.
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
void * rtnl_tc_data(struct rtnl_tc *tc)
Return pointer to private data of traffic control object.
int rtnl_tc_register(struct rtnl_tc_ops *ops)
Register a traffic control module.
void rtnl_tc_unregister(struct rtnl_tc_ops *ops)
Unregister a traffic control module.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
void nl_new_line(struct nl_dump_params *params)
Handle a new line while dumping.
@ NL_DUMP_LINE
Dump object briefly on one line.
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.