1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2003-2011 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker */
5*4dc78e53SAndroid Build Coastguard Worker
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker * @ingroup tc
8*4dc78e53SAndroid Build Coastguard Worker * @defgroup qdisc Queueing Disciplines
9*4dc78e53SAndroid Build Coastguard Worker * @{
10*4dc78e53SAndroid Build Coastguard Worker */
11*4dc78e53SAndroid Build Coastguard Worker
12*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
13*4dc78e53SAndroid Build Coastguard Worker
14*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
15*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
16*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/link.h>
17*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/qdisc.h>
18*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/class.h>
19*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/classifier.h>
20*4dc78e53SAndroid Build Coastguard Worker
21*4dc78e53SAndroid Build Coastguard Worker #include "tc-api.h"
22*4dc78e53SAndroid Build Coastguard Worker
23*4dc78e53SAndroid Build Coastguard Worker static struct nl_cache_ops rtnl_qdisc_ops;
24*4dc78e53SAndroid Build Coastguard Worker static struct nl_object_ops qdisc_obj_ops;
25*4dc78e53SAndroid Build Coastguard Worker
qdisc_msg_parser(struct nl_cache_ops * ops,struct sockaddr_nl * who,struct nlmsghdr * n,struct nl_parser_param * pp)26*4dc78e53SAndroid Build Coastguard Worker static int qdisc_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
27*4dc78e53SAndroid Build Coastguard Worker struct nlmsghdr *n, struct nl_parser_param *pp)
28*4dc78e53SAndroid Build Coastguard Worker {
29*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *qdisc;
30*4dc78e53SAndroid Build Coastguard Worker int err;
31*4dc78e53SAndroid Build Coastguard Worker
32*4dc78e53SAndroid Build Coastguard Worker if (!(qdisc = rtnl_qdisc_alloc()))
33*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
34*4dc78e53SAndroid Build Coastguard Worker
35*4dc78e53SAndroid Build Coastguard Worker if ((err = rtnl_tc_msg_parse(n, TC_CAST(qdisc))) < 0)
36*4dc78e53SAndroid Build Coastguard Worker goto errout;
37*4dc78e53SAndroid Build Coastguard Worker
38*4dc78e53SAndroid Build Coastguard Worker err = pp->pp_cb(OBJ_CAST(qdisc), pp);
39*4dc78e53SAndroid Build Coastguard Worker errout:
40*4dc78e53SAndroid Build Coastguard Worker rtnl_qdisc_put(qdisc);
41*4dc78e53SAndroid Build Coastguard Worker
42*4dc78e53SAndroid Build Coastguard Worker return err;
43*4dc78e53SAndroid Build Coastguard Worker }
44*4dc78e53SAndroid Build Coastguard Worker
qdisc_request_update(struct nl_cache * c,struct nl_sock * sk)45*4dc78e53SAndroid Build Coastguard Worker static int qdisc_request_update(struct nl_cache *c, struct nl_sock *sk)
46*4dc78e53SAndroid Build Coastguard Worker {
47*4dc78e53SAndroid Build Coastguard Worker struct tcmsg tchdr = {
48*4dc78e53SAndroid Build Coastguard Worker .tcm_family = AF_UNSPEC,
49*4dc78e53SAndroid Build Coastguard Worker .tcm_ifindex = c->c_iarg1,
50*4dc78e53SAndroid Build Coastguard Worker };
51*4dc78e53SAndroid Build Coastguard Worker
52*4dc78e53SAndroid Build Coastguard Worker return nl_send_simple(sk, RTM_GETQDISC, NLM_F_DUMP, &tchdr,
53*4dc78e53SAndroid Build Coastguard Worker sizeof(tchdr));
54*4dc78e53SAndroid Build Coastguard Worker }
55*4dc78e53SAndroid Build Coastguard Worker
56*4dc78e53SAndroid Build Coastguard Worker /**
57*4dc78e53SAndroid Build Coastguard Worker * @name Allocation/Freeing
58*4dc78e53SAndroid Build Coastguard Worker * @{
59*4dc78e53SAndroid Build Coastguard Worker */
60*4dc78e53SAndroid Build Coastguard Worker
rtnl_qdisc_alloc(void)61*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *rtnl_qdisc_alloc(void)
62*4dc78e53SAndroid Build Coastguard Worker {
63*4dc78e53SAndroid Build Coastguard Worker struct rtnl_tc *tc;
64*4dc78e53SAndroid Build Coastguard Worker
65*4dc78e53SAndroid Build Coastguard Worker tc = TC_CAST(nl_object_alloc(&qdisc_obj_ops));
66*4dc78e53SAndroid Build Coastguard Worker if (tc)
67*4dc78e53SAndroid Build Coastguard Worker tc->tc_type = RTNL_TC_TYPE_QDISC;
68*4dc78e53SAndroid Build Coastguard Worker
69*4dc78e53SAndroid Build Coastguard Worker return (struct rtnl_qdisc *) tc;
70*4dc78e53SAndroid Build Coastguard Worker }
71*4dc78e53SAndroid Build Coastguard Worker
rtnl_qdisc_put(struct rtnl_qdisc * qdisc)72*4dc78e53SAndroid Build Coastguard Worker void rtnl_qdisc_put(struct rtnl_qdisc *qdisc)
73*4dc78e53SAndroid Build Coastguard Worker {
74*4dc78e53SAndroid Build Coastguard Worker nl_object_put((struct nl_object *) qdisc);
75*4dc78e53SAndroid Build Coastguard Worker }
76*4dc78e53SAndroid Build Coastguard Worker
77*4dc78e53SAndroid Build Coastguard Worker /** @} */
78*4dc78e53SAndroid Build Coastguard Worker
79*4dc78e53SAndroid Build Coastguard Worker /**
80*4dc78e53SAndroid Build Coastguard Worker * @name Addition / Modification / Deletion
81*4dc78e53SAndroid Build Coastguard Worker * @{
82*4dc78e53SAndroid Build Coastguard Worker */
83*4dc78e53SAndroid Build Coastguard Worker
build_qdisc_msg(struct rtnl_qdisc * qdisc,int type,int flags,struct nl_msg ** result)84*4dc78e53SAndroid Build Coastguard Worker static int build_qdisc_msg(struct rtnl_qdisc *qdisc, int type, int flags,
85*4dc78e53SAndroid Build Coastguard Worker struct nl_msg **result)
86*4dc78e53SAndroid Build Coastguard Worker {
87*4dc78e53SAndroid Build Coastguard Worker if (!(qdisc->ce_mask & TCA_ATTR_IFINDEX)) {
88*4dc78e53SAndroid Build Coastguard Worker APPBUG("ifindex must be specified");
89*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
90*4dc78e53SAndroid Build Coastguard Worker }
91*4dc78e53SAndroid Build Coastguard Worker
92*4dc78e53SAndroid Build Coastguard Worker return rtnl_tc_msg_build(TC_CAST(qdisc), type, flags, result);
93*4dc78e53SAndroid Build Coastguard Worker }
94*4dc78e53SAndroid Build Coastguard Worker
95*4dc78e53SAndroid Build Coastguard Worker /**
96*4dc78e53SAndroid Build Coastguard Worker * Build a netlink message requesting the addition of a qdisc
97*4dc78e53SAndroid Build Coastguard Worker * @arg qdisc Qdisc to add
98*4dc78e53SAndroid Build Coastguard Worker * @arg flags Additional netlink message flags
99*4dc78e53SAndroid Build Coastguard Worker * @arg result Pointer to store resulting netlink message
100*4dc78e53SAndroid Build Coastguard Worker *
101*4dc78e53SAndroid Build Coastguard Worker * The behaviour of this function is identical to rtnl_qdisc_add() with
102*4dc78e53SAndroid Build Coastguard Worker * the exception that it will not send the message but return it int the
103*4dc78e53SAndroid Build Coastguard Worker * provided return pointer instead.
104*4dc78e53SAndroid Build Coastguard Worker *
105*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_qdisc_add()
106*4dc78e53SAndroid Build Coastguard Worker *
107*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
108*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_build_add_request(struct rtnl_qdisc * qdisc,int flags,struct nl_msg ** result)109*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_build_add_request(struct rtnl_qdisc *qdisc, int flags,
110*4dc78e53SAndroid Build Coastguard Worker struct nl_msg **result)
111*4dc78e53SAndroid Build Coastguard Worker {
112*4dc78e53SAndroid Build Coastguard Worker if (!(qdisc->ce_mask & (TCA_ATTR_HANDLE | TCA_ATTR_PARENT))) {
113*4dc78e53SAndroid Build Coastguard Worker APPBUG("handle or parent must be specified");
114*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
115*4dc78e53SAndroid Build Coastguard Worker }
116*4dc78e53SAndroid Build Coastguard Worker
117*4dc78e53SAndroid Build Coastguard Worker return build_qdisc_msg(qdisc, RTM_NEWQDISC, flags, result);
118*4dc78e53SAndroid Build Coastguard Worker }
119*4dc78e53SAndroid Build Coastguard Worker
120*4dc78e53SAndroid Build Coastguard Worker /**
121*4dc78e53SAndroid Build Coastguard Worker * Add qdisc
122*4dc78e53SAndroid Build Coastguard Worker * @arg sk Netlink socket
123*4dc78e53SAndroid Build Coastguard Worker * @arg qdisc Qdisc to add
124*4dc78e53SAndroid Build Coastguard Worker * @arg flags Additional netlink message flags
125*4dc78e53SAndroid Build Coastguard Worker *
126*4dc78e53SAndroid Build Coastguard Worker * Builds a \c RTM_NEWQDISC netlink message requesting the addition
127*4dc78e53SAndroid Build Coastguard Worker * of a new qdisc and sends the message to the kernel. The configuration
128*4dc78e53SAndroid Build Coastguard Worker * of the qdisc is derived from the attributes of the specified qdisc.
129*4dc78e53SAndroid Build Coastguard Worker *
130*4dc78e53SAndroid Build Coastguard Worker * The following flags may be specified:
131*4dc78e53SAndroid Build Coastguard Worker * - \c NLM_F_CREATE: Create qdisc if it does not exist, otherwise
132*4dc78e53SAndroid Build Coastguard Worker * -NLE_OBJ_NOTFOUND is returned.
133*4dc78e53SAndroid Build Coastguard Worker * - \c NLM_F_REPLACE: If another qdisc is already attached to the
134*4dc78e53SAndroid Build Coastguard Worker * parent, replace it even if the handles mismatch.
135*4dc78e53SAndroid Build Coastguard Worker * - \c NLM_F_EXCL: Return -NLE_EXISTS if a qdisc with matching
136*4dc78e53SAndroid Build Coastguard Worker * handle exists already.
137*4dc78e53SAndroid Build Coastguard Worker *
138*4dc78e53SAndroid Build Coastguard Worker * Existing qdiscs with matching handles will be updated, unless the
139*4dc78e53SAndroid Build Coastguard Worker * flag \c NLM_F_EXCL is specified. If their handles do not match, the
140*4dc78e53SAndroid Build Coastguard Worker * error -NLE_EXISTS is returned unless the flag \c NLM_F_REPLACE is
141*4dc78e53SAndroid Build Coastguard Worker * specified in which case the existing qdisc is replaced with the new
142*4dc78e53SAndroid Build Coastguard Worker * one. If no matching qdisc exists, it will be created if the flag
143*4dc78e53SAndroid Build Coastguard Worker * \c NLM_F_CREATE is set, otherwise the error -NLE_OBJ_NOTFOUND is
144*4dc78e53SAndroid Build Coastguard Worker * returned.
145*4dc78e53SAndroid Build Coastguard Worker *
146*4dc78e53SAndroid Build Coastguard Worker * After sending, the function will wait for the ACK or an eventual
147*4dc78e53SAndroid Build Coastguard Worker * error message to be received and will therefore block until the
148*4dc78e53SAndroid Build Coastguard Worker * operation has been completed.
149*4dc78e53SAndroid Build Coastguard Worker *
150*4dc78e53SAndroid Build Coastguard Worker * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause
151*4dc78e53SAndroid Build Coastguard Worker * this function to return immediately after sending. In this case,
152*4dc78e53SAndroid Build Coastguard Worker * it is the responsibility of the caller to handle any error
153*4dc78e53SAndroid Build Coastguard Worker * messages returned.
154*4dc78e53SAndroid Build Coastguard Worker *
155*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
156*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_add(struct nl_sock * sk,struct rtnl_qdisc * qdisc,int flags)157*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_add(struct nl_sock *sk, struct rtnl_qdisc *qdisc, int flags)
158*4dc78e53SAndroid Build Coastguard Worker {
159*4dc78e53SAndroid Build Coastguard Worker struct nl_msg *msg;
160*4dc78e53SAndroid Build Coastguard Worker int err;
161*4dc78e53SAndroid Build Coastguard Worker
162*4dc78e53SAndroid Build Coastguard Worker if ((err = rtnl_qdisc_build_add_request(qdisc, flags, &msg)) < 0)
163*4dc78e53SAndroid Build Coastguard Worker return err;
164*4dc78e53SAndroid Build Coastguard Worker
165*4dc78e53SAndroid Build Coastguard Worker return nl_send_sync(sk, msg);
166*4dc78e53SAndroid Build Coastguard Worker }
167*4dc78e53SAndroid Build Coastguard Worker
168*4dc78e53SAndroid Build Coastguard Worker /**
169*4dc78e53SAndroid Build Coastguard Worker * Build netlink message requesting the update of a qdisc
170*4dc78e53SAndroid Build Coastguard Worker * @arg qdisc Qdisc to update
171*4dc78e53SAndroid Build Coastguard Worker * @arg new Qdisc with updated attributes
172*4dc78e53SAndroid Build Coastguard Worker * @arg flags Additional netlink message flags
173*4dc78e53SAndroid Build Coastguard Worker * @arg result Pointer to store resulting netlink message
174*4dc78e53SAndroid Build Coastguard Worker *
175*4dc78e53SAndroid Build Coastguard Worker * The behaviour of this function is identical to rtnl_qdisc_update() with
176*4dc78e53SAndroid Build Coastguard Worker * the exception that it will not send the message but return it in the
177*4dc78e53SAndroid Build Coastguard Worker * provided return pointer instead.
178*4dc78e53SAndroid Build Coastguard Worker *
179*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_qdisc_update()
180*4dc78e53SAndroid Build Coastguard Worker *
181*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
182*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_build_update_request(struct rtnl_qdisc * qdisc,struct rtnl_qdisc * new,int flags,struct nl_msg ** result)183*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_build_update_request(struct rtnl_qdisc *qdisc,
184*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *new, int flags,
185*4dc78e53SAndroid Build Coastguard Worker struct nl_msg **result)
186*4dc78e53SAndroid Build Coastguard Worker {
187*4dc78e53SAndroid Build Coastguard Worker if (flags & (NLM_F_CREATE | NLM_F_EXCL)) {
188*4dc78e53SAndroid Build Coastguard Worker APPBUG("NLM_F_CREATE and NLM_F_EXCL may not be used here, "
189*4dc78e53SAndroid Build Coastguard Worker "use rtnl_qdisc_add()");
190*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
191*4dc78e53SAndroid Build Coastguard Worker }
192*4dc78e53SAndroid Build Coastguard Worker
193*4dc78e53SAndroid Build Coastguard Worker if (!(qdisc->ce_mask & TCA_ATTR_IFINDEX)) {
194*4dc78e53SAndroid Build Coastguard Worker APPBUG("ifindex must be specified");
195*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
196*4dc78e53SAndroid Build Coastguard Worker }
197*4dc78e53SAndroid Build Coastguard Worker
198*4dc78e53SAndroid Build Coastguard Worker if (!(qdisc->ce_mask & (TCA_ATTR_HANDLE | TCA_ATTR_PARENT))) {
199*4dc78e53SAndroid Build Coastguard Worker APPBUG("handle or parent must be specified");
200*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
201*4dc78e53SAndroid Build Coastguard Worker }
202*4dc78e53SAndroid Build Coastguard Worker
203*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_set_ifindex(TC_CAST(new), qdisc->q_ifindex);
204*4dc78e53SAndroid Build Coastguard Worker
205*4dc78e53SAndroid Build Coastguard Worker if (qdisc->ce_mask & TCA_ATTR_HANDLE)
206*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_set_handle(TC_CAST(new), qdisc->q_handle);
207*4dc78e53SAndroid Build Coastguard Worker
208*4dc78e53SAndroid Build Coastguard Worker if (qdisc->ce_mask & TCA_ATTR_PARENT)
209*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_set_parent(TC_CAST(new), qdisc->q_parent);
210*4dc78e53SAndroid Build Coastguard Worker
211*4dc78e53SAndroid Build Coastguard Worker return build_qdisc_msg(new, RTM_NEWQDISC, flags, result);
212*4dc78e53SAndroid Build Coastguard Worker }
213*4dc78e53SAndroid Build Coastguard Worker
214*4dc78e53SAndroid Build Coastguard Worker /**
215*4dc78e53SAndroid Build Coastguard Worker * Update qdisc
216*4dc78e53SAndroid Build Coastguard Worker * @arg sk Netlink socket
217*4dc78e53SAndroid Build Coastguard Worker * @arg qdisc Qdisc to update
218*4dc78e53SAndroid Build Coastguard Worker * @arg new Qdisc with updated attributes
219*4dc78e53SAndroid Build Coastguard Worker * @arg flags Additional netlink message flags
220*4dc78e53SAndroid Build Coastguard Worker *
221*4dc78e53SAndroid Build Coastguard Worker * Builds a \c RTM_NEWQDISC netlink message requesting the update
222*4dc78e53SAndroid Build Coastguard Worker * of an existing qdisc and sends the message to the kernel.
223*4dc78e53SAndroid Build Coastguard Worker *
224*4dc78e53SAndroid Build Coastguard Worker * This function is a varation of rtnl_qdisc_add() to update qdiscs
225*4dc78e53SAndroid Build Coastguard Worker * if the qdisc to be updated is available as qdisc object. The
226*4dc78e53SAndroid Build Coastguard Worker * behaviour is identical to the one of rtnl_qdisc_add except that
227*4dc78e53SAndroid Build Coastguard Worker * before constructing the message, it copies the \c ifindex,
228*4dc78e53SAndroid Build Coastguard Worker * \c handle, and \c parent from the original \p qdisc to the \p new
229*4dc78e53SAndroid Build Coastguard Worker * qdisc.
230*4dc78e53SAndroid Build Coastguard Worker *
231*4dc78e53SAndroid Build Coastguard Worker * After sending, the function will wait for the ACK or an eventual
232*4dc78e53SAndroid Build Coastguard Worker * error message to be received and will therefore block until the
233*4dc78e53SAndroid Build Coastguard Worker * operation has been completed.
234*4dc78e53SAndroid Build Coastguard Worker *
235*4dc78e53SAndroid Build Coastguard Worker * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause
236*4dc78e53SAndroid Build Coastguard Worker * this function to return immediately after sending. In this case,
237*4dc78e53SAndroid Build Coastguard Worker * it is the responsibility of the caller to handle any error
238*4dc78e53SAndroid Build Coastguard Worker * messages returned.
239*4dc78e53SAndroid Build Coastguard Worker *
240*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
241*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_update(struct nl_sock * sk,struct rtnl_qdisc * qdisc,struct rtnl_qdisc * new,int flags)242*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_update(struct nl_sock *sk, struct rtnl_qdisc *qdisc,
243*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *new, int flags)
244*4dc78e53SAndroid Build Coastguard Worker {
245*4dc78e53SAndroid Build Coastguard Worker struct nl_msg *msg;
246*4dc78e53SAndroid Build Coastguard Worker int err;
247*4dc78e53SAndroid Build Coastguard Worker
248*4dc78e53SAndroid Build Coastguard Worker err = rtnl_qdisc_build_update_request(qdisc, new, flags, &msg);
249*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
250*4dc78e53SAndroid Build Coastguard Worker return err;
251*4dc78e53SAndroid Build Coastguard Worker
252*4dc78e53SAndroid Build Coastguard Worker return nl_send_sync(sk, msg);
253*4dc78e53SAndroid Build Coastguard Worker }
254*4dc78e53SAndroid Build Coastguard Worker
255*4dc78e53SAndroid Build Coastguard Worker /**
256*4dc78e53SAndroid Build Coastguard Worker * Build netlink message requesting the deletion of a qdisc
257*4dc78e53SAndroid Build Coastguard Worker * @arg qdisc Qdisc to delete
258*4dc78e53SAndroid Build Coastguard Worker * @arg result Pointer to store resulting netlink message
259*4dc78e53SAndroid Build Coastguard Worker *
260*4dc78e53SAndroid Build Coastguard Worker * The behaviour of this function is identical to rtnl_qdisc_delete() with
261*4dc78e53SAndroid Build Coastguard Worker * the exception that it will not send the message but return it in the
262*4dc78e53SAndroid Build Coastguard Worker * provided return pointer instead.
263*4dc78e53SAndroid Build Coastguard Worker *
264*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_qdisc_delete()
265*4dc78e53SAndroid Build Coastguard Worker *
266*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
267*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_build_delete_request(struct rtnl_qdisc * qdisc,struct nl_msg ** result)268*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_build_delete_request(struct rtnl_qdisc *qdisc,
269*4dc78e53SAndroid Build Coastguard Worker struct nl_msg **result)
270*4dc78e53SAndroid Build Coastguard Worker {
271*4dc78e53SAndroid Build Coastguard Worker struct nl_msg *msg;
272*4dc78e53SAndroid Build Coastguard Worker struct tcmsg tchdr;
273*4dc78e53SAndroid Build Coastguard Worker uint32_t required = TCA_ATTR_IFINDEX | TCA_ATTR_PARENT;
274*4dc78e53SAndroid Build Coastguard Worker
275*4dc78e53SAndroid Build Coastguard Worker if ((qdisc->ce_mask & required) != required) {
276*4dc78e53SAndroid Build Coastguard Worker APPBUG("ifindex and parent must be specified");
277*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
278*4dc78e53SAndroid Build Coastguard Worker }
279*4dc78e53SAndroid Build Coastguard Worker
280*4dc78e53SAndroid Build Coastguard Worker if (!(msg = nlmsg_alloc_simple(RTM_DELQDISC, 0)))
281*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
282*4dc78e53SAndroid Build Coastguard Worker
283*4dc78e53SAndroid Build Coastguard Worker memset(&tchdr, 0, sizeof(tchdr));
284*4dc78e53SAndroid Build Coastguard Worker
285*4dc78e53SAndroid Build Coastguard Worker tchdr.tcm_family = AF_UNSPEC;
286*4dc78e53SAndroid Build Coastguard Worker tchdr.tcm_ifindex = qdisc->q_ifindex;
287*4dc78e53SAndroid Build Coastguard Worker tchdr.tcm_parent = qdisc->q_parent;
288*4dc78e53SAndroid Build Coastguard Worker
289*4dc78e53SAndroid Build Coastguard Worker if (qdisc->ce_mask & TCA_ATTR_HANDLE)
290*4dc78e53SAndroid Build Coastguard Worker tchdr.tcm_handle = qdisc->q_handle;
291*4dc78e53SAndroid Build Coastguard Worker
292*4dc78e53SAndroid Build Coastguard Worker if (nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO) < 0)
293*4dc78e53SAndroid Build Coastguard Worker goto nla_put_failure;
294*4dc78e53SAndroid Build Coastguard Worker
295*4dc78e53SAndroid Build Coastguard Worker if (qdisc->ce_mask & TCA_ATTR_KIND)
296*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_STRING(msg, TCA_KIND, qdisc->q_kind);
297*4dc78e53SAndroid Build Coastguard Worker
298*4dc78e53SAndroid Build Coastguard Worker *result = msg;
299*4dc78e53SAndroid Build Coastguard Worker return 0;
300*4dc78e53SAndroid Build Coastguard Worker
301*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
302*4dc78e53SAndroid Build Coastguard Worker nlmsg_free(msg);
303*4dc78e53SAndroid Build Coastguard Worker return -NLE_MSGSIZE;
304*4dc78e53SAndroid Build Coastguard Worker }
305*4dc78e53SAndroid Build Coastguard Worker
306*4dc78e53SAndroid Build Coastguard Worker /**
307*4dc78e53SAndroid Build Coastguard Worker * Delete qdisc
308*4dc78e53SAndroid Build Coastguard Worker * @arg sk Netlink socket
309*4dc78e53SAndroid Build Coastguard Worker * @arg qdisc Qdisc to add
310*4dc78e53SAndroid Build Coastguard Worker *
311*4dc78e53SAndroid Build Coastguard Worker * Builds a \c RTM_NEWQDISC netlink message requesting the deletion
312*4dc78e53SAndroid Build Coastguard Worker * of a qdisc and sends the message to the kernel.
313*4dc78e53SAndroid Build Coastguard Worker *
314*4dc78e53SAndroid Build Coastguard Worker * The message is constructed out of the following attributes:
315*4dc78e53SAndroid Build Coastguard Worker * - \c ifindex and \c parent
316*4dc78e53SAndroid Build Coastguard Worker * - \c handle (optional, must match if provided)
317*4dc78e53SAndroid Build Coastguard Worker * - \c kind (optional, must match if provided)
318*4dc78e53SAndroid Build Coastguard Worker *
319*4dc78e53SAndroid Build Coastguard Worker * All other qdisc attributes including all qdisc type specific
320*4dc78e53SAndroid Build Coastguard Worker * attributes are ignored.
321*4dc78e53SAndroid Build Coastguard Worker *
322*4dc78e53SAndroid Build Coastguard Worker * After sending, the function will wait for the ACK or an eventual
323*4dc78e53SAndroid Build Coastguard Worker * error message to be received and will therefore block until the
324*4dc78e53SAndroid Build Coastguard Worker * operation has been completed.
325*4dc78e53SAndroid Build Coastguard Worker *
326*4dc78e53SAndroid Build Coastguard Worker * @note It is not possible to delete default qdiscs.
327*4dc78e53SAndroid Build Coastguard Worker *
328*4dc78e53SAndroid Build Coastguard Worker * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause
329*4dc78e53SAndroid Build Coastguard Worker * this function to return immediately after sending. In this case,
330*4dc78e53SAndroid Build Coastguard Worker * it is the responsibility of the caller to handle any error
331*4dc78e53SAndroid Build Coastguard Worker * messages returned.
332*4dc78e53SAndroid Build Coastguard Worker *
333*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
334*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_delete(struct nl_sock * sk,struct rtnl_qdisc * qdisc)335*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_delete(struct nl_sock *sk, struct rtnl_qdisc *qdisc)
336*4dc78e53SAndroid Build Coastguard Worker {
337*4dc78e53SAndroid Build Coastguard Worker struct nl_msg *msg;
338*4dc78e53SAndroid Build Coastguard Worker int err;
339*4dc78e53SAndroid Build Coastguard Worker
340*4dc78e53SAndroid Build Coastguard Worker if ((err = rtnl_qdisc_build_delete_request(qdisc, &msg)) < 0)
341*4dc78e53SAndroid Build Coastguard Worker return err;
342*4dc78e53SAndroid Build Coastguard Worker
343*4dc78e53SAndroid Build Coastguard Worker return nl_send_sync(sk, msg);
344*4dc78e53SAndroid Build Coastguard Worker }
345*4dc78e53SAndroid Build Coastguard Worker
346*4dc78e53SAndroid Build Coastguard Worker /** @} */
347*4dc78e53SAndroid Build Coastguard Worker
348*4dc78e53SAndroid Build Coastguard Worker /**
349*4dc78e53SAndroid Build Coastguard Worker * @name Cache Related Functions
350*4dc78e53SAndroid Build Coastguard Worker * @{
351*4dc78e53SAndroid Build Coastguard Worker */
352*4dc78e53SAndroid Build Coastguard Worker
353*4dc78e53SAndroid Build Coastguard Worker /**
354*4dc78e53SAndroid Build Coastguard Worker * Allocate a cache and fill it with all configured qdiscs
355*4dc78e53SAndroid Build Coastguard Worker * @arg sk Netlink socket
356*4dc78e53SAndroid Build Coastguard Worker * @arg result Pointer to store the created cache
357*4dc78e53SAndroid Build Coastguard Worker *
358*4dc78e53SAndroid Build Coastguard Worker * Allocates a new qdisc cache and fills it with a list of all configured
359*4dc78e53SAndroid Build Coastguard Worker * qdiscs on all network devices. Release the cache with nl_cache_free().
360*4dc78e53SAndroid Build Coastguard Worker *
361*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
362*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_alloc_cache(struct nl_sock * sk,struct nl_cache ** result)363*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_alloc_cache(struct nl_sock *sk, struct nl_cache **result)
364*4dc78e53SAndroid Build Coastguard Worker {
365*4dc78e53SAndroid Build Coastguard Worker return nl_cache_alloc_and_fill(&rtnl_qdisc_ops, sk, result);
366*4dc78e53SAndroid Build Coastguard Worker }
367*4dc78e53SAndroid Build Coastguard Worker
368*4dc78e53SAndroid Build Coastguard Worker /**
369*4dc78e53SAndroid Build Coastguard Worker * Search qdisc by interface index and parent
370*4dc78e53SAndroid Build Coastguard Worker * @arg cache Qdisc cache
371*4dc78e53SAndroid Build Coastguard Worker * @arg ifindex Interface index
372*4dc78e53SAndroid Build Coastguard Worker * @arg parent Handle of parent qdisc
373*4dc78e53SAndroid Build Coastguard Worker *
374*4dc78e53SAndroid Build Coastguard Worker * Searches a qdisc cache previously allocated with rtnl_qdisc_alloc_cache()
375*4dc78e53SAndroid Build Coastguard Worker * and searches for a qdisc matching the interface index and parent qdisc.
376*4dc78e53SAndroid Build Coastguard Worker *
377*4dc78e53SAndroid Build Coastguard Worker * The reference counter is incremented before returning the qdisc, therefore
378*4dc78e53SAndroid Build Coastguard Worker * the reference must be given back with rtnl_qdisc_put() after usage.
379*4dc78e53SAndroid Build Coastguard Worker *
380*4dc78e53SAndroid Build Coastguard Worker * @return pointer to qdisc inside the cache or NULL if no match was found.
381*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_get_by_parent(struct nl_cache * cache,int ifindex,uint32_t parent)382*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *rtnl_qdisc_get_by_parent(struct nl_cache *cache,
383*4dc78e53SAndroid Build Coastguard Worker int ifindex, uint32_t parent)
384*4dc78e53SAndroid Build Coastguard Worker {
385*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *q;
386*4dc78e53SAndroid Build Coastguard Worker
387*4dc78e53SAndroid Build Coastguard Worker if (cache->c_ops != &rtnl_qdisc_ops)
388*4dc78e53SAndroid Build Coastguard Worker return NULL;
389*4dc78e53SAndroid Build Coastguard Worker
390*4dc78e53SAndroid Build Coastguard Worker nl_list_for_each_entry(q, &cache->c_items, ce_list) {
391*4dc78e53SAndroid Build Coastguard Worker if (q->q_parent == parent &&
392*4dc78e53SAndroid Build Coastguard Worker q->q_ifindex == ((unsigned)ifindex)) {
393*4dc78e53SAndroid Build Coastguard Worker nl_object_get((struct nl_object *) q);
394*4dc78e53SAndroid Build Coastguard Worker return q;
395*4dc78e53SAndroid Build Coastguard Worker }
396*4dc78e53SAndroid Build Coastguard Worker }
397*4dc78e53SAndroid Build Coastguard Worker
398*4dc78e53SAndroid Build Coastguard Worker return NULL;
399*4dc78e53SAndroid Build Coastguard Worker }
400*4dc78e53SAndroid Build Coastguard Worker
401*4dc78e53SAndroid Build Coastguard Worker /**
402*4dc78e53SAndroid Build Coastguard Worker * Search qdisc by kind
403*4dc78e53SAndroid Build Coastguard Worker * @arg cache Qdisc cache
404*4dc78e53SAndroid Build Coastguard Worker * @arg ifindex Interface index
405*4dc78e53SAndroid Build Coastguard Worker * @arg kind Qdisc kind (tbf, htb, cbq, etc)
406*4dc78e53SAndroid Build Coastguard Worker *
407*4dc78e53SAndroid Build Coastguard Worker * Searches a qdisc cache previously allocated with rtnl_qdisc_alloc_cache()
408*4dc78e53SAndroid Build Coastguard Worker * and searches for a qdisc matching the interface index and kind.
409*4dc78e53SAndroid Build Coastguard Worker *
410*4dc78e53SAndroid Build Coastguard Worker * The reference counter is incremented before returning the qdisc, therefore
411*4dc78e53SAndroid Build Coastguard Worker * the reference must be given back with rtnl_qdisc_put() after usage.
412*4dc78e53SAndroid Build Coastguard Worker *
413*4dc78e53SAndroid Build Coastguard Worker * @return pointer to qdisc inside the cache or NULL if no match was found.
414*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_get_by_kind(struct nl_cache * cache,int ifindex,char * kind)415*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *rtnl_qdisc_get_by_kind(struct nl_cache *cache,
416*4dc78e53SAndroid Build Coastguard Worker int ifindex, char *kind)
417*4dc78e53SAndroid Build Coastguard Worker {
418*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *q;
419*4dc78e53SAndroid Build Coastguard Worker
420*4dc78e53SAndroid Build Coastguard Worker if (cache->c_ops != &rtnl_qdisc_ops)
421*4dc78e53SAndroid Build Coastguard Worker return NULL;
422*4dc78e53SAndroid Build Coastguard Worker
423*4dc78e53SAndroid Build Coastguard Worker nl_list_for_each_entry(q, &cache->c_items, ce_list) {
424*4dc78e53SAndroid Build Coastguard Worker if ((q->q_ifindex == ((unsigned)ifindex)) &&
425*4dc78e53SAndroid Build Coastguard Worker (!strcmp(q->q_kind, kind))) {
426*4dc78e53SAndroid Build Coastguard Worker nl_object_get((struct nl_object *) q);
427*4dc78e53SAndroid Build Coastguard Worker return q;
428*4dc78e53SAndroid Build Coastguard Worker }
429*4dc78e53SAndroid Build Coastguard Worker }
430*4dc78e53SAndroid Build Coastguard Worker
431*4dc78e53SAndroid Build Coastguard Worker return NULL;
432*4dc78e53SAndroid Build Coastguard Worker }
433*4dc78e53SAndroid Build Coastguard Worker
434*4dc78e53SAndroid Build Coastguard Worker /**
435*4dc78e53SAndroid Build Coastguard Worker * Search qdisc by interface index and handle
436*4dc78e53SAndroid Build Coastguard Worker * @arg cache Qdisc cache
437*4dc78e53SAndroid Build Coastguard Worker * @arg ifindex Interface index
438*4dc78e53SAndroid Build Coastguard Worker * @arg handle Handle
439*4dc78e53SAndroid Build Coastguard Worker *
440*4dc78e53SAndroid Build Coastguard Worker * Searches a qdisc cache previously allocated with rtnl_qdisc_alloc_cache()
441*4dc78e53SAndroid Build Coastguard Worker * and searches for a qdisc matching the interface index and handle.
442*4dc78e53SAndroid Build Coastguard Worker *
443*4dc78e53SAndroid Build Coastguard Worker * The reference counter is incremented before returning the qdisc, therefore
444*4dc78e53SAndroid Build Coastguard Worker * the reference must be given back with rtnl_qdisc_put() after usage.
445*4dc78e53SAndroid Build Coastguard Worker *
446*4dc78e53SAndroid Build Coastguard Worker * @return Qdisc or NULL if no match was found.
447*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_get(struct nl_cache * cache,int ifindex,uint32_t handle)448*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *rtnl_qdisc_get(struct nl_cache *cache, int ifindex,
449*4dc78e53SAndroid Build Coastguard Worker uint32_t handle)
450*4dc78e53SAndroid Build Coastguard Worker {
451*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *q;
452*4dc78e53SAndroid Build Coastguard Worker
453*4dc78e53SAndroid Build Coastguard Worker if (cache->c_ops != &rtnl_qdisc_ops)
454*4dc78e53SAndroid Build Coastguard Worker return NULL;
455*4dc78e53SAndroid Build Coastguard Worker
456*4dc78e53SAndroid Build Coastguard Worker nl_list_for_each_entry(q, &cache->c_items, ce_list) {
457*4dc78e53SAndroid Build Coastguard Worker if (q->q_handle == handle &&
458*4dc78e53SAndroid Build Coastguard Worker q->q_ifindex == ((unsigned)ifindex)) {
459*4dc78e53SAndroid Build Coastguard Worker nl_object_get((struct nl_object *) q);
460*4dc78e53SAndroid Build Coastguard Worker return q;
461*4dc78e53SAndroid Build Coastguard Worker }
462*4dc78e53SAndroid Build Coastguard Worker }
463*4dc78e53SAndroid Build Coastguard Worker
464*4dc78e53SAndroid Build Coastguard Worker return NULL;
465*4dc78e53SAndroid Build Coastguard Worker }
466*4dc78e53SAndroid Build Coastguard Worker
467*4dc78e53SAndroid Build Coastguard Worker /** @} */
468*4dc78e53SAndroid Build Coastguard Worker
469*4dc78e53SAndroid Build Coastguard Worker /**
470*4dc78e53SAndroid Build Coastguard Worker * @name Deprecated Functions
471*4dc78e53SAndroid Build Coastguard Worker * @{
472*4dc78e53SAndroid Build Coastguard Worker */
473*4dc78e53SAndroid Build Coastguard Worker
474*4dc78e53SAndroid Build Coastguard Worker /**
475*4dc78e53SAndroid Build Coastguard Worker * Call a callback for each child class of a qdisc (deprecated)
476*4dc78e53SAndroid Build Coastguard Worker *
477*4dc78e53SAndroid Build Coastguard Worker * @deprecated Use of this function is deprecated, it does not allow
478*4dc78e53SAndroid Build Coastguard Worker * to handle the out of memory situation that can occur.
479*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_foreach_child(struct rtnl_qdisc * qdisc,struct nl_cache * cache,void (* cb)(struct nl_object *,void *),void * arg)480*4dc78e53SAndroid Build Coastguard Worker void rtnl_qdisc_foreach_child(struct rtnl_qdisc *qdisc, struct nl_cache *cache,
481*4dc78e53SAndroid Build Coastguard Worker void (*cb)(struct nl_object *, void *), void *arg)
482*4dc78e53SAndroid Build Coastguard Worker {
483*4dc78e53SAndroid Build Coastguard Worker struct rtnl_class *filter;
484*4dc78e53SAndroid Build Coastguard Worker
485*4dc78e53SAndroid Build Coastguard Worker filter = rtnl_class_alloc();
486*4dc78e53SAndroid Build Coastguard Worker if (!filter)
487*4dc78e53SAndroid Build Coastguard Worker return;
488*4dc78e53SAndroid Build Coastguard Worker
489*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_set_parent(TC_CAST(filter), qdisc->q_handle);
490*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_set_ifindex(TC_CAST(filter), qdisc->q_ifindex);
491*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_set_kind(TC_CAST(filter), qdisc->q_kind);
492*4dc78e53SAndroid Build Coastguard Worker
493*4dc78e53SAndroid Build Coastguard Worker nl_cache_foreach_filter(cache, OBJ_CAST(filter), cb, arg);
494*4dc78e53SAndroid Build Coastguard Worker
495*4dc78e53SAndroid Build Coastguard Worker rtnl_class_put(filter);
496*4dc78e53SAndroid Build Coastguard Worker }
497*4dc78e53SAndroid Build Coastguard Worker
498*4dc78e53SAndroid Build Coastguard Worker /**
499*4dc78e53SAndroid Build Coastguard Worker * Call a callback for each filter attached to the qdisc (deprecated)
500*4dc78e53SAndroid Build Coastguard Worker *
501*4dc78e53SAndroid Build Coastguard Worker * @deprecated Use of this function is deprecated, it does not allow
502*4dc78e53SAndroid Build Coastguard Worker * to handle the out of memory situation that can occur.
503*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_foreach_cls(struct rtnl_qdisc * qdisc,struct nl_cache * cache,void (* cb)(struct nl_object *,void *),void * arg)504*4dc78e53SAndroid Build Coastguard Worker void rtnl_qdisc_foreach_cls(struct rtnl_qdisc *qdisc, struct nl_cache *cache,
505*4dc78e53SAndroid Build Coastguard Worker void (*cb)(struct nl_object *, void *), void *arg)
506*4dc78e53SAndroid Build Coastguard Worker {
507*4dc78e53SAndroid Build Coastguard Worker struct rtnl_cls *filter;
508*4dc78e53SAndroid Build Coastguard Worker
509*4dc78e53SAndroid Build Coastguard Worker if (!(filter = rtnl_cls_alloc()))
510*4dc78e53SAndroid Build Coastguard Worker return;
511*4dc78e53SAndroid Build Coastguard Worker
512*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_set_ifindex(TC_CAST(filter), qdisc->q_ifindex);
513*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_set_parent(TC_CAST(filter), qdisc->q_parent);
514*4dc78e53SAndroid Build Coastguard Worker
515*4dc78e53SAndroid Build Coastguard Worker nl_cache_foreach_filter(cache, OBJ_CAST(filter), cb, arg);
516*4dc78e53SAndroid Build Coastguard Worker rtnl_cls_put(filter);
517*4dc78e53SAndroid Build Coastguard Worker }
518*4dc78e53SAndroid Build Coastguard Worker
519*4dc78e53SAndroid Build Coastguard Worker /**
520*4dc78e53SAndroid Build Coastguard Worker * Build a netlink message requesting the update of a qdisc
521*4dc78e53SAndroid Build Coastguard Worker *
522*4dc78e53SAndroid Build Coastguard Worker * @deprecated Use of this function is deprecated in favour of
523*4dc78e53SAndroid Build Coastguard Worker * rtnl_qdisc_build_update_request() due to the missing
524*4dc78e53SAndroid Build Coastguard Worker * possibility of specifying additional flags.
525*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_build_change_request(struct rtnl_qdisc * qdisc,struct rtnl_qdisc * new,struct nl_msg ** result)526*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_build_change_request(struct rtnl_qdisc *qdisc,
527*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *new,
528*4dc78e53SAndroid Build Coastguard Worker struct nl_msg **result)
529*4dc78e53SAndroid Build Coastguard Worker {
530*4dc78e53SAndroid Build Coastguard Worker return rtnl_qdisc_build_update_request(qdisc, new, NLM_F_REPLACE,
531*4dc78e53SAndroid Build Coastguard Worker result);
532*4dc78e53SAndroid Build Coastguard Worker }
533*4dc78e53SAndroid Build Coastguard Worker
534*4dc78e53SAndroid Build Coastguard Worker /**
535*4dc78e53SAndroid Build Coastguard Worker * Change attributes of a qdisc
536*4dc78e53SAndroid Build Coastguard Worker *
537*4dc78e53SAndroid Build Coastguard Worker * @deprecated Use of this function is deprecated in favour of
538*4dc78e53SAndroid Build Coastguard Worker * rtnl_qdisc_update() due to the missing possibility of
539*4dc78e53SAndroid Build Coastguard Worker * specifying additional flags.
540*4dc78e53SAndroid Build Coastguard Worker */
rtnl_qdisc_change(struct nl_sock * sk,struct rtnl_qdisc * qdisc,struct rtnl_qdisc * new)541*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_change(struct nl_sock *sk, struct rtnl_qdisc *qdisc,
542*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *new)
543*4dc78e53SAndroid Build Coastguard Worker {
544*4dc78e53SAndroid Build Coastguard Worker return rtnl_qdisc_update(sk, qdisc, new, NLM_F_REPLACE);
545*4dc78e53SAndroid Build Coastguard Worker }
546*4dc78e53SAndroid Build Coastguard Worker
547*4dc78e53SAndroid Build Coastguard Worker /** @} */
548*4dc78e53SAndroid Build Coastguard Worker
qdisc_dump_details(struct rtnl_tc * tc,struct nl_dump_params * p)549*4dc78e53SAndroid Build Coastguard Worker static void qdisc_dump_details(struct rtnl_tc *tc, struct nl_dump_params *p)
550*4dc78e53SAndroid Build Coastguard Worker {
551*4dc78e53SAndroid Build Coastguard Worker struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) tc;
552*4dc78e53SAndroid Build Coastguard Worker
553*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "refcnt %u", qdisc->q_info);
554*4dc78e53SAndroid Build Coastguard Worker }
555*4dc78e53SAndroid Build Coastguard Worker
556*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_type_ops qdisc_ops = {
557*4dc78e53SAndroid Build Coastguard Worker .tt_type = RTNL_TC_TYPE_QDISC,
558*4dc78e53SAndroid Build Coastguard Worker .tt_dump_prefix = "qdisc",
559*4dc78e53SAndroid Build Coastguard Worker .tt_dump = {
560*4dc78e53SAndroid Build Coastguard Worker [NL_DUMP_DETAILS] = qdisc_dump_details,
561*4dc78e53SAndroid Build Coastguard Worker },
562*4dc78e53SAndroid Build Coastguard Worker };
563*4dc78e53SAndroid Build Coastguard Worker
564*4dc78e53SAndroid Build Coastguard Worker static struct nl_cache_ops rtnl_qdisc_ops = {
565*4dc78e53SAndroid Build Coastguard Worker .co_name = "route/qdisc",
566*4dc78e53SAndroid Build Coastguard Worker .co_hdrsize = sizeof(struct tcmsg),
567*4dc78e53SAndroid Build Coastguard Worker .co_msgtypes = {
568*4dc78e53SAndroid Build Coastguard Worker { RTM_NEWQDISC, NL_ACT_NEW, "new" },
569*4dc78e53SAndroid Build Coastguard Worker { RTM_DELQDISC, NL_ACT_DEL, "del" },
570*4dc78e53SAndroid Build Coastguard Worker { RTM_GETQDISC, NL_ACT_GET, "get" },
571*4dc78e53SAndroid Build Coastguard Worker END_OF_MSGTYPES_LIST,
572*4dc78e53SAndroid Build Coastguard Worker },
573*4dc78e53SAndroid Build Coastguard Worker .co_protocol = NETLINK_ROUTE,
574*4dc78e53SAndroid Build Coastguard Worker .co_groups = tc_groups,
575*4dc78e53SAndroid Build Coastguard Worker .co_request_update = qdisc_request_update,
576*4dc78e53SAndroid Build Coastguard Worker .co_msg_parser = qdisc_msg_parser,
577*4dc78e53SAndroid Build Coastguard Worker .co_obj_ops = &qdisc_obj_ops,
578*4dc78e53SAndroid Build Coastguard Worker };
579*4dc78e53SAndroid Build Coastguard Worker
580*4dc78e53SAndroid Build Coastguard Worker static struct nl_object_ops qdisc_obj_ops = {
581*4dc78e53SAndroid Build Coastguard Worker .oo_name = "route/qdisc",
582*4dc78e53SAndroid Build Coastguard Worker .oo_size = sizeof(struct rtnl_qdisc),
583*4dc78e53SAndroid Build Coastguard Worker .oo_free_data = rtnl_tc_free_data,
584*4dc78e53SAndroid Build Coastguard Worker .oo_clone = rtnl_tc_clone,
585*4dc78e53SAndroid Build Coastguard Worker .oo_dump = {
586*4dc78e53SAndroid Build Coastguard Worker [NL_DUMP_LINE] = rtnl_tc_dump_line,
587*4dc78e53SAndroid Build Coastguard Worker [NL_DUMP_DETAILS] = rtnl_tc_dump_details,
588*4dc78e53SAndroid Build Coastguard Worker [NL_DUMP_STATS] = rtnl_tc_dump_stats,
589*4dc78e53SAndroid Build Coastguard Worker },
590*4dc78e53SAndroid Build Coastguard Worker .oo_compare = rtnl_tc_compare,
591*4dc78e53SAndroid Build Coastguard Worker .oo_id_attrs = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE),
592*4dc78e53SAndroid Build Coastguard Worker };
593*4dc78e53SAndroid Build Coastguard Worker
qdisc_init(void)594*4dc78e53SAndroid Build Coastguard Worker static void _nl_init qdisc_init(void)
595*4dc78e53SAndroid Build Coastguard Worker {
596*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_type_register(&qdisc_ops);
597*4dc78e53SAndroid Build Coastguard Worker nl_cache_mngt_register(&rtnl_qdisc_ops);
598*4dc78e53SAndroid Build Coastguard Worker }
599*4dc78e53SAndroid Build Coastguard Worker
qdisc_exit(void)600*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit qdisc_exit(void)
601*4dc78e53SAndroid Build Coastguard Worker {
602*4dc78e53SAndroid Build Coastguard Worker nl_cache_mngt_unregister(&rtnl_qdisc_ops);
603*4dc78e53SAndroid Build Coastguard Worker rtnl_tc_type_unregister(&qdisc_ops);
604*4dc78e53SAndroid Build Coastguard Worker }
605*4dc78e53SAndroid Build Coastguard Worker
606*4dc78e53SAndroid Build Coastguard Worker /** @} */
607