libnl  3.6.0
mall.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2017 Volodymyr Bendiuga <volodymyr.bendiuga@gmail.com>
4  */
5 
6 /**
7  * @ingroup cls
8  * @defgroup cls_mall Match-all Classifier
9  *
10  * @{
11  */
12 
13 #include <netlink-private/netlink.h>
14 #include <netlink-private/tc.h>
15 #include <netlink/netlink.h>
16 #include <netlink/attr.h>
17 #include <netlink/utils.h>
18 #include <netlink-private/route/tc-api.h>
19 #include <netlink/route/classifier.h>
20 #include <netlink/route/cls/matchall.h>
21 #include <netlink/route/action.h>
22 
23 
24 #define MALL_ATTR_CLASSID 0x01
25 #define MALL_ATTR_FLAGS 0x02
26 #define MALL_ATTR_ACTION 0x03
27 
28 
29 static struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = {
30  [TCA_MATCHALL_CLASSID] = { .type = NLA_U32 },
31  [TCA_MATCHALL_FLAGS] = { .type = NLA_U32 },
32 };
33 
34 /**
35  * @name Attribute Modifications
36  * @{
37  */
38 
39 int rtnl_mall_set_classid(struct rtnl_cls *cls, uint32_t classid)
40 {
41  struct rtnl_mall *mall;
42  if (!(mall = rtnl_tc_data(TC_CAST(cls))))
43  return -NLE_NOMEM;
44 
45  mall->m_classid = classid;
46  mall->m_mask |= MALL_ATTR_CLASSID;
47 
48  return 0;
49 }
50 
51 int rtnl_mall_get_classid(struct rtnl_cls *cls, uint32_t *classid)
52 {
53  struct rtnl_mall *mall;
54 
55  if (!(mall = rtnl_tc_data_peek(TC_CAST(cls))))
56  return -NLE_INVAL;
57 
58  if (!(mall->m_mask & MALL_ATTR_CLASSID))
59  return -NLE_INVAL;
60 
61  *classid = mall->m_classid;
62  return 0;
63 }
64 
65 int rtnl_mall_set_flags(struct rtnl_cls *cls, uint32_t flags)
66 {
67  struct rtnl_mall *mall;
68 
69  if (!(mall = rtnl_tc_data(TC_CAST(cls))))
70  return -NLE_NOMEM;
71 
72  mall->m_flags = flags;
73  mall->m_mask |= MALL_ATTR_FLAGS;
74 
75  return 0;
76 }
77 
78 int rtnl_mall_get_flags(struct rtnl_cls *cls, uint32_t *flags)
79 {
80  struct rtnl_mall *mall;
81 
82  if (!(mall = rtnl_tc_data_peek(TC_CAST(cls))))
83  return -NLE_INVAL;
84 
85  if (!(mall->m_mask & MALL_ATTR_FLAGS))
86  return -NLE_INVAL;
87 
88  *flags = mall->m_flags;
89  return 0;
90 }
91 
92 int rtnl_mall_append_action(struct rtnl_cls *cls, struct rtnl_act *act)
93 {
94  struct rtnl_mall *mall;
95  int err;
96 
97  if (!act)
98  return 0;
99 
100  if (!(mall = rtnl_tc_data(TC_CAST(cls))))
101  return -NLE_NOMEM;
102 
103  mall->m_mask |= MALL_ATTR_ACTION;
104  err = rtnl_act_append(&mall->m_act, act);
105  if (err < 0)
106  return err;
107 
108  rtnl_act_get(act);
109  return 0;
110 }
111 
112 struct rtnl_act *rtnl_mall_get_first_action(struct rtnl_cls *cls)
113 {
114  struct rtnl_mall *mall;
115  struct rtnl_act *act;
116 
117  if (!(mall = rtnl_tc_data(TC_CAST(cls))))
118  return NULL;
119 
120  if (!(mall->m_mask & MALL_ATTR_ACTION))
121  return NULL;
122 
123  act = mall->m_act;
124  rtnl_act_get(act);
125 
126  return act;
127 }
128 
129 int rtnl_mall_del_action(struct rtnl_cls *cls, struct rtnl_act *act)
130 {
131  struct rtnl_mall *mall;
132  int ret;
133 
134  if (!act)
135  return 0;
136 
137  if (!(mall = rtnl_tc_data(TC_CAST(cls))))
138  return -NLE_NOMEM;
139 
140  if (!(mall->m_mask & MALL_ATTR_ACTION))
141  return -NLE_INVAL;
142 
143  ret = rtnl_act_remove(&mall->m_act, act);
144  if (ret < 0)
145  return ret;
146 
147  rtnl_act_put(act);
148 
149  return 0;
150 }
151 
152 /** @} */
153 
154 static void mall_free_data(struct rtnl_tc *tc, void *data)
155 {
156  struct rtnl_mall *mall = data;
157 
158  if (mall->m_act)
159  rtnl_act_put_all(&mall->m_act);
160 }
161 
162 static int mall_msg_parser(struct rtnl_tc *tc, void *data)
163 {
164  struct rtnl_mall *mall = data;
165  struct nlattr *tb[TCA_MATCHALL_MAX + 1];
166  int err;
167 
168  err = tca_parse(tb, TCA_MATCHALL_MAX, tc, mall_policy);
169  if (err < 0)
170  return err;
171 
172  if (tb[TCA_MATCHALL_CLASSID]) {
173  mall->m_classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]);
174  mall->m_mask |= MALL_ATTR_CLASSID;
175  }
176 
177  if (tb[TCA_MATCHALL_FLAGS]) {
178  mall->m_flags = nla_get_u32(tb[TCA_MATCHALL_FLAGS]);
179  mall->m_mask |= MALL_ATTR_FLAGS;
180  }
181 
182  if (tb[TCA_MATCHALL_ACT]) {
183  mall->m_mask |= MALL_ATTR_ACTION;
184  err = rtnl_act_parse(&mall->m_act, tb[TCA_MATCHALL_ACT]);
185  if (err < 0)
186  return err;
187  }
188 
189  return 0;
190 }
191 
192 static int mall_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
193 {
194  struct rtnl_mall *mall = data;
195 
196  if (!mall)
197  return 0;
198 
199  if (mall->m_mask & MALL_ATTR_CLASSID)
200  NLA_PUT_U32(msg, TCA_MATCHALL_CLASSID, mall->m_classid);
201 
202  if (mall->m_mask & MALL_ATTR_FLAGS)
203  NLA_PUT_U32(msg, TCA_MATCHALL_FLAGS, mall->m_flags);
204 
205  if (mall->m_mask & MALL_ATTR_ACTION) {
206  int err;
207 
208  err = rtnl_act_fill(msg, TCA_MATCHALL_ACT, mall->m_act);
209  if (err < 0)
210  return err;
211  }
212 
213  return 0;
214 
215 nla_put_failure:
216  return -NLE_NOMEM;
217 }
218 
219 static int mall_clone(void *_dst, void *_src)
220 {
221  struct rtnl_mall *dst = _dst, *src = _src;
222  struct rtnl_act *next, *new;
223  int err;
224 
225  dst->m_act = NULL;
226 
227  if (src->m_act) {
228  if (!(dst->m_act = rtnl_act_alloc()))
229  return -NLE_NOMEM;
230 
231  /* action nl list next and prev pointers must be updated */
232  nl_init_list_head(&dst->m_act->ce_list);
233 
234  memcpy(dst->m_act, src->m_act, sizeof(struct rtnl_act));
235  next = rtnl_act_next(src->m_act);
236  while (next) {
237  new = (struct rtnl_act *) nl_object_clone((struct nl_object *) next);
238  if (!new)
239  return -NLE_NOMEM;
240 
241  err = rtnl_act_append(&dst->m_act, new);
242  if (err < 0)
243  return err;
244 
245  next = rtnl_act_next(next);
246  }
247  }
248 
249  return 0;
250 }
251 
252 static void mall_dump_line(struct rtnl_tc *tc, void *data,
253  struct nl_dump_params *p)
254 {
255  struct rtnl_mall *mall = data;
256  char buf[32];
257 
258  if (!mall)
259  return;
260 
261  if (mall->m_mask & MALL_ATTR_CLASSID)
262  nl_dump(p, " target %s",
263  rtnl_tc_handle2str(mall->m_classid, buf, sizeof(buf)));
264 }
265 
266 static void mall_dump_details(struct rtnl_tc *tc, void *data,
267  struct nl_dump_params *p)
268 {
269  struct rtnl_mall *mall = data;
270 
271  if (!mall)
272  return;
273 
274  nl_dump(p, "no details for match-all");
275 }
276 
277 static struct rtnl_tc_ops mall_ops = {
278  .to_kind = "matchall",
279  .to_type = RTNL_TC_TYPE_CLS,
280  .to_size = sizeof(struct rtnl_mall),
281  .to_msg_parser = mall_msg_parser,
282  .to_free_data = mall_free_data,
283  .to_clone = mall_clone,
284  .to_msg_fill = mall_msg_fill,
285  .to_dump = {
286  [NL_DUMP_LINE] = mall_dump_line,
287  [NL_DUMP_DETAILS] = mall_dump_details,
288  },
289 };
290 
291 static void __init mall_init(void)
292 {
293  rtnl_tc_register(&mall_ops);
294 }
295 
296 static void __exit mall_exit(void)
297 {
298  rtnl_tc_unregister(&mall_ops);
299 }
300 
301 /** @} */
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:699
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition: attr.h:230
@ NLA_U32
32 bit integer
Definition: attr.h:37
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:103
struct nl_object * nl_object_clone(struct nl_object *obj)
Allocate a new object and copy all data from an existing object.
Definition: object.c:104
void * rtnl_tc_data(struct rtnl_tc *tc)
Return pointer to private data of traffic control object.
Definition: tc.c:1079
void * rtnl_tc_data_peek(struct rtnl_tc *tc)
Returns the private data of the traffic control object.
Definition: tc.c:1065
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
Definition: tc.h:50
int rtnl_tc_register(struct rtnl_tc_ops *ops)
Register a traffic control module.
Definition: tc.c:1018
void rtnl_tc_unregister(struct rtnl_tc_ops *ops)
Unregister a traffic control module.
Definition: tc.c:1052
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:955
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition: types.h:16
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition: types.h:17
Dumping parameters.
Definition: types.h:28
Attribute validation policy.
Definition: attr.h:63
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:65