/* SPDX-License-Identifier: GPL-2.0 */ /* * bpf_glue.c: BPF code to call both legacy and libbpf code * Authors: Hangbin Liu * */ #include #include #include #include #include "bpf_util.h" #ifdef HAVE_LIBBPF #include #endif int bpf(int cmd, union bpf_attr *attr, unsigned int size) { #ifdef __NR_bpf return syscall(__NR_bpf, cmd, attr, size); #else fprintf(stderr, "No bpf syscall, kernel headers too old?\n"); errno = ENOSYS; return -1; #endif } int bpf_program_attach(int prog_fd, int target_fd, enum bpf_attach_type type) { #ifdef HAVE_LIBBPF return bpf_prog_attach(prog_fd, target_fd, type, 0); #else return bpf_prog_attach_fd(prog_fd, target_fd, type); #endif } #ifdef HAVE_LIBBPF static const char *_libbpf_compile_version = LIBBPF_VERSION; static char _libbpf_version[10] = {}; const char *get_libbpf_version(void) { /* Start by copying compile-time version into buffer so we have a * fallback value in case we are dynamically linked, or can't find a * version in /proc/self/maps below. */ strncpy(_libbpf_version, _libbpf_compile_version, sizeof(_libbpf_version)-1); #ifdef LIBBPF_DYNAMIC char buf[PATH_MAX], *s; bool found = false; FILE *fp; /* When dynamically linking against libbpf, we can't be sure that the * version we discovered at compile time is actually the one we are * using at runtime. This can lead to hard-to-debug errors, so we try to * discover the correct version at runtime. * * The simple solution to this would be if libbpf itself exported a * version in its API. But since it doesn't, we work around this by * parsing the mappings of the binary at runtime, looking for the full * filename of libbpf.so and using that. */ fp = fopen("/proc/self/maps", "r"); if (fp == NULL) goto out; while (fgets(buf, sizeof(buf), fp) != NULL) { if ((s = strstr(buf, "libbpf.so.")) != NULL) { strncpy(_libbpf_version, s+10, sizeof(_libbpf_version)-1); strtok(_libbpf_version, "\n"); found = true; break; } } fclose(fp); out: if (!found) fprintf(stderr, "Couldn't find runtime libbpf version - falling back to compile-time value!\n"); #endif /* LIBBPF_DYNAMIC */ _libbpf_version[sizeof(_libbpf_version)-1] = '\0'; return _libbpf_version; } #else const char *get_libbpf_version(void) { return NULL; } #endif /* HAVE_LIBBPF */