1 /* SPDX-License-Identifier: LGPL-2.1+
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
;
27 struct tc_gred_sopt opt
= {};
36 opt
.DPs
= gred
->virtual_queues
;
37 opt
.def_DP
= gred
->default_virtual_queue
;
40 opt
.grio
= gred
->grio
;
42 r
= sd_netlink_message_open_container_union(req
, TCA_OPTIONS
, "gred");
44 return log_link_error_errno(link
, r
, "Could not open container TCA_OPTIONS: %m");
46 r
= sd_netlink_message_append_data(req
, TCA_GRED_DPS
, &opt
, sizeof(struct tc_gred_sopt
));
48 return log_link_error_errno(link
, r
, "Could not append TCA_GRED_DPS attribute: %m");
50 r
= sd_netlink_message_close_container(req
);
52 return log_link_error_errno(link
, r
, "Could not close container TCA_OPTIONS: %m");
57 static int generic_random_early_detection_verify(QDisc
*qdisc
) {
58 GenericRandomEarlyDetection
*gred
= GRED(qdisc
);
60 if (gred
->default_virtual_queue
>= gred
->virtual_queues
)
61 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
62 "%s: DefaultVirtualQueue= must be less than VirtualQueues=. "
63 "Ignoring [GenericRandomEarlyDetection] section from line %u.",
64 qdisc
->section
->filename
, qdisc
->section
->line
);
69 int config_parse_generic_random_early_detection_u32(
74 unsigned section_line
,
81 _cleanup_(qdisc_free_or_set_invalidp
) QDisc
*qdisc
= NULL
;
82 GenericRandomEarlyDetection
*gred
;
83 Network
*network
= data
;
93 r
= qdisc_new_static(QDISC_KIND_GRED
, network
, filename
, section_line
, &qdisc
);
97 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
98 "More than one kind of queueing discipline, ignoring assignment: %m");
104 if (streq(lvalue
, "VirtualQueues"))
105 p
= &gred
->virtual_queues
;
106 else if (streq(lvalue
, "DefaultVirtualQueue"))
107 p
= &gred
->default_virtual_queue
;
109 assert_not_reached("Invalid lvalue.");
111 if (isempty(rvalue
)) {
118 r
= safe_atou32(rvalue
, &v
);
120 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
121 "Failed to parse '%s=', ignoring assignment: %s",
127 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
128 "Invalid '%s=', ignoring assignment: %s",
137 int config_parse_generic_random_early_detection_bool(
139 const char *filename
,
142 unsigned section_line
,
149 _cleanup_(qdisc_free_or_set_invalidp
) QDisc
*qdisc
= NULL
;
150 GenericRandomEarlyDetection
*gred
;
151 Network
*network
= data
;
159 r
= qdisc_new_static(QDISC_KIND_GRED
, network
, filename
, section_line
, &qdisc
);
163 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
164 "More than one kind of queueing discipline, ignoring assignment: %m");
170 if (isempty(rvalue
)) {
177 r
= parse_boolean(rvalue
);
179 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
180 "Failed to parse '%s=', ignoring assignment: %s",
191 const QDiscVTable gred_vtable
= {
192 .object_size
= sizeof(GenericRandomEarlyDetection
),
194 .init
= generic_random_early_detection_init
,
195 .fill_message
= generic_random_early_detection_fill_message
,
196 .verify
= generic_random_early_detection_verify
,