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>
23 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
32 static void explain(void)
34 fprintf(stderr
, "Usage: ... pie [ limit PACKETS ][ target TIME us]\n");
35 fprintf(stderr
, " [ tupdate TIME us][ alpha ALPHA ]");
36 fprintf(stderr
, "[beta BETA ][bytemode | nobytemode][ecn | noecn ]\n");
44 static int pie_parse_opt(struct qdisc_util
*qu
, int argc
, char **argv
,
47 unsigned int limit
= 0;
48 unsigned int target
= 0;
49 unsigned int tupdate
= 0;
50 unsigned int alpha
= 0;
51 unsigned int beta
= 0;
57 if (strcmp(*argv
, "limit") == 0) {
59 if (get_unsigned(&limit
, *argv
, 0)) {
60 fprintf(stderr
, "Illegal \"limit\"\n");
63 } else if (strcmp(*argv
, "target") == 0) {
65 if (get_time(&target
, *argv
)) {
66 fprintf(stderr
, "Illegal \"target\"\n");
69 } else if (strcmp(*argv
, "tupdate") == 0) {
71 if (get_time(&tupdate
, *argv
)) {
72 fprintf(stderr
, "Illegal \"tupdate\"\n");
75 } else if (strcmp(*argv
, "alpha") == 0) {
77 if (get_unsigned(&alpha
, *argv
, 0) ||
78 (alpha
> ALPHA_MAX
) || (alpha
< ALPHA_MIN
)) {
79 fprintf(stderr
, "Illegal \"alpha\"\n");
82 } else if (strcmp(*argv
, "beta") == 0) {
84 if (get_unsigned(&beta
, *argv
, 0) ||
85 (beta
> BETA_MAX
) || (beta
< BETA_MIN
)) {
86 fprintf(stderr
, "Illegal \"beta\"\n");
89 } else if (strcmp(*argv
, "ecn") == 0) {
91 } else if (strcmp(*argv
, "noecn") == 0) {
93 } else if (strcmp(*argv
, "bytemode") == 0) {
95 } else if (strcmp(*argv
, "nobytemode") == 0) {
97 } else if (strcmp(*argv
, "help") == 0) {
101 fprintf(stderr
, "What is \"%s\"?\n", *argv
);
109 tail
= NLMSG_TAIL(n
);
110 addattr_l(n
, 1024, TCA_OPTIONS
, NULL
, 0);
112 addattr_l(n
, 1024, TCA_PIE_LIMIT
, &limit
, sizeof(limit
));
114 addattr_l(n
, 1024, TCA_PIE_TUPDATE
, &tupdate
, sizeof(tupdate
));
116 addattr_l(n
, 1024, TCA_PIE_TARGET
, &target
, sizeof(target
));
118 addattr_l(n
, 1024, TCA_PIE_ALPHA
, &alpha
, sizeof(alpha
));
120 addattr_l(n
, 1024, TCA_PIE_BETA
, &beta
, sizeof(beta
));
122 addattr_l(n
, 1024, TCA_PIE_ECN
, &ecn
, sizeof(ecn
));
124 addattr_l(n
, 1024, TCA_PIE_BYTEMODE
, &bytemode
,
127 tail
->rta_len
= (void *)NLMSG_TAIL(n
) - (void *)tail
;
131 static int pie_print_opt(struct qdisc_util
*qu
, FILE *f
, struct rtattr
*opt
)
133 struct rtattr
*tb
[TCA_PIE_MAX
+ 1];
135 unsigned int tupdate
;
146 parse_rtattr_nested(tb
, TCA_PIE_MAX
, opt
);
148 if (tb
[TCA_PIE_LIMIT
] &&
149 RTA_PAYLOAD(tb
[TCA_PIE_LIMIT
]) >= sizeof(__u32
)) {
150 limit
= rta_getattr_u32(tb
[TCA_PIE_LIMIT
]);
151 fprintf(f
, "limit %up ", limit
);
153 if (tb
[TCA_PIE_TARGET
] &&
154 RTA_PAYLOAD(tb
[TCA_PIE_TARGET
]) >= sizeof(__u32
)) {
155 target
= rta_getattr_u32(tb
[TCA_PIE_TARGET
]);
156 fprintf(f
, "target %s ", sprint_time(target
, b1
));
158 if (tb
[TCA_PIE_TUPDATE
] &&
159 RTA_PAYLOAD(tb
[TCA_PIE_TUPDATE
]) >= sizeof(__u32
)) {
160 tupdate
= rta_getattr_u32(tb
[TCA_PIE_TUPDATE
]);
161 fprintf(f
, "tupdate %s ", sprint_time(tupdate
, b1
));
163 if (tb
[TCA_PIE_ALPHA
] &&
164 RTA_PAYLOAD(tb
[TCA_PIE_ALPHA
]) >= sizeof(__u32
)) {
165 alpha
= rta_getattr_u32(tb
[TCA_PIE_ALPHA
]);
166 fprintf(f
, "alpha %u ", alpha
);
168 if (tb
[TCA_PIE_BETA
] &&
169 RTA_PAYLOAD(tb
[TCA_PIE_BETA
]) >= sizeof(__u32
)) {
170 beta
= rta_getattr_u32(tb
[TCA_PIE_BETA
]);
171 fprintf(f
, "beta %u ", beta
);
174 if (tb
[TCA_PIE_ECN
] && RTA_PAYLOAD(tb
[TCA_PIE_ECN
]) >= sizeof(__u32
)) {
175 ecn
= rta_getattr_u32(tb
[TCA_PIE_ECN
]);
180 if (tb
[TCA_PIE_BYTEMODE
] &&
181 RTA_PAYLOAD(tb
[TCA_PIE_BYTEMODE
]) >= sizeof(__u32
)) {
182 bytemode
= rta_getattr_u32(tb
[TCA_PIE_BYTEMODE
]);
184 fprintf(f
, "bytemode ");
190 static int pie_print_xstats(struct qdisc_util
*qu
, FILE *f
,
191 struct rtattr
*xstats
)
193 struct tc_pie_xstats
*st
;
198 if (RTA_PAYLOAD(xstats
) < sizeof(*st
))
201 st
= RTA_DATA(xstats
);
202 /*prob is returned as a fracion of maximum integer value */
203 fprintf(f
, "prob %f delay %uus avg_dq_rate %u\n",
204 (double)st
->prob
/ (double)0xffffffff, st
->delay
,
206 fprintf(f
, "pkts_in %u overlimit %u dropped %u maxq %u ecn_mark %u\n",
207 st
->packets_in
, st
->overlimit
, st
->dropped
, st
->maxq
,
213 struct qdisc_util pie_qdisc_util
= {
215 .parse_qopt
= pie_parse_opt
,
216 .print_qopt
= pie_print_opt
,
217 .print_xstats
= pie_print_xstats
,