usbmodeswitch: Updated to v.1.2.6 from shibby's branch.
[tomato.git] / release / src / router / iproute2 / tc / q_esfq.c
blobb37546a7350b295e2091b7033941184a1b4b5340
1 /*
2 * q_esfq.c ESFQ.
4 * This program is free software; you can redistribute 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>
11 * Changes: Alexander Atanasov, <alex@ssi.bg>
12 * Alexander Clouter, <alex@digriz.org.uk>
13 * Corey Hickey, <bugfood-c@fatooh.org>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <syslog.h>
21 #include <fcntl.h>
22 #include <math.h>
23 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
26 #include <string.h>
28 #include "utils.h"
29 #include "tc_util.h"
31 static void explain(void)
33 fprintf(stderr, "Usage: ... esfq [ perturb SECS ] [ quantum BYTES ] [ depth FLOWS ]\n\t[ divisor HASHBITS ] [ limit PKTS ] [ hash HASHTYPE]\n");
34 fprintf(stderr,"Where: \n");
35 fprintf(stderr,"HASHTYPE := { classic | src | dst | fwmark | ctorigdst | ctorigsrc | ctrepldst | ctreplsrc | ctnatchg }\n");
38 static void explain1(char *arg)
40 fprintf(stderr, "Illegal \"%s\"\n", arg);
41 explain();
44 #define usage() return(-1)
46 static int esfq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
48 int ok=0;
49 struct tc_esfq_qopt opt;
51 memset(&opt, 0, sizeof(opt));
53 opt.hash_kind= TCA_SFQ_HASH_CLASSIC;
55 while (argc > 0) {
56 if (strcmp(*argv, "quantum") == 0) {
57 NEXT_ARG();
58 if (get_size(&opt.quantum, *argv)) {
59 explain1("quantum"); return -1;
61 ok++;
62 } else if (strcmp(*argv, "perturb") == 0) {
63 NEXT_ARG();
64 if (get_integer(&opt.perturb_period, *argv, 0)) {
65 explain1("perturb"); return -1;
67 ok++;
68 } else if (strcmp(*argv, "depth") == 0) {
69 NEXT_ARG();
70 if (get_integer((int *) &opt.flows, *argv, 0)) {
71 explain1("depth"); return -1;
73 ok++;
74 } else if (strcmp(*argv, "divisor") == 0) {
75 NEXT_ARG();
76 if (get_integer((int *) &opt.divisor, *argv, 0)) {
77 explain1("divisor"); return -1;
79 if(opt.divisor >= 14) {
80 fprintf(stderr, "Illegal \"divisor\": must be < 14\n");
81 return -1;
83 opt.divisor=pow(2,opt.divisor);
84 ok++;
85 } else if (strcmp(*argv, "limit") == 0) {
86 NEXT_ARG();
87 if (get_integer((int *) &opt.limit, *argv, 0)) {
88 explain1("limit"); return -1;
90 ok++;
91 } else if (strcmp(*argv, "hash") == 0) {
92 NEXT_ARG();
93 if(strcmp(*argv, "classic") == 0) {
94 opt.hash_kind= TCA_SFQ_HASH_CLASSIC;
95 } else
96 if(strcmp(*argv, "dst") == 0) {
97 opt.hash_kind= TCA_SFQ_HASH_DST;
98 } else
99 if(strcmp(*argv, "src") == 0) {
100 opt.hash_kind= TCA_SFQ_HASH_SRC;
101 } else
102 if(strcmp(*argv, "fwmark") == 0) {
103 opt.hash_kind= TCA_SFQ_HASH_FWMARK;
104 } else
105 if(strcmp(*argv, "ctorigsrc") == 0) {
106 opt.hash_kind= TCA_SFQ_HASH_CTORIGSRC;
107 } else
108 if(strcmp(*argv, "ctorigdst") == 0) {
109 opt.hash_kind= TCA_SFQ_HASH_CTORIGDST;
110 } else
111 if(strcmp(*argv, "ctreplsrc") == 0) {
112 opt.hash_kind= TCA_SFQ_HASH_CTREPLSRC;
113 } else
114 if(strcmp(*argv, "ctrepldst") == 0) {
115 opt.hash_kind= TCA_SFQ_HASH_CTREPLDST;
116 } else
117 if(strcmp(*argv, "ctnatchg") == 0) {
118 opt.hash_kind= TCA_SFQ_HASH_CTNATCHG;
119 } else {
120 explain1("hash"); return -1;
122 ok++;
123 } else if (strcmp(*argv, "help") == 0) {
124 explain();
125 return -1;
126 } else {
127 fprintf(stderr, "What is \"%s\"?\n", *argv);
128 explain();
129 return -1;
131 argc--; argv++;
134 if (ok)
135 addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt));
136 return 0;
139 static int esfq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
141 struct tc_esfq_qopt *qopt;
142 SPRINT_BUF(b1);
144 if (opt == NULL)
145 return 0;
147 if (RTA_PAYLOAD(opt) < sizeof(*qopt))
148 return -1;
149 qopt = RTA_DATA(opt);
150 fprintf(f, "quantum %s ", sprint_size(qopt->quantum, b1));
151 if (show_details) {
152 fprintf(f, "limit %up flows %u/%u ",
153 qopt->limit, qopt->flows, qopt->divisor);
155 if (qopt->perturb_period)
156 fprintf(f, "perturb %dsec ", qopt->perturb_period);
158 fprintf(f,"hash: ");
159 switch(qopt->hash_kind)
161 case TCA_SFQ_HASH_CLASSIC:
162 fprintf(f,"classic");
163 break;
164 case TCA_SFQ_HASH_DST:
165 fprintf(f,"dst");
166 break;
167 case TCA_SFQ_HASH_SRC:
168 fprintf(f,"src");
169 break;
170 case TCA_SFQ_HASH_FWMARK:
171 fprintf(f,"fwmark");
172 break;
173 case TCA_SFQ_HASH_CTORIGSRC:
174 fprintf(f,"ctorigsrc");
175 break;
176 case TCA_SFQ_HASH_CTORIGDST:
177 fprintf(f,"ctorigdst");
178 break;
179 case TCA_SFQ_HASH_CTREPLSRC:
180 fprintf(f,"ctreplsrc");
181 break;
182 case TCA_SFQ_HASH_CTREPLDST:
183 fprintf(f,"ctrepldst");
184 break;
185 case TCA_SFQ_HASH_CTNATCHG:
186 fprintf(f,"ctnatchg");
187 break;
188 default:
189 fprintf(f,"Unknown");
191 return 0;
194 static int esfq_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats)
196 return 0;
200 struct qdisc_util esfq_util = {
201 NULL,
202 "esfq",
203 esfq_parse_opt,
204 esfq_print_opt,
205 esfq_print_xstats,