]> git.proxmox.com Git - mirror_iproute2.git/blob - tc/f_tcindex.c
Switch helpers tc_core_{time2ktime,ktime2time} from long to unsigned as well.
[mirror_iproute2.git] / tc / f_tcindex.c
1 /*
2 * f_tcindex.c Traffic control index filter
3 *
4 * Written 1998,1999 by Werner Almesberger
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <syslog.h>
11 #include <fcntl.h>
12 #include <string.h>
13 #include <netinet/in.h>
14
15 #include "utils.h"
16 #include "tc_util.h"
17
18 static void explain(void)
19 {
20 fprintf(stderr," Usage: ... tcindex [ hash SIZE ] [ mask MASK ]"
21 " [ shift SHIFT ]\n");
22 fprintf(stderr," [ pass_on | fall_through ]\n");
23 fprintf(stderr," [ classid CLASSID ] "
24 "[ police POLICE_SPEC ]\n");
25 }
26
27
28 #define usage() return(-1)
29
30
31 static int tcindex_parse_opt(struct filter_util *qu, char *handle, int argc,
32 char **argv, struct nlmsghdr *n)
33 {
34 struct tcmsg *t = NLMSG_DATA(n);
35 struct rtattr *tail;
36 char *end;
37
38 if (handle) {
39 t->tcm_handle = strtoul(handle,&end,0);
40 if (*end) {
41 fprintf(stderr, "Illegal filter ID\n");
42 return -1;
43 }
44 }
45 if (!argc) return 0;
46 tail = NLMSG_TAIL(n);
47 addattr_l(n,4096,TCA_OPTIONS,NULL,0);
48 while (argc) {
49 if (!strcmp(*argv,"hash")) {
50 int hash;
51
52 NEXT_ARG();
53 hash = strtoul(*argv,&end,0);
54 if (*end || !hash || hash > 0x10000) {
55 explain();
56 return -1;
57 }
58 addattr_l(n,4096,TCA_TCINDEX_HASH,&hash,sizeof(hash));
59 }
60 else if (!strcmp(*argv,"mask")) {
61 __u16 mask;
62
63 NEXT_ARG();
64 mask = strtoul(*argv,&end,0);
65 if (*end) {
66 explain();
67 return -1;
68 }
69 addattr_l(n,4096,TCA_TCINDEX_MASK,&mask,sizeof(mask));
70 }
71 else if (!strcmp(*argv,"shift")) {
72 int shift;
73
74 NEXT_ARG();
75 shift = strtoul(*argv,&end,0);
76 if (*end) {
77 explain();
78 return -1;
79 }
80 addattr_l(n,4096,TCA_TCINDEX_SHIFT,&shift,
81 sizeof(shift));
82 }
83 else if (!strcmp(*argv,"fall_through")) {
84 int value = 1;
85
86 addattr_l(n,4096,TCA_TCINDEX_FALL_THROUGH,&value,
87 sizeof(value));
88 }
89 else if (!strcmp(*argv,"pass_on")) {
90 int value = 0;
91
92 addattr_l(n,4096,TCA_TCINDEX_FALL_THROUGH,&value,
93 sizeof(value));
94 }
95 else if (!strcmp(*argv,"classid")) {
96 __u32 handle;
97
98 NEXT_ARG();
99 if (get_tc_classid(&handle,*argv)) {
100 fprintf(stderr, "Illegal \"classid\"\n");
101 return -1;
102 }
103 addattr_l(n, 4096, TCA_TCINDEX_CLASSID, &handle, 4);
104 }
105 else if (!strcmp(*argv,"police")) {
106 NEXT_ARG();
107 if (parse_police(&argc, &argv, TCA_TCINDEX_POLICE, n)) {
108 fprintf(stderr, "Illegal \"police\"\n");
109 return -1;
110 }
111 continue;
112 }
113 else {
114 explain();
115 return -1;
116 }
117 argc--;
118 argv++;
119 }
120 tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
121 return 0;
122 }
123
124
125 static int tcindex_print_opt(struct filter_util *qu, FILE *f,
126 struct rtattr *opt, __u32 handle)
127 {
128 struct rtattr *tb[TCA_TCINDEX_MAX+1];
129
130 if (opt == NULL)
131 return 0;
132
133 parse_rtattr_nested(tb, TCA_TCINDEX_MAX, opt);
134
135 if (handle != ~0) fprintf(f,"handle 0x%04x ",handle);
136 if (tb[TCA_TCINDEX_HASH]) {
137 __u16 hash;
138
139 if (RTA_PAYLOAD(tb[TCA_TCINDEX_HASH]) < sizeof(hash))
140 return -1;
141 hash = *(__u16 *) RTA_DATA(tb[TCA_TCINDEX_HASH]);
142 fprintf(f,"hash %d ",hash);
143 }
144 if (tb[TCA_TCINDEX_MASK]) {
145 __u16 mask;
146
147 if (RTA_PAYLOAD(tb[TCA_TCINDEX_MASK]) < sizeof(mask))
148 return -1;
149 mask = *(__u16 *) RTA_DATA(tb[TCA_TCINDEX_MASK]);
150 fprintf(f,"mask 0x%04x ",mask);
151 }
152 if (tb[TCA_TCINDEX_SHIFT]) {
153 int shift;
154
155 if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT]) < sizeof(shift))
156 return -1;
157 shift = *(int *) RTA_DATA(tb[TCA_TCINDEX_SHIFT]);
158 fprintf(f,"shift %d ",shift);
159 }
160 if (tb[TCA_TCINDEX_FALL_THROUGH]) {
161 int fall_through;
162
163 if (RTA_PAYLOAD(tb[TCA_TCINDEX_FALL_THROUGH]) <
164 sizeof(fall_through))
165 return -1;
166 fall_through = *(int *) RTA_DATA(tb[TCA_TCINDEX_FALL_THROUGH]);
167 fprintf(f,fall_through ? "fall_through " : "pass_on ");
168 }
169 if (tb[TCA_TCINDEX_CLASSID]) {
170 SPRINT_BUF(b1);
171 fprintf(f, "classid %s ",sprint_tc_classid(*(__u32 *)
172 RTA_DATA(tb[TCA_TCINDEX_CLASSID]), b1));
173 }
174 if (tb[TCA_TCINDEX_POLICE]) {
175 fprintf(f, "\n");
176 tc_print_police(f, tb[TCA_TCINDEX_POLICE]);
177 }
178 return 0;
179 }
180
181 struct filter_util tcindex_filter_util = {
182 .id = "tcindex",
183 .parse_fopt = tcindex_parse_opt,
184 .print_fopt = tcindex_print_opt,
185 };