libnl  3.5.0
skbedit.c
1 /*
2  * lib/route/act/skbedit.c skbedit action
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation version 2.1
7  * of the License.
8  *
9  * Copyright (c) 2015 Cong Wang <xiyou.wangcong@gmail.com>
10  */
11 
12 /**
13  * @ingroup act
14  * @defgroup act_skbedit SKB Editing
15  *
16  * @{
17  */
18 
19 #include <netlink-private/netlink.h>
20 #include <netlink-private/tc.h>
21 #include <netlink/netlink.h>
22 #include <netlink/attr.h>
23 #include <netlink/utils.h>
24 #include <netlink-private/route/tc-api.h>
25 #include <netlink/route/act/skbedit.h>
26 
27 static struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = {
28  [TCA_SKBEDIT_PARMS] = { .minlen = sizeof(struct tc_skbedit) },
29  [TCA_SKBEDIT_PRIORITY] = { .type = NLA_U32 },
30  [TCA_SKBEDIT_QUEUE_MAPPING] = { .type = NLA_U16 },
31  [TCA_SKBEDIT_MARK] = { .type = NLA_U32 },
32 };
33 
34 static int skbedit_msg_parser(struct rtnl_tc *tc, void *data)
35 {
36  struct rtnl_skbedit *u = data;
37  struct nlattr *tb[TCA_SKBEDIT_MAX + 1];
38  int err;
39 
40  err = tca_parse(tb, TCA_SKBEDIT_MAX, tc, skbedit_policy);
41  if (err < 0)
42  return err;
43 
44  if (!tb[TCA_SKBEDIT_PARMS])
45  return -NLE_MISSING_ATTR;
46 
47  u->s_flags = 0;
48  if (tb[TCA_SKBEDIT_PRIORITY] != NULL) {
49  u->s_flags |= SKBEDIT_F_PRIORITY;
50  u->s_prio = nla_get_u32(tb[TCA_SKBEDIT_PRIORITY]);
51  }
52 
53  if (tb[TCA_SKBEDIT_QUEUE_MAPPING] != NULL) {
54  u->s_flags |= SKBEDIT_F_QUEUE_MAPPING;
55  u->s_queue_mapping = nla_get_u16(tb[TCA_SKBEDIT_QUEUE_MAPPING]);
56  }
57 
58  if (tb[TCA_SKBEDIT_MARK] != NULL) {
59  u->s_flags |= SKBEDIT_F_MARK;
60  u->s_mark = nla_get_u32(tb[TCA_SKBEDIT_MARK]);
61  }
62 
63  return 0;
64 }
65 
66 static void skbedit_free_data(struct rtnl_tc *tc, void *data)
67 {
68 }
69 
70 static int skbedit_clone(void *_dst, void *_src)
71 {
72  struct rtnl_skbedit *dst = _dst, *src = _src;
73 
74  memcpy(dst, src, sizeof(*src));
75  return 0;
76 }
77 
78 static void skbedit_dump_line(struct rtnl_tc *tc, void *data,
79  struct nl_dump_params *p)
80 {
81  struct rtnl_skbedit *u = data;
82 
83  if (!u)
84  return;
85 
86  if (u->s_flags & SKBEDIT_F_PRIORITY)
87  nl_dump(p, " priority %u", u->s_prio);
88 
89  if (u->s_flags & SKBEDIT_F_MARK)
90  nl_dump(p, " mark %u", u->s_mark);
91 
92  if (u->s_flags & SKBEDIT_F_QUEUE_MAPPING)
93  nl_dump(p, " queue_mapping %u", u->s_queue_mapping);
94 
95  switch(u->s_parm.action){
96  case TC_ACT_UNSPEC:
97  nl_dump(p, " unspecified");
98  break;
99  case TC_ACT_PIPE:
100  nl_dump(p, " pipe");
101  break;
102  case TC_ACT_STOLEN:
103  nl_dump(p, " stolen");
104  break;
105  case TC_ACT_SHOT:
106  nl_dump(p, " shot");
107  break;
108  case TC_ACT_QUEUED:
109  nl_dump(p, " queued");
110  break;
111  case TC_ACT_REPEAT:
112  nl_dump(p, " repeat");
113  break;
114  }
115 }
116 
117 static void skbedit_dump_details(struct rtnl_tc *tc, void *data,
118  struct nl_dump_params *p)
119 {
120 }
121 
122 static void skbedit_dump_stats(struct rtnl_tc *tc, void *data,
123  struct nl_dump_params *p)
124 {
125  struct rtnl_skbedit *u = data;
126 
127  if (!u)
128  return;
129  /* TODO */
130 }
131 
132 
133 static int skbedit_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
134 {
135  struct rtnl_skbedit *u = data;
136 
137  if (!u)
138  return 0;
139 
140  NLA_PUT(msg, TCA_SKBEDIT_PARMS, sizeof(u->s_parm), &u->s_parm);
141 
142  if (u->s_flags & SKBEDIT_F_MARK)
143  NLA_PUT_U32(msg, TCA_SKBEDIT_MARK, u->s_mark);
144 
145  if (u->s_flags & SKBEDIT_F_PRIORITY)
146  NLA_PUT_U32(msg, TCA_SKBEDIT_PRIORITY, u->s_prio);
147 
148  if (u->s_flags & SKBEDIT_F_QUEUE_MAPPING)
149  NLA_PUT_U32(msg, TCA_SKBEDIT_QUEUE_MAPPING, u->s_queue_mapping);
150 
151  return 0;
152 
153 nla_put_failure:
154  return -NLE_NOMEM;
155 }
156 
157 /**
158  * @name Attribute Modifications
159  * @{
160  */
161 
162 int rtnl_skbedit_set_action(struct rtnl_act *act, int action)
163 {
164  struct rtnl_skbedit *u;
165 
166  if (!(u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act))))
167  return -NLE_NOMEM;
168 
169  if (action > TC_ACT_REPEAT || action < TC_ACT_UNSPEC)
170  return -NLE_INVAL;
171 
172  u->s_parm.action = action;
173  return 0;
174 }
175 
176 int rtnl_skbedit_get_action(struct rtnl_act *act)
177 {
178  struct rtnl_skbedit *u;
179 
180  if (!(u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act))))
181  return -NLE_NOMEM;
182  return u->s_parm.action;
183 }
184 
185 int rtnl_skbedit_set_queue_mapping(struct rtnl_act *act, uint16_t index)
186 {
187  struct rtnl_skbedit *u;
188 
189  if (!(u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act))))
190  return -NLE_NOMEM;
191 
192  u->s_queue_mapping = index;
193  u->s_flags |= SKBEDIT_F_QUEUE_MAPPING;
194  return 0;
195 }
196 
197 int rtnl_skbedit_get_queue_mapping(struct rtnl_act *act, uint16_t *index)
198 {
199  struct rtnl_skbedit *u;
200 
201  u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act));
202  if (!u)
203  return -NLE_NOMEM;
204  if (!(u->s_flags & SKBEDIT_F_QUEUE_MAPPING))
205  return -NLE_NOATTR;
206 
207  *index = u->s_queue_mapping;
208  return 0;
209 }
210 
211 int rtnl_skbedit_set_mark(struct rtnl_act *act, uint32_t mark)
212 {
213  struct rtnl_skbedit *u;
214 
215  if (!(u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act))))
216  return -NLE_NOMEM;
217 
218  u->s_mark = mark;
219  u->s_flags |= SKBEDIT_F_MARK;
220  return 0;
221 }
222 
223 int rtnl_skbedit_get_mark(struct rtnl_act *act, uint32_t *mark)
224 {
225  struct rtnl_skbedit *u;
226 
227  u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act));
228  if (!u)
229  return -NLE_NOMEM;
230  if (!(u->s_flags & SKBEDIT_F_MARK))
231  return -NLE_NOATTR;
232 
233  *mark = u->s_mark;
234  return 0;
235 }
236 
237 int rtnl_skbedit_set_priority(struct rtnl_act *act, uint32_t prio)
238 {
239  struct rtnl_skbedit *u;
240 
241  if (!(u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act))))
242  return -NLE_NOMEM;
243 
244  u->s_prio = prio;
245  u->s_flags |= SKBEDIT_F_PRIORITY;
246  return 0;
247 }
248 
249 int rtnl_skbedit_get_priority(struct rtnl_act *act, uint32_t *prio)
250 {
251  struct rtnl_skbedit *u;
252 
253  u = (struct rtnl_skbedit *) rtnl_tc_data(TC_CAST(act));
254  if (!u)
255  return -NLE_NOMEM;
256  if (!(u->s_flags & SKBEDIT_F_PRIORITY))
257  return -NLE_NOATTR;
258 
259  *prio = u->s_prio;
260  return 0;
261 }
262 
263 /** @} */
264 
265 static struct rtnl_tc_ops skbedit_ops = {
266  .to_kind = "skbedit",
267  .to_type = RTNL_TC_TYPE_ACT,
268  .to_size = sizeof(struct rtnl_skbedit),
269  .to_msg_parser = skbedit_msg_parser,
270  .to_free_data = skbedit_free_data,
271  .to_clone = skbedit_clone,
272  .to_msg_fill = skbedit_msg_fill,
273  .to_dump = {
274  [NL_DUMP_LINE] = skbedit_dump_line,
275  [NL_DUMP_DETAILS] = skbedit_dump_details,
276  [NL_DUMP_STATS] = skbedit_dump_stats,
277  },
278 };
279 
280 static void __init skbedit_init(void)
281 {
282  rtnl_tc_register(&skbedit_ops);
283 }
284 
285 static void __exit skbedit_exit(void)
286 {
287  rtnl_tc_unregister(&skbedit_ops);
288 }
289 
290 /** @} */
Dump object briefly on one line.
Definition: types.h:22
int rtnl_tc_register(struct rtnl_tc_ops *ops)
Register a traffic control module.
Definition: tc.c:1021
Attribute validation policy.
Definition: attr.h:69
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:707
Dump all attributes but no statistics.
Definition: types.h:23
void rtnl_tc_unregister(struct rtnl_tc_ops *ops)
Unregister a traffic control module.
Definition: tc.c:1055
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
Definition: tc.h:56
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
Definition: attr.h:165
16 bit integer
Definition: attr.h:42
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition: attr.h:236
uint16_t minlen
Minimal length of payload required.
Definition: attr.h:74
void * rtnl_tc_data(struct rtnl_tc *tc)
Return pointer to private data of traffic control object.
Definition: tc.c:1082
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:657
32 bit integer
Definition: attr.h:43
Dumping parameters.
Definition: types.h:33
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:962
Dump all attributes including statistics.
Definition: types.h:24