diff options
Diffstat (limited to 'tools/bpf/bpftool/feature.c')
| -rw-r--r-- | tools/bpf/bpftool/feature.c | 152 |
1 files changed, 47 insertions, 105 deletions
diff --git a/tools/bpf/bpftool/feature.c b/tools/bpf/bpftool/feature.c index 36cf0f1517c9..0f6070a0c8e7 100644 --- a/tools/bpf/bpftool/feature.c +++ b/tools/bpf/bpftool/feature.c @@ -10,7 +10,6 @@ #ifdef USE_LIBCAP #include <sys/capability.h> #endif -#include <sys/utsname.h> #include <sys/vfs.h> #include <linux/filter.h> @@ -18,7 +17,6 @@ #include <bpf/bpf.h> #include <bpf/libbpf.h> -#include <zlib.h> #include "main.h" @@ -167,12 +165,12 @@ static int get_vendor_id(int ifindex) return strtol(buf, NULL, 0); } -static int read_procfs(const char *path) +static long read_procfs(const char *path) { char *endptr, *line = NULL; size_t len = 0; FILE *fd; - int res; + long res; fd = fopen(path, "r"); if (!fd) @@ -194,9 +192,9 @@ static int read_procfs(const char *path) static void probe_unprivileged_disabled(void) { - int res; + long res; - /* No support for C-style ouptut */ + /* No support for C-style output */ res = read_procfs("/proc/sys/kernel/unprivileged_bpf_disabled"); if (json_output) { @@ -216,16 +214,16 @@ static void probe_unprivileged_disabled(void) printf("Unable to retrieve required privileges for bpf() syscall\n"); break; default: - printf("bpf() syscall restriction has unknown value %d\n", res); + printf("bpf() syscall restriction has unknown value %ld\n", res); } } } static void probe_jit_enable(void) { - int res; + long res; - /* No support for C-style ouptut */ + /* No support for C-style output */ res = read_procfs("/proc/sys/net/core/bpf_jit_enable"); if (json_output) { @@ -245,7 +243,7 @@ static void probe_jit_enable(void) printf("Unable to retrieve JIT-compiler status\n"); break; default: - printf("JIT-compiler status has unknown value %d\n", + printf("JIT-compiler status has unknown value %ld\n", res); } } @@ -253,9 +251,9 @@ static void probe_jit_enable(void) static void probe_jit_harden(void) { - int res; + long res; - /* No support for C-style ouptut */ + /* No support for C-style output */ res = read_procfs("/proc/sys/net/core/bpf_jit_harden"); if (json_output) { @@ -275,7 +273,7 @@ static void probe_jit_harden(void) printf("Unable to retrieve JIT hardening status\n"); break; default: - printf("JIT hardening status has unknown value %d\n", + printf("JIT hardening status has unknown value %ld\n", res); } } @@ -283,9 +281,9 @@ static void probe_jit_harden(void) static void probe_jit_kallsyms(void) { - int res; + long res; - /* No support for C-style ouptut */ + /* No support for C-style output */ res = read_procfs("/proc/sys/net/core/bpf_jit_kallsyms"); if (json_output) { @@ -302,16 +300,16 @@ static void probe_jit_kallsyms(void) printf("Unable to retrieve JIT kallsyms export status\n"); break; default: - printf("JIT kallsyms exports status has unknown value %d\n", res); + printf("JIT kallsyms exports status has unknown value %ld\n", res); } } } static void probe_jit_limit(void) { - int res; + long res; - /* No support for C-style ouptut */ + /* No support for C-style output */ res = read_procfs("/proc/sys/net/core/bpf_jit_limit"); if (json_output) { @@ -322,45 +320,14 @@ static void probe_jit_limit(void) printf("Unable to retrieve global memory limit for JIT compiler for unprivileged users\n"); break; default: - printf("Global memory limit for JIT compiler for unprivileged users is %d bytes\n", res); + printf("Global memory limit for JIT compiler for unprivileged users is %ld bytes\n", res); } } } -static bool read_next_kernel_config_option(gzFile file, char *buf, size_t n, - char **value) -{ - char *sep; - - while (gzgets(file, buf, n)) { - if (strncmp(buf, "CONFIG_", 7)) - continue; - - sep = strchr(buf, '='); - if (!sep) - continue; - - /* Trim ending '\n' */ - buf[strlen(buf) - 1] = '\0'; - - /* Split on '=' and ensure that a value is present. */ - *sep = '\0'; - if (!sep[1]) - continue; - - *value = sep + 1; - return true; - } - - return false; -} - static void probe_kernel_image_config(const char *define_prefix) { - static const struct { - const char * const name; - bool macro_dump; - } options[] = { + struct kernel_config_option options[] = { /* Enable BPF */ { "CONFIG_BPF", }, /* Enable bpf() syscall */ @@ -426,10 +393,6 @@ static void probe_kernel_image_config(const char *define_prefix) { "CONFIG_BPF_STREAM_PARSER", }, /* xt_bpf module for passing BPF programs to netfilter */ { "CONFIG_NETFILTER_XT_MATCH_BPF", }, - /* bpfilter back-end for iptables */ - { "CONFIG_BPFILTER", }, - /* bpftilter module with "user mode helper" */ - { "CONFIG_BPFILTER_UMH", }, /* test_bpf module for BPF tests */ { "CONFIG_TEST_BPF", }, @@ -439,56 +402,11 @@ static void probe_kernel_image_config(const char *define_prefix) { "CONFIG_HZ", true, } }; char *values[ARRAY_SIZE(options)] = { }; - struct utsname utsn; - char path[PATH_MAX]; - gzFile file = NULL; - char buf[4096]; - char *value; size_t i; - if (!uname(&utsn)) { - snprintf(path, sizeof(path), "/boot/config-%s", utsn.release); - - /* gzopen also accepts uncompressed files. */ - file = gzopen(path, "r"); - } - - if (!file) { - /* Some distributions build with CONFIG_IKCONFIG=y and put the - * config file at /proc/config.gz. - */ - file = gzopen("/proc/config.gz", "r"); - } - if (!file) { - p_info("skipping kernel config, can't open file: %s", - strerror(errno)); - goto end_parse; - } - /* Sanity checks */ - if (!gzgets(file, buf, sizeof(buf)) || - !gzgets(file, buf, sizeof(buf))) { - p_info("skipping kernel config, can't read from file: %s", - strerror(errno)); - goto end_parse; - } - if (strcmp(buf, "# Automatically generated file; DO NOT EDIT.\n")) { - p_info("skipping kernel config, can't find correct file"); - goto end_parse; - } - - while (read_next_kernel_config_option(file, buf, sizeof(buf), &value)) { - for (i = 0; i < ARRAY_SIZE(options); i++) { - if ((define_prefix && !options[i].macro_dump) || - values[i] || strcmp(buf, options[i].name)) - continue; - - values[i] = strdup(value); - } - } - -end_parse: - if (file) - gzclose(file); + if (read_kernel_config(options, ARRAY_SIZE(options), values, + define_prefix)) + return; for (i = 0; i < ARRAY_SIZE(options); i++) { if (define_prefix && !options[i].macro_dump) @@ -668,7 +586,8 @@ probe_helper_ifindex(enum bpf_func_id id, enum bpf_prog_type prog_type, probe_prog_load_ifindex(prog_type, insns, ARRAY_SIZE(insns), buf, sizeof(buf), ifindex); - res = !grep(buf, "invalid func ") && !grep(buf, "unknown func "); + res = !grep(buf, "invalid func ") && !grep(buf, "unknown func ") && + !grep(buf, "program of this type cannot use helper "); switch (get_vendor_id(ifindex)) { case 0x19ee: /* Netronome specific */ @@ -757,7 +676,7 @@ probe_helpers_for_progtype(enum bpf_prog_type prog_type, case BPF_FUNC_probe_write_user: if (!full_mode) continue; - /* fallthrough */ + fallthrough; default: probe_res |= probe_helper_for_progtype(prog_type, supported_type, define_prefix, id, prog_type_str, @@ -888,6 +807,28 @@ probe_v3_isa_extension(const char *define_prefix, __u32 ifindex) "V3_ISA_EXTENSION"); } +/* + * Probe for the v4 instruction set extension introduced in commit 1f9a1ea821ff + * ("bpf: Support new sign-extension load insns"). + */ +static void +probe_v4_isa_extension(const char *define_prefix, __u32 ifindex) +{ + struct bpf_insn insns[5] = { + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_JMP32_IMM(BPF_JEQ, BPF_REG_0, 1, 1), + BPF_JMP32_A(1), + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN() + }; + + probe_misc_feature(insns, ARRAY_SIZE(insns), + define_prefix, ifindex, + "have_v4_isa_extension", + "ISA extension v4", + "V4_ISA_EXTENSION"); +} + static void section_system_config(enum probe_component target, const char *define_prefix) { @@ -1032,6 +973,7 @@ static void section_misc(const char *define_prefix, __u32 ifindex) probe_bounded_loops(define_prefix, ifindex); probe_v2_isa_extension(define_prefix, ifindex); probe_v3_isa_extension(define_prefix, ifindex); + probe_v4_isa_extension(define_prefix, ifindex); print_end_section(); } |
