26 #include <netlink-local.h>
27 #include <netlink-tc.h>
28 #include <netlink/netlink.h>
29 #include <netlink/utils.h>
30 #include <netlink/route/qdisc.h>
31 #include <netlink/route/qdisc-modules.h>
32 #include <netlink/route/sch/sfq.h>
35 #define SCH_SFQ_ATTR_QUANTUM 0x01
36 #define SCH_SFQ_ATTR_PERTURB 0x02
37 #define SCH_SFQ_ATTR_LIMIT 0x04
38 #define SCH_SFQ_ATTR_DIVISOR 0x08
39 #define SCH_SFQ_ATTR_FLOWS 0x10
42 static inline struct rtnl_sfq *sfq_qdisc(
struct rtnl_qdisc *qdisc)
44 return (
struct rtnl_sfq *) qdisc->q_subdata;
47 static inline struct rtnl_sfq *sfq_alloc(
struct rtnl_qdisc *qdisc)
49 if (!qdisc->q_subdata)
50 qdisc->q_subdata = calloc(1,
sizeof(
struct rtnl_sfq));
52 return sfq_qdisc(qdisc);
55 static int sfq_msg_parser(
struct rtnl_qdisc *qdisc)
58 struct tc_sfq_qopt *opts;
60 if (!(qdisc->ce_mask & TCA_ATTR_OPTS))
63 if (qdisc->q_opts->d_size <
sizeof(*opts))
64 return nl_error(EINVAL,
"SFQ specific options size mismatch");
66 sfq = sfq_alloc(qdisc);
68 return nl_errno(ENOMEM);
70 opts = (
struct tc_sfq_qopt *) qdisc->q_opts->d_data;
72 sfq->qs_quantum = opts->quantum;
73 sfq->qs_perturb = opts->perturb_period;
74 sfq->qs_limit = opts->limit;
75 sfq->qs_divisor = opts->divisor;
76 sfq->qs_flows = opts->flows;
78 sfq->qs_mask = (SCH_SFQ_ATTR_QUANTUM | SCH_SFQ_ATTR_PERTURB |
79 SCH_SFQ_ATTR_LIMIT | SCH_SFQ_ATTR_DIVISOR |
85 static void sfq_free_data(
struct rtnl_qdisc *qdisc)
87 free(qdisc->q_subdata);
90 static int sfq_dump_brief(
struct rtnl_qdisc *qdisc,
struct nl_dump_params *p,
93 struct rtnl_sfq *sfq = sfq_qdisc(qdisc);
96 dp_dump(p,
" quantum %u perturb %us",
103 static int sfq_dump_full(
struct rtnl_qdisc *qdisc,
struct nl_dump_params *p,
106 struct rtnl_sfq *sfq = sfq_qdisc(qdisc);
109 dp_dump(p,
"limit %u divisor %u",
110 sfq->qs_limit, sfq->qs_divisor);
115 static struct nl_msg *sfq_get_opts(
struct rtnl_qdisc *qdisc)
117 struct rtnl_sfq *sfq;
118 struct tc_sfq_qopt opts;
121 sfq = sfq_qdisc(qdisc);
129 memset(&opts, 0,
sizeof(opts));
130 opts.quantum = sfq->qs_quantum;
131 opts.perturb_period = sfq->qs_perturb;
132 opts.limit = sfq->qs_limit;
134 if (
nlmsg_append(msg, &opts,
sizeof(opts), NL_DONTPAD) < 0)
156 struct rtnl_sfq *sfq;
158 sfq = sfq_alloc(qdisc);
160 return nl_errno(ENOMEM);
162 sfq->qs_quantum = quantum;
163 sfq->qs_mask |= SCH_SFQ_ATTR_QUANTUM;
175 struct rtnl_sfq *sfq;
177 sfq = sfq_qdisc(qdisc);
178 if (sfq && sfq->qs_mask & SCH_SFQ_ATTR_QUANTUM)
179 return sfq->qs_quantum;
181 return nl_errno(ENOENT);
192 struct rtnl_sfq *sfq;
194 sfq = sfq_alloc(qdisc);
196 return nl_errno(ENOMEM);
198 sfq->qs_limit = limit;
199 sfq->qs_mask |= SCH_SFQ_ATTR_LIMIT;
211 struct rtnl_sfq *sfq;
213 sfq = sfq_qdisc(qdisc);
214 if (sfq && sfq->qs_mask & SCH_SFQ_ATTR_LIMIT)
215 return sfq->qs_limit;
217 return nl_errno(ENOENT);
229 struct rtnl_sfq *sfq;
231 sfq = sfq_alloc(qdisc);
233 return nl_errno(ENOMEM);
235 sfq->qs_perturb = perturb;
236 sfq->qs_mask |= SCH_SFQ_ATTR_PERTURB;
248 struct rtnl_sfq *sfq;
250 sfq = sfq_qdisc(qdisc);
251 if (sfq && sfq->qs_mask & SCH_SFQ_ATTR_PERTURB)
252 return sfq->qs_perturb;
254 return nl_errno(ENOENT);
264 struct rtnl_sfq *sfq;
266 sfq = sfq_qdisc(qdisc);
267 if (sfq && sfq->qs_mask & SCH_SFQ_ATTR_DIVISOR)
268 return sfq->qs_divisor;
270 return nl_errno(ENOENT);
277 .qo_msg_parser = sfq_msg_parser,
278 .qo_free_data = sfq_free_data,
281 .qo_get_opts = sfq_get_opts,
284 static void __init sfq_init(
void)
289 static void __exit sfq_exit(
void)
Dump object in a brief one-liner.
char qo_kind[32]
Kind/Name of Qdisc.
int rtnl_sfq_get_quantum(struct rtnl_qdisc *qdisc)
Get quantum of SFQ qdisc.
int rtnl_qdisc_unregister(struct rtnl_qdisc_ops *qops)
Unregister a qdisc module.
struct nl_msg * nlmsg_alloc(void)
Allocate a new netlink message with the default maximum payload size.
void nlmsg_free(struct nl_msg *n)
Free a netlink message.
int rtnl_sfq_set_limit(struct rtnl_qdisc *qdisc, int limit)
Set limit of SFQ qdisc.
int rtnl_sfq_set_perturb(struct rtnl_qdisc *qdisc, int perturb)
Set perturbation interval of SFQ qdisc.
uint32_t nl_ticks2us(uint32_t ticks)
Convert ticks to micro seconds.
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
int rtnl_sfq_get_divisor(struct rtnl_qdisc *qdisc)
Get divisor of SFQ qdisc.
int rtnl_qdisc_register(struct rtnl_qdisc_ops *qops)
Register a qdisc module.
int rtnl_sfq_set_quantum(struct rtnl_qdisc *qdisc, int quantum)
Set quantum of SFQ qdisc.
int nl_get_hz(void)
Return the value of HZ.
Dump all attributes but no statistics.
int rtnl_sfq_get_perturb(struct rtnl_qdisc *qdisc)
Get perturbation interval of SFQ qdisc.
int rtnl_sfq_get_limit(struct rtnl_qdisc *qdisc)
Get limit of SFQ qdisc.