forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/tools/bpf/bpftool/cgroup.c
....@@ -1,4 +1,4 @@
1
-// SPDX-License-Identifier: GPL-2.0+
1
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
22 // Copyright (C) 2017 Facebook
33 // Author: Roman Gushchin <guro@fb.com>
44
....@@ -14,7 +14,7 @@
1414 #include <sys/types.h>
1515 #include <unistd.h>
1616
17
-#include <bpf.h>
17
+#include <bpf/bpf.h>
1818
1919 #include "main.h"
2020
....@@ -25,39 +25,28 @@
2525 " ATTACH_TYPE := { ingress | egress | sock_create |\n" \
2626 " sock_ops | device | bind4 | bind6 |\n" \
2727 " post_bind4 | post_bind6 | connect4 |\n" \
28
- " connect6 | sendmsg4 | sendmsg6 }"
28
+ " connect6 | getpeername4 | getpeername6 |\n" \
29
+ " getsockname4 | getsockname6 | sendmsg4 |\n" \
30
+ " sendmsg6 | recvmsg4 | recvmsg6 |\n" \
31
+ " sysctl | getsockopt | setsockopt |\n" \
32
+ " sock_release }"
2933
30
-static const char * const attach_type_strings[] = {
31
- [BPF_CGROUP_INET_INGRESS] = "ingress",
32
- [BPF_CGROUP_INET_EGRESS] = "egress",
33
- [BPF_CGROUP_INET_SOCK_CREATE] = "sock_create",
34
- [BPF_CGROUP_SOCK_OPS] = "sock_ops",
35
- [BPF_CGROUP_DEVICE] = "device",
36
- [BPF_CGROUP_INET4_BIND] = "bind4",
37
- [BPF_CGROUP_INET6_BIND] = "bind6",
38
- [BPF_CGROUP_INET4_CONNECT] = "connect4",
39
- [BPF_CGROUP_INET6_CONNECT] = "connect6",
40
- [BPF_CGROUP_INET4_POST_BIND] = "post_bind4",
41
- [BPF_CGROUP_INET6_POST_BIND] = "post_bind6",
42
- [BPF_CGROUP_UDP4_SENDMSG] = "sendmsg4",
43
- [BPF_CGROUP_UDP6_SENDMSG] = "sendmsg6",
44
- [__MAX_BPF_ATTACH_TYPE] = NULL,
45
-};
34
+static unsigned int query_flags;
4635
4736 static enum bpf_attach_type parse_attach_type(const char *str)
4837 {
4938 enum bpf_attach_type type;
5039
5140 for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) {
52
- if (attach_type_strings[type] &&
53
- is_prefix(str, attach_type_strings[type]))
41
+ if (attach_type_name[type] &&
42
+ is_prefix(str, attach_type_name[type]))
5443 return type;
5544 }
5645
5746 return __MAX_BPF_ATTACH_TYPE;
5847 }
5948
60
-static int show_bpf_prog(int id, const char *attach_type_str,
49
+static int show_bpf_prog(int id, enum bpf_attach_type attach_type,
6150 const char *attach_flags_str,
6251 int level)
6352 {
....@@ -77,18 +66,22 @@
7766 if (json_output) {
7867 jsonw_start_object(json_wtr);
7968 jsonw_uint_field(json_wtr, "id", info.id);
80
- jsonw_string_field(json_wtr, "attach_type",
81
- attach_type_str);
69
+ if (attach_type < ARRAY_SIZE(attach_type_name))
70
+ jsonw_string_field(json_wtr, "attach_type",
71
+ attach_type_name[attach_type]);
72
+ else
73
+ jsonw_uint_field(json_wtr, "attach_type", attach_type);
8274 jsonw_string_field(json_wtr, "attach_flags",
8375 attach_flags_str);
8476 jsonw_string_field(json_wtr, "name", info.name);
8577 jsonw_end_object(json_wtr);
8678 } else {
87
- printf("%s%-8u %-15s %-15s %-15s\n", level ? " " : "",
88
- info.id,
89
- attach_type_str,
90
- attach_flags_str,
91
- info.name);
79
+ printf("%s%-8u ", level ? " " : "", info.id);
80
+ if (attach_type < ARRAY_SIZE(attach_type_name))
81
+ printf("%-15s", attach_type_name[attach_type]);
82
+ else
83
+ printf("type %-10u", attach_type);
84
+ printf(" %-15s %-15s\n", attach_flags_str, info.name);
9285 }
9386
9487 close(prog_fd);
....@@ -100,26 +93,46 @@
10093 __u32 prog_cnt = 0;
10194 int ret;
10295
103
- ret = bpf_prog_query(cgroup_fd, type, 0, NULL, NULL, &prog_cnt);
96
+ ret = bpf_prog_query(cgroup_fd, type, query_flags, NULL,
97
+ NULL, &prog_cnt);
10498 if (ret)
10599 return -1;
106100
107101 return prog_cnt;
108102 }
109103
104
+static int cgroup_has_attached_progs(int cgroup_fd)
105
+{
106
+ enum bpf_attach_type type;
107
+ bool no_prog = true;
108
+
109
+ for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) {
110
+ int count = count_attached_bpf_progs(cgroup_fd, type);
111
+
112
+ if (count < 0 && errno != EINVAL)
113
+ return -1;
114
+
115
+ if (count > 0) {
116
+ no_prog = false;
117
+ break;
118
+ }
119
+ }
120
+
121
+ return no_prog ? 0 : 1;
122
+}
110123 static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
111124 int level)
112125 {
126
+ const char *attach_flags_str;
113127 __u32 prog_ids[1024] = {0};
114
- char *attach_flags_str;
115128 __u32 prog_cnt, iter;
116129 __u32 attach_flags;
117130 char buf[32];
118131 int ret;
119132
120133 prog_cnt = ARRAY_SIZE(prog_ids);
121
- ret = bpf_prog_query(cgroup_fd, type, 0, &attach_flags, prog_ids,
122
- &prog_cnt);
134
+ ret = bpf_prog_query(cgroup_fd, type, query_flags, &attach_flags,
135
+ prog_ids, &prog_cnt);
123136 if (ret)
124137 return ret;
125138
....@@ -142,7 +155,7 @@
142155 }
143156
144157 for (iter = 0; iter < prog_cnt; iter++)
145
- show_bpf_prog(prog_ids[iter], attach_type_strings[type],
158
+ show_bpf_prog(prog_ids[iter], type,
146159 attach_flags_str, level);
147160
148161 return 0;
....@@ -151,21 +164,46 @@
151164 static int do_show(int argc, char **argv)
152165 {
153166 enum bpf_attach_type type;
167
+ int has_attached_progs;
168
+ const char *path;
154169 int cgroup_fd;
155170 int ret = -1;
156171
157
- if (argc < 1) {
158
- p_err("too few parameters for cgroup show");
159
- goto exit;
160
- } else if (argc > 1) {
161
- p_err("too many parameters for cgroup show");
172
+ query_flags = 0;
173
+
174
+ if (!REQ_ARGS(1))
175
+ return -1;
176
+ path = GET_ARG();
177
+
178
+ while (argc) {
179
+ if (is_prefix(*argv, "effective")) {
180
+ if (query_flags & BPF_F_QUERY_EFFECTIVE) {
181
+ p_err("duplicated argument: %s", *argv);
182
+ return -1;
183
+ }
184
+ query_flags |= BPF_F_QUERY_EFFECTIVE;
185
+ NEXT_ARG();
186
+ } else {
187
+ p_err("expected no more arguments, 'effective', got: '%s'?",
188
+ *argv);
189
+ return -1;
190
+ }
191
+ }
192
+
193
+ cgroup_fd = open(path, O_RDONLY);
194
+ if (cgroup_fd < 0) {
195
+ p_err("can't open cgroup %s", path);
162196 goto exit;
163197 }
164198
165
- cgroup_fd = open(argv[0], O_RDONLY);
166
- if (cgroup_fd < 0) {
167
- p_err("can't open cgroup %s", argv[0]);
168
- goto exit;
199
+ has_attached_progs = cgroup_has_attached_progs(cgroup_fd);
200
+ if (has_attached_progs < 0) {
201
+ p_err("can't query bpf programs attached to %s: %s",
202
+ path, strerror(errno));
203
+ goto exit_cgroup;
204
+ } else if (!has_attached_progs) {
205
+ ret = 0;
206
+ goto exit_cgroup;
169207 }
170208
171209 if (json_output)
....@@ -188,6 +226,7 @@
188226 if (json_output)
189227 jsonw_end_array(json_wtr);
190228
229
+exit_cgroup:
191230 close(cgroup_fd);
192231 exit:
193232 return ret;
....@@ -204,7 +243,7 @@
204243 int typeflag, struct FTW *ftw)
205244 {
206245 enum bpf_attach_type type;
207
- bool skip = true;
246
+ int has_attached_progs;
208247 int cgroup_fd;
209248
210249 if (typeflag != FTW_D)
....@@ -216,22 +255,13 @@
216255 return SHOW_TREE_FN_ERR;
217256 }
218257
219
- for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) {
220
- int count = count_attached_bpf_progs(cgroup_fd, type);
221
-
222
- if (count < 0 && errno != EINVAL) {
223
- p_err("can't query bpf programs attached to %s: %s",
224
- fpath, strerror(errno));
225
- close(cgroup_fd);
226
- return SHOW_TREE_FN_ERR;
227
- }
228
- if (count > 0) {
229
- skip = false;
230
- break;
231
- }
232
- }
233
-
234
- if (skip) {
258
+ has_attached_progs = cgroup_has_attached_progs(cgroup_fd);
259
+ if (has_attached_progs < 0) {
260
+ p_err("can't query bpf programs attached to %s: %s",
261
+ fpath, strerror(errno));
262
+ close(cgroup_fd);
263
+ return SHOW_TREE_FN_ERR;
264
+ } else if (!has_attached_progs) {
235265 close(cgroup_fd);
236266 return 0;
237267 }
....@@ -247,6 +277,13 @@
247277
248278 for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++)
249279 show_attached_bpf_progs(cgroup_fd, type, ftw->level);
280
+
281
+ if (errno == EINVAL)
282
+ /* Last attach type does not support query.
283
+ * Do not report an error for this, especially because batch
284
+ * mode would stop processing commands.
285
+ */
286
+ errno = 0;
250287
251288 if (json_output) {
252289 jsonw_end_array(json_wtr);
....@@ -280,25 +317,36 @@
280317
281318 static int do_show_tree(int argc, char **argv)
282319 {
283
- char *cgroup_root;
320
+ char *cgroup_root, *cgroup_alloced = NULL;
284321 int ret;
285322
286
- switch (argc) {
287
- case 0:
288
- cgroup_root = find_cgroup_root();
289
- if (!cgroup_root) {
323
+ query_flags = 0;
324
+
325
+ if (!argc) {
326
+ cgroup_alloced = find_cgroup_root();
327
+ if (!cgroup_alloced) {
290328 p_err("cgroup v2 isn't mounted");
291329 return -1;
292330 }
293
- break;
294
- case 1:
295
- cgroup_root = argv[0];
296
- break;
297
- default:
298
- p_err("too many parameters for cgroup tree");
299
- return -1;
300
- }
331
+ cgroup_root = cgroup_alloced;
332
+ } else {
333
+ cgroup_root = GET_ARG();
301334
335
+ while (argc) {
336
+ if (is_prefix(*argv, "effective")) {
337
+ if (query_flags & BPF_F_QUERY_EFFECTIVE) {
338
+ p_err("duplicated argument: %s", *argv);
339
+ return -1;
340
+ }
341
+ query_flags |= BPF_F_QUERY_EFFECTIVE;
342
+ NEXT_ARG();
343
+ } else {
344
+ p_err("expected no more arguments, 'effective', got: '%s'?",
345
+ *argv);
346
+ return -1;
347
+ }
348
+ }
349
+ }
302350
303351 if (json_output)
304352 jsonw_start_array(json_wtr);
....@@ -324,8 +372,7 @@
324372 if (json_output)
325373 jsonw_end_array(json_wtr);
326374
327
- if (argc == 0)
328
- free(cgroup_root);
375
+ free(cgroup_alloced);
329376
330377 return ret;
331378 }
....@@ -445,20 +492,18 @@
445492 }
446493
447494 fprintf(stderr,
448
- "Usage: %s %s { show | list } CGROUP\n"
449
- " %s %s tree [CGROUP_ROOT]\n"
450
- " %s %s attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS]\n"
451
- " %s %s detach CGROUP ATTACH_TYPE PROG\n"
452
- " %s %s help\n"
495
+ "Usage: %1$s %2$s { show | list } CGROUP [**effective**]\n"
496
+ " %1$s %2$s tree [CGROUP_ROOT] [**effective**]\n"
497
+ " %1$s %2$s attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS]\n"
498
+ " %1$s %2$s detach CGROUP ATTACH_TYPE PROG\n"
499
+ " %1$s %2$s help\n"
453500 "\n"
454501 HELP_SPEC_ATTACH_TYPES "\n"
455502 " " HELP_SPEC_ATTACH_FLAGS "\n"
456503 " " HELP_SPEC_PROGRAM "\n"
457504 " " HELP_SPEC_OPTIONS "\n"
458505 "",
459
- bin_name, argv[-2],
460
- bin_name, argv[-2], bin_name, argv[-2],
461
- bin_name, argv[-2], bin_name, argv[-2]);
506
+ bin_name, argv[-2]);
462507
463508 return 0;
464509 }