25 #include <netlink-private/netlink.h>
26 #include <netlink-private/tc.h>
27 #include <netlink/netlink.h>
28 #include <netlink-private/route/tc-api.h>
29 #include <netlink/route/classifier.h>
30 #include <netlink/route/action.h>
31 #include <netlink/route/cls/basic.h>
32 #include <netlink/route/cls/ematch.h>
37 struct rtnl_ematch_tree * b_ematch;
39 struct rtnl_act * b_act;
43 #define BASIC_ATTR_TARGET 0x001
44 #define BASIC_ATTR_EMATCH 0x002
45 #define BASIC_ATTR_ACTION 0x004
48 static struct nla_policy basic_policy[TCA_BASIC_MAX+1] = {
53 static int basic_clone(
void *_dst,
void *_src)
55 return -NLE_OPNOTSUPP;
58 static void basic_free_data(
struct rtnl_tc *tc,
void *data)
66 rtnl_act_put_all(&b->b_act);
70 static int basic_msg_parser(
struct rtnl_tc *tc,
void *data)
72 struct nlattr *tb[TCA_BASIC_MAX + 1];
76 err = tca_parse(tb, TCA_BASIC_MAX, tc, basic_policy);
80 if (tb[TCA_BASIC_CLASSID]) {
82 b->b_mask |= BASIC_ATTR_TARGET;
85 if (tb[TCA_BASIC_EMATCHES]) {
91 b->b_mask |= BASIC_ATTR_EMATCH;
93 if (tb[TCA_BASIC_ACT]) {
94 b->b_mask |= BASIC_ATTR_ACTION;
95 err = rtnl_act_parse(&b->b_act, tb[TCA_BASIC_ACT]);
103 static void basic_dump_line(
struct rtnl_tc *tc,
void *data,
112 if (b->b_mask & BASIC_ATTR_EMATCH)
117 if (b->b_mask & BASIC_ATTR_TARGET)
122 static void basic_dump_details(
struct rtnl_tc *tc,
void *data,
130 if (b->b_mask & BASIC_ATTR_EMATCH) {
131 nl_dump_line(p,
" ematch ");
132 rtnl_ematch_tree_dump(b->b_ematch, p);
137 static int basic_msg_fill(
struct rtnl_tc *tc,
void *data,
145 if (!(b->b_mask & BASIC_ATTR_TARGET))
146 return -NLE_MISSING_ATTR;
150 if (b->b_mask & BASIC_ATTR_EMATCH &&
151 rtnl_ematch_fill_attr(msg, TCA_BASIC_EMATCHES, b->b_ematch) < 0)
152 goto nla_put_failure;
154 if (b->b_mask & BASIC_ATTR_ACTION) {
157 err = rtnl_act_fill(msg, TCA_BASIC_ACT, b->b_act);
173 void rtnl_basic_set_target(
struct rtnl_cls *cls, uint32_t target)
180 b->b_target = target;
181 b->b_mask |= BASIC_ATTR_TARGET;
184 uint32_t rtnl_basic_get_target(
struct rtnl_cls *cls)
194 void rtnl_basic_set_ematch(
struct rtnl_cls *cls,
struct rtnl_ematch_tree *tree)
203 b->b_mask &= ~BASIC_ATTR_EMATCH;
209 b->b_mask |= BASIC_ATTR_EMATCH;
212 struct rtnl_ematch_tree *rtnl_basic_get_ematch(
struct rtnl_cls *cls)
222 int rtnl_basic_add_action(
struct rtnl_cls *cls,
struct rtnl_act *act)
232 b->b_mask |= BASIC_ATTR_ACTION;
233 return rtnl_act_append(&b->b_act, act);
236 int rtnl_basic_del_action(
struct rtnl_cls *cls,
struct rtnl_act *act)
247 if (!(b->b_mask & BASIC_ATTR_ACTION))
249 ret = rtnl_act_remove(&b->b_act, act);
251 b->b_mask &= ~BASIC_ATTR_ACTION;
256 static struct rtnl_tc_ops basic_ops = {
258 .to_type = RTNL_TC_TYPE_CLS,
260 .to_msg_parser = basic_msg_parser,
261 .to_clone = basic_clone,
262 .to_free_data = basic_free_data,
263 .to_msg_fill = basic_msg_fill,
270 static void __init basic_init(
void)
275 static void __exit basic_exit(
void)