1 /* Copyright (C) 2013 Cisco Systems, Inc, 2013.
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License
5 * as published by the Free Software Foundation; either version 2
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * Author: Vijay Subramanian <vijaynsu@cisco.com>
14 * Author: Mythili Prabhu <mysuryan@cisco.com>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
31 static void explain(void)
34 "Usage: ... pie [ limit PACKETS ][ target TIME us]\n"
35 " [ tupdate TIME us][ alpha ALPHA ]"
36 "[beta BETA ][bytemode | nobytemode][ecn | noecn ]\n");
42 static int pie_parse_opt(struct qdisc_util
*qu
, int argc
, char **argv
,
43 struct nlmsghdr
*n
, const char *dev
)
45 unsigned int limit
= 0;
46 unsigned int target
= 0;
47 unsigned int tupdate
= 0;
48 unsigned int alpha
= 0;
49 unsigned int beta
= 0;
55 if (strcmp(*argv
, "limit") == 0) {
57 if (get_unsigned(&limit
, *argv
, 0)) {
58 fprintf(stderr
, "Illegal \"limit\"\n");
61 } else if (strcmp(*argv
, "target") == 0) {
63 if (get_time(&target
, *argv
)) {
64 fprintf(stderr
, "Illegal \"target\"\n");
67 } else if (strcmp(*argv
, "tupdate") == 0) {
69 if (get_time(&tupdate
, *argv
)) {
70 fprintf(stderr
, "Illegal \"tupdate\"\n");
73 } else if (strcmp(*argv
, "alpha") == 0) {
75 if (get_unsigned(&alpha
, *argv
, 0) ||
76 (alpha
> ALPHA_MAX
)) {
77 fprintf(stderr
, "Illegal \"alpha\"\n");
80 } else if (strcmp(*argv
, "beta") == 0) {
82 if (get_unsigned(&beta
, *argv
, 0) ||
84 fprintf(stderr
, "Illegal \"beta\"\n");
87 } else if (strcmp(*argv
, "ecn") == 0) {
89 } else if (strcmp(*argv
, "noecn") == 0) {
91 } else if (strcmp(*argv
, "bytemode") == 0) {
93 } else if (strcmp(*argv
, "nobytemode") == 0) {
95 } else if (strcmp(*argv
, "help") == 0) {
99 fprintf(stderr
, "What is \"%s\"?\n", *argv
);
107 tail
= addattr_nest(n
, 1024, TCA_OPTIONS
);
109 addattr_l(n
, 1024, TCA_PIE_LIMIT
, &limit
, sizeof(limit
));
111 addattr_l(n
, 1024, TCA_PIE_TUPDATE
, &tupdate
, sizeof(tupdate
));
113 addattr_l(n
, 1024, TCA_PIE_TARGET
, &target
, sizeof(target
));
115 addattr_l(n
, 1024, TCA_PIE_ALPHA
, &alpha
, sizeof(alpha
));
117 addattr_l(n
, 1024, TCA_PIE_BETA
, &beta
, sizeof(beta
));
119 addattr_l(n
, 1024, TCA_PIE_ECN
, &ecn
, sizeof(ecn
));
121 addattr_l(n
, 1024, TCA_PIE_BYTEMODE
, &bytemode
,
124 addattr_nest_end(n
, tail
);
128 static int pie_print_opt(struct qdisc_util
*qu
, FILE *f
, struct rtattr
*opt
)
130 struct rtattr
*tb
[TCA_PIE_MAX
+ 1];
132 unsigned int tupdate
;
137 unsigned int bytemode
;
144 parse_rtattr_nested(tb
, TCA_PIE_MAX
, opt
);
146 if (tb
[TCA_PIE_LIMIT
] &&
147 RTA_PAYLOAD(tb
[TCA_PIE_LIMIT
]) >= sizeof(__u32
)) {
148 limit
= rta_getattr_u32(tb
[TCA_PIE_LIMIT
]);
149 fprintf(f
, "limit %up ", limit
);
151 if (tb
[TCA_PIE_TARGET
] &&
152 RTA_PAYLOAD(tb
[TCA_PIE_TARGET
]) >= sizeof(__u32
)) {
153 target
= rta_getattr_u32(tb
[TCA_PIE_TARGET
]);
154 fprintf(f
, "target %s ", sprint_time(target
, b1
));
156 if (tb
[TCA_PIE_TUPDATE
] &&
157 RTA_PAYLOAD(tb
[TCA_PIE_TUPDATE
]) >= sizeof(__u32
)) {
158 tupdate
= rta_getattr_u32(tb
[TCA_PIE_TUPDATE
]);
159 fprintf(f
, "tupdate %s ", sprint_time(tupdate
, b1
));
161 if (tb
[TCA_PIE_ALPHA
] &&
162 RTA_PAYLOAD(tb
[TCA_PIE_ALPHA
]) >= sizeof(__u32
)) {
163 alpha
= rta_getattr_u32(tb
[TCA_PIE_ALPHA
]);
164 fprintf(f
, "alpha %u ", alpha
);
166 if (tb
[TCA_PIE_BETA
] &&
167 RTA_PAYLOAD(tb
[TCA_PIE_BETA
]) >= sizeof(__u32
)) {
168 beta
= rta_getattr_u32(tb
[TCA_PIE_BETA
]);
169 fprintf(f
, "beta %u ", beta
);
172 if (tb
[TCA_PIE_ECN
] && RTA_PAYLOAD(tb
[TCA_PIE_ECN
]) >= sizeof(__u32
)) {
173 ecn
= rta_getattr_u32(tb
[TCA_PIE_ECN
]);
178 if (tb
[TCA_PIE_BYTEMODE
] &&
179 RTA_PAYLOAD(tb
[TCA_PIE_BYTEMODE
]) >= sizeof(__u32
)) {
180 bytemode
= rta_getattr_u32(tb
[TCA_PIE_BYTEMODE
]);
182 fprintf(f
, "bytemode ");
188 static int pie_print_xstats(struct qdisc_util
*qu
, FILE *f
,
189 struct rtattr
*xstats
)
191 struct tc_pie_xstats
*st
;
196 if (RTA_PAYLOAD(xstats
) < sizeof(*st
))
199 st
= RTA_DATA(xstats
);
200 /*prob is returned as a fracion of maximum integer value */
201 fprintf(f
, "prob %f delay %uus avg_dq_rate %u\n",
202 (double)st
->prob
/ UINT64_MAX
, st
->delay
,
204 fprintf(f
, "pkts_in %u overlimit %u dropped %u maxq %u ecn_mark %u\n",
205 st
->packets_in
, st
->overlimit
, st
->dropped
, st
->maxq
,
211 struct qdisc_util pie_qdisc_util
= {
213 .parse_qopt
= pie_parse_opt
,
214 .print_qopt
= pie_print_opt
,
215 .print_xstats
= pie_print_xstats
,