libnl  1.1
class_obj.c
1 /*
2  * lib/route/class.c Queueing Classes
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) 2003-2006 Thomas Graf <tgraf@suug.ch>
10  */
11 
12 /**
13  * @ingroup class
14  * @defgroup class_obj Class Object
15  * @{
16  */
17 
18 #include <netlink-local.h>
19 #include <netlink-tc.h>
20 #include <netlink/netlink.h>
21 #include <netlink/route/tc.h>
22 #include <netlink/route/class.h>
23 #include <netlink/route/class-modules.h>
24 #include <netlink/route/qdisc.h>
25 #include <netlink/route/classifier.h>
26 #include <netlink/utils.h>
27 
28 static void class_free_data(struct nl_object *obj)
29 {
30  struct rtnl_class *class = (struct rtnl_class *) obj;
31  struct rtnl_class_ops *cops;
32 
33  tca_free_data((struct rtnl_tca *) class);
34 
35  cops = rtnl_class_lookup_ops(class);
36  if (cops && cops->co_free_data)
37  cops->co_free_data(class);
38 }
39 
40 static int class_clone(struct nl_object *_dst, struct nl_object *_src)
41 {
42  struct rtnl_class *dst = nl_object_priv(_dst);
43  struct rtnl_class *src = nl_object_priv(_src);
44  struct rtnl_class_ops *cops;
45  int err;
46 
47  err = tca_clone((struct rtnl_tca *) dst, (struct rtnl_tca *) src);
48  if (err < 0)
49  goto errout;
50 
51  cops = rtnl_class_lookup_ops(src);
52  if (cops && cops->co_clone)
53  err = cops->co_clone(dst, src);
54 errout:
55  return err;
56 }
57 
58 static int class_dump_brief(struct nl_object *obj, struct nl_dump_params *p)
59 {
60  struct rtnl_class *class = (struct rtnl_class *) obj;
61  struct rtnl_class_ops *cops;
62 
63  int line = tca_dump_brief((struct rtnl_tca *) class, "class", p, 0);
64 
65  cops = rtnl_class_lookup_ops(class);
66  if (cops && cops->co_dump[NL_DUMP_BRIEF])
67  line = cops->co_dump[NL_DUMP_BRIEF](class, p, line);
68  dp_dump(p, "\n");
69 
70  return line;
71 }
72 
73 static int class_dump_full(struct nl_object *obj, struct nl_dump_params *p)
74 {
75  struct rtnl_class *class = (struct rtnl_class *) obj;
76  struct rtnl_class_ops *cops;
77  int line;
78 
79  line = class_dump_brief(obj, p);
80  line = tca_dump_full((struct rtnl_tca *) class, p, line);
81 
82  if (class->c_info) {
83  char buf[32];
84  dp_dump(p, "child-qdisc %s ",
85  rtnl_tc_handle2str(class->c_info, buf, sizeof(buf)));
86  }
87 
88  cops = rtnl_class_lookup_ops(class);
89  if (cops && cops->co_dump[NL_DUMP_FULL])
90  line = cops->co_dump[NL_DUMP_FULL](class, p, line);
91  else if (!class->c_info)
92  dp_dump(p, "noop (no leaf qdisc)");
93 
94  dp_dump(p, "\n");
95 
96  return line;
97 }
98 
99 static int class_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
100 {
101  struct rtnl_class *class = (struct rtnl_class *) obj;
102  struct rtnl_class_ops *cops;
103  int line;
104 
105  line = class_dump_full(obj, p);
106  line = tca_dump_stats((struct rtnl_tca *) class, p, line);
107  dp_dump(p, "\n");
108 
109  cops = rtnl_class_lookup_ops(class);
110  if (cops && cops->co_dump[NL_DUMP_STATS])
111  line = cops->co_dump[NL_DUMP_STATS](class, p, line);
112 
113  return line;
114 }
115 
116 /**
117  * @name Allocation/Freeing
118  * @{
119  */
120 
121 struct rtnl_class *rtnl_class_alloc(void)
122 {
123  return (struct rtnl_class *) nl_object_alloc(&class_obj_ops);
124 }
125 
126 void rtnl_class_put(struct rtnl_class *class)
127 {
128  nl_object_put((struct nl_object *) class);
129 }
130 
131 /** @} */
132 
133 /**
134  * @name Leaf Qdisc
135  * @{
136  */
137 
138 /**
139  * Lookup the leaf qdisc of a class
140  * @arg class the parent class
141  * @arg cache a qdisc cache including at laest all qdiscs of the
142  * interface the specified class is attached to
143  * @return The qdisc from the cache or NULL if the class has no leaf qdisc
144  */
145 struct rtnl_qdisc *rtnl_class_leaf_qdisc(struct rtnl_class *class,
146  struct nl_cache *cache)
147 {
148  struct rtnl_qdisc *leaf;
149 
150  if (!class->c_info)
151  return NULL;
152 
153  leaf = rtnl_qdisc_get_by_parent(cache, class->c_ifindex,
154  class->c_handle);
155  if (!leaf || leaf->q_handle != class->c_info)
156  return NULL;
157 
158  return leaf;
159 }
160 
161 /** @} */
162 
163 
164 /**
165  * @name Iterators
166  * @{
167  */
168 
169 /**
170  * Call a callback for each child of a class
171  * @arg class the parent class
172  * @arg cache a class cache including all classes of the interface
173  * the specified class is attached to
174  * @arg cb callback function
175  * @arg arg argument to be passed to callback function
176  */
177 void rtnl_class_foreach_child(struct rtnl_class *class, struct nl_cache *cache,
178  void (*cb)(struct nl_object *, void *), void *arg)
179 {
180  struct rtnl_class *filter;
181 
182  filter = rtnl_class_alloc();
183  if (!filter)
184  return;
185 
186  rtnl_class_set_parent(filter, class->c_handle);
187  rtnl_class_set_ifindex(filter, class->c_ifindex);
188  rtnl_class_set_kind(filter, class->c_kind);
189 
190  nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg);
191  rtnl_class_put(filter);
192 }
193 
194 /**
195  * Call a callback for each classifier attached to the class
196  * @arg class the parent class
197  * @arg cache a filter cache including at least all the filters
198  * attached to the specified class
199  * @arg cb callback function
200  * @arg arg argument to be passed to callback function
201  */
202 void rtnl_class_foreach_cls(struct rtnl_class *class, struct nl_cache *cache,
203  void (*cb)(struct nl_object *, void *), void *arg)
204 {
205  struct rtnl_cls *filter;
206 
207  filter = rtnl_cls_alloc();
208  if (!filter)
209  return;
210 
211  rtnl_cls_set_ifindex(filter, class->c_ifindex);
212  rtnl_cls_set_parent(filter, class->c_parent);
213 
214  nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg);
215  rtnl_cls_put(filter);
216 }
217 
218 /** @} */
219 
220 
221 /**
222  * @name Attributes
223  * @{
224  */
225 
226 void rtnl_class_set_ifindex(struct rtnl_class *class, int ifindex)
227 {
228  tca_set_ifindex((struct rtnl_tca *) class, ifindex);
229 }
230 
231 int rtnl_class_get_ifindex(struct rtnl_class *class)
232 {
233  return tca_get_ifindex((struct rtnl_tca *) class);
234 }
235 
236 void rtnl_class_set_handle(struct rtnl_class *class, uint32_t handle)
237 {
238  tca_set_handle((struct rtnl_tca *) class, handle);
239 }
240 
241 uint32_t rtnl_class_get_handle(struct rtnl_class *class)
242 {
243  return tca_get_handle((struct rtnl_tca *) class);
244 }
245 
246 void rtnl_class_set_parent(struct rtnl_class *class, uint32_t parent)
247 {
248  tca_set_parent((struct rtnl_tca *) class, parent);
249 }
250 
251 uint32_t rtnl_class_get_parent(struct rtnl_class *class)
252 {
253  return tca_get_parent((struct rtnl_tca *) class);
254 }
255 
256 void rtnl_class_set_kind(struct rtnl_class *class, const char *name)
257 {
258  tca_set_kind((struct rtnl_tca *) class, name);
259  class->c_ops = __rtnl_class_lookup_ops(name);
260 }
261 
262 char *rtnl_class_get_kind(struct rtnl_class *class)
263 {
264  return tca_get_kind((struct rtnl_tca *) class);
265 }
266 
267 uint64_t rtnl_class_get_stat(struct rtnl_class *class,
268  enum rtnl_tc_stats_id id)
269 {
270  return tca_get_stat((struct rtnl_tca *) class, id);
271 }
272 
273 /** @} */
274 
275 struct nl_object_ops class_obj_ops = {
276  .oo_name = "route/class",
277  .oo_size = sizeof(struct rtnl_class),
278  .oo_free_data = class_free_data,
279  .oo_clone = class_clone,
280  .oo_dump[NL_DUMP_BRIEF] = class_dump_brief,
281  .oo_dump[NL_DUMP_FULL] = class_dump_full,
282  .oo_dump[NL_DUMP_STATS] = class_dump_stats,
283  .oo_compare = tca_compare,
284  .oo_id_attrs = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE),
285 };
286 
287 /** @} */
Dump object in a brief one-liner.
Definition: types.h:22
struct rtnl_qdisc * rtnl_qdisc_get_by_parent(struct nl_cache *cache, int ifindex, uint32_t parent)
Look up qdisc by its parent in the provided cache.
Definition: qdisc.c:407
struct rtnl_qdisc * rtnl_class_leaf_qdisc(struct rtnl_class *class, struct nl_cache *cache)
Lookup the leaf qdisc of a class.
Definition: class_obj.c:145
Class operations.
Definition: class-modules.h:25
int(* co_dump[NL_DUMP_MAX+1])(struct rtnl_class *, struct nl_dump_params *, int)
Dump callbacks.
Definition: class-modules.h:35
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
Definition: object.c:42
struct rtnl_class_ops * rtnl_class_lookup_ops(struct rtnl_class *class)
Lookup class operations for a class object.
Definition: class_api.c:91
void rtnl_class_foreach_child(struct rtnl_class *class, struct nl_cache *cache, void(*cb)(struct nl_object *, void *), void *arg)
Call a callback for each child of a class.
Definition: class_obj.c:177
void nl_cache_foreach_filter(struct nl_cache *cache, struct nl_object *filter, void(*cb)(struct nl_object *, void *), void *arg)
Call a callback on each element of the cache (filtered).
Definition: cache.c:790
char * rtnl_tc_handle2str(uint32_t handle, char *buf, size_t len)
Convert a traffic control handle to a character string (Reentrant).
Definition: tc.c:493
rtnl_tc_stats_id
TC statistics identifiers.
Definition: tc.h:27
void(* co_free_data)(struct rtnl_class *)
Called before a class object gets destroyed.
Definition: class-modules.h:51
int(* co_clone)(struct rtnl_class *, struct rtnl_class *)
Called whenever a class object needs to be cloned.
Definition: class-modules.h:56
Object Operations.
Definition: object-api.h:254
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
Definition: object.c:173
Dumping parameters.
Definition: types.h:36
char * oo_name
Unique name of object type.
Definition: object-api.h:261
Dump all attributes but no statistics.
Definition: types.h:23
Dump all attributes including statistics.
Definition: types.h:24
void rtnl_class_foreach_cls(struct rtnl_class *class, struct nl_cache *cache, void(*cb)(struct nl_object *, void *), void *arg)
Call a callback for each classifier attached to the class.
Definition: class_obj.c:202