1 /* SPDX-License-Identifier: LGPL-2.1-or-later
2 * Copyright © 2020 VMware, Inc. */
4 #include <linux/pkt_sched.h>
6 #include "alloc-util.h"
7 #include "conf-parser.h"
8 #include "netlink-util.h"
9 #include "parse-util.h"
11 #include "string-util.h"
13 static int generic_random_early_detection_init(QDisc
*qdisc
) {
14 GenericRandomEarlyDetection
*gred
;
25 static int generic_random_early_detection_fill_message(Link
*link
, QDisc
*qdisc
, sd_netlink_message
*req
) {
26 GenericRandomEarlyDetection
*gred
;
33 assert_se(gred
= GRED(qdisc
));
35 const struct tc_gred_sopt opt
= {
36 .DPs
= gred
->virtual_queues
,
37 .def_DP
= gred
->default_virtual_queue
,
41 r
= sd_netlink_message_open_container_union(req
, TCA_OPTIONS
, "gred");
45 r
= sd_netlink_message_append_data(req
, TCA_GRED_DPS
, &opt
, sizeof(opt
));
49 r
= sd_netlink_message_close_container(req
);
56 static int generic_random_early_detection_verify(QDisc
*qdisc
) {
57 GenericRandomEarlyDetection
*gred
= GRED(qdisc
);
59 if (gred
->default_virtual_queue
>= gred
->virtual_queues
)
60 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
61 "%s: DefaultVirtualQueue= must be less than VirtualQueues=. "
62 "Ignoring [GenericRandomEarlyDetection] section from line %u.",
63 qdisc
->section
->filename
, qdisc
->section
->line
);
68 int config_parse_generic_random_early_detection_u32(
73 unsigned section_line
,
80 _cleanup_(qdisc_free_or_set_invalidp
) QDisc
*qdisc
= NULL
;
81 GenericRandomEarlyDetection
*gred
;
82 Network
*network
= ASSERT_PTR(data
);
91 r
= qdisc_new_static(QDISC_KIND_GRED
, network
, filename
, section_line
, &qdisc
);
95 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
96 "More than one kind of queueing discipline, ignoring assignment: %m");
102 if (streq(lvalue
, "VirtualQueues"))
103 p
= &gred
->virtual_queues
;
104 else if (streq(lvalue
, "DefaultVirtualQueue"))
105 p
= &gred
->default_virtual_queue
;
107 assert_not_reached();
109 if (isempty(rvalue
)) {
116 r
= safe_atou32(rvalue
, &v
);
118 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
119 "Failed to parse '%s=', ignoring assignment: %s",
125 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
126 "Invalid '%s=', ignoring assignment: %s",
134 int config_parse_generic_random_early_detection_bool(
136 const char *filename
,
139 unsigned section_line
,
146 _cleanup_(qdisc_free_or_set_invalidp
) QDisc
*qdisc
= NULL
;
147 GenericRandomEarlyDetection
*gred
;
148 Network
*network
= ASSERT_PTR(data
);
155 r
= qdisc_new_static(QDISC_KIND_GRED
, network
, filename
, section_line
, &qdisc
);
159 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
160 "More than one kind of queueing discipline, ignoring assignment: %m");
166 if (isempty(rvalue
)) {
173 r
= parse_boolean(rvalue
);
175 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
176 "Failed to parse '%s=', ignoring assignment: %s",
187 const QDiscVTable gred_vtable
= {
188 .object_size
= sizeof(GenericRandomEarlyDetection
),
190 .init
= generic_random_early_detection_init
,
191 .fill_message
= generic_random_early_detection_fill_message
,
192 .verify
= generic_random_early_detection_verify
,