Commit 314f14ab authored by Stanislav Fomichev's avatar Stanislav Fomichev Committed by Daniel Borkmann

bpftool: Enable libbpf's strict mode by default

Otherwise, attaching with bpftool doesn't work with strict section names.

Also:

  - Add --legacy option to switch back to pre-1.0 behavior
  - Print a warning when program fails to load in strict mode to
    point to --legacy flag
  - By default, don't append / to the section name; in strict
    mode it's relevant only for a small subset of prog types

+ bpftool --legacy prog loadall tools/testing/selftests/bpf/test_cgroup_link.o /sys/fs/bpf/kprobe type kprobe
libbpf: failed to pin program: File exists
Error: failed to pin all programs
+ bpftool prog loadall tools/testing/selftests/bpf/test_cgroup_link.o /sys/fs/bpf/kprobe type kprobe

v1 -> v2:
  - strict by default (Quentin Monnet)
  - add more info to --legacy description (Quentin Monnet)
  - add bash completion (Quentin Monnet)
Signed-off-by: default avatarStanislav Fomichev <sdf@google.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Reviewed-by: default avatarQuentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/bpf/20211110192324.920934-1-sdf@google.com
parent 9faaffbe
......@@ -20,3 +20,12 @@
Print all logs available, even debug-level information. This includes
logs from libbpf as well as from the verifier, when attempting to
load programs.
-l, --legacy
Use legacy libbpf mode which has more relaxed BPF program
requirements. By default, bpftool has more strict requirements
about section names, changes pinning logic and doesn't support
some of the older non-BTF map declarations.
See https://github.com/libbpf/libbpf/wiki/Libbpf:-the-road-to-v1.0
for details.
......@@ -261,7 +261,7 @@ _bpftool()
# Deal with options
if [[ ${words[cword]} == -* ]]; then
local c='--version --json --pretty --bpffs --mapcompat --debug \
--use-loader --base-btf'
--use-loader --base-btf --legacy'
COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
return 0
fi
......
......@@ -31,6 +31,7 @@ bool block_mount;
bool verifier_logs;
bool relaxed_maps;
bool use_loader;
bool legacy_libbpf;
struct btf *base_btf;
struct hashmap *refs_table;
......@@ -396,6 +397,7 @@ int main(int argc, char **argv)
{ "debug", no_argument, NULL, 'd' },
{ "use-loader", no_argument, NULL, 'L' },
{ "base-btf", required_argument, NULL, 'B' },
{ "legacy", no_argument, NULL, 'l' },
{ 0 }
};
int opt, ret;
......@@ -408,7 +410,7 @@ int main(int argc, char **argv)
bin_name = argv[0];
opterr = 0;
while ((opt = getopt_long(argc, argv, "VhpjfLmndB:",
while ((opt = getopt_long(argc, argv, "VhpjfLmndB:l",
options, NULL)) >= 0) {
switch (opt) {
case 'V':
......@@ -454,6 +456,9 @@ int main(int argc, char **argv)
case 'L':
use_loader = true;
break;
case 'l':
legacy_libbpf = true;
break;
default:
p_err("unrecognized option '%s'", argv[optind - 1]);
if (json_output)
......@@ -463,6 +468,12 @@ int main(int argc, char **argv)
}
}
if (!legacy_libbpf) {
ret = libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
if (ret)
p_err("failed to enable libbpf strict mode: %d", ret);
}
argc -= optind;
argv += optind;
if (argc < 0)
......
......@@ -57,7 +57,7 @@ static inline void *u64_to_ptr(__u64 ptr)
#define HELP_SPEC_PROGRAM \
"PROG := { id PROG_ID | pinned FILE | tag PROG_TAG | name PROG_NAME }"
#define HELP_SPEC_OPTIONS \
"OPTIONS := { {-j|--json} [{-p|--pretty}] | {-d|--debug}"
"OPTIONS := { {-j|--json} [{-p|--pretty}] | {-d|--debug} | {-l|--legacy}"
#define HELP_SPEC_MAP \
"MAP := { id MAP_ID | pinned FILE | name MAP_NAME }"
#define HELP_SPEC_LINK \
......@@ -90,6 +90,7 @@ extern bool block_mount;
extern bool verifier_logs;
extern bool relaxed_maps;
extern bool use_loader;
extern bool legacy_libbpf;
extern struct btf *base_btf;
extern struct hashmap *refs_table;
......
......@@ -1483,8 +1483,6 @@ static int load_with_options(int argc, char **argv, bool first_prog_only)
while (argc) {
if (is_prefix(*argv, "type")) {
char *type;
NEXT_ARG();
if (common_prog_type != BPF_PROG_TYPE_UNSPEC) {
......@@ -1494,21 +1492,26 @@ static int load_with_options(int argc, char **argv, bool first_prog_only)
if (!REQ_ARGS(1))
goto err_free_reuse_maps;
/* Put a '/' at the end of type to appease libbpf */
type = malloc(strlen(*argv) + 2);
if (!type) {
p_err("mem alloc failed");
goto err_free_reuse_maps;
}
*type = 0;
strcat(type, *argv);
strcat(type, "/");
err = libbpf_prog_type_by_name(*argv, &common_prog_type,
&expected_attach_type);
if (err < 0) {
/* Put a '/' at the end of type to appease libbpf */
char *type = malloc(strlen(*argv) + 2);
err = get_prog_type_by_name(type, &common_prog_type,
&expected_attach_type);
free(type);
if (err < 0)
goto err_free_reuse_maps;
if (!type) {
p_err("mem alloc failed");
goto err_free_reuse_maps;
}
*type = 0;
strcat(type, *argv);
strcat(type, "/");
err = get_prog_type_by_name(type, &common_prog_type,
&expected_attach_type);
free(type);
if (err < 0)
goto err_free_reuse_maps;
}
NEXT_ARG();
} else if (is_prefix(*argv, "map")) {
......@@ -1731,6 +1734,11 @@ static int load_with_options(int argc, char **argv, bool first_prog_only)
else
bpf_object__unpin_programs(obj, pinfile);
err_close_obj:
if (!legacy_libbpf) {
p_info("Warning: bpftool is now running in libbpf strict mode and has more stringent requirements about BPF programs.\n"
"If it used to work for this object file but now doesn't, see --legacy option for more details.\n");
}
bpf_object__close(obj);
err_free_reuse_maps:
for (i = 0; i < old_map_fds; i++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment