1 /* SPDX-License-Identifier: GPL-2.0 */
3 * f_tcindex.c Traffic control index filter
5 * 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 ] [ shift SHIFT ]\n");
21 fprintf(stderr
, " [ pass_on | fall_through ]\n");
22 fprintf(stderr
," [ classid CLASSID ] [ action ACTION_SPEC ]\n");
25 static int tcindex_parse_opt(struct filter_util
*qu
, char *handle
, int argc
,
26 char **argv
, struct nlmsghdr
*n
)
28 struct tcmsg
*t
= NLMSG_DATA(n
);
33 t
->tcm_handle
= strtoul(handle
, &end
, 0);
35 fprintf(stderr
, "Illegal filter ID\n");
40 tail
= addattr_nest(n
, 4096, TCA_OPTIONS
);
42 if (!strcmp(*argv
, "hash")) {
46 hash
= strtoul(*argv
, &end
, 0);
47 if (*end
|| !hash
|| hash
> 0x10000) {
51 addattr_l(n
, 4096, TCA_TCINDEX_HASH
, &hash
,
53 } else if (!strcmp(*argv
,"mask")) {
57 mask
= strtoul(*argv
, &end
, 0);
62 addattr_l(n
, 4096, TCA_TCINDEX_MASK
, &mask
,
64 } else if (!strcmp(*argv
,"shift")) {
68 shift
= strtoul(*argv
, &end
, 0);
73 addattr_l(n
, 4096, TCA_TCINDEX_SHIFT
, &shift
,
75 } else if (!strcmp(*argv
,"fall_through")) {
78 addattr_l(n
, 4096, TCA_TCINDEX_FALL_THROUGH
, &value
,
80 } else if (!strcmp(*argv
,"pass_on")) {
83 addattr_l(n
, 4096, TCA_TCINDEX_FALL_THROUGH
, &value
,
85 } else if (!strcmp(*argv
,"classid")) {
89 if (get_tc_classid(&handle
, *argv
)) {
90 fprintf(stderr
, "Illegal \"classid\"\n");
93 addattr_l(n
, 4096, TCA_TCINDEX_CLASSID
, &handle
, 4);
94 } else if (!strcmp(*argv
,"police")) {
96 if (parse_police(&argc
, &argv
, TCA_TCINDEX_POLICE
, n
)) {
97 fprintf(stderr
, "Illegal \"police\"\n");
101 } else if (!strcmp(*argv
,"action")) {
103 if (parse_action(&argc
, &argv
, TCA_TCINDEX_ACT
, n
)) {
104 fprintf(stderr
, "Illegal \"action\"\n");
115 addattr_nest_end(n
, tail
);
120 static int tcindex_print_opt(struct filter_util
*qu
, FILE *f
,
121 struct rtattr
*opt
, __u32 handle
)
123 struct rtattr
*tb
[TCA_TCINDEX_MAX
+1];
128 parse_rtattr_nested(tb
, TCA_TCINDEX_MAX
, opt
);
130 if (handle
!= ~0) fprintf(f
, "handle 0x%04x ", handle
);
131 if (tb
[TCA_TCINDEX_HASH
]) {
134 if (RTA_PAYLOAD(tb
[TCA_TCINDEX_HASH
]) < sizeof(hash
))
136 hash
= rta_getattr_u16(tb
[TCA_TCINDEX_HASH
]);
137 fprintf(f
, "hash %d ", hash
);
139 if (tb
[TCA_TCINDEX_MASK
]) {
142 if (RTA_PAYLOAD(tb
[TCA_TCINDEX_MASK
]) < sizeof(mask
))
144 mask
= rta_getattr_u16(tb
[TCA_TCINDEX_MASK
]);
145 fprintf(f
, "mask 0x%04x ", mask
);
147 if (tb
[TCA_TCINDEX_SHIFT
]) {
150 if (RTA_PAYLOAD(tb
[TCA_TCINDEX_SHIFT
]) < sizeof(shift
))
152 shift
= rta_getattr_u32(tb
[TCA_TCINDEX_SHIFT
]);
153 fprintf(f
, "shift %d ", shift
);
155 if (tb
[TCA_TCINDEX_FALL_THROUGH
]) {
158 if (RTA_PAYLOAD(tb
[TCA_TCINDEX_FALL_THROUGH
]) <
159 sizeof(fall_through
))
161 fall_through
= rta_getattr_u32(tb
[TCA_TCINDEX_FALL_THROUGH
]);
162 fprintf(f
, fall_through
? "fall_through " : "pass_on ");
164 if (tb
[TCA_TCINDEX_CLASSID
]) {
166 fprintf(f
, "classid %s ", sprint_tc_classid(*(__u32
*)
167 RTA_DATA(tb
[TCA_TCINDEX_CLASSID
]), b1
));
169 if (tb
[TCA_TCINDEX_POLICE
]) {
171 tc_print_police(f
, tb
[TCA_TCINDEX_POLICE
]);
173 if (tb
[TCA_TCINDEX_ACT
]) {
175 tc_print_action(f
, tb
[TCA_TCINDEX_ACT
], 0);
180 struct filter_util tcindex_filter_util
= {
182 .parse_fopt
= tcindex_parse_opt
,
183 .print_fopt
= tcindex_print_opt
,