2 * f_tcindex.c Traffic control index filter
4 * Written 1998,1999 by Werner Almesberger
13 #include <netinet/in.h>
18 static void explain(void)
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");
28 #define usage() return(-1)
31 static int tcindex_parse_opt(struct filter_util
*qu
, char *handle
, int argc
,
32 char **argv
, struct nlmsghdr
*n
)
34 struct tcmsg
*t
= NLMSG_DATA(n
);
39 t
->tcm_handle
= strtoul(handle
,&end
,0);
41 fprintf(stderr
, "Illegal filter ID\n");
47 addattr_l(n
,4096,TCA_OPTIONS
,NULL
,0);
49 if (!strcmp(*argv
,"hash")) {
53 hash
= strtoul(*argv
,&end
,0);
54 if (*end
|| !hash
|| hash
> 0x10000) {
58 addattr_l(n
,4096,TCA_TCINDEX_HASH
,&hash
,sizeof(hash
));
60 else if (!strcmp(*argv
,"mask")) {
64 mask
= strtoul(*argv
,&end
,0);
69 addattr_l(n
,4096,TCA_TCINDEX_MASK
,&mask
,sizeof(mask
));
71 else if (!strcmp(*argv
,"shift")) {
75 shift
= strtoul(*argv
,&end
,0);
80 addattr_l(n
,4096,TCA_TCINDEX_SHIFT
,&shift
,
83 else if (!strcmp(*argv
,"fall_through")) {
86 addattr_l(n
,4096,TCA_TCINDEX_FALL_THROUGH
,&value
,
89 else if (!strcmp(*argv
,"pass_on")) {
92 addattr_l(n
,4096,TCA_TCINDEX_FALL_THROUGH
,&value
,
95 else if (!strcmp(*argv
,"classid")) {
99 if (get_tc_classid(&handle
,*argv
)) {
100 fprintf(stderr
, "Illegal \"classid\"\n");
103 addattr_l(n
, 4096, TCA_TCINDEX_CLASSID
, &handle
, 4);
105 else if (!strcmp(*argv
,"police")) {
107 if (parse_police(&argc
, &argv
, TCA_TCINDEX_POLICE
, n
)) {
108 fprintf(stderr
, "Illegal \"police\"\n");
120 tail
->rta_len
= (void *) NLMSG_TAIL(n
) - (void *) tail
;
125 static int tcindex_print_opt(struct filter_util
*qu
, FILE *f
,
126 struct rtattr
*opt
, __u32 handle
)
128 struct rtattr
*tb
[TCA_TCINDEX_MAX
+1];
133 parse_rtattr_nested(tb
, TCA_TCINDEX_MAX
, opt
);
135 if (handle
!= ~0) fprintf(f
,"handle 0x%04x ",handle
);
136 if (tb
[TCA_TCINDEX_HASH
]) {
139 if (RTA_PAYLOAD(tb
[TCA_TCINDEX_HASH
]) < sizeof(hash
))
141 hash
= *(__u16
*) RTA_DATA(tb
[TCA_TCINDEX_HASH
]);
142 fprintf(f
,"hash %d ",hash
);
144 if (tb
[TCA_TCINDEX_MASK
]) {
147 if (RTA_PAYLOAD(tb
[TCA_TCINDEX_MASK
]) < sizeof(mask
))
149 mask
= *(__u16
*) RTA_DATA(tb
[TCA_TCINDEX_MASK
]);
150 fprintf(f
,"mask 0x%04x ",mask
);
152 if (tb
[TCA_TCINDEX_SHIFT
]) {
155 if (RTA_PAYLOAD(tb
[TCA_TCINDEX_SHIFT
]) < sizeof(shift
))
157 shift
= *(int *) RTA_DATA(tb
[TCA_TCINDEX_SHIFT
]);
158 fprintf(f
,"shift %d ",shift
);
160 if (tb
[TCA_TCINDEX_FALL_THROUGH
]) {
163 if (RTA_PAYLOAD(tb
[TCA_TCINDEX_FALL_THROUGH
]) <
164 sizeof(fall_through
))
166 fall_through
= *(int *) RTA_DATA(tb
[TCA_TCINDEX_FALL_THROUGH
]);
167 fprintf(f
,fall_through
? "fall_through " : "pass_on ");
169 if (tb
[TCA_TCINDEX_CLASSID
]) {
171 fprintf(f
, "classid %s ",sprint_tc_classid(*(__u32
*)
172 RTA_DATA(tb
[TCA_TCINDEX_CLASSID
]), b1
));
174 if (tb
[TCA_TCINDEX_POLICE
]) {
176 tc_print_police(f
, tb
[TCA_TCINDEX_POLICE
]);
181 struct filter_util tcindex_filter_util
= {
183 .parse_fopt
= tcindex_parse_opt
,
184 .print_fopt
= tcindex_print_opt
,