]>
git.proxmox.com Git - mirror_iproute2.git/blob - tc/m_police.c
2 * m_police.c Parse/print policing module options.
4 * This program is free software; you can u32istribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10 * FIXES: 19990619 - J Hadi Salim (hadi@cyberus.ca)
11 * simple addattr packaging fix.
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
27 static void explain(void)
29 fprintf(stderr
, "Usage: ... police rate BPS burst BYTES[/BYTES] [ mtu BYTES[/BYTES] ]\n");
30 fprintf(stderr
, " [ peakrate BPS ] [ avrate BPS ]\n");
31 fprintf(stderr
, " [ ACTION ]\n");
32 fprintf(stderr
, "Where: ACTION := reclassify | drop | continue \n");
35 static void explain1(char *arg
)
37 fprintf(stderr
, "Illegal \"%s\"\n", arg
);
40 #define usage() return(-1)
43 char *police_action_n2a(int action
, char *buf
, int len
)
55 case TC_POLICE_RECLASSIFY
:
58 snprintf(buf
, len
, "%d", action
);
63 int police_action_a2n(char *arg
, int *result
)
67 if (matches(arg
, "continue") == 0)
69 else if (matches(arg
, "drop") == 0)
71 else if (matches(arg
, "shot") == 0)
73 else if (matches(arg
, "pass") == 0)
75 else if (strcmp(arg
, "ok") == 0)
77 else if (matches(arg
, "reclassify") == 0)
78 res
= TC_POLICE_RECLASSIFY
;
81 if (sscanf(arg
, "%d%c", &res
, &dummy
) != 1)
89 int get_police_result(int *action
, int *result
, char *arg
)
91 char *p
= strchr(arg
, '/');
96 if (police_action_a2n(arg
, action
)) {
104 if (police_action_a2n(p
+1, result
))
110 int parse_police(int *argc_p
, char ***argv_p
, int tca_id
, struct nlmsghdr
*n
)
113 char **argv
= *argv_p
;
121 unsigned buffer
=0, mtu
=0, mpu
=0;
122 int Rcell_log
=-1, Pcell_log
= -1;
125 memset(&p
, 0, sizeof(p
));
126 p
.action
= TC_POLICE_RECLASSIFY
;
132 if (matches(*argv
, "index") == 0) {
134 if (get_u32(&p
.index
, *argv
, 16)) {
135 fprintf(stderr
, "Illegal \"index\"\n");
138 } else if (matches(*argv
, "burst") == 0 ||
139 strcmp(*argv
, "buffer") == 0 ||
140 strcmp(*argv
, "maxburst") == 0) {
143 fprintf(stderr
, "Double \"buffer/burst\" spec\n");
146 if (get_size_and_cell(&buffer
, &Rcell_log
, *argv
) < 0) {
150 } else if (strcmp(*argv
, "mtu") == 0 ||
151 strcmp(*argv
, "minburst") == 0) {
154 fprintf(stderr
, "Double \"mtu/minburst\" spec\n");
157 if (get_size_and_cell(&mtu
, &Pcell_log
, *argv
) < 0) {
161 } else if (strcmp(*argv
, "mpu") == 0) {
164 fprintf(stderr
, "Double \"mpu\" spec\n");
167 if (get_size(&mpu
, *argv
)) {
171 } else if (strcmp(*argv
, "rate") == 0) {
174 fprintf(stderr
, "Double \"rate\" spec\n");
177 if (get_rate(&p
.rate
.rate
, *argv
)) {
181 } else if (strcmp(*argv
, "avrate") == 0) {
184 fprintf(stderr
, "Double \"avrate\" spec\n");
187 if (get_rate(&avrate
, *argv
)) {
191 } else if (matches(*argv
, "peakrate") == 0) {
193 if (p
.peakrate
.rate
) {
194 fprintf(stderr
, "Double \"peakrate\" spec\n");
197 if (get_rate(&p
.peakrate
.rate
, *argv
)) {
198 explain1("peakrate");
201 } else if (matches(*argv
, "reclassify") == 0) {
202 p
.action
= TC_POLICE_RECLASSIFY
;
203 } else if (matches(*argv
, "drop") == 0 ||
204 matches(*argv
, "shot") == 0) {
205 p
.action
= TC_POLICE_SHOT
;
206 } else if (matches(*argv
, "continue") == 0) {
207 p
.action
= TC_POLICE_UNSPEC
;
208 } else if (matches(*argv
, "pass") == 0) {
209 p
.action
= TC_POLICE_OK
;
210 } else if (strcmp(*argv
, "action") == 0) {
212 if (get_police_result(&p
.action
, &presult
, *argv
)) {
213 fprintf(stderr
, "Illegal \"action\"\n");
216 } else if (strcmp(*argv
, "help") == 0) {
229 if (p
.rate
.rate
&& !buffer
) {
230 fprintf(stderr
, "\"burst\" requires \"rate\".\n");
233 if (p
.peakrate
.rate
) {
235 fprintf(stderr
, "\"peakrate\" requires \"rate\".\n");
239 fprintf(stderr
, "\"mtu\" is required, if \"peakrate\" is requested.\n");
245 if ((Rcell_log
= tc_calc_rtable(p
.rate
.rate
, rtab
, Rcell_log
, mtu
, mpu
)) < 0) {
246 fprintf(stderr
, "TBF: failed to calculate rate table.\n");
249 p
.burst
= tc_calc_xmittime(p
.rate
.rate
, buffer
);
250 p
.rate
.cell_log
= Rcell_log
;
254 if (p
.peakrate
.rate
) {
255 if ((Pcell_log
= tc_calc_rtable(p
.peakrate
.rate
, ptab
, Pcell_log
, mtu
, mpu
)) < 0) {
256 fprintf(stderr
, "POLICE: failed to calculate peak rate table.\n");
259 p
.peakrate
.cell_log
= Pcell_log
;
260 p
.peakrate
.mpu
= mpu
;
263 tail
= (struct rtattr
*)(((void*)n
)+NLMSG_ALIGN(n
->nlmsg_len
));
264 addattr_l(n
, 1024, tca_id
, NULL
, 0);
265 addattr_l(n
, 2024, TCA_POLICE_TBF
, &p
, sizeof(p
));
267 addattr_l(n
, 3024, TCA_POLICE_RATE
, rtab
, 1024);
269 addattr_l(n
, 4096, TCA_POLICE_PEAKRATE
, ptab
, 1024);
271 addattr32(n
, 4096, TCA_POLICE_AVRATE
, avrate
);
273 addattr32(n
, 4096, TCA_POLICE_RESULT
, presult
);
277 tail
->rta_len
= (((void*)n
)+NLMSG_ALIGN(n
->nlmsg_len
)) - (void*)tail
;
286 int tc_print_police(FILE *f
, struct rtattr
*arg
)
290 struct rtattr
*tb
[TCA_POLICE_MAX
+1];
296 memset(tb
, 0, sizeof(tb
));
297 parse_rtattr(tb
, TCA_POLICE_MAX
, RTA_DATA(arg
), RTA_PAYLOAD(arg
));
299 if (tb
[TCA_POLICE_TBF
] == NULL
) {
300 fprintf(f
, "[NULL police tbf]");
303 if (RTA_PAYLOAD(tb
[TCA_POLICE_TBF
]) < sizeof(*p
)) {
304 fprintf(f
, "[truncated police tbf]");
307 p
= RTA_DATA(tb
[TCA_POLICE_TBF
]);
309 fprintf(f
, "police %x ", p
->index
);
310 fprintf(f
, "action %s", police_action_n2a(p
->action
, b1
, sizeof(b1
)));
311 if (tb
[TCA_POLICE_RESULT
]) {
312 fprintf(f
, "/%s ", police_action_n2a(*(int*)RTA_DATA(tb
[TCA_POLICE_RESULT
]), b1
, sizeof(b1
)));
315 fprintf(f
, "rate %s ", sprint_rate(p
->rate
.rate
, b1
));
316 buffer
= ((double)p
->rate
.rate
*tc_core_tick2usec(p
->burst
))/1000000;
317 fprintf(f
, "burst %s ", sprint_size(buffer
, b1
));
318 fprintf(f
, "mtu %s ", sprint_size(p
->mtu
, b1
));
320 fprintf(f
, "[%08x] ", p
->burst
);
321 if (p
->peakrate
.rate
)
322 fprintf(f
, "peakrate %s ", sprint_rate(p
->peakrate
.rate
, b1
));
323 if (tb
[TCA_POLICE_AVRATE
])
324 fprintf(f
, "avrate %s ", sprint_rate(*(__u32
*)RTA_DATA(tb
[TCA_POLICE_AVRATE
]), b1
));