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.