]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/tc/fifo.c
journalctl: make libqrencode a weak dependency
[thirdparty/systemd.git] / src / network / tc / fifo.c
1 /* SPDX-License-Identifier: LGPL-2.1+
2 * Copyright © 2020 VMware, Inc. */
3
4 #include <linux/pkt_sched.h>
5
6 #include "alloc-util.h"
7 #include "conf-parser.h"
8 #include "fifo.h"
9 #include "netlink-util.h"
10 #include "parse-util.h"
11 #include "string-util.h"
12
13 static int fifo_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
14 struct tc_fifo_qopt opt = {};
15 FirstInFirstOut *fifo;
16 int r;
17
18 assert(link);
19 assert(qdisc);
20 assert(req);
21
22 switch(qdisc->kind) {
23 case QDISC_KIND_PFIFO:
24 fifo = PFIFO(qdisc);
25 break;
26 case QDISC_KIND_BFIFO:
27 fifo = BFIFO(qdisc);
28 break;
29 case QDISC_KIND_PFIFO_HEAD_DROP:
30 fifo = PFIFO_HEAD_DROP(qdisc);
31 break;
32 default:
33 assert_not_reached("Invalid QDisc kind.");
34 }
35
36 opt.limit = fifo->limit;
37
38 r = sd_netlink_message_append_data(req, TCA_OPTIONS, &opt, sizeof(struct tc_fifo_qopt));
39 if (r < 0)
40 return log_link_error_errno(link, r, "Could not append TCA_OPTIONS attribute: %m");
41
42 return 0;
43 }
44
45 int config_parse_pfifo_size(
46 const char *unit,
47 const char *filename,
48 unsigned line,
49 const char *section,
50 unsigned section_line,
51 const char *lvalue,
52 int ltype,
53 const char *rvalue,
54 void *data,
55 void *userdata) {
56
57 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
58 Network *network = data;
59 FirstInFirstOut *fifo;
60 int r;
61
62 assert(filename);
63 assert(lvalue);
64 assert(rvalue);
65 assert(data);
66
67 r = qdisc_new_static(ltype, network, filename, section_line, &qdisc);
68 if (r == -ENOMEM)
69 return log_oom();
70 if (r < 0)
71 return log_syntax(unit, LOG_ERR, filename, line, r,
72 "More than one kind of queueing discipline, ignoring assignment: %m");
73
74 switch(qdisc->kind) {
75 case QDISC_KIND_PFIFO:
76 fifo = PFIFO(qdisc);
77 break;
78 case QDISC_KIND_PFIFO_HEAD_DROP:
79 fifo = PFIFO_HEAD_DROP(qdisc);
80 break;
81 default:
82 assert_not_reached("Invalid QDisc kind.");
83 }
84
85 if (isempty(rvalue)) {
86 fifo->limit = 0;
87
88 qdisc = NULL;
89 return 0;
90 }
91
92 r = safe_atou32(rvalue, &fifo->limit);
93 if (r < 0) {
94 log_syntax(unit, LOG_ERR, filename, line, r,
95 "Failed to parse '%s=', ignoring assignment: %s",
96 lvalue, rvalue);
97 return 0;
98 }
99
100 qdisc = NULL;
101 return 0;
102 }
103
104 int config_parse_bfifo_size(
105 const char *unit,
106 const char *filename,
107 unsigned line,
108 const char *section,
109 unsigned section_line,
110 const char *lvalue,
111 int ltype,
112 const char *rvalue,
113 void *data,
114 void *userdata) {
115
116 _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
117 Network *network = data;
118 FirstInFirstOut *fifo;
119 uint64_t u;
120 int r;
121
122 assert(filename);
123 assert(lvalue);
124 assert(rvalue);
125 assert(data);
126
127 r = qdisc_new_static(QDISC_KIND_BFIFO, network, filename, section_line, &qdisc);
128 if (r == -ENOMEM)
129 return log_oom();
130 if (r < 0)
131 return log_syntax(unit, LOG_ERR, filename, line, r,
132 "More than one kind of queueing discipline, ignoring assignment: %m");
133
134 fifo = BFIFO(qdisc);
135
136 if (isempty(rvalue)) {
137 fifo->limit = 0;
138
139 qdisc = NULL;
140 return 0;
141 }
142
143 r = parse_size(rvalue, 1000, &u);
144 if (r < 0) {
145 log_syntax(unit, LOG_ERR, filename, line, r,
146 "Failed to parse '%s=', ignoring assignment: %s",
147 lvalue, rvalue);
148 return 0;
149 }
150 if (u > UINT32_MAX) {
151 log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid '%s=', ignoring assignment: %s",
152 lvalue, rvalue);
153 return 0;
154 }
155
156 fifo->limit = (uint32_t) u;
157
158 qdisc = NULL;
159 return 0;
160 }
161
162 const QDiscVTable pfifo_vtable = {
163 .object_size = sizeof(FirstInFirstOut),
164 .tca_kind = "pfifo",
165 .fill_message = fifo_fill_message,
166 };
167
168 const QDiscVTable bfifo_vtable = {
169 .object_size = sizeof(FirstInFirstOut),
170 .tca_kind = "bfifo",
171 .fill_message = fifo_fill_message,
172 };
173
174 const QDiscVTable pfifo_head_drop_vtable = {
175 .object_size = sizeof(FirstInFirstOut),
176 .tca_kind = "pfifo_head_drop",
177 .fill_message = fifo_fill_message,
178 };
179
180 const QDiscVTable pfifo_fast_vtable = {
181 .object_size = sizeof(FirstInFirstOut),
182 .tca_kind = "pfifo_fast",
183 };