libnl  3.5.0
basic.c
1 /*
2  * lib/route/cls/basic.c Basic Classifier
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) 2008-2013 Thomas Graf <tgraf@suug.ch>
10  */
11 
12 /**
13  * @ingroup cls
14  * @defgroup cls_basic Basic Classifier
15  *
16  * @par Introduction
17  * The basic classifier is the simplest form of a classifier. It does
18  * not have any special classification capabilities, instead it can be
19  * used to classify exclusively based on extended matches or to
20  * create a "catch-all" filter.
21  *
22  * @{
23  */
24 
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>
33 
34 struct rtnl_basic
35 {
36  uint32_t b_target;
37  struct rtnl_ematch_tree * b_ematch;
38  int b_mask;
39  struct rtnl_act * b_act;
40 };
41 
42 /** @cond SKIP */
43 #define BASIC_ATTR_TARGET 0x001
44 #define BASIC_ATTR_EMATCH 0x002
45 #define BASIC_ATTR_ACTION 0x004
46 /** @endcond */
47 
48 static struct nla_policy basic_policy[TCA_BASIC_MAX+1] = {
49  [TCA_BASIC_CLASSID] = { .type = NLA_U32 },
50  [TCA_BASIC_EMATCHES] = { .type = NLA_NESTED },
51 };
52 
53 static int basic_clone(void *_dst, void *_src)
54 {
55  return -NLE_OPNOTSUPP;
56 }
57 
58 static void basic_free_data(struct rtnl_tc *tc, void *data)
59 {
60  struct rtnl_basic *b = data;
61 
62  if (!b)
63  return;
64 
65  if (b->b_act)
66  rtnl_act_put_all(&b->b_act);
67  rtnl_ematch_tree_free(b->b_ematch);
68 }
69 
70 static int basic_msg_parser(struct rtnl_tc *tc, void *data)
71 {
72  struct nlattr *tb[TCA_BASIC_MAX + 1];
73  struct rtnl_basic *b = data;
74  int err;
75 
76  err = tca_parse(tb, TCA_BASIC_MAX, tc, basic_policy);
77  if (err < 0)
78  return err;
79 
80  if (tb[TCA_BASIC_CLASSID]) {
81  b->b_target = nla_get_u32(tb[TCA_BASIC_CLASSID]);
82  b->b_mask |= BASIC_ATTR_TARGET;
83  }
84 
85  if (tb[TCA_BASIC_EMATCHES]) {
86  if ((err = rtnl_ematch_parse_attr(tb[TCA_BASIC_EMATCHES],
87  &b->b_ematch)) < 0)
88  return err;
89 
90  if (b->b_ematch)
91  b->b_mask |= BASIC_ATTR_EMATCH;
92  }
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]);
96  if (err)
97  return err;
98  }
99 
100  return 0;
101 }
102 
103 static void basic_dump_line(struct rtnl_tc *tc, void *data,
104  struct nl_dump_params *p)
105 {
106  struct rtnl_basic *b = data;
107  char buf[32];
108 
109  if (!b)
110  return;
111 
112  if (b->b_mask & BASIC_ATTR_EMATCH)
113  nl_dump(p, " ematch");
114  else
115  nl_dump(p, " match-all");
116 
117  if (b->b_mask & BASIC_ATTR_TARGET)
118  nl_dump(p, " target %s",
119  rtnl_tc_handle2str(b->b_target, buf, sizeof(buf)));
120 }
121 
122 static void basic_dump_details(struct rtnl_tc *tc, void *data,
123  struct nl_dump_params *p)
124 {
125  struct rtnl_basic *b = data;
126 
127  if (!b)
128  return;
129 
130  if (b->b_mask & BASIC_ATTR_EMATCH) {
131  nl_dump_line(p, " ematch ");
132  rtnl_ematch_tree_dump(b->b_ematch, p);
133  } else
134  nl_dump(p, "no options.\n");
135 }
136 
137 static int basic_msg_fill(struct rtnl_tc *tc, void *data,
138  struct nl_msg *msg)
139 {
140  struct rtnl_basic *b = data;
141 
142  if (!b)
143  return 0;
144 
145  if (b->b_mask & BASIC_ATTR_TARGET)
146  NLA_PUT_U32(msg, TCA_BASIC_CLASSID, b->b_target);
147 
148  if (b->b_mask & BASIC_ATTR_EMATCH &&
149  rtnl_ematch_fill_attr(msg, TCA_BASIC_EMATCHES, b->b_ematch) < 0)
150  goto nla_put_failure;
151 
152  if (b->b_mask & BASIC_ATTR_ACTION) {
153  int err;
154 
155  err = rtnl_act_fill(msg, TCA_BASIC_ACT, b->b_act);
156  if (err)
157  return err;
158  }
159 
160  return 0;
161 
162 nla_put_failure:
163  return -NLE_NOMEM;
164 }
165 
166 /**
167  * @name Attribute Modifications
168  * @{
169  */
170 
171 void rtnl_basic_set_target(struct rtnl_cls *cls, uint32_t target)
172 {
173  struct rtnl_basic *b;
174 
175  if (!(b = rtnl_tc_data(TC_CAST(cls))))
176  return;
177 
178  b->b_target = target;
179  b->b_mask |= BASIC_ATTR_TARGET;
180 }
181 
182 uint32_t rtnl_basic_get_target(struct rtnl_cls *cls)
183 {
184  struct rtnl_basic *b;
185 
186  if (!(b = rtnl_tc_data(TC_CAST(cls))))
187  return 0;
188 
189  return b->b_target;
190 }
191 
192 void rtnl_basic_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree)
193 {
194  struct rtnl_basic *b;
195 
196  if (!(b = rtnl_tc_data(TC_CAST(cls))))
197  return;
198 
199  if (b->b_ematch) {
200  rtnl_ematch_tree_free(b->b_ematch);
201  b->b_mask &= ~BASIC_ATTR_EMATCH;
202  }
203 
204  b->b_ematch = tree;
205 
206  if (tree)
207  b->b_mask |= BASIC_ATTR_EMATCH;
208 }
209 
210 struct rtnl_ematch_tree *rtnl_basic_get_ematch(struct rtnl_cls *cls)
211 {
212  struct rtnl_basic *b;
213 
214  if (!(b = rtnl_tc_data(TC_CAST(cls))))
215  return NULL;
216 
217  return b->b_ematch;
218 }
219 
220 int rtnl_basic_add_action(struct rtnl_cls *cls, struct rtnl_act *act)
221 {
222  struct rtnl_basic *b;
223  int err;
224 
225  if (!act)
226  return 0;
227 
228  if (!(b = rtnl_tc_data(TC_CAST(cls))))
229  return -NLE_NOMEM;
230 
231  b->b_mask |= BASIC_ATTR_ACTION;
232  if ((err = rtnl_act_append(&b->b_act, act)))
233  return err;
234 
235  /* In case user frees it */
236  rtnl_act_get(act);
237  return 0;
238 }
239 
240 struct rtnl_act* rtnl_basic_get_action(struct rtnl_cls *cls)
241 {
242  struct rtnl_basic *b;
243 
244  if (!(b = rtnl_tc_data_peek(TC_CAST(cls))))
245  return NULL;
246 
247  if (!(b->b_mask & BASIC_ATTR_ACTION))
248  return NULL;
249 
250  return b->b_act;
251 }
252 
253 int rtnl_basic_del_action(struct rtnl_cls *cls, struct rtnl_act *act)
254 {
255  struct rtnl_basic *b;
256  int ret;
257 
258  if (!act)
259  return 0;
260 
261  if (!(b = rtnl_tc_data(TC_CAST(cls))))
262  return -NLE_NOMEM;
263 
264  if (!(b->b_mask & BASIC_ATTR_ACTION))
265  return -NLE_INVAL;
266  ret = rtnl_act_remove(&b->b_act, act);
267  if (ret)
268  return ret;
269 
270  if (!b->b_act)
271  b->b_mask &= ~BASIC_ATTR_ACTION;
272  rtnl_act_put(act);
273  return 0;
274 }
275 /** @} */
276 
277 static struct rtnl_tc_ops basic_ops = {
278  .to_kind = "basic",
279  .to_type = RTNL_TC_TYPE_CLS,
280  .to_size = sizeof(struct rtnl_basic),
281  .to_msg_parser = basic_msg_parser,
282  .to_clone = basic_clone,
283  .to_free_data = basic_free_data,
284  .to_msg_fill = basic_msg_fill,
285  .to_dump = {
286  [NL_DUMP_LINE] = basic_dump_line,
287  [NL_DUMP_DETAILS] = basic_dump_details,
288  },
289 };
290 
291 static void __init basic_init(void)
292 {
293  rtnl_tc_register(&basic_ops);
294 }
295 
296 static void __exit basic_exit(void)
297 {
298  rtnl_tc_unregister(&basic_ops);
299 }
300 
301 /** @} */
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
void rtnl_ematch_tree_free(struct rtnl_ematch_tree *tree)
Free ematch tree object.
Definition: ematch.c:280
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
int rtnl_ematch_parse_attr(struct nlattr *attr, struct rtnl_ematch_tree **result)
Parse ematch netlink attributes.
Definition: ematch.c:398
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
Definition: tc.h:56
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition: attr.h:236
void * rtnl_tc_data(struct rtnl_tc *tc)
Return pointer to private data of traffic control object.
Definition: tc.c:1082
Nested attributes.
Definition: attr.h:48
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:71
32 bit integer
Definition: attr.h:43
char * rtnl_tc_handle2str(uint32_t handle, char *buf, size_t len)
Convert a traffic control handle to a character string (Reentrant).
Definition: classid.c:110
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
void * rtnl_tc_data_peek(struct rtnl_tc *tc)
Returns the private data of the traffic control object.
Definition: tc.c:1068