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