]> git.proxmox.com Git - mirror_iproute2.git/blame - lib/bpf_glue.c
Merge git://git.kernel.org/pub/scm/network/iproute2/iproute2-next
[mirror_iproute2.git] / lib / bpf_glue.c
CommitLineData
503e9229
HL
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"
dc800a4e
HL
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
8498ca92
LB
17 return bpf_load_program(type, insns, size_insns / sizeof(struct bpf_insn),
18 license, 0, log, size_log);
dc800a4e
HL
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}
503e9229
HL
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 */