1 /* SPDX-License-Identifier: LGPL-2.1+
2 * Copyright © 2020 VMware, Inc. */
4 #include <linux/pkt_sched.h>
6 #include "parse-util.h"
9 #include "string-util.h"
11 #define QFQ_MAX_WEIGHT (1 << 10)
12 #define QFQ_MIN_MAX_PACKET 512
13 #define QFQ_MAX_MAX_PACKET (1 << 16)
15 const QDiscVTable qfq_vtable
= {
16 .object_size
= sizeof(QuickFairQueueing
),
20 static int quick_fair_queueing_class_fill_message(Link
*link
, TClass
*tclass
, sd_netlink_message
*req
) {
21 QuickFairQueueingClass
*qfq
;
28 qfq
= TCLASS_TO_QFQ(tclass
);
30 r
= sd_netlink_message_open_container_union(req
, TCA_OPTIONS
, "qfq");
32 return log_link_error_errno(link
, r
, "Could not open container TCA_OPTIONS: %m");
34 if (qfq
->weight
> 0) {
35 r
= sd_netlink_message_append_u32(req
, TCA_QFQ_WEIGHT
, qfq
->weight
);
37 return log_link_error_errno(link
, r
, "Could not append TCA_QFQ_WEIGHT attribute: %m");
40 if (qfq
->max_packet
> 0) {
41 r
= sd_netlink_message_append_u32(req
, TCA_QFQ_LMAX
, qfq
->max_packet
);
43 return log_link_error_errno(link
, r
, "Could not append TCA_QFQ_LMAX attribute: %m");
46 r
= sd_netlink_message_close_container(req
);
48 return log_link_error_errno(link
, r
, "Could not close container TCA_OPTIONS: %m");
52 int config_parse_quick_fair_queueing_weight(
57 unsigned section_line
,
64 _cleanup_(tclass_free_or_set_invalidp
) TClass
*tclass
= NULL
;
65 QuickFairQueueingClass
*qfq
;
66 Network
*network
= data
;
75 r
= tclass_new_static(TCLASS_KIND_QFQ
, network
, filename
, section_line
, &tclass
);
77 return log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
78 "Failed to create traffic control class, ignoring assignment: %m");
80 qfq
= TCLASS_TO_QFQ(tclass
);
82 if (isempty(rvalue
)) {
88 r
= safe_atou32(rvalue
, &v
);
90 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
91 "Failed to parse '%s=', ignoring assignment: %s",
96 if (v
== 0 || v
> QFQ_MAX_WEIGHT
) {
97 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
98 "Invalid '%s=', ignoring assignment: %s",
109 int config_parse_quick_fair_queueing_max_packet(
111 const char *filename
,
114 unsigned section_line
,
121 _cleanup_(tclass_free_or_set_invalidp
) TClass
*tclass
= NULL
;
122 QuickFairQueueingClass
*qfq
;
123 Network
*network
= data
;
132 r
= tclass_new_static(TCLASS_KIND_QFQ
, network
, filename
, section_line
, &tclass
);
134 return log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
135 "Failed to create traffic control class, ignoring assignment: %m");
137 qfq
= TCLASS_TO_QFQ(tclass
);
139 if (isempty(rvalue
)) {
145 r
= parse_size(rvalue
, 1000, &v
);
147 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
148 "Failed to parse '%s=', ignoring assignment: %s",
153 if (v
< QFQ_MIN_MAX_PACKET
|| v
> QFQ_MAX_MAX_PACKET
) {
154 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
155 "Invalid '%s=', ignoring assignment: %s",
160 qfq
->max_packet
= (uint32_t) v
;
166 const TClassVTable qfq_tclass_vtable
= {
167 .object_size
= sizeof(QuickFairQueueingClass
),
169 .fill_message
= quick_fair_queueing_class_fill_message
,