aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/bpf/libbpf_probes.c
diff options
context:
space:
mode:
authorQuentin Monnet <quentin.monnet@netronome.com>2019-01-17 10:27:55 -0500
committerAlexei Starovoitov <ast@kernel.org>2019-01-23 01:15:40 -0500
commit2d3ea5e85dd867712ba8747cb01c2d88376ead5c (patch)
treeab6e05e131cece6ffb425646ae1e1bfb6664a3c4 /tools/lib/bpf/libbpf_probes.c
parentf99e166397f0298fe78bce24c55c6d074f9bf196 (diff)
tools: bpftool: add probes for eBPF helper functions
Similarly to what was done for program types and map types, add a set of probes to test the availability of the different eBPF helper functions on the current system. For each known program type, all known helpers are tested, in order to establish a compatibility matrix. Output is provided as a set of lists of available helpers, one per program type. Sample output: # bpftool feature probe kernel ... Scanning eBPF helper functions... eBPF helpers supported for program type socket_filter: - bpf_map_lookup_elem - bpf_map_update_elem - bpf_map_delete_elem ... eBPF helpers supported for program type kprobe: - bpf_map_lookup_elem - bpf_map_update_elem - bpf_map_delete_elem ... # bpftool --json --pretty feature probe kernel { ... "helpers": { "socket_filter_available_helpers": ["bpf_map_lookup_elem", \ "bpf_map_update_elem","bpf_map_delete_elem", ... ], "kprobe_available_helpers": ["bpf_map_lookup_elem", \ "bpf_map_update_elem","bpf_map_delete_elem", ... ], ... } } v5: - In libbpf.map, move global symbol to the new LIBBPF_0.0.2 section. v4: - Use "enum bpf_func_id" instead of "__u32" in bpf_probe_helper() declaration for the type of the argument used to pass the id of the helper to probe. - Undef BPF_HELPER_MAKE_ENTRY after using it. v3: - Do not pass kernel version from bpftool to libbpf probes (kernel version for testing program with kprobes is retrieved directly from libbpf). - Dump one list of available helpers per program type (instead of one list of compatible program types per helper). v2: - Move probes from bpftool to libbpf. - Test all program types for each helper, print a list of working prog types for each helper. - Fall back on include/uapi/linux/bpf.h for names and ids of helpers. - Remove C-style macros output from this patch. Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Stanislav Fomichev <sdf@google.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'tools/lib/bpf/libbpf_probes.c')
-rw-r--r--tools/lib/bpf/libbpf_probes.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
index f511bd317b87..8c3a1c04dcb2 100644
--- a/tools/lib/bpf/libbpf_probes.c
+++ b/tools/lib/bpf/libbpf_probes.c
@@ -2,7 +2,11 @@
2/* Copyright (c) 2019 Netronome Systems, Inc. */ 2/* Copyright (c) 2019 Netronome Systems, Inc. */
3 3
4#include <errno.h> 4#include <errno.h>
5#include <fcntl.h>
6#include <string.h>
7#include <stdlib.h>
5#include <unistd.h> 8#include <unistd.h>
9#include <net/if.h>
6#include <sys/utsname.h> 10#include <sys/utsname.h>
7 11
8#include <linux/filter.h> 12#include <linux/filter.h>
@@ -11,6 +15,37 @@
11#include "bpf.h" 15#include "bpf.h"
12#include "libbpf.h" 16#include "libbpf.h"
13 17
18static bool grep(const char *buffer, const char *pattern)
19{
20 return !!strstr(buffer, pattern);
21}
22
23static int get_vendor_id(int ifindex)
24{
25 char ifname[IF_NAMESIZE], path[64], buf[8];
26 ssize_t len;
27 int fd;
28
29 if (!if_indextoname(ifindex, ifname))
30 return -1;
31
32 snprintf(path, sizeof(path), "/sys/class/net/%s/device/vendor", ifname);
33
34 fd = open(path, O_RDONLY);
35 if (fd < 0)
36 return -1;
37
38 len = read(fd, buf, sizeof(buf));
39 close(fd);
40 if (len < 0)
41 return -1;
42 if (len >= (ssize_t)sizeof(buf))
43 return -1;
44 buf[len] = '\0';
45
46 return strtol(buf, NULL, 0);
47}
48
14static int get_kernel_version(void) 49static int get_kernel_version(void)
15{ 50{
16 int version, subversion, patchlevel; 51 int version, subversion, patchlevel;
@@ -177,3 +212,31 @@ bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex)
177 212
178 return fd >= 0; 213 return fd >= 0;
179} 214}
215
216bool bpf_probe_helper(enum bpf_func_id id, enum bpf_prog_type prog_type,
217 __u32 ifindex)
218{
219 struct bpf_insn insns[2] = {
220 BPF_EMIT_CALL(id),
221 BPF_EXIT_INSN()
222 };
223 char buf[4096] = {};
224 bool res;
225
226 probe_load(prog_type, insns, ARRAY_SIZE(insns), buf, sizeof(buf),
227 ifindex);
228 res = !grep(buf, "invalid func ") && !grep(buf, "unknown func ");
229
230 if (ifindex) {
231 switch (get_vendor_id(ifindex)) {
232 case 0x19ee: /* Netronome specific */
233 res = res && !grep(buf, "not supported by FW") &&
234 !grep(buf, "unsupported function id");
235 break;
236 default:
237 break;
238 }
239 }
240
241 return res;
242}