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)
33 fprintf(stderr
, "Usage: ... pie [ limit PACKETS ][ target TIME us]\n");
34 fprintf(stderr
, " [ tupdate TIME us][ alpha ALPHA ]");
35 fprintf(stderr
, "[beta BETA ][bytemode | nobytemode][ecn | noecn ]\n");
41 static int pie_parse_opt(struct qdisc_util
*qu
, int argc
, char **argv
,
42 struct nlmsghdr
*n
, const char *dev
)
44 unsigned int limit
= 0;
45 unsigned int target
= 0;
46 unsigned int tupdate
= 0;
47 unsigned int alpha
= 0;
48 unsigned int beta
= 0;
54 if (strcmp(*argv
, "limit") == 0) {
56 if (get_unsigned(&limit
, *argv
, 0)) {
57 fprintf(stderr
, "Illegal \"limit\"\n");
60 } else if (strcmp(*argv
, "target") == 0) {
62 if (get_time(&target
, *argv
)) {
63 fprintf(stderr
, "Illegal \"target\"\n");
66 } else if (strcmp(*argv
, "tupdate") == 0) {
68 if (get_time(&tupdate
, *argv
)) {
69 fprintf(stderr
, "Illegal \"tupdate\"\n");
72 } else if (strcmp(*argv
, "alpha") == 0) {
74 if (get_unsigned(&alpha
, *argv
, 0) ||
75 (alpha
> ALPHA_MAX
)) {
76 fprintf(stderr
, "Illegal \"alpha\"\n");
79 } else if (strcmp(*argv
, "beta") == 0) {
81 if (get_unsigned(&beta
, *argv
, 0) ||
83 fprintf(stderr
, "Illegal \"beta\"\n");
86 } else if (strcmp(*argv
, "ecn") == 0) {
88 } else if (strcmp(*argv
, "noecn") == 0) {
90 } else if (strcmp(*argv
, "bytemode") == 0) {
92 } else if (strcmp(*argv
, "nobytemode") == 0) {
94 } else if (strcmp(*argv
, "help") == 0) {
98 fprintf(stderr
, "What is \"%s\"?\n", *argv
);
106 tail
= addattr_nest(n
, 1024, TCA_OPTIONS
);
108 addattr_l(n
, 1024, TCA_PIE_LIMIT
, &limit
, sizeof(limit
));
110 addattr_l(n
, 1024, TCA_PIE_TUPDATE
, &tupdate
, sizeof(tupdate
));
112 addattr_l(n
, 1024, TCA_PIE_TARGET
, &target
, sizeof(target
));
114 addattr_l(n
, 1024, TCA_PIE_ALPHA
, &alpha
, sizeof(alpha
));
116 addattr_l(n
, 1024, TCA_PIE_BETA
, &beta
, sizeof(beta
));
118 addattr_l(n
, 1024, TCA_PIE_ECN
, &ecn
, sizeof(ecn
));
120 addattr_l(n
, 1024, TCA_PIE_BYTEMODE
, &bytemode
,
123 addattr_nest_end(n
, tail
);
127 static int pie_print_opt(struct qdisc_util
*qu
, FILE *f
, struct rtattr
*opt
)
129 struct rtattr
*tb
[TCA_PIE_MAX
+ 1];
131 unsigned int tupdate
;
136 unsigned int bytemode
;
143 parse_rtattr_nested(tb
, TCA_PIE_MAX
, opt
);
145 if (tb
[TCA_PIE_LIMIT
] &&
146 RTA_PAYLOAD(tb
[TCA_PIE_LIMIT
]) >= sizeof(__u32
)) {
147 limit
= rta_getattr_u32(tb
[TCA_PIE_LIMIT
]);
148 fprintf(f
, "limit %up ", limit
);
150 if (tb
[TCA_PIE_TARGET
] &&
151 RTA_PAYLOAD(tb
[TCA_PIE_TARGET
]) >= sizeof(__u32
)) {
152 target
= rta_getattr_u32(tb
[TCA_PIE_TARGET
]);
153 fprintf(f
, "target %s ", sprint_time(target
, b1
));
155 if (tb
[TCA_PIE_TUPDATE
] &&
156 RTA_PAYLOAD(tb
[TCA_PIE_TUPDATE
]) >= sizeof(__u32
)) {
157 tupdate
= rta_getattr_u32(tb
[TCA_PIE_TUPDATE
]);
158 fprintf(f
, "tupdate %s ", sprint_time(tupdate
, b1
));
160 if (tb
[TCA_PIE_ALPHA
] &&
161 RTA_PAYLOAD(tb
[TCA_PIE_ALPHA
]) >= sizeof(__u32
)) {
162 alpha
= rta_getattr_u32(tb
[TCA_PIE_ALPHA
]);
163 fprintf(f
, "alpha %u ", alpha
);
165 if (tb
[TCA_PIE_BETA
] &&
166 RTA_PAYLOAD(tb
[TCA_PIE_BETA
]) >= sizeof(__u32
)) {
167 beta
= rta_getattr_u32(tb
[TCA_PIE_BETA
]);
168 fprintf(f
, "beta %u ", beta
);
171 if (tb
[TCA_PIE_ECN
] && RTA_PAYLOAD(tb
[TCA_PIE_ECN
]) >= sizeof(__u32
)) {
172 ecn
= rta_getattr_u32(tb
[TCA_PIE_ECN
]);
177 if (tb
[TCA_PIE_BYTEMODE
] &&
178 RTA_PAYLOAD(tb
[TCA_PIE_BYTEMODE
]) >= sizeof(__u32
)) {
179 bytemode
= rta_getattr_u32(tb
[TCA_PIE_BYTEMODE
]);
181 fprintf(f
, "bytemode ");
187 static int pie_print_xstats(struct qdisc_util
*qu
, FILE *f
,
188 struct rtattr
*xstats
)
190 struct tc_pie_xstats
*st
;
195 if (RTA_PAYLOAD(xstats
) < sizeof(*st
))
198 st
= RTA_DATA(xstats
);
199 /*prob is returned as a fracion of maximum integer value */
200 fprintf(f
, "prob %f delay %uus avg_dq_rate %u\n",
201 (double)st
->prob
/ (double)0xffffffff, st
->delay
,
203 fprintf(f
, "pkts_in %u overlimit %u dropped %u maxq %u ecn_mark %u\n",
204 st
->packets_in
, st
->overlimit
, st
->dropped
, st
->maxq
,
210 struct qdisc_util pie_qdisc_util
= {
212 .parse_qopt
= pie_parse_opt
,
213 .print_qopt
= pie_print_opt
,
214 .print_xstats
= pie_print_xstats
,