iproute2/lib/bpf_glue.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * bpf_glue.c:  BPF code to call both legacy and libbpf code
   4 * Authors:     Hangbin Liu <haliu@redhat.com>
   5 *
   6 */
   7#include "bpf_util.h"
   8#ifdef HAVE_LIBBPF
   9#include <bpf/bpf.h>
  10#endif
  11
  12int bpf_program_load(enum bpf_prog_type type, const struct bpf_insn *insns,
  13                     size_t size_insns, const char *license, char *log,
  14                     size_t size_log)
  15{
  16#ifdef HAVE_LIBBPF
  17        return bpf_load_program(type, insns, size_insns / sizeof(struct bpf_insn),
  18                                license, 0, log, size_log);
  19#else
  20        return bpf_prog_load_dev(type, insns, size_insns, license, 0, log, size_log);
  21#endif
  22}
  23
  24int bpf_program_attach(int prog_fd, int target_fd, enum bpf_attach_type type)
  25{
  26#ifdef HAVE_LIBBPF
  27        return bpf_prog_attach(prog_fd, target_fd, type, 0);
  28#else
  29        return bpf_prog_attach_fd(prog_fd, target_fd, type);
  30#endif
  31}
  32
  33#ifdef HAVE_LIBBPF
  34static const char *_libbpf_compile_version = LIBBPF_VERSION;
  35static char _libbpf_version[10] = {};
  36
  37const char *get_libbpf_version(void)
  38{
  39        /* Start by copying compile-time version into buffer so we have a
  40         * fallback value in case we are dynamically linked, or can't find a
  41         * version in /proc/self/maps below.
  42         */
  43        strncpy(_libbpf_version, _libbpf_compile_version,
  44                sizeof(_libbpf_version)-1);
  45#ifdef LIBBPF_DYNAMIC
  46        char buf[PATH_MAX], *s;
  47        bool found = false;
  48        FILE *fp;
  49
  50        /* When dynamically linking against libbpf, we can't be sure that the
  51         * version we discovered at compile time is actually the one we are
  52         * using at runtime. This can lead to hard-to-debug errors, so we try to
  53         * discover the correct version at runtime.
  54         *
  55         * The simple solution to this would be if libbpf itself exported a
  56         * version in its API. But since it doesn't, we work around this by
  57         * parsing the mappings of the binary at runtime, looking for the full
  58         * filename of libbpf.so and using that.
  59         */
  60        fp = fopen("/proc/self/maps", "r");
  61        if (fp == NULL)
  62                goto out;
  63
  64        while ((s = fgets(buf, sizeof(buf), fp)) != NULL) {
  65                if ((s = strstr(buf, "libbpf.so.")) != NULL) {
  66                        strncpy(_libbpf_version, s+10, sizeof(_libbpf_version)-1);
  67                        strtok(_libbpf_version, "\n");
  68                        found = true;
  69                        break;
  70                }
  71        }
  72
  73        fclose(fp);
  74out:
  75        if (!found)
  76                fprintf(stderr, "Couldn't find runtime libbpf version - falling back to compile-time value!\n");
  77#endif /* LIBBPF_DYNAMIC */
  78
  79        _libbpf_version[sizeof(_libbpf_version)-1] = '\0';
  80        return _libbpf_version;
  81}
  82#else
  83const char *get_libbpf_version(void)
  84{
  85        return NULL;
  86}
  87#endif /* HAVE_LIBBPF */
  88