libnl 1.1.4
qdisc_obj.c
1/*
2 * lib/route/qdisc_obj.c Queueing Discipline Object
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 qdisc
14 * @defgroup qdisc_obj Queueing Discipline Object
15 * @{
16 */
17
18#include <netlink-local.h>
19#include <netlink-tc.h>
20#include <netlink/netlink.h>
21#include <netlink/utils.h>
22#include <netlink/route/link.h>
23#include <netlink/route/tc.h>
24#include <netlink/route/qdisc.h>
25#include <netlink/route/class.h>
26#include <netlink/route/classifier.h>
27#include <netlink/route/qdisc-modules.h>
28
29static void qdisc_free_data(struct nl_object *obj)
30{
31 struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) obj;
32 struct rtnl_qdisc_ops *qops;
33
34 tca_free_data((struct rtnl_tca *) qdisc);
35
36 qops = rtnl_qdisc_lookup_ops(qdisc);
37 if (qops && qops->qo_free_data)
38 qops->qo_free_data(qdisc);
39}
40
41static int qdisc_clone(struct nl_object *_dst, struct nl_object *_src)
42{
43 struct rtnl_qdisc *dst = (struct rtnl_qdisc *) _dst;
44 struct rtnl_qdisc *src = (struct rtnl_qdisc *) _src;
45 struct rtnl_qdisc_ops *qops;
46 int err;
47
48 err = tca_clone((struct rtnl_tca *) dst, (struct rtnl_tca *) src);
49 if (err < 0)
50 goto errout;
51
52 qops = rtnl_qdisc_lookup_ops(src);
53 if (qops && qops->qo_clone)
54 err = qops->qo_clone(dst, src);
55errout:
56 return err;
57}
58
59static int qdisc_dump_brief(struct nl_object *obj, struct nl_dump_params *p)
60{
61 struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) obj;
62 struct rtnl_qdisc_ops *qops;
63
64 int line = tca_dump_brief((struct rtnl_tca *) qdisc, "qdisc", p, 0);
65
66 qops = rtnl_qdisc_lookup_ops(qdisc);
67 if (qops && qops->qo_dump[NL_DUMP_BRIEF])
68 line = qops->qo_dump[NL_DUMP_BRIEF](qdisc, p, line);
69
70 dp_dump(p, "\n");
71
72 return line;
73}
74
75static int qdisc_dump_full(struct nl_object *arg, struct nl_dump_params *p)
76{
77 struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) arg;
78 struct rtnl_qdisc_ops *qops;
79
80 int line = qdisc_dump_brief(arg, p);
81
82 line = tca_dump_full((struct rtnl_tca *) qdisc, p, line);
83 dp_dump(p, "refcnt %u ", qdisc->q_info);
84
85 qops = rtnl_qdisc_lookup_ops(qdisc);
86 if (qops && qops->qo_dump[NL_DUMP_FULL])
87 line = qops->qo_dump[NL_DUMP_FULL](qdisc, p, line);
88
89 dp_dump(p, "\n");
90 return line;
91}
92
93static int qdisc_dump_stats(struct nl_object *arg, struct nl_dump_params *p)
94{
95 struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) arg;
96 struct rtnl_qdisc_ops *qops;
97
98 int line = qdisc_dump_full(arg, p);
99 line = tca_dump_stats((struct rtnl_tca *) qdisc, p, line );
100 dp_dump(p, "\n");
101
102 qops = rtnl_qdisc_lookup_ops(qdisc);
103 if (qops && qops->qo_dump[NL_DUMP_STATS])
104 line = qops->qo_dump[NL_DUMP_STATS](qdisc, p, line);
105
106 return line;
107}
108
109/**
110 * @name Allocation/Freeing
111 * @{
112 */
113
114struct rtnl_qdisc *rtnl_qdisc_alloc(void)
115{
116 return (struct rtnl_qdisc *) nl_object_alloc(&qdisc_obj_ops);
117}
118
119void rtnl_qdisc_put(struct rtnl_qdisc *qdisc)
120{
121 nl_object_put((struct nl_object *) qdisc);
122}
123
124/** @} */
125
126/**
127 * @name Iterators
128 * @{
129 */
130
131/**
132 * Call a callback for each child class of a qdisc
133 * @arg qdisc the parent qdisc
134 * @arg cache a class cache including all classes of the interface
135 * the specified qdisc is attached to
136 * @arg cb callback function
137 * @arg arg argument to be passed to callback function
138 */
139void rtnl_qdisc_foreach_child(struct rtnl_qdisc *qdisc, struct nl_cache *cache,
140 void (*cb)(struct nl_object *, void *), void *arg)
141{
142 struct rtnl_class *filter;
143
144 filter = rtnl_class_alloc();
145 if (!filter)
146 return;
147
148 rtnl_class_set_parent(filter, qdisc->q_handle);
149 rtnl_class_set_ifindex(filter, qdisc->q_ifindex);
150 rtnl_class_set_kind(filter, qdisc->q_kind);
151
152 nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg);
153
154 rtnl_class_put(filter);
155}
156
157/**
158 * Call a callback for each filter attached to the qdisc
159 * @arg qdisc the parent qdisc
160 * @arg cache a filter cache including at least all the filters
161 * attached to the specified qdisc
162 * @arg cb callback function
163 * @arg arg argument to be passed to callback function
164 */
165void rtnl_qdisc_foreach_cls(struct rtnl_qdisc *qdisc, struct nl_cache *cache,
166 void (*cb)(struct nl_object *, void *), void *arg)
167{
168 struct rtnl_cls *filter;
169
170 filter = rtnl_cls_alloc();
171 if (!filter)
172 return;
173
174 rtnl_cls_set_ifindex(filter, qdisc->q_ifindex);
175 rtnl_cls_set_parent(filter, qdisc->q_parent);
176
177 nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg);
178 rtnl_cls_put(filter);
179}
180
181/** @} */
182
183/**
184 * @name Attributes
185 * @{
186 */
187
188void rtnl_qdisc_set_ifindex(struct rtnl_qdisc *qdisc, int ifindex)
189{
190 tca_set_ifindex((struct rtnl_tca *) qdisc, ifindex);
191}
192
193int rtnl_qdisc_get_ifindex(struct rtnl_qdisc *qdisc)
194{
195 return tca_get_ifindex((struct rtnl_tca *) qdisc);
196}
197
198void rtnl_qdisc_set_handle(struct rtnl_qdisc *qdisc, uint32_t handle)
199{
200 tca_set_handle((struct rtnl_tca *) qdisc, handle);
201}
202
203uint32_t rtnl_qdisc_get_handle(struct rtnl_qdisc *qdisc)
204{
205 return tca_get_handle((struct rtnl_tca *) qdisc);
206}
207
208void rtnl_qdisc_set_parent(struct rtnl_qdisc *qdisc, uint32_t parent)
209{
210 tca_set_parent((struct rtnl_tca *) qdisc, parent);
211}
212
213uint32_t rtnl_qdisc_get_parent(struct rtnl_qdisc *qdisc)
214{
215 return tca_get_parent((struct rtnl_tca *) qdisc);
216}
217
218void rtnl_qdisc_set_kind(struct rtnl_qdisc *qdisc, const char *name)
219{
220 tca_set_kind((struct rtnl_tca *) qdisc, name);
221 qdisc->q_ops = __rtnl_qdisc_lookup_ops(name);
222}
223
224char *rtnl_qdisc_get_kind(struct rtnl_qdisc *qdisc)
225{
226 return tca_get_kind((struct rtnl_tca *) qdisc);
227}
228
229uint64_t rtnl_qdisc_get_stat(struct rtnl_qdisc *qdisc,
230 enum rtnl_tc_stats_id id)
231{
232 return tca_get_stat((struct rtnl_tca *) qdisc, id);
233}
234
235/** @} */
236
237/**
238 * @name Qdisc Specific Options
239 * @{
240 */
241
242/**
243 * Return qdisc specific options for use in TCA_OPTIONS
244 * @arg qdisc qdisc carrying the optiosn
245 *
246 * @return new headerless netlink message carrying the options as payload
247 */
248struct nl_msg *rtnl_qdisc_get_opts(struct rtnl_qdisc *qdisc)
249{
250 struct rtnl_qdisc_ops *ops;
251
252 ops = rtnl_qdisc_lookup_ops(qdisc);
253 if (ops && ops->qo_get_opts)
254 return ops->qo_get_opts(qdisc);
255
256 return NULL;
257}
258
259/** @} */
260
261struct nl_object_ops qdisc_obj_ops = {
262 .oo_name = "route/qdisc",
263 .oo_size = sizeof(struct rtnl_qdisc),
264 .oo_free_data = qdisc_free_data,
265 .oo_clone = qdisc_clone,
266 .oo_dump[NL_DUMP_BRIEF] = qdisc_dump_brief,
267 .oo_dump[NL_DUMP_FULL] = qdisc_dump_full,
268 .oo_dump[NL_DUMP_STATS] = qdisc_dump_stats,
269 .oo_compare = tca_compare,
270 .oo_id_attrs = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE),
271};
272
273/** @} */
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
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 nl_msg * rtnl_qdisc_get_opts(struct rtnl_qdisc *qdisc)
Return qdisc specific options for use in TCA_OPTIONS.
Definition: qdisc_obj.c:248
void rtnl_qdisc_foreach_cls(struct rtnl_qdisc *qdisc, struct nl_cache *cache, void(*cb)(struct nl_object *, void *), void *arg)
Call a callback for each filter attached to the qdisc.
Definition: qdisc_obj.c:165
void rtnl_qdisc_foreach_child(struct rtnl_qdisc *qdisc, struct nl_cache *cache, void(*cb)(struct nl_object *, void *), void *arg)
Call a callback for each child class of a qdisc.
Definition: qdisc_obj.c:139
rtnl_tc_stats_id
TC statistics identifiers.
Definition: tc.h:27
@ 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
Qdisc Operations.
Definition: qdisc-modules.h:26
struct nl_msg *(* qo_get_opts)(struct rtnl_qdisc *)
Must return the contents supposed to be in TCA_OPTIONS.
Definition: qdisc-modules.h:41
void(* qo_free_data)(struct rtnl_qdisc *)
Called before a Qdisc object gets destroyed.
Definition: qdisc-modules.h:51
int(* qo_clone)(struct rtnl_qdisc *, struct rtnl_qdisc *)
Called whenever a qdisc object needs to be cloned.
Definition: qdisc-modules.h:56
int(* qo_dump[NL_DUMP_MAX+1])(struct rtnl_qdisc *, struct nl_dump_params *, int)
Dump callbacks.
Definition: qdisc-modules.h:35