2 * f_matchall.c Match-all Classifier
4 * This program is free software; you can distribute 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: Jiri Pirko <jiri@mellanox.com>, Yotam Gigi <yotamg@mellanox.com>
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
26 static void explain(void)
29 "Usage: ... matchall [skip_sw | skip_hw]\n"
30 " [ action ACTION_SPEC ] [ classid CLASSID ]\n"
32 "Where: SELECTOR := SAMPLE SAMPLE ...\n"
33 " FILTERID := X:Y:Z\n"
34 " ACTION_SPEC := ... look at individual actions\n"
36 "NOTE: CLASSID is parsed as hexadecimal input.\n");
39 static int matchall_parse_opt(struct filter_util
*qu
, char *handle
,
40 int argc
, char **argv
, struct nlmsghdr
*n
)
42 struct tcmsg
*t
= NLMSG_DATA(n
);
48 h
= strtol(handle
, NULL
, 0);
49 if (h
== LONG_MIN
|| h
== LONG_MAX
) {
50 fprintf(stderr
, "Illegal handle \"%s\", must be numeric.\n",
60 tail
= (struct rtattr
*)(((void *)n
)+NLMSG_ALIGN(n
->nlmsg_len
));
61 addattr_l(n
, MAX_MSG
, TCA_OPTIONS
, NULL
, 0);
64 if (matches(*argv
, "classid") == 0 ||
65 strcmp(*argv
, "flowid") == 0) {
69 if (get_tc_classid(&handle
, *argv
)) {
70 fprintf(stderr
, "Illegal \"classid\"\n");
73 addattr_l(n
, MAX_MSG
, TCA_MATCHALL_CLASSID
, &handle
, 4);
74 } else if (matches(*argv
, "action") == 0) {
76 if (parse_action(&argc
, &argv
, TCA_MATCHALL_ACT
, n
)) {
77 fprintf(stderr
, "Illegal \"action\"\n");
82 } else if (strcmp(*argv
, "skip_hw") == 0) {
84 flags
|= TCA_CLS_FLAGS_SKIP_HW
;
86 } else if (strcmp(*argv
, "skip_sw") == 0) {
88 flags
|= TCA_CLS_FLAGS_SKIP_SW
;
90 } else if (strcmp(*argv
, "help") == 0) {
94 fprintf(stderr
, "What is \"%s\"?\n", *argv
);
102 if (!(flags
^ (TCA_CLS_FLAGS_SKIP_HW
|
103 TCA_CLS_FLAGS_SKIP_SW
))) {
105 "skip_hw and skip_sw are mutually exclusive\n");
108 addattr_l(n
, MAX_MSG
, TCA_MATCHALL_FLAGS
, &flags
, 4);
111 tail
->rta_len
= (((void *)n
)+n
->nlmsg_len
) - (void *)tail
;
115 static int matchall_print_opt(struct filter_util
*qu
, FILE *f
,
116 struct rtattr
*opt
, __u32 handle
)
118 struct rtattr
*tb
[TCA_MATCHALL_MAX
+1];
119 struct tc_matchall_pcnt
*pf
= NULL
;
124 parse_rtattr_nested(tb
, TCA_MATCHALL_MAX
, opt
);
127 print_uint(PRINT_ANY
, "handle", "handle 0x%x ", handle
);
129 if (tb
[TCA_MATCHALL_CLASSID
]) {
131 print_string(PRINT_ANY
, "flowid", "flowid %s ",
132 sprint_tc_classid(rta_getattr_u32(tb
[TCA_MATCHALL_CLASSID
]), b1
));
135 if (tb
[TCA_MATCHALL_FLAGS
]) {
136 __u32 flags
= rta_getattr_u32(tb
[TCA_MATCHALL_FLAGS
]);
138 if (flags
& TCA_CLS_FLAGS_SKIP_HW
)
139 print_bool(PRINT_ANY
, "skip_hw", "\n skip_hw", true);
140 if (flags
& TCA_CLS_FLAGS_SKIP_SW
)
141 print_bool(PRINT_ANY
, "skip_sw", "\n skip_sw", true);
143 if (flags
& TCA_CLS_FLAGS_IN_HW
)
144 print_bool(PRINT_ANY
, "in_hw", "\n in_hw", true);
145 else if (flags
& TCA_CLS_FLAGS_NOT_IN_HW
)
146 print_bool(PRINT_ANY
, "not_in_hw", "\n not_in_hw", true);
149 if (tb
[TCA_MATCHALL_PCNT
]) {
150 if (RTA_PAYLOAD(tb
[TCA_MATCHALL_PCNT
]) < sizeof(*pf
)) {
151 print_string(PRINT_FP
, NULL
, "Broken perf counters\n", NULL
);
154 pf
= RTA_DATA(tb
[TCA_MATCHALL_PCNT
]);
157 if (show_stats
&& NULL
!= pf
)
158 print_u64(PRINT_ANY
, "rule_hit", " (rule hit %llu)",
159 (unsigned long long) pf
->rhit
);
162 if (tb
[TCA_MATCHALL_ACT
])
163 tc_print_action(f
, tb
[TCA_MATCHALL_ACT
], 0);
168 struct filter_util matchall_filter_util
= {
170 .parse_fopt
= matchall_parse_opt
,
171 .print_fopt
= matchall_print_opt
,