1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2019 Mohit P. Tahiliani <tahiliani@nitk.edu.in>
6 * Copyright (C) 2019 Sachin D. Patil <sdp.sachin@gmail.com>
7 * Copyright (C) 2019 V. Saicharan <vsaicharan1998@gmail.com>
8 * Copyright (C) 2019 Mohit Bhasi <mohitbhasi1998@gmail.com>
9 * Copyright (C) 2019 Leslie Monis <lesliemonis@gmail.com>
10 * Copyright (C) 2019 Gautam Ramakrishnan <gautamramk@gmail.com>
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
25 static void explain(void)
28 "Usage: ... fq_pie [ limit PACKETS ] [ flows NUMBER ]\n"
29 " [ target TIME ] [ tupdate TIME ]\n"
30 " [ alpha NUMBER ] [ beta NUMBER ]\n"
31 " [ quantum BYTES ] [ memory_limit BYTES ]\n"
32 " [ ecn_prob PERCENTAGE ] [ [no]ecn ]\n"
33 " [ [no]bytemode ] [ [no_]dq_rate_estimator ]\n");
39 static int fq_pie_parse_opt(struct qdisc_util
*qu
, int argc
, char **argv
,
40 struct nlmsghdr
*n
, const char *dev
)
42 unsigned int limit
= 0;
43 unsigned int flows
= 0;
44 unsigned int target
= 0;
45 unsigned int tupdate
= 0;
46 unsigned int alpha
= 0;
47 unsigned int beta
= 0;
48 unsigned int quantum
= 0;
49 unsigned int memory_limit
= 0;
50 unsigned int ecn_prob
= 0;
53 int dq_rate_estimator
= -1;
57 if (strcmp(*argv
, "limit") == 0) {
59 if (get_unsigned(&limit
, *argv
, 0)) {
60 fprintf(stderr
, "Illegal \"limit\"\n");
63 } else if (strcmp(*argv
, "flows") == 0) {
65 if (get_unsigned(&flows
, *argv
, 0)) {
66 fprintf(stderr
, "Illegal \"flows\"\n");
69 } else if (strcmp(*argv
, "target") == 0) {
71 if (get_time(&target
, *argv
)) {
72 fprintf(stderr
, "Illegal \"target\"\n");
75 } else if (strcmp(*argv
, "tupdate") == 0) {
77 if (get_time(&tupdate
, *argv
)) {
78 fprintf(stderr
, "Illegal \"tupdate\"\n");
81 } else if (strcmp(*argv
, "alpha") == 0) {
83 if (get_unsigned(&alpha
, *argv
, 0) ||
85 fprintf(stderr
, "Illegal \"alpha\"\n");
88 } else if (strcmp(*argv
, "beta") == 0) {
90 if (get_unsigned(&beta
, *argv
, 0) ||
92 fprintf(stderr
, "Illegal \"beta\"\n");
95 } else if (strcmp(*argv
, "quantum") == 0) {
97 if (get_size(&quantum
, *argv
)) {
98 fprintf(stderr
, "Illegal \"quantum\"\n");
101 } else if (strcmp(*argv
, "memory_limit") == 0) {
103 if (get_size(&memory_limit
, *argv
)) {
104 fprintf(stderr
, "Illegal \"memory_limit\"\n");
107 } else if (strcmp(*argv
, "ecn_prob") == 0) {
109 if (get_unsigned(&ecn_prob
, *argv
, 0) ||
111 fprintf(stderr
, "Illegal \"ecn_prob\"\n");
114 } else if (strcmp(*argv
, "ecn") == 0) {
116 } else if (strcmp(*argv
, "noecn") == 0) {
118 } else if (strcmp(*argv
, "bytemode") == 0) {
120 } else if (strcmp(*argv
, "nobytemode") == 0) {
122 } else if (strcmp(*argv
, "dq_rate_estimator") == 0) {
123 dq_rate_estimator
= 1;
124 } else if (strcmp(*argv
, "no_dq_rate_estimator") == 0) {
125 dq_rate_estimator
= 0;
126 } else if (strcmp(*argv
, "help") == 0) {
130 fprintf(stderr
, "What is \"%s\"?\n", *argv
);
139 tail
= addattr_nest(n
, 1024, TCA_OPTIONS
| NLA_F_NESTED
);
141 addattr_l(n
, 1024, TCA_FQ_PIE_LIMIT
, &limit
, sizeof(limit
));
143 addattr_l(n
, 1024, TCA_FQ_PIE_FLOWS
, &flows
, sizeof(flows
));
145 addattr_l(n
, 1024, TCA_FQ_PIE_TARGET
, &target
, sizeof(target
));
147 addattr_l(n
, 1024, TCA_FQ_PIE_TUPDATE
, &tupdate
,
150 addattr_l(n
, 1024, TCA_FQ_PIE_ALPHA
, &alpha
, sizeof(alpha
));
152 addattr_l(n
, 1024, TCA_FQ_PIE_BETA
, &beta
, sizeof(beta
));
154 addattr_l(n
, 1024, TCA_FQ_PIE_QUANTUM
, &quantum
,
157 addattr_l(n
, 1024, TCA_FQ_PIE_MEMORY_LIMIT
, &memory_limit
,
158 sizeof(memory_limit
));
160 addattr_l(n
, 1024, TCA_FQ_PIE_ECN_PROB
, &ecn_prob
,
163 addattr_l(n
, 1024, TCA_FQ_PIE_ECN
, &ecn
, sizeof(ecn
));
165 addattr_l(n
, 1024, TCA_FQ_PIE_BYTEMODE
, &bytemode
,
167 if (dq_rate_estimator
!= -1)
168 addattr_l(n
, 1024, TCA_FQ_PIE_DQ_RATE_ESTIMATOR
,
169 &dq_rate_estimator
, sizeof(dq_rate_estimator
));
170 addattr_nest_end(n
, tail
);
175 static int fq_pie_print_opt(struct qdisc_util
*qu
, FILE *f
, struct rtattr
*opt
)
177 struct rtattr
*tb
[TCA_FQ_PIE_MAX
+ 1];
178 unsigned int limit
= 0;
179 unsigned int flows
= 0;
180 unsigned int target
= 0;
181 unsigned int tupdate
= 0;
182 unsigned int alpha
= 0;
183 unsigned int beta
= 0;
184 unsigned int quantum
= 0;
185 unsigned int memory_limit
= 0;
186 unsigned int ecn_prob
= 0;
189 int dq_rate_estimator
= -1;
196 parse_rtattr_nested(tb
, TCA_FQ_PIE_MAX
, opt
);
198 if (tb
[TCA_FQ_PIE_LIMIT
] &&
199 RTA_PAYLOAD(tb
[TCA_FQ_PIE_LIMIT
]) >= sizeof(__u32
)) {
200 limit
= rta_getattr_u32(tb
[TCA_FQ_PIE_LIMIT
]);
201 print_uint(PRINT_ANY
, "limit", "limit %up ", limit
);
203 if (tb
[TCA_FQ_PIE_FLOWS
] &&
204 RTA_PAYLOAD(tb
[TCA_FQ_PIE_FLOWS
]) >= sizeof(__u32
)) {
205 flows
= rta_getattr_u32(tb
[TCA_FQ_PIE_FLOWS
]);
206 print_uint(PRINT_ANY
, "flows", "flows %u ", flows
);
208 if (tb
[TCA_FQ_PIE_TARGET
] &&
209 RTA_PAYLOAD(tb
[TCA_FQ_PIE_TARGET
]) >= sizeof(__u32
)) {
210 target
= rta_getattr_u32(tb
[TCA_FQ_PIE_TARGET
]);
211 print_uint(PRINT_JSON
, "target", NULL
, target
);
212 print_string(PRINT_FP
, NULL
, "target %s ",
213 sprint_time(target
, b1
));
215 if (tb
[TCA_FQ_PIE_TUPDATE
] &&
216 RTA_PAYLOAD(tb
[TCA_FQ_PIE_TUPDATE
]) >= sizeof(__u32
)) {
217 tupdate
= rta_getattr_u32(tb
[TCA_FQ_PIE_TUPDATE
]);
218 print_uint(PRINT_JSON
, "tupdate", NULL
, tupdate
);
219 print_string(PRINT_FP
, NULL
, "tupdate %s ",
220 sprint_time(tupdate
, b1
));
222 if (tb
[TCA_FQ_PIE_ALPHA
] &&
223 RTA_PAYLOAD(tb
[TCA_FQ_PIE_ALPHA
]) >= sizeof(__u32
)) {
224 alpha
= rta_getattr_u32(tb
[TCA_FQ_PIE_ALPHA
]);
225 print_uint(PRINT_ANY
, "alpha", "alpha %u ", alpha
);
227 if (tb
[TCA_FQ_PIE_BETA
] &&
228 RTA_PAYLOAD(tb
[TCA_FQ_PIE_BETA
]) >= sizeof(__u32
)) {
229 beta
= rta_getattr_u32(tb
[TCA_FQ_PIE_BETA
]);
230 print_uint(PRINT_ANY
, "beta", "beta %u ", beta
);
232 if (tb
[TCA_FQ_PIE_QUANTUM
] &&
233 RTA_PAYLOAD(tb
[TCA_FQ_PIE_QUANTUM
]) >= sizeof(__u32
)) {
234 quantum
= rta_getattr_u32(tb
[TCA_FQ_PIE_QUANTUM
]);
235 print_uint(PRINT_JSON
, "quantum", NULL
, quantum
);
236 print_string(PRINT_FP
, NULL
, "quantum %s ",
237 sprint_size(quantum
, b1
));
239 if (tb
[TCA_FQ_PIE_MEMORY_LIMIT
] &&
240 RTA_PAYLOAD(tb
[TCA_FQ_PIE_MEMORY_LIMIT
]) >= sizeof(__u32
)) {
241 memory_limit
= rta_getattr_u32(tb
[TCA_FQ_PIE_MEMORY_LIMIT
]);
242 print_uint(PRINT_JSON
, "memory_limit", NULL
, memory_limit
);
243 print_string(PRINT_FP
, NULL
, "memory_limit %s ",
244 sprint_size(memory_limit
, b1
));
246 if (tb
[TCA_FQ_PIE_ECN_PROB
] &&
247 RTA_PAYLOAD(tb
[TCA_FQ_PIE_ECN_PROB
]) >= sizeof(__u32
)) {
248 ecn_prob
= rta_getattr_u32(tb
[TCA_FQ_PIE_ECN_PROB
]);
249 print_uint(PRINT_ANY
, "ecn_prob", "ecn_prob %u ", ecn_prob
);
251 if (tb
[TCA_FQ_PIE_ECN
] &&
252 RTA_PAYLOAD(tb
[TCA_FQ_PIE_ECN
]) >= sizeof(__u32
)) {
253 ecn
= rta_getattr_u32(tb
[TCA_FQ_PIE_ECN
]);
255 print_bool(PRINT_ANY
, "ecn", "ecn ", true);
257 if (tb
[TCA_FQ_PIE_BYTEMODE
] &&
258 RTA_PAYLOAD(tb
[TCA_FQ_PIE_BYTEMODE
]) >= sizeof(__u32
)) {
259 bytemode
= rta_getattr_u32(tb
[TCA_FQ_PIE_BYTEMODE
]);
261 print_bool(PRINT_ANY
, "bytemode", "bytemode ", true);
263 if (tb
[TCA_FQ_PIE_DQ_RATE_ESTIMATOR
] &&
264 RTA_PAYLOAD(tb
[TCA_FQ_PIE_DQ_RATE_ESTIMATOR
]) >= sizeof(__u32
)) {
266 rta_getattr_u32(tb
[TCA_FQ_PIE_DQ_RATE_ESTIMATOR
]);
267 if (dq_rate_estimator
)
268 print_bool(PRINT_ANY
, "dq_rate_estimator",
269 "dq_rate_estimator ", true);
275 static int fq_pie_print_xstats(struct qdisc_util
*qu
, FILE *f
,
276 struct rtattr
*xstats
)
278 struct tc_fq_pie_xstats _st
= {}, *st
;
283 st
= RTA_DATA(xstats
);
284 if (RTA_PAYLOAD(xstats
) < sizeof(*st
)) {
285 memcpy(&_st
, st
, RTA_PAYLOAD(xstats
));
289 print_uint(PRINT_ANY
, "pkts_in", " pkts_in %u",
291 print_uint(PRINT_ANY
, "overlimit", " overlimit %u",
293 print_uint(PRINT_ANY
, "overmemory", " overmemory %u",
295 print_uint(PRINT_ANY
, "dropped", " dropped %u",
297 print_uint(PRINT_ANY
, "ecn_mark", " ecn_mark %u",
300 print_uint(PRINT_ANY
, "new_flow_count", " new_flow_count %u",
302 print_uint(PRINT_ANY
, "new_flows_len", " new_flows_len %u",
304 print_uint(PRINT_ANY
, "old_flows_len", " old_flows_len %u",
306 print_uint(PRINT_ANY
, "memory_used", " memory_used %u",
313 struct qdisc_util fq_pie_qdisc_util
= {
315 .parse_qopt
= fq_pie_parse_opt
,
316 .print_qopt
= fq_pie_print_opt
,
317 .print_xstats
= fq_pie_print_xstats
,