xref: /aosp_15_r20/external/libnl/lib/route/qdisc/fifo.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
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 qdisc
8*4dc78e53SAndroid Build Coastguard Worker  * @defgroup qdisc_fifo Packet/Bytes FIFO (pfifo/bfifo)
9*4dc78e53SAndroid Build Coastguard Worker  * @brief
10*4dc78e53SAndroid Build Coastguard Worker  *
11*4dc78e53SAndroid Build Coastguard Worker  * The FIFO qdisc comes in two flavours:
12*4dc78e53SAndroid Build Coastguard Worker  * @par bfifo (Byte FIFO)
13*4dc78e53SAndroid Build Coastguard Worker  * Allows enqueuing until the currently queued volume in bytes exceeds
14*4dc78e53SAndroid Build Coastguard Worker  * the configured limit.backlog contains currently enqueued volume in bytes.
15*4dc78e53SAndroid Build Coastguard Worker  *
16*4dc78e53SAndroid Build Coastguard Worker  * @par pfifo (Packet FIFO)
17*4dc78e53SAndroid Build Coastguard Worker  * Allows enquueing until the currently queued number of packets
18*4dc78e53SAndroid Build Coastguard Worker  * exceeds the configured limit.
19*4dc78e53SAndroid Build Coastguard Worker  *
20*4dc78e53SAndroid Build Coastguard Worker  * The configuration is exactly the same, the decision which of
21*4dc78e53SAndroid Build Coastguard Worker  * the two variations is going to be used is made based on the
22*4dc78e53SAndroid Build Coastguard Worker  * kind of the qdisc (rtnl_tc_set_kind()).
23*4dc78e53SAndroid Build Coastguard Worker  * @{
24*4dc78e53SAndroid Build Coastguard Worker  */
25*4dc78e53SAndroid Build Coastguard Worker 
26*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
27*4dc78e53SAndroid Build Coastguard Worker 
28*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
29*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/qdisc.h>
30*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/qdisc/fifo.h>
31*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
32*4dc78e53SAndroid Build Coastguard Worker 
33*4dc78e53SAndroid Build Coastguard Worker #include "tc-api.h"
34*4dc78e53SAndroid Build Coastguard Worker 
35*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
36*4dc78e53SAndroid Build Coastguard Worker struct rtnl_fifo {
37*4dc78e53SAndroid Build Coastguard Worker 	uint32_t qf_limit;
38*4dc78e53SAndroid Build Coastguard Worker 	uint32_t qf_mask;
39*4dc78e53SAndroid Build Coastguard Worker };
40*4dc78e53SAndroid Build Coastguard Worker 
41*4dc78e53SAndroid Build Coastguard Worker #define SCH_FIFO_ATTR_LIMIT 1
42*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
43*4dc78e53SAndroid Build Coastguard Worker 
fifo_msg_parser(struct rtnl_tc * tc,void * data)44*4dc78e53SAndroid Build Coastguard Worker static int fifo_msg_parser(struct rtnl_tc *tc, void *data)
45*4dc78e53SAndroid Build Coastguard Worker {
46*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_fifo *fifo = data;
47*4dc78e53SAndroid Build Coastguard Worker 	struct tc_fifo_qopt *opt;
48*4dc78e53SAndroid Build Coastguard Worker 
49*4dc78e53SAndroid Build Coastguard Worker 	if (tc->tc_opts->d_size < sizeof(struct tc_fifo_qopt))
50*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
51*4dc78e53SAndroid Build Coastguard Worker 
52*4dc78e53SAndroid Build Coastguard Worker 	opt = (struct tc_fifo_qopt *) tc->tc_opts->d_data;
53*4dc78e53SAndroid Build Coastguard Worker 	fifo->qf_limit = opt->limit;
54*4dc78e53SAndroid Build Coastguard Worker 	fifo->qf_mask = SCH_FIFO_ATTR_LIMIT;
55*4dc78e53SAndroid Build Coastguard Worker 
56*4dc78e53SAndroid Build Coastguard Worker 	return 0;
57*4dc78e53SAndroid Build Coastguard Worker }
58*4dc78e53SAndroid Build Coastguard Worker 
pfifo_dump_line(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)59*4dc78e53SAndroid Build Coastguard Worker static void pfifo_dump_line(struct rtnl_tc *tc, void *data,
60*4dc78e53SAndroid Build Coastguard Worker 			    struct nl_dump_params *p)
61*4dc78e53SAndroid Build Coastguard Worker {
62*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_fifo *fifo = data;
63*4dc78e53SAndroid Build Coastguard Worker 
64*4dc78e53SAndroid Build Coastguard Worker 	if (fifo)
65*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " limit %u packets", fifo->qf_limit);
66*4dc78e53SAndroid Build Coastguard Worker }
67*4dc78e53SAndroid Build Coastguard Worker 
bfifo_dump_line(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)68*4dc78e53SAndroid Build Coastguard Worker static void bfifo_dump_line(struct rtnl_tc *tc, void *data,
69*4dc78e53SAndroid Build Coastguard Worker 			    struct nl_dump_params *p)
70*4dc78e53SAndroid Build Coastguard Worker {
71*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_fifo *fifo = data;
72*4dc78e53SAndroid Build Coastguard Worker 	char *unit;
73*4dc78e53SAndroid Build Coastguard Worker 	double r;
74*4dc78e53SAndroid Build Coastguard Worker 
75*4dc78e53SAndroid Build Coastguard Worker 	if (!fifo)
76*4dc78e53SAndroid Build Coastguard Worker 		return;
77*4dc78e53SAndroid Build Coastguard Worker 
78*4dc78e53SAndroid Build Coastguard Worker 	r = nl_cancel_down_bytes(fifo->qf_limit, &unit);
79*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, " limit %.1f%s", r, unit);
80*4dc78e53SAndroid Build Coastguard Worker }
81*4dc78e53SAndroid Build Coastguard Worker 
fifo_msg_fill(struct rtnl_tc * tc,void * data,struct nl_msg * msg)82*4dc78e53SAndroid Build Coastguard Worker static int fifo_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
83*4dc78e53SAndroid Build Coastguard Worker {
84*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_fifo *fifo = data;
85*4dc78e53SAndroid Build Coastguard Worker 	struct tc_fifo_qopt opts = {0};
86*4dc78e53SAndroid Build Coastguard Worker 
87*4dc78e53SAndroid Build Coastguard Worker 	if (!fifo || !(fifo->qf_mask & SCH_FIFO_ATTR_LIMIT))
88*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
89*4dc78e53SAndroid Build Coastguard Worker 
90*4dc78e53SAndroid Build Coastguard Worker 	opts.limit = fifo->qf_limit;
91*4dc78e53SAndroid Build Coastguard Worker 
92*4dc78e53SAndroid Build Coastguard Worker 	return nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD);
93*4dc78e53SAndroid Build Coastguard Worker }
94*4dc78e53SAndroid Build Coastguard Worker 
95*4dc78e53SAndroid Build Coastguard Worker /**
96*4dc78e53SAndroid Build Coastguard Worker  * @name Attribute Modification
97*4dc78e53SAndroid Build Coastguard Worker  * @{
98*4dc78e53SAndroid Build Coastguard Worker  */
99*4dc78e53SAndroid Build Coastguard Worker 
100*4dc78e53SAndroid Build Coastguard Worker /**
101*4dc78e53SAndroid Build Coastguard Worker  * Set limit of FIFO qdisc.
102*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc		FIFO qdisc to be modified.
103*4dc78e53SAndroid Build Coastguard Worker  * @arg limit		New limit.
104*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
105*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_fifo_set_limit(struct rtnl_qdisc * qdisc,int limit)106*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_fifo_set_limit(struct rtnl_qdisc *qdisc, int limit)
107*4dc78e53SAndroid Build Coastguard Worker {
108*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_fifo *fifo;
109*4dc78e53SAndroid Build Coastguard Worker 
110*4dc78e53SAndroid Build Coastguard Worker 	if (!(fifo = rtnl_tc_data(TC_CAST(qdisc))))
111*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
112*4dc78e53SAndroid Build Coastguard Worker 
113*4dc78e53SAndroid Build Coastguard Worker 	fifo->qf_limit = limit;
114*4dc78e53SAndroid Build Coastguard Worker 	fifo->qf_mask |= SCH_FIFO_ATTR_LIMIT;
115*4dc78e53SAndroid Build Coastguard Worker 
116*4dc78e53SAndroid Build Coastguard Worker 	return 0;
117*4dc78e53SAndroid Build Coastguard Worker }
118*4dc78e53SAndroid Build Coastguard Worker 
119*4dc78e53SAndroid Build Coastguard Worker /**
120*4dc78e53SAndroid Build Coastguard Worker  * Get limit of a FIFO qdisc.
121*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc		FIFO qdisc.
122*4dc78e53SAndroid Build Coastguard Worker  * @return Numeric limit or a negative error code.
123*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_fifo_get_limit(struct rtnl_qdisc * qdisc)124*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_fifo_get_limit(struct rtnl_qdisc *qdisc)
125*4dc78e53SAndroid Build Coastguard Worker {
126*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_fifo *fifo;
127*4dc78e53SAndroid Build Coastguard Worker 
128*4dc78e53SAndroid Build Coastguard Worker 	if (!(fifo = rtnl_tc_data(TC_CAST(qdisc))))
129*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
130*4dc78e53SAndroid Build Coastguard Worker 
131*4dc78e53SAndroid Build Coastguard Worker 	if (fifo->qf_mask & SCH_FIFO_ATTR_LIMIT)
132*4dc78e53SAndroid Build Coastguard Worker 		return fifo->qf_limit;
133*4dc78e53SAndroid Build Coastguard Worker 	else
134*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOATTR;
135*4dc78e53SAndroid Build Coastguard Worker }
136*4dc78e53SAndroid Build Coastguard Worker 
137*4dc78e53SAndroid Build Coastguard Worker /** @} */
138*4dc78e53SAndroid Build Coastguard Worker 
139*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops pfifo_ops = {
140*4dc78e53SAndroid Build Coastguard Worker 	.to_kind		= "pfifo",
141*4dc78e53SAndroid Build Coastguard Worker 	.to_type		= RTNL_TC_TYPE_QDISC,
142*4dc78e53SAndroid Build Coastguard Worker 	.to_size		= sizeof(struct rtnl_fifo),
143*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_parser		= fifo_msg_parser,
144*4dc78e53SAndroid Build Coastguard Worker 	.to_dump[NL_DUMP_LINE]	= pfifo_dump_line,
145*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_fill		= fifo_msg_fill,
146*4dc78e53SAndroid Build Coastguard Worker };
147*4dc78e53SAndroid Build Coastguard Worker 
148*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops bfifo_ops = {
149*4dc78e53SAndroid Build Coastguard Worker 	.to_kind		= "bfifo",
150*4dc78e53SAndroid Build Coastguard Worker 	.to_type		= RTNL_TC_TYPE_QDISC,
151*4dc78e53SAndroid Build Coastguard Worker 	.to_size		= sizeof(struct rtnl_fifo),
152*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_parser		= fifo_msg_parser,
153*4dc78e53SAndroid Build Coastguard Worker 	.to_dump[NL_DUMP_LINE]	= bfifo_dump_line,
154*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_fill		= fifo_msg_fill,
155*4dc78e53SAndroid Build Coastguard Worker };
156*4dc78e53SAndroid Build Coastguard Worker 
fifo_init(void)157*4dc78e53SAndroid Build Coastguard Worker static void _nl_init fifo_init(void)
158*4dc78e53SAndroid Build Coastguard Worker {
159*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_register(&pfifo_ops);
160*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_register(&bfifo_ops);
161*4dc78e53SAndroid Build Coastguard Worker }
162*4dc78e53SAndroid Build Coastguard Worker 
fifo_exit(void)163*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit fifo_exit(void)
164*4dc78e53SAndroid Build Coastguard Worker {
165*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_unregister(&pfifo_ops);
166*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_unregister(&bfifo_ops);
167*4dc78e53SAndroid Build Coastguard Worker }
168*4dc78e53SAndroid Build Coastguard Worker 
169*4dc78e53SAndroid Build Coastguard Worker /** @} */
170