19 #include <netlink-local.h>
20 #include <netlink-tc.h>
21 #include <netlink/netlink.h>
22 #include <netlink/utils.h>
23 #include <netlink/route/qdisc.h>
24 #include <netlink/route/qdisc-modules.h>
25 #include <netlink/route/class.h>
26 #include <netlink/route/class-modules.h>
27 #include <netlink/route/sch/dsmark.h>
30 #define SCH_DSMARK_ATTR_INDICES 0x1
31 #define SCH_DSMARK_ATTR_DEFAULT_INDEX 0x2
32 #define SCH_DSMARK_ATTR_SET_TC_INDEX 0x4
34 #define SCH_DSMARK_ATTR_MASK 0x1
35 #define SCH_DSMARK_ATTR_VALUE 0x2
38 static inline struct rtnl_dsmark_qdisc *dsmark_qdisc(
struct rtnl_qdisc *qdisc)
40 return (
struct rtnl_dsmark_qdisc *) qdisc->q_subdata;
43 static inline struct rtnl_dsmark_qdisc *
44 dsmark_qdisc_alloc(
struct rtnl_qdisc *qdisc)
46 if (!qdisc->q_subdata)
47 qdisc->q_subdata = calloc(1,
sizeof(
struct rtnl_dsmark_qdisc));
49 return dsmark_qdisc(qdisc);
52 static struct nla_policy dsmark_policy[TCA_DSMARK_MAX+1] = {
54 [TCA_DSMARK_DEFAULT_INDEX] = { .type =
NLA_U16 },
55 [TCA_DSMARK_SET_TC_INDEX] = { .type =
NLA_FLAG },
56 [TCA_DSMARK_VALUE] = { .type =
NLA_U8 },
57 [TCA_DSMARK_MASK] = { .type =
NLA_U8 },
60 static int dsmark_qdisc_msg_parser(
struct rtnl_qdisc *qdisc)
63 struct nlattr *tb[TCA_DSMARK_MAX + 1];
64 struct rtnl_dsmark_qdisc *dsmark;
66 err = tca_parse(tb, TCA_DSMARK_MAX, (
struct rtnl_tca *) qdisc,
71 dsmark = dsmark_qdisc_alloc(qdisc);
73 return nl_errno(ENOMEM);
75 if (tb[TCA_DSMARK_INDICES]) {
76 dsmark->qdm_indices =
nla_get_u16(tb[TCA_DSMARK_INDICES]);
77 dsmark->qdm_mask |= SCH_DSMARK_ATTR_INDICES;
80 if (tb[TCA_DSMARK_DEFAULT_INDEX]) {
81 dsmark->qdm_default_index =
83 dsmark->qdm_mask |= SCH_DSMARK_ATTR_DEFAULT_INDEX;
86 if (tb[TCA_DSMARK_SET_TC_INDEX]) {
87 dsmark->qdm_set_tc_index = 1;
88 dsmark->qdm_mask |= SCH_DSMARK_ATTR_SET_TC_INDEX;
94 static inline struct rtnl_dsmark_class *dsmark_class(
struct rtnl_class *
class)
96 return (
struct rtnl_dsmark_class *)
class->c_subdata;
99 static inline struct rtnl_dsmark_class *
100 dsmark_class_alloc(
struct rtnl_class *
class)
102 if (!class->c_subdata)
103 class->c_subdata = calloc(1,
sizeof(
struct rtnl_dsmark_class));
105 return dsmark_class(
class);
108 static int dsmark_class_msg_parser(
struct rtnl_class *
class)
111 struct nlattr *tb[TCA_DSMARK_MAX + 1];
112 struct rtnl_dsmark_class *dsmark;
114 err = tca_parse(tb, TCA_DSMARK_MAX, (
struct rtnl_tca *)
class,
119 dsmark = dsmark_class_alloc(
class);
121 return nl_errno(ENOMEM);
123 if (tb[TCA_DSMARK_MASK]) {
124 dsmark->cdm_bmask =
nla_get_u8(tb[TCA_DSMARK_MASK]);
125 dsmark->cdm_mask |= SCH_DSMARK_ATTR_MASK;
128 if (tb[TCA_DSMARK_VALUE]) {
129 dsmark->cdm_value =
nla_get_u8(tb[TCA_DSMARK_VALUE]);
130 dsmark->cdm_mask |= SCH_DSMARK_ATTR_VALUE;
136 static int dsmark_qdisc_dump_brief(
struct rtnl_qdisc *qdisc,
139 struct rtnl_dsmark_qdisc *dsmark = dsmark_qdisc(qdisc);
141 if (dsmark && (dsmark->qdm_mask & SCH_DSMARK_ATTR_INDICES))
142 dp_dump(p,
" indices 0x%04x", dsmark->qdm_indices);
147 static int dsmark_qdisc_dump_full(
struct rtnl_qdisc *qdisc,
150 struct rtnl_dsmark_qdisc *dsmark = dsmark_qdisc(qdisc);
155 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_DEFAULT_INDEX)
156 dp_dump(p,
" default index 0x%04x", dsmark->qdm_default_index);
158 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_SET_TC_INDEX)
159 dp_dump(p,
" set-tc-index");
165 static int dsmark_class_dump_brief(
struct rtnl_class *
class,
168 struct rtnl_dsmark_class *dsmark = dsmark_class(
class);
173 if (dsmark->cdm_mask & SCH_DSMARK_ATTR_VALUE)
174 dp_dump(p,
" value 0x%02x", dsmark->cdm_value);
176 if (dsmark->cdm_mask & SCH_DSMARK_ATTR_MASK)
177 dp_dump(p,
" mask 0x%02x", dsmark->cdm_bmask);
183 static struct nl_msg *dsmark_qdisc_get_opts(
struct rtnl_qdisc *qdisc)
185 struct rtnl_dsmark_qdisc *dsmark = dsmark_qdisc(qdisc);
193 goto nla_put_failure;
195 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_INDICES)
196 NLA_PUT_U16(msg, TCA_DSMARK_INDICES, dsmark->qdm_indices);
198 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_DEFAULT_INDEX)
200 dsmark->qdm_default_index);
202 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_SET_TC_INDEX)
212 static struct nl_msg *dsmark_class_get_opts(
struct rtnl_class *
class)
214 struct rtnl_dsmark_class *dsmark = dsmark_class(
class);
222 goto nla_put_failure;
224 if (dsmark->cdm_mask & SCH_DSMARK_ATTR_MASK)
225 NLA_PUT_U8(msg, TCA_DSMARK_MASK, dsmark->cdm_bmask);
227 if (dsmark->cdm_mask & SCH_DSMARK_ATTR_VALUE)
228 NLA_PUT_U8(msg, TCA_DSMARK_VALUE, dsmark->cdm_value);
250 struct rtnl_dsmark_class *dsmark;
252 dsmark = dsmark_class(
class);
254 return nl_errno(ENOMEM);
256 dsmark->cdm_bmask = mask;
257 dsmark->cdm_mask |= SCH_DSMARK_ATTR_MASK;
269 struct rtnl_dsmark_class *dsmark;
271 dsmark = dsmark_class(
class);
272 if (dsmark && dsmark->cdm_mask & SCH_DSMARK_ATTR_MASK)
273 return dsmark->cdm_bmask;
275 return nl_errno(ENOENT);
286 struct rtnl_dsmark_class *dsmark;
288 dsmark = dsmark_class(
class);
290 return nl_errno(ENOMEM);
292 dsmark->cdm_value = value;
293 dsmark->cdm_mask |= SCH_DSMARK_ATTR_VALUE;
305 struct rtnl_dsmark_class *dsmark;
307 dsmark = dsmark_class(
class);
308 if (dsmark && dsmark->cdm_mask & SCH_DSMARK_ATTR_VALUE)
309 return dsmark->cdm_value;
311 return nl_errno(ENOENT);
328 struct rtnl_dsmark_qdisc *dsmark;
330 dsmark = dsmark_qdisc(qdisc);
332 return nl_errno(ENOMEM);
334 dsmark->qdm_indices = indices;
335 dsmark->qdm_mask |= SCH_DSMARK_ATTR_INDICES;
347 struct rtnl_dsmark_qdisc *dsmark;
349 dsmark = dsmark_qdisc(qdisc);
350 if (dsmark && dsmark->qdm_mask & SCH_DSMARK_ATTR_INDICES)
351 return dsmark->qdm_indices;
353 return nl_errno(ENOENT);
363 uint16_t default_index)
365 struct rtnl_dsmark_qdisc *dsmark;
367 dsmark = dsmark_qdisc(qdisc);
369 return nl_errno(ENOMEM);
371 dsmark->qdm_default_index = default_index;
372 dsmark->qdm_mask |= SCH_DSMARK_ATTR_DEFAULT_INDEX;
384 struct rtnl_dsmark_qdisc *dsmark;
386 dsmark = dsmark_qdisc(qdisc);
387 if (dsmark && dsmark->qdm_mask & SCH_DSMARK_ATTR_DEFAULT_INDEX)
388 return dsmark->qdm_default_index;
390 return nl_errno(ENOENT);
401 struct rtnl_dsmark_qdisc *dsmark;
403 dsmark = dsmark_qdisc(qdisc);
405 return nl_errno(ENOMEM);
407 dsmark->qdm_set_tc_index = !!flag;
408 dsmark->qdm_mask |= SCH_DSMARK_ATTR_SET_TC_INDEX;
421 struct rtnl_dsmark_qdisc *dsmark;
423 dsmark = dsmark_qdisc(qdisc);
424 if (dsmark && dsmark->qdm_mask & SCH_DSMARK_ATTR_SET_TC_INDEX)
425 return dsmark->qdm_set_tc_index;
427 return nl_errno(ENOENT);
434 .qo_msg_parser = dsmark_qdisc_msg_parser,
437 .qo_get_opts = dsmark_qdisc_get_opts,
442 .co_msg_parser = dsmark_class_msg_parser,
444 .co_get_opts = dsmark_class_get_opts,
447 static void __init dsmark_init(
void)
453 static void __exit dsmark_exit(
void)