hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/tools/bpf/bpftool/main.c
....@@ -1,37 +1,6 @@
1
-/*
2
- * Copyright (C) 2017-2018 Netronome Systems, Inc.
3
- *
4
- * This software is dual licensed under the GNU General License Version 2,
5
- * June 1991 as shown in the file COPYING in the top-level directory of this
6
- * source tree or the BSD 2-Clause License provided below. You have the
7
- * option to license this software under the complete terms of either license.
8
- *
9
- * The BSD 2-Clause License:
10
- *
11
- * Redistribution and use in source and binary forms, with or
12
- * without modification, are permitted provided that the following
13
- * conditions are met:
14
- *
15
- * 1. Redistributions of source code must retain the above
16
- * copyright notice, this list of conditions and the following
17
- * disclaimer.
18
- *
19
- * 2. Redistributions in binary form must reproduce the above
20
- * copyright notice, this list of conditions and the following
21
- * disclaimer in the documentation and/or other materials
22
- * provided with the distribution.
23
- *
24
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
- * SOFTWARE.
32
- */
1
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2
+/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
333
34
-#include <bfd.h>
354 #include <ctype.h>
365 #include <errno.h>
376 #include <getopt.h>
....@@ -40,7 +9,8 @@
409 #include <stdlib.h>
4110 #include <string.h>
4211
43
-#include <bpf.h>
12
+#include <bpf/bpf.h>
13
+#include <bpf/libbpf.h>
4414
4515 #include "main.h"
4616
....@@ -55,8 +25,13 @@
5525 bool pretty_output;
5626 bool json_output;
5727 bool show_pinned;
28
+bool block_mount;
29
+bool verifier_logs;
30
+bool relaxed_maps;
5831 struct pinned_obj_table prog_table;
5932 struct pinned_obj_table map_table;
33
+struct pinned_obj_table link_table;
34
+struct obj_refs_table refs_table;
6035
6136 static void __noreturn clean_and_exit(int i)
6237 {
....@@ -85,7 +60,7 @@
8560 " %s batch file FILE\n"
8661 " %s version\n"
8762 "\n"
88
- " OBJECT := { prog | map | cgroup | perf }\n"
63
+ " OBJECT := { prog | map | link | cgroup | perf | net | feature | btf | gen | struct_ops | iter }\n"
8964 " " HELP_SPEC_OPTIONS "\n"
9065 "",
9166 bin_name, bin_name, bin_name);
....@@ -95,13 +70,42 @@
9570
9671 static int do_version(int argc, char **argv)
9772 {
73
+#ifdef HAVE_LIBBFD_SUPPORT
74
+ const bool has_libbfd = true;
75
+#else
76
+ const bool has_libbfd = false;
77
+#endif
78
+#ifdef BPFTOOL_WITHOUT_SKELETONS
79
+ const bool has_skeletons = false;
80
+#else
81
+ const bool has_skeletons = true;
82
+#endif
83
+
9884 if (json_output) {
99
- jsonw_start_object(json_wtr);
85
+ jsonw_start_object(json_wtr); /* root object */
86
+
10087 jsonw_name(json_wtr, "version");
10188 jsonw_printf(json_wtr, "\"%s\"", BPFTOOL_VERSION);
102
- jsonw_end_object(json_wtr);
89
+
90
+ jsonw_name(json_wtr, "features");
91
+ jsonw_start_object(json_wtr); /* features */
92
+ jsonw_bool_field(json_wtr, "libbfd", has_libbfd);
93
+ jsonw_bool_field(json_wtr, "skeletons", has_skeletons);
94
+ jsonw_end_object(json_wtr); /* features */
95
+
96
+ jsonw_end_object(json_wtr); /* root object */
10397 } else {
98
+ unsigned int nb_features = 0;
99
+
104100 printf("%s v%s\n", bin_name, BPFTOOL_VERSION);
101
+ printf("features:");
102
+ if (has_libbfd) {
103
+ printf(" libbfd");
104
+ nb_features++;
105
+ }
106
+ if (has_skeletons)
107
+ printf("%s skeletons", nb_features++ ? "," : "");
108
+ printf("\n");
105109 }
106110 return 0;
107111 }
....@@ -118,9 +122,16 @@
118122 if (argc < 1 && cmds[0].func)
119123 return cmds[0].func(argc, argv);
120124
121
- for (i = 0; cmds[i].func; i++)
122
- if (is_prefix(*argv, cmds[i].cmd))
125
+ for (i = 0; cmds[i].cmd; i++) {
126
+ if (is_prefix(*argv, cmds[i].cmd)) {
127
+ if (!cmds[i].func) {
128
+ p_err("command '%s' is not supported in bootstrap mode",
129
+ cmds[i].cmd);
130
+ return -1;
131
+ }
123132 return cmds[i].func(argc - 1, argv + 1);
133
+ }
134
+ }
124135
125136 help(argc - 1, argv + 1);
126137
....@@ -135,6 +146,35 @@
135146 return false;
136147
137148 return !memcmp(str, pfx, strlen(pfx));
149
+}
150
+
151
+/* Last argument MUST be NULL pointer */
152
+int detect_common_prefix(const char *arg, ...)
153
+{
154
+ unsigned int count = 0;
155
+ const char *ref;
156
+ char msg[256];
157
+ va_list ap;
158
+
159
+ snprintf(msg, sizeof(msg), "ambiguous prefix: '%s' could be '", arg);
160
+ va_start(ap, arg);
161
+ while ((ref = va_arg(ap, const char *))) {
162
+ if (!is_prefix(arg, ref))
163
+ continue;
164
+ count++;
165
+ if (count > 1)
166
+ strncat(msg, "' or '", sizeof(msg) - strlen(msg) - 1);
167
+ strncat(msg, ref, sizeof(msg) - strlen(msg) - 1);
168
+ }
169
+ va_end(ap);
170
+ strncat(msg, "'", sizeof(msg) - strlen(msg) - 1);
171
+
172
+ if (count >= 2) {
173
+ p_err("%s", msg);
174
+ return -1;
175
+ }
176
+
177
+ return 0;
138178 }
139179
140180 void fprint_hex(FILE *f, void *arg, unsigned int n, const char *sep)
....@@ -213,8 +253,15 @@
213253 { "batch", do_batch },
214254 { "prog", do_prog },
215255 { "map", do_map },
256
+ { "link", do_link },
216257 { "cgroup", do_cgroup },
217258 { "perf", do_perf },
259
+ { "net", do_net },
260
+ { "feature", do_feature },
261
+ { "btf", do_btf },
262
+ { "gen", do_gen },
263
+ { "struct_ops", do_struct_ops },
264
+ { "iter", do_iter },
218265 { "version", do_version },
219266 { 0 }
220267 };
....@@ -227,7 +274,7 @@
227274 int n_argc;
228275 FILE *fp;
229276 char *cp;
230
- int err;
277
+ int err = 0;
231278 int i;
232279
233280 if (argc < 2) {
....@@ -321,8 +368,8 @@
321368 p_err("reading batch file failed: %s", strerror(errno));
322369 err = -1;
323370 } else {
324
- p_info("processed %d commands", lines);
325
- err = 0;
371
+ if (!json_output)
372
+ printf("processed %d commands\n", lines);
326373 }
327374 err_close:
328375 if (fp != stdin)
....@@ -342,21 +389,38 @@
342389 { "pretty", no_argument, NULL, 'p' },
343390 { "version", no_argument, NULL, 'V' },
344391 { "bpffs", no_argument, NULL, 'f' },
392
+ { "mapcompat", no_argument, NULL, 'm' },
393
+ { "nomount", no_argument, NULL, 'n' },
394
+ { "debug", no_argument, NULL, 'd' },
345395 { 0 }
346396 };
347397 int opt, ret;
398
+
399
+ setlinebuf(stdout);
400
+
401
+#ifdef USE_LIBCAP
402
+ /* Libcap < 2.63 hooks before main() to compute the number of
403
+ * capabilities of the running kernel, and doing so it calls prctl()
404
+ * which may fail and set errno to non-zero.
405
+ * Let's reset errno to make sure this does not interfere with the
406
+ * batch mode.
407
+ */
408
+ errno = 0;
409
+#endif
348410
349411 last_do_help = do_help;
350412 pretty_output = false;
351413 json_output = false;
352414 show_pinned = false;
415
+ block_mount = false;
353416 bin_name = argv[0];
354417
355418 hash_init(prog_table.table);
356419 hash_init(map_table.table);
420
+ hash_init(link_table.table);
357421
358422 opterr = 0;
359
- while ((opt = getopt_long(argc, argv, "Vhpjf",
423
+ while ((opt = getopt_long(argc, argv, "Vhpjfmnd",
360424 options, NULL)) >= 0) {
361425 switch (opt) {
362426 case 'V':
....@@ -380,6 +444,16 @@
380444 case 'f':
381445 show_pinned = true;
382446 break;
447
+ case 'm':
448
+ relaxed_maps = true;
449
+ break;
450
+ case 'n':
451
+ block_mount = true;
452
+ break;
453
+ case 'd':
454
+ libbpf_set_print(print_all_levels);
455
+ verifier_logs = true;
456
+ break;
383457 default:
384458 p_err("unrecognized option '%s'", argv[optind - 1]);
385459 if (json_output)
....@@ -394,8 +468,6 @@
394468 if (argc < 0)
395469 usage();
396470
397
- bfd_init();
398
-
399471 ret = cmd_select(cmds, argc, argv, do_help);
400472
401473 if (json_output)
....@@ -404,6 +476,7 @@
404476 if (show_pinned) {
405477 delete_pinned_obj_table(&prog_table);
406478 delete_pinned_obj_table(&map_table);
479
+ delete_pinned_obj_table(&link_table);
407480 }
408481
409482 return ret;