libnl 1.1.4
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
28static 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
40static 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);
54errout:
55 return err;
56}
57
58static 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
73static 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
99static 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
121struct rtnl_class *rtnl_class_alloc(void)
122{
123 return (struct rtnl_class *) nl_object_alloc(&class_obj_ops);
124}
125
126void 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 */
145struct 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 */
177void 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 */
202void 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
226void rtnl_class_set_ifindex(struct rtnl_class *class, int ifindex)
227{
228 tca_set_ifindex((struct rtnl_tca *) class, ifindex);
229}
230
231int rtnl_class_get_ifindex(struct rtnl_class *class)
232{
233 return tca_get_ifindex((struct rtnl_tca *) class);
234}
235
236void rtnl_class_set_handle(struct rtnl_class *class, uint32_t handle)
237{
238 tca_set_handle((struct rtnl_tca *) class, handle);
239}
240
241uint32_t rtnl_class_get_handle(struct rtnl_class *class)
242{
243 return tca_get_handle((struct rtnl_tca *) class);
244}
245
246void rtnl_class_set_parent(struct rtnl_class *class, uint32_t parent)
247{
248 tca_set_parent((struct rtnl_tca *) class, parent);
249}
250
251uint32_t rtnl_class_get_parent(struct rtnl_class *class)
252{
253 return tca_get_parent((struct rtnl_tca *) class);
254}
255
256void 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
262char *rtnl_class_get_kind(struct rtnl_class *class)
263{
264 return tca_get_kind((struct rtnl_tca *) class);
265}
266
267uint64_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
275struct 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/** @} */
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:808
struct rtnl_class_ops * rtnl_class_lookup_ops(struct rtnl_class *class)
Lookup class operations for a class object.
Definition: class_api.c:91
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
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
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_object_put(struct nl_object *obj)
Release a reference from an object.
Definition: object.c:178
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_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
rtnl_tc_stats_id
TC statistics identifiers.
Definition: tc.h:27
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
@ NL_DUMP_FULL
Dump all attributes but no statistics.
Definition: types.h:23
@ NL_DUMP_BRIEF
Dump object in a brief one-liner.
Definition: types.h:22
@ NL_DUMP_STATS
Dump all attributes including statistics.
Definition: types.h:24
Dumping parameters.
Definition: types.h:37
Object Operations.
Definition: object-api.h:255
char * oo_name
Unique name of object type.
Definition: object-api.h:261
Class operations.
Definition: class-modules.h:26
void(* co_free_data)(struct rtnl_class *)
Called before a class object gets destroyed.
Definition: class-modules.h:51
int(* co_dump[NL_DUMP_MAX+1])(struct rtnl_class *, struct nl_dump_params *, int)
Dump callbacks.
Definition: class-modules.h:35
int(* co_clone)(struct rtnl_class *, struct rtnl_class *)
Called whenever a class object needs to be cloned.
Definition: class-modules.h:56