1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker * m_police.c Parse/print policing module options.
3*de1e4e89SAndroid Build Coastguard Worker *
4*de1e4e89SAndroid Build Coastguard Worker * This program is free software; you can u32istribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker * modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker * as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker * 2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker *
9*de1e4e89SAndroid Build Coastguard Worker * Authors: Alexey Kuznetsov, <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker * FIXES: 19990619 - J Hadi Salim ([email protected])
11*de1e4e89SAndroid Build Coastguard Worker * simple addattr packaging fix.
12*de1e4e89SAndroid Build Coastguard Worker * 2002: J Hadi Salim - Add tc action extensions syntax
13*de1e4e89SAndroid Build Coastguard Worker *
14*de1e4e89SAndroid Build Coastguard Worker */
15*de1e4e89SAndroid Build Coastguard Worker
16*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <unistd.h>
19*de1e4e89SAndroid Build Coastguard Worker #include <syslog.h>
20*de1e4e89SAndroid Build Coastguard Worker #include <fcntl.h>
21*de1e4e89SAndroid Build Coastguard Worker #include <sys/socket.h>
22*de1e4e89SAndroid Build Coastguard Worker #include <netinet/in.h>
23*de1e4e89SAndroid Build Coastguard Worker #include <arpa/inet.h>
24*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
25*de1e4e89SAndroid Build Coastguard Worker
26*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
27*de1e4e89SAndroid Build Coastguard Worker #include "tc_util.h"
28*de1e4e89SAndroid Build Coastguard Worker
29*de1e4e89SAndroid Build Coastguard Worker struct action_util police_action_util = {
30*de1e4e89SAndroid Build Coastguard Worker .id = "police",
31*de1e4e89SAndroid Build Coastguard Worker .parse_aopt = act_parse_police,
32*de1e4e89SAndroid Build Coastguard Worker .print_aopt = print_police,
33*de1e4e89SAndroid Build Coastguard Worker };
34*de1e4e89SAndroid Build Coastguard Worker
usage(void)35*de1e4e89SAndroid Build Coastguard Worker static void usage(void)
36*de1e4e89SAndroid Build Coastguard Worker {
37*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Usage: ... police rate BPS burst BYTES[/BYTES] [ mtu BYTES[/BYTES] ]\n");
38*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, " [ peakrate BPS ] [ avrate BPS ] [ overhead BYTES ]\n");
39*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, " [ linklayer TYPE ] [ CONTROL ]\n");
40*de1e4e89SAndroid Build Coastguard Worker
41*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Where: CONTROL := conform-exceed <EXCEEDACT>[/NOTEXCEEDACT]\n");
42*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, " Define how to handle packets which exceed (<EXCEEDACT>)\n");
43*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, " or conform (<NOTEXCEEDACT>) the configured bandwidth limit.\n");
44*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, " EXCEEDACT/NOTEXCEEDACT := { pipe | ok | reclassify | drop | continue |\n");
45*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, " goto chain <CHAIN_INDEX> }\n");
46*de1e4e89SAndroid Build Coastguard Worker exit(-1);
47*de1e4e89SAndroid Build Coastguard Worker }
48*de1e4e89SAndroid Build Coastguard Worker
explain1(char * arg)49*de1e4e89SAndroid Build Coastguard Worker static void explain1(char *arg)
50*de1e4e89SAndroid Build Coastguard Worker {
51*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Illegal \"%s\"\n", arg);
52*de1e4e89SAndroid Build Coastguard Worker }
53*de1e4e89SAndroid Build Coastguard Worker
act_parse_police(struct action_util * a,int * argc_p,char *** argv_p,int tca_id,struct nlmsghdr * n)54*de1e4e89SAndroid Build Coastguard Worker int act_parse_police(struct action_util *a, int *argc_p, char ***argv_p,
55*de1e4e89SAndroid Build Coastguard Worker int tca_id, struct nlmsghdr *n)
56*de1e4e89SAndroid Build Coastguard Worker {
57*de1e4e89SAndroid Build Coastguard Worker int argc = *argc_p;
58*de1e4e89SAndroid Build Coastguard Worker char **argv = *argv_p;
59*de1e4e89SAndroid Build Coastguard Worker int res = -1;
60*de1e4e89SAndroid Build Coastguard Worker int ok = 0;
61*de1e4e89SAndroid Build Coastguard Worker struct tc_police p = { .action = TC_POLICE_RECLASSIFY };
62*de1e4e89SAndroid Build Coastguard Worker __u32 rtab[256];
63*de1e4e89SAndroid Build Coastguard Worker __u32 ptab[256];
64*de1e4e89SAndroid Build Coastguard Worker __u32 avrate = 0;
65*de1e4e89SAndroid Build Coastguard Worker int presult = 0;
66*de1e4e89SAndroid Build Coastguard Worker unsigned buffer = 0, mtu = 0, mpu = 0;
67*de1e4e89SAndroid Build Coastguard Worker unsigned short overhead = 0;
68*de1e4e89SAndroid Build Coastguard Worker unsigned int linklayer = LINKLAYER_ETHERNET; /* Assume ethernet */
69*de1e4e89SAndroid Build Coastguard Worker int Rcell_log = -1, Pcell_log = -1;
70*de1e4e89SAndroid Build Coastguard Worker struct rtattr *tail;
71*de1e4e89SAndroid Build Coastguard Worker
72*de1e4e89SAndroid Build Coastguard Worker if (a) /* new way of doing things */
73*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
74*de1e4e89SAndroid Build Coastguard Worker
75*de1e4e89SAndroid Build Coastguard Worker if (argc <= 0)
76*de1e4e89SAndroid Build Coastguard Worker return -1;
77*de1e4e89SAndroid Build Coastguard Worker
78*de1e4e89SAndroid Build Coastguard Worker while (argc > 0) {
79*de1e4e89SAndroid Build Coastguard Worker
80*de1e4e89SAndroid Build Coastguard Worker if (matches(*argv, "index") == 0) {
81*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
82*de1e4e89SAndroid Build Coastguard Worker if (get_u32(&p.index, *argv, 10)) {
83*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Illegal \"index\"\n");
84*de1e4e89SAndroid Build Coastguard Worker return -1;
85*de1e4e89SAndroid Build Coastguard Worker }
86*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "burst") == 0 ||
87*de1e4e89SAndroid Build Coastguard Worker strcmp(*argv, "buffer") == 0 ||
88*de1e4e89SAndroid Build Coastguard Worker strcmp(*argv, "maxburst") == 0) {
89*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
90*de1e4e89SAndroid Build Coastguard Worker if (buffer) {
91*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Double \"buffer/burst\" spec\n");
92*de1e4e89SAndroid Build Coastguard Worker return -1;
93*de1e4e89SAndroid Build Coastguard Worker }
94*de1e4e89SAndroid Build Coastguard Worker if (get_size_and_cell(&buffer, &Rcell_log, *argv) < 0) {
95*de1e4e89SAndroid Build Coastguard Worker explain1("buffer");
96*de1e4e89SAndroid Build Coastguard Worker return -1;
97*de1e4e89SAndroid Build Coastguard Worker }
98*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "mtu") == 0 ||
99*de1e4e89SAndroid Build Coastguard Worker strcmp(*argv, "minburst") == 0) {
100*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
101*de1e4e89SAndroid Build Coastguard Worker if (mtu) {
102*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Double \"mtu/minburst\" spec\n");
103*de1e4e89SAndroid Build Coastguard Worker return -1;
104*de1e4e89SAndroid Build Coastguard Worker }
105*de1e4e89SAndroid Build Coastguard Worker if (get_size_and_cell(&mtu, &Pcell_log, *argv) < 0) {
106*de1e4e89SAndroid Build Coastguard Worker explain1("mtu");
107*de1e4e89SAndroid Build Coastguard Worker return -1;
108*de1e4e89SAndroid Build Coastguard Worker }
109*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "mpu") == 0) {
110*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
111*de1e4e89SAndroid Build Coastguard Worker if (mpu) {
112*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Double \"mpu\" spec\n");
113*de1e4e89SAndroid Build Coastguard Worker return -1;
114*de1e4e89SAndroid Build Coastguard Worker }
115*de1e4e89SAndroid Build Coastguard Worker if (get_size(&mpu, *argv)) {
116*de1e4e89SAndroid Build Coastguard Worker explain1("mpu");
117*de1e4e89SAndroid Build Coastguard Worker return -1;
118*de1e4e89SAndroid Build Coastguard Worker }
119*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "rate") == 0) {
120*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
121*de1e4e89SAndroid Build Coastguard Worker if (p.rate.rate) {
122*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Double \"rate\" spec\n");
123*de1e4e89SAndroid Build Coastguard Worker return -1;
124*de1e4e89SAndroid Build Coastguard Worker }
125*de1e4e89SAndroid Build Coastguard Worker if (get_rate(&p.rate.rate, *argv)) {
126*de1e4e89SAndroid Build Coastguard Worker explain1("rate");
127*de1e4e89SAndroid Build Coastguard Worker return -1;
128*de1e4e89SAndroid Build Coastguard Worker }
129*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "avrate") == 0) {
130*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
131*de1e4e89SAndroid Build Coastguard Worker if (avrate) {
132*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Double \"avrate\" spec\n");
133*de1e4e89SAndroid Build Coastguard Worker return -1;
134*de1e4e89SAndroid Build Coastguard Worker }
135*de1e4e89SAndroid Build Coastguard Worker if (get_rate(&avrate, *argv)) {
136*de1e4e89SAndroid Build Coastguard Worker explain1("avrate");
137*de1e4e89SAndroid Build Coastguard Worker return -1;
138*de1e4e89SAndroid Build Coastguard Worker }
139*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "peakrate") == 0) {
140*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
141*de1e4e89SAndroid Build Coastguard Worker if (p.peakrate.rate) {
142*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Double \"peakrate\" spec\n");
143*de1e4e89SAndroid Build Coastguard Worker return -1;
144*de1e4e89SAndroid Build Coastguard Worker }
145*de1e4e89SAndroid Build Coastguard Worker if (get_rate(&p.peakrate.rate, *argv)) {
146*de1e4e89SAndroid Build Coastguard Worker explain1("peakrate");
147*de1e4e89SAndroid Build Coastguard Worker return -1;
148*de1e4e89SAndroid Build Coastguard Worker }
149*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "reclassify") == 0 ||
150*de1e4e89SAndroid Build Coastguard Worker matches(*argv, "drop") == 0 ||
151*de1e4e89SAndroid Build Coastguard Worker matches(*argv, "shot") == 0 ||
152*de1e4e89SAndroid Build Coastguard Worker matches(*argv, "continue") == 0 ||
153*de1e4e89SAndroid Build Coastguard Worker matches(*argv, "pass") == 0 ||
154*de1e4e89SAndroid Build Coastguard Worker matches(*argv, "pipe") == 0 ||
155*de1e4e89SAndroid Build Coastguard Worker matches(*argv, "goto") == 0) {
156*de1e4e89SAndroid Build Coastguard Worker if (parse_action_control(&argc, &argv, &p.action, false))
157*de1e4e89SAndroid Build Coastguard Worker return -1;
158*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "conform-exceed") == 0) {
159*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
160*de1e4e89SAndroid Build Coastguard Worker if (parse_action_control_slash(&argc, &argv, &p.action,
161*de1e4e89SAndroid Build Coastguard Worker &presult, true))
162*de1e4e89SAndroid Build Coastguard Worker return -1;
163*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "overhead") == 0) {
164*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
165*de1e4e89SAndroid Build Coastguard Worker if (get_u16(&overhead, *argv, 10)) {
166*de1e4e89SAndroid Build Coastguard Worker explain1("overhead"); return -1;
167*de1e4e89SAndroid Build Coastguard Worker }
168*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "linklayer") == 0) {
169*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
170*de1e4e89SAndroid Build Coastguard Worker if (get_linklayer(&linklayer, *argv)) {
171*de1e4e89SAndroid Build Coastguard Worker explain1("linklayer"); return -1;
172*de1e4e89SAndroid Build Coastguard Worker }
173*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "help") == 0) {
174*de1e4e89SAndroid Build Coastguard Worker usage();
175*de1e4e89SAndroid Build Coastguard Worker } else {
176*de1e4e89SAndroid Build Coastguard Worker break;
177*de1e4e89SAndroid Build Coastguard Worker }
178*de1e4e89SAndroid Build Coastguard Worker ok++;
179*de1e4e89SAndroid Build Coastguard Worker argc--; argv++;
180*de1e4e89SAndroid Build Coastguard Worker }
181*de1e4e89SAndroid Build Coastguard Worker
182*de1e4e89SAndroid Build Coastguard Worker if (!ok)
183*de1e4e89SAndroid Build Coastguard Worker return -1;
184*de1e4e89SAndroid Build Coastguard Worker
185*de1e4e89SAndroid Build Coastguard Worker if (p.rate.rate && avrate)
186*de1e4e89SAndroid Build Coastguard Worker return -1;
187*de1e4e89SAndroid Build Coastguard Worker
188*de1e4e89SAndroid Build Coastguard Worker /* Must at least do late binding, use TB or ewma policing */
189*de1e4e89SAndroid Build Coastguard Worker if (!p.rate.rate && !avrate && !p.index) {
190*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\"rate\" or \"avrate\" MUST be specified.\n");
191*de1e4e89SAndroid Build Coastguard Worker return -1;
192*de1e4e89SAndroid Build Coastguard Worker }
193*de1e4e89SAndroid Build Coastguard Worker
194*de1e4e89SAndroid Build Coastguard Worker /* When the TB policer is used, burst is required */
195*de1e4e89SAndroid Build Coastguard Worker if (p.rate.rate && !buffer && !avrate) {
196*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\"burst\" requires \"rate\".\n");
197*de1e4e89SAndroid Build Coastguard Worker return -1;
198*de1e4e89SAndroid Build Coastguard Worker }
199*de1e4e89SAndroid Build Coastguard Worker
200*de1e4e89SAndroid Build Coastguard Worker if (p.peakrate.rate) {
201*de1e4e89SAndroid Build Coastguard Worker if (!p.rate.rate) {
202*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\"peakrate\" requires \"rate\".\n");
203*de1e4e89SAndroid Build Coastguard Worker return -1;
204*de1e4e89SAndroid Build Coastguard Worker }
205*de1e4e89SAndroid Build Coastguard Worker if (!mtu) {
206*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "\"mtu\" is required, if \"peakrate\" is requested.\n");
207*de1e4e89SAndroid Build Coastguard Worker return -1;
208*de1e4e89SAndroid Build Coastguard Worker }
209*de1e4e89SAndroid Build Coastguard Worker }
210*de1e4e89SAndroid Build Coastguard Worker
211*de1e4e89SAndroid Build Coastguard Worker if (p.rate.rate) {
212*de1e4e89SAndroid Build Coastguard Worker p.rate.mpu = mpu;
213*de1e4e89SAndroid Build Coastguard Worker p.rate.overhead = overhead;
214*de1e4e89SAndroid Build Coastguard Worker if (tc_calc_rtable(&p.rate, rtab, Rcell_log, mtu,
215*de1e4e89SAndroid Build Coastguard Worker linklayer) < 0) {
216*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "POLICE: failed to calculate rate table.\n");
217*de1e4e89SAndroid Build Coastguard Worker return -1;
218*de1e4e89SAndroid Build Coastguard Worker }
219*de1e4e89SAndroid Build Coastguard Worker p.burst = tc_calc_xmittime(p.rate.rate, buffer);
220*de1e4e89SAndroid Build Coastguard Worker }
221*de1e4e89SAndroid Build Coastguard Worker p.mtu = mtu;
222*de1e4e89SAndroid Build Coastguard Worker if (p.peakrate.rate) {
223*de1e4e89SAndroid Build Coastguard Worker p.peakrate.mpu = mpu;
224*de1e4e89SAndroid Build Coastguard Worker p.peakrate.overhead = overhead;
225*de1e4e89SAndroid Build Coastguard Worker if (tc_calc_rtable(&p.peakrate, ptab, Pcell_log, mtu,
226*de1e4e89SAndroid Build Coastguard Worker linklayer) < 0) {
227*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "POLICE: failed to calculate peak rate table.\n");
228*de1e4e89SAndroid Build Coastguard Worker return -1;
229*de1e4e89SAndroid Build Coastguard Worker }
230*de1e4e89SAndroid Build Coastguard Worker }
231*de1e4e89SAndroid Build Coastguard Worker
232*de1e4e89SAndroid Build Coastguard Worker tail = NLMSG_TAIL(n);
233*de1e4e89SAndroid Build Coastguard Worker addattr_l(n, MAX_MSG, tca_id, NULL, 0);
234*de1e4e89SAndroid Build Coastguard Worker addattr_l(n, MAX_MSG, TCA_POLICE_TBF, &p, sizeof(p));
235*de1e4e89SAndroid Build Coastguard Worker if (p.rate.rate)
236*de1e4e89SAndroid Build Coastguard Worker addattr_l(n, MAX_MSG, TCA_POLICE_RATE, rtab, 1024);
237*de1e4e89SAndroid Build Coastguard Worker if (p.peakrate.rate)
238*de1e4e89SAndroid Build Coastguard Worker addattr_l(n, MAX_MSG, TCA_POLICE_PEAKRATE, ptab, 1024);
239*de1e4e89SAndroid Build Coastguard Worker if (avrate)
240*de1e4e89SAndroid Build Coastguard Worker addattr32(n, MAX_MSG, TCA_POLICE_AVRATE, avrate);
241*de1e4e89SAndroid Build Coastguard Worker if (presult)
242*de1e4e89SAndroid Build Coastguard Worker addattr32(n, MAX_MSG, TCA_POLICE_RESULT, presult);
243*de1e4e89SAndroid Build Coastguard Worker
244*de1e4e89SAndroid Build Coastguard Worker tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
245*de1e4e89SAndroid Build Coastguard Worker res = 0;
246*de1e4e89SAndroid Build Coastguard Worker
247*de1e4e89SAndroid Build Coastguard Worker *argc_p = argc;
248*de1e4e89SAndroid Build Coastguard Worker *argv_p = argv;
249*de1e4e89SAndroid Build Coastguard Worker return res;
250*de1e4e89SAndroid Build Coastguard Worker }
251*de1e4e89SAndroid Build Coastguard Worker
parse_police(int * argc_p,char *** argv_p,int tca_id,struct nlmsghdr * n)252*de1e4e89SAndroid Build Coastguard Worker int parse_police(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n)
253*de1e4e89SAndroid Build Coastguard Worker {
254*de1e4e89SAndroid Build Coastguard Worker return act_parse_police(NULL, argc_p, argv_p, tca_id, n);
255*de1e4e89SAndroid Build Coastguard Worker }
256*de1e4e89SAndroid Build Coastguard Worker
print_police(struct action_util * a,FILE * f,struct rtattr * arg)257*de1e4e89SAndroid Build Coastguard Worker int print_police(struct action_util *a, FILE *f, struct rtattr *arg)
258*de1e4e89SAndroid Build Coastguard Worker {
259*de1e4e89SAndroid Build Coastguard Worker SPRINT_BUF(b1);
260*de1e4e89SAndroid Build Coastguard Worker SPRINT_BUF(b2);
261*de1e4e89SAndroid Build Coastguard Worker struct tc_police *p;
262*de1e4e89SAndroid Build Coastguard Worker struct rtattr *tb[TCA_POLICE_MAX+1];
263*de1e4e89SAndroid Build Coastguard Worker unsigned int buffer;
264*de1e4e89SAndroid Build Coastguard Worker unsigned int linklayer;
265*de1e4e89SAndroid Build Coastguard Worker
266*de1e4e89SAndroid Build Coastguard Worker if (arg == NULL)
267*de1e4e89SAndroid Build Coastguard Worker return 0;
268*de1e4e89SAndroid Build Coastguard Worker
269*de1e4e89SAndroid Build Coastguard Worker parse_rtattr_nested(tb, TCA_POLICE_MAX, arg);
270*de1e4e89SAndroid Build Coastguard Worker
271*de1e4e89SAndroid Build Coastguard Worker if (tb[TCA_POLICE_TBF] == NULL) {
272*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "[NULL police tbf]");
273*de1e4e89SAndroid Build Coastguard Worker return 0;
274*de1e4e89SAndroid Build Coastguard Worker }
275*de1e4e89SAndroid Build Coastguard Worker #ifndef STOOPID_8BYTE
276*de1e4e89SAndroid Build Coastguard Worker if (RTA_PAYLOAD(tb[TCA_POLICE_TBF]) < sizeof(*p)) {
277*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "[truncated police tbf]");
278*de1e4e89SAndroid Build Coastguard Worker return -1;
279*de1e4e89SAndroid Build Coastguard Worker }
280*de1e4e89SAndroid Build Coastguard Worker #endif
281*de1e4e89SAndroid Build Coastguard Worker p = RTA_DATA(tb[TCA_POLICE_TBF]);
282*de1e4e89SAndroid Build Coastguard Worker
283*de1e4e89SAndroid Build Coastguard Worker fprintf(f, " police 0x%x ", p->index);
284*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "rate %s ", sprint_rate(p->rate.rate, b1));
285*de1e4e89SAndroid Build Coastguard Worker buffer = tc_calc_xmitsize(p->rate.rate, p->burst);
286*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "burst %s ", sprint_size(buffer, b1));
287*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "mtu %s ", sprint_size(p->mtu, b1));
288*de1e4e89SAndroid Build Coastguard Worker if (show_raw)
289*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "[%08x] ", p->burst);
290*de1e4e89SAndroid Build Coastguard Worker
291*de1e4e89SAndroid Build Coastguard Worker if (p->peakrate.rate)
292*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "peakrate %s ", sprint_rate(p->peakrate.rate, b1));
293*de1e4e89SAndroid Build Coastguard Worker
294*de1e4e89SAndroid Build Coastguard Worker if (tb[TCA_POLICE_AVRATE])
295*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "avrate %s ",
296*de1e4e89SAndroid Build Coastguard Worker sprint_rate(rta_getattr_u32(tb[TCA_POLICE_AVRATE]),
297*de1e4e89SAndroid Build Coastguard Worker b1));
298*de1e4e89SAndroid Build Coastguard Worker
299*de1e4e89SAndroid Build Coastguard Worker print_action_control(f, "action ", p->action, "");
300*de1e4e89SAndroid Build Coastguard Worker
301*de1e4e89SAndroid Build Coastguard Worker if (tb[TCA_POLICE_RESULT]) {
302*de1e4e89SAndroid Build Coastguard Worker __u32 action = rta_getattr_u32(tb[TCA_POLICE_RESULT]);
303*de1e4e89SAndroid Build Coastguard Worker
304*de1e4e89SAndroid Build Coastguard Worker print_action_control(f, "/", action, " ");
305*de1e4e89SAndroid Build Coastguard Worker } else
306*de1e4e89SAndroid Build Coastguard Worker fprintf(f, " ");
307*de1e4e89SAndroid Build Coastguard Worker
308*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "overhead %ub ", p->rate.overhead);
309*de1e4e89SAndroid Build Coastguard Worker linklayer = (p->rate.linklayer & TC_LINKLAYER_MASK);
310*de1e4e89SAndroid Build Coastguard Worker if (linklayer > TC_LINKLAYER_ETHERNET || show_details)
311*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "linklayer %s ", sprint_linklayer(linklayer, b2));
312*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "\n\tref %d bind %d", p->refcnt, p->bindcnt);
313*de1e4e89SAndroid Build Coastguard Worker if (show_stats) {
314*de1e4e89SAndroid Build Coastguard Worker if (tb[TCA_POLICE_TM]) {
315*de1e4e89SAndroid Build Coastguard Worker struct tcf_t *tm = RTA_DATA(tb[TCA_POLICE_TM]);
316*de1e4e89SAndroid Build Coastguard Worker
317*de1e4e89SAndroid Build Coastguard Worker print_tm(f, tm);
318*de1e4e89SAndroid Build Coastguard Worker }
319*de1e4e89SAndroid Build Coastguard Worker }
320*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "\n");
321*de1e4e89SAndroid Build Coastguard Worker
322*de1e4e89SAndroid Build Coastguard Worker
323*de1e4e89SAndroid Build Coastguard Worker return 0;
324*de1e4e89SAndroid Build Coastguard Worker }
325*de1e4e89SAndroid Build Coastguard Worker
tc_print_police(FILE * f,struct rtattr * arg)326*de1e4e89SAndroid Build Coastguard Worker int tc_print_police(FILE *f, struct rtattr *arg)
327*de1e4e89SAndroid Build Coastguard Worker {
328*de1e4e89SAndroid Build Coastguard Worker return print_police(&police_action_util, f, arg);
329*de1e4e89SAndroid Build Coastguard Worker }
330