libnl  3.2.27
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 
224  if (!act)
225  return 0;
226 
227  if (!(b = rtnl_tc_data(TC_CAST(cls))))
228  return -NLE_NOMEM;
229 
230  b->b_mask |= BASIC_ATTR_ACTION;
231  /* In case user frees it */
232  rtnl_act_get(act);
233  return rtnl_act_append(&b->b_act, act);
234 }
235 
236 int rtnl_basic_del_action(struct rtnl_cls *cls, struct rtnl_act *act)
237 {
238  struct rtnl_basic *b;
239  int ret;
240 
241  if (!act)
242  return 0;
243 
244  if (!(b = rtnl_tc_data(TC_CAST(cls))))
245  return -NLE_NOMEM;
246 
247  if (!(b->b_mask & BASIC_ATTR_ACTION))
248  return -NLE_INVAL;
249  ret = rtnl_act_remove(&b->b_act, act);
250  if (ret)
251  return ret;
252 
253  if (!b->b_act)
254  b->b_mask &= ~BASIC_ATTR_ACTION;
255  rtnl_act_put(act);
256  return 0;
257 }
258 /** @} */
259 
260 static struct rtnl_tc_ops basic_ops = {
261  .to_kind = "basic",
262  .to_type = RTNL_TC_TYPE_CLS,
263  .to_size = sizeof(struct rtnl_basic),
264  .to_msg_parser = basic_msg_parser,
265  .to_clone = basic_clone,
266  .to_free_data = basic_free_data,
267  .to_msg_fill = basic_msg_fill,
268  .to_dump = {
269  [NL_DUMP_LINE] = basic_dump_line,
270  [NL_DUMP_DETAILS] = basic_dump_details,
271  },
272 };
273 
274 static void __init basic_init(void)
275 {
276  rtnl_tc_register(&basic_ops);
277 }
278 
279 static void __exit basic_exit(void)
280 {
281  rtnl_tc_unregister(&basic_ops);
282 }
283 
284 /** @} */
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:983
Attribute validation policy.
Definition: attr.h:67
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:699
void rtnl_ematch_tree_free(struct rtnl_ematch_tree *tree)
Free ematch tree object.
Definition: ematch.c:279
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:1017
int rtnl_ematch_parse_attr(struct nlattr *attr, struct rtnl_ematch_tree **result)
Parse ematch netlink attributes.
Definition: ematch.c:340
#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:233
void * rtnl_tc_data(struct rtnl_tc *tc)
Return pointer to private data of traffic control object.
Definition: tc.c:1044
Nested attributes.
Definition: attr.h:46
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:69
32 bit integer
Definition: attr.h:41
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:109
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:914